Intereting Posts
Доступ только к главной странице и панели администратора Заголовок сайта и теглайн на странице параметров темы Предупреждение об ошибке: Объявление описания_walker :: start_el после обновления PHP Проблемы с загрузкой Jquery на веб-сайте WordPress Перегрузка плагина WordPress с помощью таблиц tmp Автоматически извлекать новые сообщения и добавлять к текущей странице. Создание короткого кода WordPress удалить термин из пользовательского списка таксономии Сайт WP только показывает Javascript для главной страницы wp_insert_post работает, но сообщение не отображается в списке сообщений администратора или в интерфейсе Определить переменную PHP из отдельного API, если оператор Как показать продукт без цены, как первый в списке при сортировке цены продукта с высокой до низкой? динамическая форма запроса Добавить описание / подсказку на странице администратора плагина Как отображать только выдержку содержимого с пользовательскими типами сообщений?

WordPress популярные сообщения по недельному коду

Я пытаюсь сделать код, который перечисляет популярные сообщения за неделю. До сих пор я был в состоянии создать счетчик veiws и отобразить 4 популярных сообщения. Так что мне все еще нужно сделать этот запрос более точным. Я бы хотел получить миниатюры и ссылки и получить самую популярную из недели.

functions.php

remove_action( 'wp_head', 'adjacent_posts_rel_link_wp_head', 10, 0); function wpb_track_post_views ($post_id) { if ( !is_single() ) return; if ( empty ( $post_id) ) { global $post; $post_id = $post->ID; } wpb_set_post_views($post_id); } add_action( 'wp_head', 'wpb_track_post_views'); function wpb_get_post_views($postID){ $count_key = 'wpb_post_views_count'; $count = get_post_meta($postID, $count_key, true); if($count==''){ delete_post_meta($postID, $count_key); add_post_meta($postID, $count_key, '0'); return "0 View"; } return $count.' Views'; } 

single.php

 wpb_set_post_views(get_the_ID()); <?php echo wpb_get_post_views(get_the_ID()); ?> // show 4 most popular posts <?php $popularpost = new WP_Query( array( 'posts_per_page' => 4, 'meta_key' => 'wpb_post_views_count', 'orderby' => 'meta_value_num', 'order' => 'DESC' ) ); while ( $popularpost->have_posts() ) : $popularpost->the_post(); the_title(); endwhile; ?> 

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

Примечание. Вы сохраняете представления сообщений следующим образом:

 add_post_meta($postID, $count_key, '0'); 

Чтобы иметь возможность захватить «Наиболее просматриваемые в период», вам нужно будет сделать что-то более сложное, возможно, с дополнительной таблицей базы данных. Прямо сейчас у вас нет никакой связи между количеством просмотров и периодом времени.

Например, если вы создали в своей базе следующую таблицу:

{$ prefix} должен использовать префикс таблицы базы данных wordpress (например, wp_)

 CREATE TABLE {$prefix}post_views ( post_id bigint(20) NOT NULL, entry_day datetime NOT NULL, num_views int NOT NULL, PRIMARY KEY (post_id,entry_day), KEY idx_pv_ed (entry_day) ); 

С этой таблицей вы можете отслеживать самые высокие сообщения за определенный период.

Вот пересмотренная версия, написанная как класс с протоколированием, обработкой ошибок и примером использования сценария использования, чтобы показать, что происходит.

Класс обработчика

Нижеприведенный код – это небольшой класс, который включает в себя отладочную информацию, чтобы вы могли видеть, где какие-либо проблемы.

Я посыпал его записками, чтобы объяснить, что происходит

 class My_Most_Viewed_Posts { protected $errors = null; protected $notices = null; protected $debug = false; # This just sets up the errors, notices, and debug variables able function __construct($debug = false) { $this->clear_all(); if ( $debug ) { $this->debug = true; } } # This lets you add notices about what is going on so you can display them later protected function add_notice($msg = '') { if ( is_array($msg) || is_object($msg) ) { $this->notices[] = print_r($msg, true); } else { $this->notices[] = $msg; } } # Get an array of the most viewed posts as an array of the form ( post_id => number_of_views ) # - $oldest_date : should be of the form YYYY-MM-DD # - $newest_date : should be of the form YYYY-MM-DD ( if null is provided, it will default to the current day ) # - $num_to_get : the number of results to return (eg 4 highest by default) function get_highest_posts_in_range( $oldest_date, $newest_date = null, $num_to_get = 4 ) { # Set up our return value $found = array(); # Debug notice noting what was passed in if ( $this->debug ) { $this->add_notice( "Starting get_highest_posts_in_range( '{$oldest_date}', '{$newest_date}', {$num_to_get} )" ); } # Do all real processing in a try / catch block to ensure can log problems instead of just throwing errors try { # Get a handle to the global database connection global $wpdb; # Verify that the provided $oldest_date is 10 characters long if ( 10 !== strlen($oldest_date) ) { throw new Exception("Parameter 1: Must be of the form YYYY-MM-DD", 10001); } else { # Appends time to the oldest date to make any between query include everything on the date $oldest_date .= ' 00:00:00'; } # Initialize the $newest_date variable OR validate that any non null value could be in the right format if ( is_null( $newest_date ) ) { $newest_date = date('Ym-d') . ' 23:59:59'; } else if ( 10 !== strlen( $newest_date ) ) { # Error throw new Exception("Parameter 2: Must be null or in the form YYYY-MM-DD", 10002); } else { # Appends time to make any between query contain everything entered that day $newest_date .= ' 23:59:59'; } # Make sure that the number of records to get is sane $num_to_get = (int) $num_to_get; if ( $num_to_get <= 0 ) { throw new Exception("Parameter 3: Must be a positive integer", 10003); } # Debug message to note the final values of provided variables after validation if ( $this->debug ) { $this->add_notice( "After Validation - Oldest: {$oldest_date}, Newest: {$newest_date}, Number to get: {$num_to_get}" ); } # Build our query # It will return the post_id and number of views (as views_in_period) for the most viewed items in the given date range $query = <<<SQL SELECT post_id, SUM(num_views) as views_in_period FROM {$wpdb->prefix}post_views WHERE entry_day BETWEEN %s AND %s GROUP BY post_id ORDER BY views_in_period DESC LIMIT %d SQL; # Add our variables to the mysql query above safely $query = $wpdb->prepare( $query, $oldest_date, $newest_date, $num_to_get ); # Debug message to note what the final prepared query is if ( $this->debug ) { $this->add_notice( "Prepared Query:<br />{$query}" ); } # Run the query and get the results $results = $wpdb->query( $query ); if ( false === $results ) { $error = $wpdb->last_error; throw new Exception("Bad Database query: {$query}, DB Error: {$error}", 10004); } else if ( 0 < count($results) ) { # There is at least one result. Add a debug message to show what the results are $this->add_notice("Results detected:"); $this->add_notice( $results ); # Cycle through each result and add it to our return value foreach ( $results as $row ) { $found["{$row['post_id']}"] = $row['views']; } } else if ( $this->debug ) { # No results returned, add a notice if in debug mode $this->add_notice("Found no results for query"); } } catch ( Exception $e ) { # Exception detected, add it to the array of errors $this->errors[] = $e; } return $found; } # This adds a new row to the post views table OR updates an existing row's num_views by 1 # The record is automatically added as viewed on the current day function add_post_view( $post_id ) { # Log how we were called if ( $this->debug ) { $this->add_notice("Called add_post_view( {$post_id} )"); } # Initialize our return value $added = 0; try { # Get hold of the database global $wpdb; # Add a new record. If there is a key violation, update the number of views instead. # ( the unique key on the table is on the post_id and entry_day ) $query = <<<SQL INSERT INTO {$wpdb->prefix}post_views ( post_id, entry_day, num_views ) VALUES ( %d, UTC_DATE(), 1 ) ON DUPLICATE KEY UPDATE num_views = num_views + 1 SQL; # Add our variables to the query in a safe manner $query = $wpdb->prepare( $query, $post_id ); # Log the query to be ran so we can look at it if needed if ( $this->debug ) { $this->add_notice("Prepared Query: {$query}"); } # Determine our results $result = $wpdb->query( $query ); if ( false === $result ) { # Error $error = $wpdb->last_error; throw new Exception("Bad Query: {$query}, Database Claims: {$error}", 10001); } else if ( 0 === $result ) { # Should never happen - would be an error as result is numer affected and there should be at least 1 row affected throw new Exception("Bad Query: {$query}, Database claims no records updated!", 10002); } else { # Note how many changes were made (anything over 1 is fine) if ( $this->debug ) { $this->add_notice("Query completed with {$result} results"); } $added = $added + $result; } } catch ( Exception $e ) { # Make note of the exception $this->errors[] = "Exception Ahoy!"; $this->errors[] = $e; } if ( $this->debug ) { $this->add_notice("Leaving add_post_view"); } return $added; } # Get the list of all errors as an array function get_errors() { if ( is_null( $this->errors ) ) { $errors = array(); } else { $errors = $this->errors; } return $errors; } # Get the list of all notices as an array function get_notices() { if ( is_null( $this->notices ) ) { $notices = array(); } else { $notices = $this->notices; } return $notices; } # Clear all errors and notices # Used on initialization and between calls function clear_all() { $this->notices = array(); $this->errors = array(); } } 

Чтобы использовать этот класс, вам нужно будет сделать следующее:

  1. Вариант 1: превратить его в плагин
  2. Вариант 2: превратите его в файл библиотеки (см. Ниже)
  3. Вариант 3: добавьте его в конец вашего файла functions.php тем.
  4. Вариант 4. Добавьте его в начало шаблона, в котором вы хотите его использовать.

Превращение класса в простой файл библиотеки

Если вы хотите использовать это при необходимости, вы можете создать новый файл (например, class-my-most-seen-posts.php) и скопировать код в него с помощью <?php в первой строке файла

Поместите его в свой каталог тем, и затем вы можете вызвать его из следующего шаблона:

 # Load the class file so that the class is made available $found = locate_template('class-my-most-viewed-posts.php', true); if ( empty($found) ) { echo "<p>Failed to locate template class-my-most-viewed-posts.php</p>"; } else { # NOTE - If you copy this into functions.php or into the template (instead of creating its own file): # - copy from the line below to the line further down labeled INLINE DECLARATION METHOD END if ( ! class_exists('My_Most_Viewed_Posts') ) { echo "<p>Failed to find class My_Most_Viewed_Posts</p>"; } else { # Create an instance of the class in debug mode $Popularity = new My_Most_Viewed_Posts( true ); if ( !is_object( $Popularity ) ) { echo "<p>Failed to create My_Most_Viewed_Posts object</p>"; } else { # NOTE - the $post_id here should be the post to add it for! $entries_added = $Popularity->add_post_view( $post_id ); if ( 0 === $entries_added ) { # Failed, show problems. echo "<p>Notices:</p><pre>" . print_r( $Popularity->get_notices(), true ) . "</pre>"; echo "<p>Errors:</p><pre>" . print_r( $Popularity->get_errors(), true ) . "</pre>"; } else { # Clear notices so far $Popularity->clear_all(); # Tell user we are making progress - comment out when done debugging echo "<p>It seems to have worked. Added {$entries_added} record(s).</p>"; echo "<p>Checking counts</p>"; # Get the highest counts now that we have added a record (from the first of the year to tonight at midnight) $highest_counts = $Popularity->get_highest_posts_in_range( '2015-01-01', null, $num_to_get = 4 ); if ( ! is_array($highest_counts) ) { echo "<p>Bad return value for highest posts in range</p>"; echo "<p>Notices:</p><pre>" . print_r( $Popularity->get_notices(), true ) . "</pre>"; echo "<p>Errors:</p><pre>" . print_r( $Popularity->get_errors(), true ) . "</pre>"; } else { # We have some highest counts in the form post_id => views # Get the ids of the posts (see note 2 below) # see: http://php.net/manual/en/function.array-keys.php $wanted_ids = array_keys( $highest_counts ); # Build arguments for [WP_Query] (see note 3 below) # - posts_per_page : -1 means to show them all # - post_type : any will show all but those flagged exclude from search # - post_parent__in will require that the results have keys in the provided array # see http://codex.wordpress.org/Class_Reference/WP_Query $wanted_args = array( 'posts_per_page' => -1, 'post_type' => 'any', 'post_parent__in' => $wanted_ids ); $wanted = new WP_Query( $wanted_args ); if ( $wanted->have_posts() ) { while ( $wanted->have_posts() ) { $most_viewed = $wanted->next_post(); echo "<p>Post Found:</p><pre>" . print_r( $most_viewed, true ) . "</pre>"; } unset( $wanted ); } else { echo "<p>No posts found for wp_query using args:</p><pre>" . print_r( $wanted, true ) . "</pre>"; } } } } } # INLINE DECLARATION METHOD END } 

Очевидно, что код может быть намного короче без всех сообщений отладки, но они должны быть полезны для отслеживания проблемы.

Если вы решите поместить структуру классов в свои темы functions.php или в свой шаблон, скопируйте раздел только между методом INLINE DECLARATION METHOD для запуска кода. (например, вы не используете locate_template)