web-dev-qa-db-fra.com

Comment obtenir le slug de l'image courante dans WP_image_editor?

J'ai écrit des classes et des fonctions pour modifier le chemin des vignettes. J'ai étendu la classe WP_Image_Editor d'origine pour obtenir une structure personnalisée.

Ce que je veux: pour stocker les vignettes dans différents dossiers en fonction de leurs slugs, dans le répertoire de téléchargement. tels que: http://example.com/uploads/medium/image.jpg

Ce que j'ai déjà fait:

class WP_Image_Editor_Custom extends WP_Image_Editor_Gd {
    public function generate_filename($prefix = NULL, $dest_path = NULL, $extension = NULL) {
        global $current_size_slug;
        // If empty, generate a prefix with the parent method get_suffix().
        if(!$prefix)
            $prefix = $this->get_suffix();

        // Determine extension and directory based on file path.
        $info = pathinfo($this->file);
        $dir  = ABSPATH."/media/";
        $ext  = $info['extension'];

        // Determine image name.
        $name = wp_basename($this->file, ".$ext");

        // Allow extension to be changed via method argument.
        $new_ext = strtolower($extension ? $extension : $ext);

        // Default to $_dest_path if method argument is not set or invalid.
        if(!is_null($dest_path) && $_dest_path = realpath($dest_path))
            $dir = $_dest_path;

        // Return our new prefixed filename.
        $slug = $current_size_slug; 
        return trailingslashit($dir)."{$slug}/{$name}.{$new_ext}";
    }
    function multi_resize($sizes) {
        $sizes = parent::multi_resize($sizes);
        foreach($sizes as $slug => $data)
            $sizes[$slug]['file'] = $slug."/".$data['file'];
            $current_size_slug = $slug;
        return $sizes;
    }
}

Lorsque je télécharge l'image, les vignettes sont créées correctement, mais les noms de fichiers ne le sont pas. La valeur $slug n'est pas passée de multi_resize() à generate_filename.

J'ai essayé d'écrire la fonction multi_resize() comme ci-dessous:

class WP_Image_Editor_Custom extends WP_Image_Editor_Gd {
    public function generate_filename($prefix = NULL, $dest_path = NULL, $extension = NULL) {
        global $current_size_slug;
        // If empty, generate a prefix with the parent method get_suffix().
        if(!$prefix)
            $prefix = $this->get_suffix();

        // Determine extension and directory based on file path.
        $info = pathinfo($this->file);
        $dir  = ABSPATH."/media/";
        $ext  = $info['extension'];

        // Determine image name.
        $name = wp_basename($this->file, ".$ext");

        // Allow extension to be changed via method argument.
        $new_ext = strtolower($extension ? $extension : $ext);

        // Default to $_dest_path if method argument is not set or invalid.
        if(!is_null($dest_path) && $_dest_path = realpath($dest_path))
            $dir = $_dest_path;

        // Return our new prefixed filename.
        $slug = $current_size_slug; 
        return trailingslashit($dir)."{$slug}/{$name}.{$new_ext}";
    }
    function multi_resize($sizes) {
        $sizes = parent::multi_resize($sizes);
        foreach($sizes as $slug => $data)
            $sizes[$slug]['file'] = $slug."/".$data['file'];
            $current_size_slug = $slug;
        return $sizes;
    }
}

Maintenant, le $slug est passé à generate_filename() mais les miniatures sont toutes générées dans le dossier uploads, les unes sur les autres. Comment puis-je faire ceci?

Je ne sais pas quoi que ce soit, toute aide est la bienvenue.

1
Jack Johansson

Essayez d'ajouter ceci à functions.php:

add_filter("wp_image_editors", "my_wp_image_editors");

function my_wp_image_editors($editors) {
    array_unshift($editors, "WP_Image_Editor_Custom");
    return $editors;
}

// Include the existing classes first in order to extend them.
require_once ABSPATH . WPINC . "/class-wp-image-editor.php";
require_once ABSPATH . WPINC . "/class-wp-image-editor-Gd.php";

class WP_Image_Editor_Custom extends WP_Image_Editor_Gd {

    public function generate_filename($suffix = null, $dest_path = null, $extension = null) {
        // $suffix will be appended to the destination filename, just before the extension
        if (!$suffix) {
            $suffix = $this->get_suffix();
        }

        $dir = pathinfo($this->file, PATHINFO_DIRNAME);
        $ext = pathinfo($this->file, PATHINFO_EXTENSION);

        $name = wp_basename($this->file, ".$ext");
        $new_ext = strtolower($extension ? $extension : $ext );

        if (!is_null($dest_path) && $_dest_path = realpath($dest_path)) {
            $dir = $_dest_path;
        }
        //we get the dimensions using explode, we could have used the properties of $this->file[height] but the suffix could have been provided
        $size_from_suffix = explode("x", $suffix);
        //we get the slug_name for this dimension
        $slug_name = $this->get_slug_by_size($size_from_suffix[0], $size_from_suffix[1]);

        return trailingslashit($dir) . "{$slug_name}/{$name}.{$new_ext}";
    }

    function multi_resize($sizes) {
        $sizes = parent::multi_resize($sizes);

        //we add the slug to the file path
        foreach ($sizes as $slug => $data) {
            $sizes[$slug]['file'] = $slug . "/" . $data['file'];
        }

        return $sizes;
    }

    function get_slug_by_size($width, $height) {

        // Make thumbnails and other intermediate sizes.
        $_wp_additional_image_sizes = wp_get_additional_image_sizes();

        $image_sizes = array(); //all sizes the default ones and the custom ones in one array
        foreach (get_intermediate_image_sizes() as $s) {
            $image_sizes[$s] = array('width' => '', 'height' => '', 'crop' => false);
            if (isset($_wp_additional_image_sizes[$s]['width'])) {
                // For theme-added sizes
                $image_sizes[$s]['width'] = intval($_wp_additional_image_sizes[$s]['width']);
            } else {
                // For default sizes set in options
                $image_sizes[$s]['width'] = get_option("{$s}_size_w");
            }

            if (isset($_wp_additional_image_sizes[$s]['height'])) {
                // For theme-added sizes
                $image_sizes[$s]['height'] = intval($_wp_additional_image_sizes[$s]['height']);
            } else {
                // For default sizes set in options
                $image_sizes[$s]['height'] = get_option("{$s}_size_h");
            }

            if (isset($_wp_additional_image_sizes[$s]['crop'])) {
                // For theme-added sizes
                $image_sizes[$s]['crop'] = $_wp_additional_image_sizes[$s]['crop'];
            } else {
                // For default sizes set in options
                $image_sizes[$s]['crop'] = get_option("{$s}_crop");
            }
        }
        $slug_name = ""; //the slug name

        if($width >= $height){
          foreach ($image_sizes as $slug => $data) { //we start checking
            if ($data['width'] == $width) {//we use only width because regardless of the height, the width is the one used for resizing in all cases with crop 1 or 0
                $slug_name = $slug;
            }
            /*
             * There could be custom added image sizes that have the same width as one of the defaults so we also use height here
             * if there are several image sizes with the same width all of them will override the previous one leaving the last one, here we get also the last one
             * since is looping the entire list, the height is used as a max value for non-hard cropped sizes
             *  */
              if ($data['width'] == $width && $data['height'] == $height) {
                  $slug_name = $slug;
              }
          }
         }else{
           foreach ($image_sizes as $slug => $data) {
              if ($data['height'] == $height) {
                  $slug_name = $slug;
              }
              if ($data['height'] == $height && $data['width'] == $width ) {
                  $slug_name = $slug;
              }
            }
         }
        return $slug_name;
    }
}

je sais que vous connaissez déjà la quasi-totalité de ce code. Notez que la fonction generate_filename a été mise à jour pour correspondre à celle actuelle. Vous serez plus intéressé par la fonction get_slug_by_size, qui est l'élément clé qui vous manquait. Cela fonctionne également avec des tailles d'image personnalisées, comme on peut le voir ici:

enter image description here

home-bottom est une taille d'image que j'ai ajoutée. À l'heure actuelle, wordpress a 4 tailles d'image par défaut différentes:

    Array
    (
        [thumbnail] => Array // Thumbnail (150 x 150 hard cropped)
            (
                [width] => 150
                [height] => 150
                [crop] => 1
            )

        [medium] => Array // Medium resolution (300 x 300 max height 300px)
            (
                [width] => 300
                [height] => 300
                [crop] => 
            )

        [medium_large] => Array //Medium Large (added in WP 4.4) resolution (768 x 0 infinite height)
            (
                [width] => 768
                [height] => 0
                [crop] => 
            )

        [large] => Array // Large resolution (1024 x 1024 max height 1024px)
            (
                [width] => 1024
                [height] => 1024
                [crop] => 
            )

    )
// Full resolution (original size uploaded) this one is not in the array.

si vous importez une image de width 310 uniquement, des images thumbnail et medium seront créées. WordPress n'en créera pas plus volumineux. Ainsi, avec le code ci-dessus, seuls 2 dossiers seront créés.

2
David Lee

Un exemple de code expliquant son cas d'utilisation sera plus utile. Vous ne savez pas comment vous allez l’utiliser, mais vous pouvez simplement accéder à toutes les limaces à l’intérieur des tailles.

Multi_resize () obtient ses 'tailles' en tant que paramètre, qui lui est fourni par wp_generate_attachment_metadata () ici . Une approche simple pour obtenir le tableau de tailles consiste à le stocker dans une propriété de classe. Tel que

Ajoutez ceci avant toutes les fonctions.

public $current_size_slug = '';

C'est la fonction generate_filename () avec les modifications et les commentaires nécessaires pour vous aider à comprendre comment cela fonctionne:

public function generate_filename( $prefix = null, $dest_path = null, $extension = null ) {
// <-- Now we have the current thumbnail slug.-->
$slug = $this->current_size_slug;
// If empty, generate a prefix with the parent method get_suffix().
if ( ! $prefix ) {
    $prefix = $this->get_suffix();
}

// Determine extension and directory based on file path.
$info = pathinfo( $this->file );
$dir  = $info['dirname'];
$ext  = $info['extension'];

// Determine image name.
$name = wp_basename( $this->file, ".$ext" );

// Allow extension to be changed via method argument.
$new_ext = strtolower( $extension ? $extension : $ext );

// Default to $_dest_path if method argument is not set or invalid.
if ( ! is_null( $dest_path ) && $_dest_path = realpath( $dest_path ) ) {
    $dir = $_dest_path;
}

// Return our new prefixed filename.
// <-- Replaced prefix with slug. -->
return trailingslashit( $dir ) . "{$slug}/{$name}.{$new_ext}"; 

}

Cette fonction multi_resize () qui définit le $ current_size_slug avant d'appeler _save ()

function multi_resize( $sizes ) {
$metadata  = array();
$orig_size = $this->size;

foreach ( $sizes as $size => $size_data ) {
    if ( ! isset( $size_data['width'] ) && ! isset( $size_data['height'] ) ) {
        continue;
    }

    if ( ! isset( $size_data['width'] ) ) {
        $size_data['width'] = null;
    }
    if ( ! isset( $size_data['height'] ) ) {
        $size_data['height'] = null;
    }

    if ( ! isset( $size_data['crop'] ) ) {
        $size_data['crop'] = false;
    }

    $image     = $this->_resize( $size_data['width'], $size_data['height'], $size_data['crop'] );
    $duplicate = ( ( $orig_size['width'] == $size_data['width'] ) && ( $orig_size['height'] == $size_data['height'] ) );

    if ( ! is_wp_error( $image ) && ! $duplicate ) {
        // We set the current slug before calling the save function.
        $this->current_size_slug = $size;

        $resized = $this->_save( $image );

        imagedestroy( $image );

        if ( ! is_wp_error( $resized ) && $resized ) {
            unset( $resized['path'] );
            $metadata[ $size ] = $resized;
        }
    }

    $this->size = $orig_size;
}

return $metadata;
}

La fonction _save () enregistre le fichier sur le serveur. Pour ce faire, elle appelle le generate_filename (). J'espère que cela répond à votre question.
Si vous n'êtes pas à l'aise avec PHP et WordPress , envisagez de faire appel à un développeur pour des travaux personnalisés tels que ceux-ci.
Ne Pas Copiez et collez du code, sauf si vous savez ce que vous faites.

1
devkabiir