Работа с meta полями (custom fields) и картинками в WordPress ускоряемся в 10 раз.

Если ваша тема активно использует механизм мета полей WordPress то это приведет к неизбежным потерям производительности т.к. каждый вызов get_post_meta или get_post_custom может генерировать лишний SQL к базе данных, если данных нет в кеш. Особенно заметно это будет при создании списка категории или главной страницы, когда эти функции вызываются в теле основного цикла.
Чтобы этого избежать можно подключить фильтр posts_results в фильтре мы получим результат последней выборки — массив постов, далее собираем все ID и формируем новый запрос в таблицу postmeta забираем там сразу все meta для всех постов и это будет намного быстрее чем каждый раз дергать выше упомянутые функции.

//  этот фильтр добавляем в function.php
function ads_addImgMeta($posts){
   global $wpdb, $wp_query;
   if(is_admin() or is_page() )   return $posts;
// сохраняем состояние объекта $wp_query и $wpdb
   if(( (), '5.0', '>=' )){
     $wpdb_save = clone($wpdb);
     $wp_query_save = clone($wp_query);
   } else{
     $wpdb_save = $wpdb;
     $wp_query_save = $wp_query;
   }
   $ar_post_id = ();
   foreach ($posts as $key => $post) {
        $ar_post_id[] = $post->ID;
        $ar_link[$post->ID] = & $posts[$key];
   }
   $st_id = @("','", $ar_post_id);
    // складываем получаем общий список
   $st_id = ("','", $ar_post_id);
   $query = "SELECT * FROM $wpdb->postmeta
            WHERE post_id IN ('$st_id') ";
   $meta = $wpdb->get_results($query);
   if(!($meta))return $posts;
   // теперь цепляем meta дане к постам
   $uploads_dir = wp_upload_dir('baseurl');
   foreach ($meta as $row) {
       $meta_value = maybe_unserialize($row->meta_value);
       $ar_link[$row->post_id]->meta[$row->meta_key] = $meta_value;
   }
   // востанавливаем состояние объектов
   ( $wpdb, $wp_query );
   $wpdb  =  & $wpdb_save;
   $wp_query = & $wp_query_save;
   ( $wpdb_save, $wp_query_save );
   return $posts;
}
 
 add_filter('posts_results', 'ads_addImgMeta');

Вот так вот одним махом теперь все мета поля сидят у нас в $post. Используйте в теле основного цикла if ( have_posts() ) : while ( have_posts() ) : the_post(); доступ к вашим полям $post->meta[meta_key]

А вот если мы используем WordPress как CMS, часто возникает задача добавлять картинки к короткому анонсу поста, то есть когда html код тега img надо удалить или надо использовать цитату (http://codex.wordpress.org/Template_Tags/the_excerpt) совмесно с картинкой вот как здесь
В этом случае нужно потратится на еще один SQL и получить сразу все атачменты для сразу всех постов а затем для всех ID получить мета поля. Привожу код:

function AddImgMeta($posts){
// можно исключить категории в которых не надо поулучать meta
   if(is_admin() or is_category('307,3,5,4')) return $posts;
 
   global $wpdb, $wp_query;
// сохраняем состояние объекта $wp_query и $wpdb
   if(( (), '5.0', '>=' )){
     $wpdb_save = clone($wpdb);
     $wp_query_save = clone($wp_query);
   } else{
     $wpdb_save = $wpdb;
     $wp_query_save = $wp_query;
   }
   $ar_post_id = ();
   foreach ($posts as $key => $post) {
        $ar_post_id[] = $post->ID;
        $ar_link[$post->ID] = & $posts[$key];
   }
   $st_id = @("','", $ar_post_id);
   //сначала добываем атачменты
   $query = "SELECT $wpdb->posts.* FROM $wpdb->posts
WHERE  $wpdb->posts.post_parent IN('$st_id')
AND $wpdb->posts.post_parent
   AND $wpdb->posts.post_type = 'attachment'";
 
   $files = $wpdb->get_results($query);
   //  получаем список id атачментов
   $ar_file_id = ();
   foreach ($files as $key=>$file) {
      $ar_file_id[] =  $file->ID;
      $ar_link[$file->ID] = & $files[$key];
   }
   // складываем получаем общий список
   $ar_all_id = @($ar_post_id,$ar_file_id);
   $st_id = ("','", $ar_all_id);
   $query = "SELECT * FROM $wpdb->postmeta WHERE post_id IN ('$st_id') ";
   $meta = $wpdb->get_results($query);
   if(!($meta))return $posts;
   // теперь цепляем meta дане к постам
   $uploads_dir = wp_upload_dir('baseurl');
   foreach ($meta as $row) {
       $meta_value = maybe_unserialize($row->meta_value);
      //'thumbnail' | 'medium' |
      if('_wp_attachment_metadata'==$row->meta_key AND ($meta_value) ){
          $imgUrl =  ($meta_value['file'], '/wp-content');
          if(!$imgUrl){
            $imgUrl = $uploads_dir['baseurl'].'/'. $meta_value['file'];
          }
          $dirname = ($imgUrl);
          $thumbUrl =  $dirname.'/'.$meta_value['sizes']['thumbnail']['file'];
          $mediumUrl =  $dirname.'/'.$meta_value['sizes']['medium']['file'];
          $ar_link[$row->post_id]->imgUrl = $imgUrl;
          $ar_link[$row->post_id]->thumbUrl = $thumbUrl;
          $ar_link[$row->post_id]->mediumUrl = $mediumUrl;
      }
      $ar_link[$row->post_id]->meta[$row->meta_key] = $meta_value;
   }
   //  теперь цепляем атачменты к постам
   foreach ($files as $row) {
       $ar_link[$row->post_parent]->files[$row->menu_order] = $row;
   }
 // востанавливаем состояние объектов
   ( $wpdb, $wp_query );
   $wpdb  =  & $wpdb_save;
   $wp_query = & $wp_query_save;
   ( $wpdb_save, $wp_query_save );
   return $posts;
}
add_filter('posts_results', 'AddImgMeta');

Сначала получаем ID всех постов из массива $posts, делаем первый SELECT для всех постов получаем все атачменты (см. SQL оператор IN) затем получаем ID всех атачментов напомню, что атачменты это такие же посты только без текста и хранятся они в одной таблице. Складываем два массива $ar_all_id = @array_merge($ar_post_id,$ar_file_id); и делаем запрос теперь уже в таблицу postmeta получаем все мета поля.
Надо также сказать, что WP хранит дополнительную информацию о закачанных картинках в тех же самых мета полях глвное нас интересует поля с именем _wp_attachment_metadata здесь хранятся ссылки на две превьюшки маленькую и среднюю которые автоматически нарезаются WP при загрузке изображений.
Мы обработаем эти данные и создадим дополнительно 3 свойства imgUrl thumbUrl mediumUrl которые содержат соответственно полный url на кртинку, url на маленькую превьюшку и url на среднюю картинку.

Чтобы посмотреть, что где лежит распечатайте переменную $post в теле основного цикла  
echo ‘<pre>’; print_r(  $post ); echo ‘</pre>’;
Да ! самое главное не путайте где массив, а где свойство объекта а то получите фатальную ошибку.

Чтобы все разложить по полочкам приведу пример что же мы получим в переменной $post .

stdClass Object
(
    [ID] => 900
    [post_author] => 2
    [post_date] => 2009-03-23 16:06:03
    [post_date_gmt] => 2009-03-23 13:06:03
    [post_content] => Паркетная доска Barlinek это пол высочайшего класса, изготовленный из древесины, не подверженной процессам модификации. Отлично соединяет эстетические качества с легкостью монтажа и обновления. Паркетная доска Барлинек обеспечивает высокую термическую и акустическую изоляцию, имеет большое        [post_title] => Продажа паркетной доски!!!
    [post_category] => 0
    [post_excerpt] => 
    [post_status] => publish
    [comment_status] => closed
    [ping_status] => closed
    [post_password] => 
    [post_name] => prodazha-parketnoj-doski
    [to_ping] => 
    [pinged] => 
    [post_modified] => 2009-03-23 16:06:03
    [post_modified_gmt] => 2009-03-23 13:06:03
    [post_content_filtered] => 
    [post_parent] => 0
    [guid] => http://wtb.od.ua/?p=900
    [menu_order] => 0
    [post_type] => post
    [post_mime_type] => 
    [comment_count] => 0
    [meta] => 
        (
            [ads_location] => 0
            [ads_url] => 
            [ads_phone] => 096-358-94-21 / 093-050-35-43
            [ads_email] => morabend_sin@.ru
            [ads_password] => qwewe
            [ads_basecat] => 6
            [ads_files] => 
                (
                    [0] => 899
                )
 
        )
 
    [files] => 
        (
            [0] => stdClass Object
                (
                    [ID] => 899
                    [post_author] => 0
                    [post_date] => 2009-03-23 16:05:40
                    [post_date_gmt] => 2009-03-23 13:05:40
                    [post_content] => 
                    [post_title] => barlinek4.jpg
                    [post_category] => 0
                    [post_excerpt] => 
                    [post_status] => inherit
                    [comment_status] => open
                    [ping_status] => closed
                    [post_password] => 
                    [post_name] => barlinek4jpg
                    [to_ping] => 
                    [pinged] => 
                    [post_modified] => 2009-03-23 16:05:40
                    [post_modified_gmt] => 2009-03-23 13:05:40
                    [post_content_filtered] => 
                    [post_parent] => 900
                    [guid] => http://wtb.od.ua/wp-content/uploads/2009/03/barlinek4.jpg
                    [menu_order] => 0
                    [post_type] => attachment
                    [post_mime_type] => image/jpeg
                    [comment_count] => 0
                    [meta] => 
                        (
                            [_wp_attached_file] => 2009/03/barlinek4.jpg
                            [_wp_attachment_metadata] => 
                                (
                                    [width] => 274
                                    [height] => 480
                                    [hwstring_small] => height='96' width='54'
                                    [] => 2009/03/barlinek4.jpg
                                    [sizes] => 
                                        (
                                            [thumbnail] => 
                                                (
                                                    [] => barlinek4-150x150.jpg
                                                    [width] => 150
                                                    [height] => 150
                                                )
 
                                            [medium] => 
                                                (
                                                    [] => barlinek4-171x300.jpg
                                                    [width] => 171
                                                    [height] => 300
                                                )
 
                                        )
 
                                    [image_meta] => 
                                        (
                                            [aperture] => 0
                                            [credit] => 
                                            [camera] => 
                                            [caption] => 
                                            [created_timestamp] => 0
                                            [copyright] => 
                                            [focal_length] => 0
                                            [iso] => 0
                                            [shutter_speed] => 0
                                            [title] => 
                                        )
 
                                )
 
                        )
 
                    [imgUrl] => http://wtb.od.ua/wp-content/uploads/2009/03/barlinek4.jpg
                    [thumbUrl] => http://wtb.od.ua/wp-content/uploads/2009/03/barlinek4-150x150.jpg
                    [mediumUrl] => http://wtb.od.ua/wp-content/uploads/2009/03/barlinek4-171x300.jpg
                )
 
        )
 
)

Вывести любое мета поле например ads_email

<?=$post->meta['ads_email']?>

А теперь как вывести первую картинку в шаблоне.

<? if($post->files[0]):?>
   <a href="<?the_permalink()?>"><img src="<?=$post->files[0]->thumbUrl?>" title="<?=$post->files[0]->post_title?>" width="80px" /></a>
<?endif;?>

Здесь есть тонкий момент все атачменты — картинки или другие файлы zip или rar архивы будут сортироваться по времени и все они будут содержатся в массиве $files, поэтому чтобы все правильно отобразилось картинку надо загружать первой.
Ну а теперь выводим все картинки в виде превьюшек со сcылкой на основную картинку.

          <div>
            <?foreach ($post->files as $key=>$value):?>
               <? if(($value->post_mime_type,'image/') === false ) continue;?>
               <a  href="<?=$post->files[$key]->guid;?>">
                   <img class="alignleft" src="<?=$post->files[$key]->thumbUrl?>" />
               </a>
            <?endforeach;?>
          </div>

Цикл выведет все картинки, дополнительно реализованна проверка mime type у файла if(strstr($value->post_mime_type,’image/’) === false ) continue; в данном случае только изображения.

Напомню что все эти конструкции мы применяем внутри основного цикла вашего шаблона темы!
if ( have_posts() ) : while ( have_posts() ) : the_post();

Обсуждение на сайте:

Рубрика:  марта 19, 2009.
/ » » »


Похожие записи:

6 Responses to Работа с meta полями (custom fields) и картинками в WordPress ускоряемся в 10 раз.

  1. Дмитрий says:

    Здравствуйте, не подскажете более подробно как этим пользоваться, у меня из картинки берутся из custom filds вот таким образом:
    <a href=»"><img class=»preview» width=»133″ height=»100″ src=»ID, «preview», true); ?>» />
    Как использовать Ваш код, заранее спасибо!

  2. admin says:

    ну да все правильно на 2 запроса больше, очевидно ваша тема не настолько активно использует мета поля так что нет смысла внедрять этот код

  3. dak says:

    а как вывести полный список городов расположения со ссылками, например в виджете?

  4. admin says:

    Используйте текстовый виджет например

  5. dak says:

    то есть вручную набирать ссылки?

  6. admin says:

    Ну да типа того лично просто сделал отдельный файл и inclode вставил вот и все

Новости

  • Кабмин разрешил вырубать парки под застройку
  • В Украине была проведена проверка всех имеющихся в стране аттракционов
  • Проверка аттракционов на Украине
  • Украина принимает Евро-2012!
  • ЧП в международном аэропорту г. Харькова
  • Украинское образование не пасет задних
  • Новая модернизированная армия Украины
  • Комментарии


    Расширеный поиск +

    Другие статьи

    Объявления

    Мои проекты на WordPress

    , - специализированная доска объявлений по недвижимости на стоимость сборки $300 с установкой.
    городская доска объявлений, основные разделы: недвижимость, транспорт, услуги, работа, куплю-продам. Стоимость сборки $300 с установкой.
    - разработка, поддержка.

    Счетчики