• Ситуация:
    В админке я ввожу данные, по нажатию на кнопку «сохранить» они сохраняются в моей юзерской таблице и должны публиковаться на сайте. И эти данные я хочу выводить в качестве постов в конкретной катеогории, назовем ее «Specific». У меня есть основной файл плагина и файл класса плагина. В файле класса плагина пишу:

    function viewMytableInSite()
       {
            global $wpdb;
    
            $mytable_table_name = $wpdb->prefix . "mytable";
    
            $sql_select = "SELECT * FROM " . $mytable_table_name;
    
            $result = $wpdb->get_results($sql_select, ARRAY_A);
    
            foreach ($result as $mytable_value)
            {
                $content = $mytable_value['full_description']  ;
            }
            return $content;
    }
    
    function add_viewMytableInSite_filter()
    {     
    
           if ( is_category('Specific') )
    
           {
            add_filter('the_content', array($this,'viewMytableInSite'));
    
           }
       }

    И в файле плагина делаю такую запись:
    add_action('wp', array($mytable,'add_viewMytableInSite_filter'));

    $mytable- это указатель на экземпляр класса
    wp — экшн срабатывает, когда выполнен запрос к БД и получены значения необходимых постов, но перед применением тегов для вывода

    Вопрос: это все срабатывает для постов, которые сохранены в стандартной таблице. То есть, если есть категория Test, в которую были вставлены посты стандартным способом, то их содержимое замениться содержимым из моей таблицы. Но если у меня есть пустая категория «Specific» — она так пустой и остается. Можно это как-то решить с помощью фильтров или нет?.

Просмотр 14 ответов — с 1 по 14 (всего 14)
  • Модератор Sergey Biryukov

    (@sergeybiryukov)

    Live and Learn

    Содержимое категории должно формироваться на лету? Теоретически да — стоит попробовать фильтры, использующиеся в get_posts() в query.php: например, posts_join, posts_where и the_posts. Возможно, последнего будет достаточно, чтобы дополнить массив записей данными из таблицы.

    На сколько поняла для использования posts_join, posts_where — ytj,[jlbvf cdzpm c nf,kbwt

    Насколько поняла для использования posts_join, posts_where — необходима связь с таблицей wp_posts, а у меня ее нет. Попробую разобраться с the_posts.

    Ничего не получается. the_posts применяется к результатам запроса к БД, а для posts_join, posts_where — необходима ссылка для подключения к wp_posts. Выходит, если есть собственная таблица, то она должна быть обязательно как-то привязана к wp_posts? Или можно как-то перехватить именно сам момент извлечения данных. Неужели ни у кого не бывает случая, что данные нужно хранить в отдельной таблице, не связанной с wp_posts?

    Модератор Sergey Biryukov

    (@sergeybiryukov)

    Live and Learn

    1. В the_posts можно дополнить результаты запроса своими. Примерно так:

    function add_special_posts($posts) {
    	global $wpdb;
    
    	$mytable_table_name = $wpdb->prefix . "mytable";
    
    	$sql_select = "SELECT * FROM " . $mytable_table_name;
    
            $result = $wpdb->get_results($sql_select, ARRAY_A);
    
            foreach ($result as $mytable_value)
    		$post->post_content = $mytable_value['full_description'];
    		$posts[] = $post;
    	}
    
    	return $posts;
    }
    add_filter('the_posts', 'add_special_posts');

    2. Возможно, есть вариант проще? Например, создать страницу с особым шаблоном для вывода этих данных.

    Спасибо, да это работает если переопределить все стандартные поля $post: $post->ID, $post->post_author, $post->post_date и т.д.

    Но что касается отображения в конкретной категории: то такая запись в основном файле плагина не работает (сама функция add_special_posts — в файле класса):

    if (is_category('Specific')){
        add_filter('the_posts', array(&pointer_to_class,'add_special_posts');
      }

    Выдается ошибка: Trying to get property of non-object in D:\localhost\wp\wp-includes\query.php on line 191. Это ссылка на функцию is_catуgory(), получается я обращаюсь к свойству сущности, которая не является объектом?

    function add_special_posts($posts) {
    	global $wpdb;
    
    	$mytable_table_name = $wpdb->prefix . "mytable";
            if (is_category('Specific'))
            {
    	   $sql_select = "SELECT * FROM " . $mytable_table_name;
    
               $result = $wpdb->get_results($sql_select, ARRAY_A);
    
               foreach ($result as $mytable_value)
               {
    	$post->post_content =   $mytable_value['full_description'];
    		$posts[] = $post;
    	}
            }
    	return $posts;
    }
    
    add_filter('the_posts', 'add_special_posts');

    Удалось решить проблему таким вот способом. Возник другой вопрос, почему то выводится 10 раз содержимое последней записи из таблицы. А должен выводить 10 разных. При этом массив $posts содержит все записи таблицы.

    Все говорит о том, что глобальный $post это ссылка. Вы его обновляете и вставляете в массив, потом снова обновляете и вставляете в массив. Вы меняете и вставляете 10 ссылок на один объект и получаете 10 копий последнего состояния объекта.

    Почему тогда, когда я вывожу массив $posts — он содержит все записи из моей таблицы, а не последнюю, клонированную 10 раз.

    Хм… тогда не ссылка. Может, нужны уникальные идентификаторы? Какой-нибудь ID, не пересекающийся с родными постами WP? Надо смотреть код вывода, а то так гадать можно до второго пришествия…

    Все говорит о том, что глобальный $post это ссылка. Вы его обновляете и вставляете в массив, потом снова обновляете и вставляете в массив. Вы меняете и вставляете 10 ссылок на один объект и получаете 10 копий последнего состояния объекта.

    Я ошиблась с выводом $posts. Скорее всего Вы правы, но я не совсем понимаю, на что ссылается глобальный $post.
    Прочитала в документации следуюющее:

    have_posts() и the_post() являются удобными обертками вокруг глобального объекта $wp_query, в котором происходят все эти действия. $wp_query вызывается в заголовке блога и аргументы запроса передаются к нему через GET и PATH_INFO. Приняв аргументы, $wp_query, строит и выполняет запрос к базе данных, а результаты запроса возвращает в виде массива записей. Этот массив записывается в объект и также возвращается назад в заголовок блога, где он заполняется в глобальный массив $posts (для обратной совместимости со старыми версиями циклов).

    Глобальный $post — это ссылка на одну запись из $posts или нет, и где это можно найти в коде WP? Не могли бы Вы объяснить про $post, пожалуйста.

    $post (опять же, «по идее») это глобальный объект, в котором внутри Цикла находится текущий пост. И ссылаться он может на элемент $posts с поправкой на счетчик цикла. Попробуйте var_dump-нуть его, что ли…

    Вот что получается:

    array(9) {
    [0]=> object(stdClass)#108 (9) {
    [«ID»]=> string(2) «49»
    [«post_author»]=> string(1) «1»
    [«post_date»]=> string(19) «2009-11-24 14:11:14»
    [«post_type»]=> string(4) «post»
    [«post_title»]=> string(11) «portfolio 6»
    [«post_content»]=> string(28) «full description portfolio 6» [«post_status»]=> string(7) «publish»
    [«comment_status»]=> string(4) «open»
    [«ping_status»]=> string(4) «open»
    }
    [1]=> object(stdClass)#108 (9) {
    [«ID»]=> string(2) «49»
    [«post_author»]=> string(1) «1»
    [«post_date»]=> string(19) «2009-11-24 14:11:14»
    [«post_type»]=> string(4) «post»
    [«post_title»]=> string(11) «portfolio 6»
    [«post_content»]=> string(28) «full description portfolio 6» [«post_status»]=> string(7) «publish»
    [«comment_status»]=> string(4) «open»
    [«ping_status»]=> string(4) «open»
    }
    ….
    [8]=> object(stdClass)#108 (9) {
    [«ID»]=> string(2) «49»
    [«post_author»]=> string(1) «1»
    [«post_date»]=> string(19) «2009-11-24 14:11:14»
    [«post_type»]=> string(4) «post»
    [«post_title»]=> string(11) «portfolio 6»
    [«post_content»]=> string(28) «full description portfolio 6» [«post_status»]=> string(7) «publish»
    [«comment_status»]=> string(4) «open»
    [«ping_status»]=> string(4) «open»
    }
    }

    Последняя запись клонированная 9 раз.

    Я использую фильтр the_posts: вот место его применения, то, куда мой массив передается в query.php:

    function &get_posts() {
    global $wpdb, $user_ID;
    …………………..
    if ( !$q[‘suppress_filters’] )
    $this->posts = apply_filters(‘the_posts’, $this->posts);

    update_post_caches($this->posts);

    $this->post_count = count($this->posts);
    if ($this->post_count > 0) {
    $this->post = $this->posts[0];
    }
    return $this->posts;
    }

    Все решилось созданием нового объекта $post в цикле:

    function add_special_posts($posts) {
    global $wpdb;

    $mytable_table_name = $wpdb->prefix . «mytable»;
    if (is_category(‘Specific’))
    {
    $sql_select = «SELECT * FROM » . $mytable_table_name;

    $result = $wpdb->get_results($sql_select, ARRAY_A);

    $posts = array();

    foreach ($result as $mytable_value)
    {
    $post = new stdClass();
    $post->post_content = $mytable_value[‘full_description’];
    $posts[] = $post;
    }
    }
    return $posts;
    }

    add_filter(‘the_posts’, ‘add_special_posts’);

    Спасибо огромное Atrax и SergeyBiryukov. Вы мне очень помогли.

Просмотр 14 ответов — с 1 по 14 (всего 14)
  • Тема «Как использовать фильтры для вывода данных в конкретн» закрыта для новых ответов.