Large image does not get smushed (made smaller)

Hey everyone,

It is a long time that I’ve posted something about PHP. And I did not really know if I should place this on the Wordpress category or the PHP one. Anyway.

I am writing a service package (it’s like a plugin) for an opensource project that is smushing images using the re-smush API. And it seems to smush the thumbnail, medium_large, medium sized images.

The problem I am facing is that it won’t smush (optimize) the Large images during the
wp_generate_attachment_metadata filter. (the other images seem to work fine).

First I wanted to use the wp_handle_upload to hook into the original image. But after some thinking, it seems like a bad idea to change the original image.

when I trigger this function $this->smushDemention($image, $key, 'large'); The $image["sizes"][$size]["file"] does not return anything.

<?php

namespace OffbeatWP\ReSmush;

use OffbeatWP\Services\AbstractService;
use OffbeatWP\ReSmush\Helpers\SmushImage;
use OffbeatWP\Contracts\SiteSettings;

class Service extends AbstractService
{

    protected $settings;

    public function register(SiteSettings $settings)
    {
        // --------------------- Add settings page ---------------------

        $settings->addPage(AddSettings::class);

        // --------------------- WP Filters ---------------------

        //        add_filter('wp_handle_upload', [$this, 'handleUpload'], 10, 2);

        if (setting('re_smush_enabled_thumbnails') == true) {
            add_filter('wp_generate_attachment_metadata', [$this, 'handleThumbnails'], 10, 2);
        }

        // --------------------- Set default quality ---------------------

        if (setting('re_smush_image_quality') != null && setting('re_smush_image_quality') != '') {
            $this->defaultQuality = setting('re_smush_image_quality');
        } else {
            $this->defaultQuality = 90;
        }
    }

    public function handleUpload($image)
    {
        $apiCall = new SmushImage($image['type'], $image['file']);
        $apiCall->setQuality($this->defaultQuality);
        $apiCall->execute();

        return $image;
    }

    public function handleThumbnails($image, $key)
    {
        $this->smushDemention($image, $key, 'thumbnail');
        $this->smushDemention($image, $key, 'medium_large');
        $this->smushDemention($image, $key, 'medium');
        $this->smushDemention($image, $key, 'large');

        return $image;
    }

    protected function smushDemention($image, $key, $size)
    {
        $apiCall = new SmushImage(get_post_mime_type($key), $this->getFile($image, $size));
        $apiCall->setQuality($this->defaultQuality);
        $apiCall->execute();
    }

    protected function getBasePath($image)
    {
        return substr($image["file"], 0, strrpos($image["file"], '/'));
    }

    protected function getFile($image, $size = 'thumbnail')
    {
        return wp_upload_dir()['basedir'] . '/' . $this->getBasePath($image) . '/' . $image["sizes"][$size]["file"];
    }

}

well smushDemention doesnt return a value . So i’m not sure what you’re expecting to have happened.

I can’t find any documentation for any of the plugins you’re mentioning, so… my answer at this point is ‘Ask the developers on the wordpress plugin page where you got this from.’

Hey @m_hutley firstly thank you for your response, the function is returning nothing, it just makes a call to another function. I added an error in the smushDemention function.
When I make a call using for example $this->smushDemention($image, $key, 'medium'); it is returning the right location of the image.

But not for the large images ($this->smushDemention($image, $key, 'large').

The smushDemention is calling an own written class SmushImage . That is also in the project :slight_smile:. (https://github.com/offbeatwp/re-smush).

the image comes from the wp_generate_attachment_metadata filter. This filter is called when metadata and thumbnails are generated

SmushImage class

<?php

namespace OffbeatWP\ReSmush\Helpers;

use \Exception;

class SmushImage
{

    public function __construct($imageType, $imageFile)
    {
        $this->image->type = $imageType;
        $this->image->file = $imageFile;
        $this->url = 'http://api.resmush.it/?qlty=';
        $this->exif = true;
    }

    public function execute()
    {
        if ($this->hasAllowedType($this->image->type) == true && $this->hasAllowedSize($this->image->file) == true) {
            $request = $this->makeCurlRequest($this->image->file);

            if ($request != false) {
                $this->pullImage($request, $this->image->file);
            }
        }
    }

    public function setExif($exif)
    {
        if ($exif == true) {
            $this->exif = 'true';
        } else {
            $this->exif = 'false';
        }
    }

    public function hasAllowedType($image)
    {
        switch ($image) {
            case "image/jpeg":
                return true;
                break;
            case "image/png":
                return true;
                break;
            case "image/gif":
                return true;
                break;
            default:
                return false;
                break;
        }
    }

    public function hasAllowedSize($image)
    {
        if (filesize($image) < 5242880) {
            return true;
        }

        return false;
    }

    public function setUrl($url)
    {
        $this->url = $url;
    }

    public function setQuality($quality)
    {
        $this->quality = $quality;
    }

    public function pullImage($result, $file)
    {
        $content = file_get_contents($result->dest);
        file_put_contents($file, $content);
    }

    public function makeCurlRequest($file)
    {
        $mime = mime_content_type($file);
        $info = pathinfo($file);
        $name = $info['basename'];
        $output = new \CURLFile($file, $mime, $name);

        $data = [
            "files" => $output,
        ];

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $this->url . $this->quality . '&exif=' . $this->exif);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);

        $result = curl_exec($ch);

        if (curl_errno($ch)) {
            error_log(curl_error($ch));

            return false;
        }

        curl_close($ch);

        try {
            $this->hasNoCurlError($result);
        } catch (Exception $e) {
            error_log($e->getMessage());

            return false;
        }

        return json_decode($result);
    }

    public function hasNoCurlError($result)
    {
        $checkError = json_decode($result);
        $this->beforeLog = 'error Log: ';

        if (isset($checkError->error)) {
            switch ($checkError->error) {
                case 301:

                    throw new Exception($this->beforeLog . $checkError->error_long);

                    break;
                case 400:
                    throw new Exception($this->beforeLog . $checkError->error_long);

                    break;
                case 402:
                    throw new Exception($this->beforeLog . $checkError->error_long);

                    break;
                case 403:
                    throw new Exception($this->beforeLog . $checkError->error_long);

                    break;
                case 404:
                    throw new Exception($this->beforeLog . $checkError->error_long);

                    break;
                case 501:
                    throw new Exception($this->beforeLog . $checkError->error_long);

                    break;
                case 502:
                    throw new Exception($this->beforeLog . $checkError->error_long);

                    break;
                case 503:
                    throw new Exception($this->beforeLog . $checkError->error_long);

                    break;
                case 504:
                    throw new Exception($this->beforeLog . $checkError->error_long);

                    break;
            }
        }

        return true;
    }

}

Well I have fixed it. It must be $this->smushDemention($image, $key, 'hero'); . Large images don’t exist is seems to be a hero

1 Like

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.