The Absence of an ‘S’ Can Create a Big Mess
Tags: PHP, wordpress, debugging, webdev
Published: 2020-05-25 13:10:04

After deploying one of our sites to production, one of my colleagues wrote to me on Slack:

>    Look at the image at the bottom of the front page. In Test, the image is a rectangle, and in production, it’s square. How can that be? The Production code and images are an exact duplicate of the Test site’s code and images.

![Both images were 280 pixels wide, but the image on the Test server was 220 pixels high, while the image on Production was 280 pixels high](https://dev-to-uploads.s3.amazonaws.com/i/ew897mczf5pn3v0a7vm8.jpeg)
<figcaption>The left side shows the rectangle image on the test site; the right side is the square image on Production. Credit to Rachel Bratt-Tannenbaum for artistically designing the screenshots</figcaption>

Weird. This is a standard WordPress site built with Elementor and using one of the Pojo themes. What on earth could have caused this difference in sizes and proportions?

## First Step — Dev Tools

I started by checking the Dev Tools and found that not only were the sizes different, but **the image source was different**: the image in the test site came from **the year and month folder** in the uploads folder, and the image on production came from **the thumbs folder** in the uploads folder.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/a0yp9crcg6n1n91sfl65.jpeg)
<figcaption>The left side shows the image source on the test site is in the thumbs folder; the right side is the image source on Production, in the year/month folder. Credit to Rachel Bratt-Tannenbaum for artistically designing the screenshots</figcaption>

The colleague who brought this problem to my attention gave me a lead: the CSS class given to the image was `small-thumbnail`. A quick search led her to the `recent_post.php` file in the theme’s `content` folder, and that’s where I started my journey in search of the culprit.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/e08ouy1olamb82wnsp49.jpeg)

## Down the Rabbit Hole

The code that retrieves the image url in `content/recent_post.php` was easy to locate:
    
    $image_url = Pojo_Thumbnails::get_post_thumbnail_url( array( 'width' => '360', 'height' => '360', 'crop' => true, 'placeholder' => true ) ) )


This was my starting point, and from there, I started following the clues. The first clue led me to the `get_post_thumbnail_url` function, which resides in the `\core\helpers\class-pojo-thumbnails.php` theme file:

{% gist https://gist.github.com/leac/9d49c1a3ab9de82f18f44b44a66bf48c %}

The function `get_post_thumbnail_url` calls a few WordPress functions. Those aren’t suspects because I know them, and none of them retrieves a url with the `thumbs` folder in it. The only Pojo theme-specific function that’s called is `get_attachment_image_src`, and that’s where I continued my search.

{% gist https://gist.github.com/leac/5590c0677e996146a8c91d3509c68f2f %}

The `get_attachment_image_src`, like its predecessor `get_post_thumbnail_url`, mainly calls WP functions. Here, the only theme-specific function that’s called is `get_thumb`.

The `get_thumb function` calls the Class’s `init()` function which, in turn, includes the `BFI_Thumb.php` file which reside in the Pojo theme’s `/core/helpers/bfi_thumb` folder. Then the `get_thumb` function calls the `bfi_thumb` function:

{% gist https://gist.github.com/leac/665657166fef3c8d7741839745586c3f %}

Here, the function doesn’t directly call another function but uses the [`call_user_func`](https://www.php.net/manual/en/function.call-user-func.php) PHP function to call the next function dynamically. `call_user_func`'s first parameter is a callback function. In our case, this parameter is an array, in which the first item is a class name, and the second item is the function within that class. While the second item was explicitly defined — the ‘thumb’ function — the class was determined using the `BFI_Class_Factory::getNewestVersion` function, which retrieved the newest version of `BFI_Thumb`. I’ll spare you the intricacies of the Newest Version calculation and tell you that in our installation, the class name is `BFI_Thumb_1_2`.

Thankfully, the `BFI_Thumb_1_2` class resides in the same file, so all that was needed was that I hop over to its `thumb` function.

## Nearing the End

The `thumb` function, in contrast to its predecessors, isn’t a short little 10–20 lines function. This one is a lengthy, detailed ~170 line function, with many conditions and exit-points. On the other hand, it’s very well commented.

Luckily, the line in which the divergence of the Test site from production occurred, was pretty early on:

{% gist https://gist.github.com/leac/ca846dc6327d404cd6b81c9e48c7415d %}

As I debugged the code (shamefully, I used the `echo` function to do the debugging), I got to the point of divergence:
The code in Production entered this condition, and the Test code — didn’t:

    strpos( $url, $upload_url ) !== false

The condition is: Does the image url contain the upload url? In other words — is the image inside this site’s uploads folder?
Now, *__I knew__* that the images on both sites ARE in the upload folder. So why isn’t the condition being met on Test???

I checked the values of `$url` and `$upload_url`:

    $url = https://test-server/site-name/wp-content/uploads/2019/06/בריא1.jpg

    $upload_url = http://test-server/site-name/wp-content/uploads

Do you see the difference in the url?

**The `$url`’s protocol is HTTPS, and the `$upload_url`'s protocol is HTTP!** 

Somewhere, somehow, even though the site uses the https protocol, the upload folder’s definition omitted the `s`. *__That’s__* the reason that the code didn’t enter the condition!

Now all that was left was for me to find where the `$upload_url` is defined. The code states that it’s defined in the `$upload_info[‘baseurl’]` parameter, but where is that parameter set? Hmmm… baseurl. Sounds familiar. Don’t I know that from somewhere? Isn’t that defined in the wp-admin of the site — in Settings -> General?

![site address and WordPress address both started with http](https://dev-to-uploads.s3.amazonaws.com/i/9lyyem1spycagut1pvq5.jpeg)

It is! I fixed the two URLs that set the site address, adding an `s` after the HTTP— and voila! The image on the Test site miraculously became identical to the one on the Production site.

### Why were they a different size and proportion?

Although I didn’t go on to read the rest of the code, I assume that when the image IS in the uploads dir, the code creates a copy and puts it in the thumbs folder and returns that address, and when the image isn’t there — the image’s original address is returned.

## What Have We Learned?

Not only is it important to cross your T’s and dot your I’s, but mind your S’s too!