В программировании для 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;
}