Блог Михаила Крамера. PHP и JS

Установка миниатюр для постов, создаваемых через PHP

В программировании для WordPress иногда сталкиваешься с ситуациями, когда необходимо добавлять посты из PHP-кода. Обычно такое случается, если вы не хотите, по каким-то причинам, показывать пользователю админку, China но хотите, чтоб он мог добавлять материалы. Или, как было в моём случае, когда вы используете  пользовательские типы записей, и опять же, пользователь сайта должен иметь возможность добавлять новые записи.

В моей задаче к таким постам нужна была ещё миниатюра. Немного покопавшись в буржуйнете, я нашёл неплохое решение:

$upload_dir = wp_upload_dir();
$filetype = wp_check_filetype($photo_url);
    $args = array(
            'post_mime_type' => $filetype['type'],
            'post_title'     => esc_attr( $photo_title ), // you may want something different here
            'post_content'   => '',
            'post_status'    => 'inherit'
        );

    // Вставляем новый аттач к посту - для нашей будущей миниатюрки
    $thumb_id = wp_insert_attachment($args, $photo_url,  $new_post_id);

    require_once(ABSPATH . 'wp-admin/includes/image.php');

    $metadata = wp_generate_attachment_metadata( $thumb_id, $photo_url ); // Генерация метаданных для картинки
    $metadata["sizes"] = generate_all_sizes($upload_dir, basename($photo_url)); // По поводу этой строчки - см. ниже в статье
    wp_update_attachment_metadata( $thumb_id, $metadata ); 
    set_post_thumbnail($new_post_id, $thumb_id);

Правда, радовался я не долго. Оказалось, что именно у меня вызов wp_generate_attachment_metadata(), которая среди прочего генерирует уменьшенные версии картинки, приводил к тому, что содержимое уменьшенных картинок выкидывалось в браузер, вместо того, чтобы сохраняться в файл. Я нашёл описание такой же проблемы в интеренете, но там, к сожалению, не было решения. Покопавшись в исходниках WordPress, я понял, что в одной из функций не срабатывает функция PHP ob_start(), по неизвестной науке причине.

В общем, побившись с этим приличное время, я решил просто самостоятельно сгенерировать картинки всех размеров. Частично код взят прямо из WordPress:

 
function generate_all_sizes($dir, $fname) {
    $ext = substr($fname, strrpos($fname, '.')+1);
    $name = substr($fname, 1, strrpos($fname, '.')-1);
    $result = array();
    $size = getimagesize($dir["path"] . "/$fname");
    switch ($size[2]) {
        case IMAGETYPE_JPEG:
            $image = imagecreatefromjpeg($dir["path"] . "/$fname");
            break;
         case IMAGETYPE_PNG:
            $image = imagecreatefrompng($dir["path"] . "/$fname");
            break;
    }
    global $_wp_additional_image_sizes;

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

    foreach ($sizes as $sname=>$s) {
        $new_image = imagecreatetruecolor($s["width"], $s["height"]);
        imagecopyresampled($new_image, $image, 0, 0, 0, 0, $s["width"], $s["height"], $size[0], $size[1]);

        $new_image_fname = "$name-$s[width]x$s[height].$ext";

        switch ($size[2]) {
            case IMAGETYPE_JPEG:
                imagejpeg($new_image, $dir["path"] . "/$new_image_fname", 100);
                break;
            case IMAGETYPE_PNG:
                imagepng($new_image, $dir["path"] . "/$new_image_fname");
                break;
        }

        $result[$sname] = array ("file"=>$new_image_fname, "width"=>$s["width"], "height"=>$s["height"], "mime-type"=>$size["mime"]);
        imagedestroy($new_image);
    }
    return $result;
}

Ну и осталось теперь отключить именно для нашей страницы генерацию маленьких картинок функцией wordpress. Для этого нужно использовать хук intermediate_image_sizes_advanced:

add_filter("intermediate_image_sizes_advanced", "int_sizes");

function int_sizes() {
    if (is_page(68)) // У меня форма, для которой я это всё пишу, стоит на странице 68
        return null;
}
Ваш комментарий
Комментарии