mbtNewsFeed插件欢迎任何反馈!
Edit
我们讨论了OOP和代码设计,所以现在有了一个符合社区需求的版本。相同的原理,相同的结果,但基于功能的设计–感谢Pieter Goosen和Mark Kaplen的反馈
逐步:感谢@toscho的概念设计
让我们试着总结一下。我们需要一个按钮来取消/跟踪用户
function mbt_news_feed_button($user_id, $follow=true) {
$class = \'unfollow\';
$label = __(\'Unfollow\',\'newsfeed\');
if (true === $follow) {
$class = \'follow\';
$label = __(\'Follow\',\'newsfeed\');
}
return "<a href=\'#mbt-news-feed\' class=\'button {$class}\' data-user_id=\'{$user_id}\'>{$label}</a>";
}
我们想要操纵用户的跟随状态。我们创建了两个函数:一个是follow,另一个是unfollow。
function mbt_follow() {
$user_id = self::helper_check_data();
$current_user = wp_get_current_user();
$followers = get_user_meta( $current_user->ID, \'following\', true);
if (!is_array($followers)){
$followers = array();
}
$followers[$user_id] = 1;
update_user_meta( $current_user->ID, \'following\', $followers );
echo self::button($user_id, true);
exit;
}
function mbt_unfollow() {
$user_id = self::helper_check_data();
$current_user = wp_get_current_user();
$followers = get_user_meta( $current_user->ID, \'following\', true);
if (is_array($followers) && !empty($followers)){
unset($followers[$user_id]);
} else {
$followers = array();
}
update_user_meta( $current_user->ID, \'following\', $followers );
echo self::button($user_id, false);
exit;
}
为了帮助我们验证ajax nonce并过滤输入,需要一个helper函数。
function mbt_news_feed_helper_check_data() {
if(!wp_verify_nonce( $_POST[\'_ajax_nonce\'], \'mbtNewsFeed\' )) {
die(-1);
}
if (!array_key_exists(\'user_id\', $_POST)) {
die(-1);
}
$user_id = absint($_POST[\'user_id\']);
if ($user_id < 1) {
die(-1);
}
return $user_id;
}
要检查登录用户当前是否在跟踪所述用户,我们需要另一个功能
function mbt_news_feed_is_following($user_id) {
$followers = get_user_meta( $user_id, \'following\', true);
if (empty($followers)) {
return false;
}
if (array_key_exists($user_id, $followers) && $followers[$user_id]) {
return true;
}
return false;
}
我们喜欢保持整洁,所以我们创建了一个函数,该函数返回该类所有有效AJAX调用的数组
mbt_news_feed_function valid_actions() {
return array(
\'mbt_follow\',
\'mbt_unfollow\',
);
}
我们想让AJAX调用正常工作,所以我们在类外注册我们的操作
if (is_admin()){
foreach (mbt_news_feed_valid_actions() as $action) {
add_action(\'wp_ajax_\'.$action, $action);
}
}
然后,如果通过AJAX请求,我们也要调用这些操作
function mbt_news_feed_init() {
if(in_array($_REQUEST[\'action\'], mbt_news_feed_valid_actions())) {
do_action( \'wp_ajax_\' . $_REQUEST[\'action\'] );
}
}
要使我们创建的按钮正常工作,我们需要一些JS。
jQuery(document).ready(function($) {
$(\'body\').on(\'click\', \'#mbt-news-feed .follow, #mbt-news-feed .unfollow\', function(e) {
e.preventDefault();
var $me = $(this),
action = \'mbt_follow\';
if ($me.hasClass(\'unfollow\')) action = \'mbt_unfollow\';
var data = $.extend(true, $me.data(), {
action: action,
_ajax_nonce: admin_ajax.nonce
});
$.post(admin_ajax.url, data, function(response) {
if(response == \'0\' || response == \'-1\'){
} else {
$($me).parent().empty().html(response);
}
});
});
});
要获取管理AJAX URL和前端的nonce,我们需要排队并本地化脚本,如果尚未加载jQuery,也需要排队。为了节省加载时间,我们将脚本放在页脚中。
function mbt_news_feed_enqueue_scripts() {
if (is_user_logged_in()) {
wp_enqueue_script(\'jquery\');
wp_enqueue_script( \'mbt-news-feed\', plugins_url(\'newsfeed.js\', __FILE__), array(\'jquery\'), NULL, true);
wp_localize_script(\'mbt-news-feed\', \'admin_ajax\', array(
\'url\' => admin_url(\'admin-ajax.php\'),
\'nonce\' => wp_create_nonce(\'mbtNewsFeed\'),
));
wp_enqueue_style( \'mbt-news-feed-css\', plugins_url(\'newsfeed.css\', __FILE__) );
}
}
现在,我们需要在某些页面上显示我们的按钮,(单个帖子/页面模板和作者存档模板)
function mbt_news_feed_wp_footer() {
if (is_user_logged_in()) {
$render_button = false;
$user_id = 0;
if (is_singular()) {
$render_button = true;
$post_id = get_queried_object_id();
$user_id = get_post_field( \'post_author\', $post_id );
}
if (is_author()) {
$render_button = true;
$user_id = get_queried_object_id();
}
if (true === $render_button && $user_id > 0) {
$follow = self::is_following($user_id);
echo "<div id=\'mbt-news-feed\'>";
echo self::button($user_id, !$follow);
echo "</div>";
}
}
}
在添加所有操作之前,我们需要过滤主页上的帖子。如果用户登录并跟踪至少一位其他作者,我们将显示他的个人提要。
static function pre_get_posts($query) {
if (is_user_logged_in()) {
if ( $query->is_main_query() && $query->is_home() && !is_admin()) {
$current_user = wp_get_current_user();
$followers = get_user_meta( $current_user->ID, \'following\', true);
if (is_array($followers) && !empty($followers)) {
$followers = array_keys($followers);
$followers[] = $current_user->ID;
$query->set(\'author__in\', $followers);
}
}
}
return $query;
}
现在添加一些操作以使插件最终工作
add_action( \'init\', \'mbt_news_feed_init\');
add_action( \'wp_enqueue_scripts\', \'mbt_news_feed_enqueue_scripts\');
add_action( \'pre_get_posts\', \'mbt_news_feed_pre_get_posts\');
add_action( \'wp_footer\', \'mbt_news_feed_wp_footer\');
不要忘记CSS来正确显示您的按钮。
文件
newsfeed.php
/**
* mbtNewsFeed for purists
*
* @package mbtNewsFeed
* @author iantsch
* @copyright 2016 mbt.wien
* @license GPL-2.0+
*
* @wordpress-plugin
* Plugin Name: mbtNewsFeed
* Plugin URI: http://wordpress.stackexchange.com/questions/41934/
* Description: If you are logged in and follow some authors, the home feed will only show their posts.
* Version: 1.0.0
* Author: iantsch
* Author URI: http://mbt.wien
* Text Domain: newsfeed
* License: GPL-2.0+
* License URI: http://www.gnu.org/licenses/gpl-2.0.txt
*/
function mbt_news_feed_init() {
if(in_array($_REQUEST[\'action\'], mbt_news_feed_valid_actions())) {
do_action( \'wp_ajax_\' . $_REQUEST[\'action\'] );
}
}
function mbt_news_feed_pre_get_posts($query) {
if (is_user_logged_in()) {
if ( $query->is_main_query() && $query->is_home() && !is_admin()) {
$current_user = wp_get_current_user();
$followers = get_user_meta( $current_user->ID, \'following\', true);
if (is_array($followers) && !empty($followers)) {
$followers = array_keys($followers);
$followers[] = $current_user->ID;
$query->set(\'author__in\', $followers);
}
}
}
return $query;
}
function mbt_news_feed_is_following($user_id) {
$followers = get_user_meta( $user_id, \'following\', true);
if (empty($followers)) {
return false;
}
if (array_key_exists($user_id, $followers) && $followers[$user_id]) {
return true;
}
return false;
}
function mbt_news_feed_helper_check_data() {
if(!wp_verify_nonce( $_POST[\'_ajax_nonce\'], \'mbtNewsFeed\' )) {
die(-1);
}
if (!array_key_exists(\'user_id\', $_POST)) {
die(-1);
}
$user_id = absint($_POST[\'user_id\']);
if ($user_id < 1) {
die(-1);
}
return $user_id;
}
function mbt_follow() {
$user_id = mbt_news_feed_helper_check_data();
$current_user = wp_get_current_user();
$followers = get_user_meta( $current_user->ID, \'following\', true);
if (!is_array($followers)){
$followers = array();
}
$followers[$user_id] = 1;
update_user_meta( $current_user->ID, \'following\', $followers );
echo mbt_news_feed_button($user_id, false);
exit;
}
function mbt_unfollow() {
$user_id = mbt_news_feed_helper_check_data();
$current_user = wp_get_current_user();
$followers = get_user_meta( $current_user->ID, \'following\', true);
if (is_array($followers) && !empty($followers)){
unset($followers[$user_id]);
} else {
$followers = array();
}
update_user_meta( $current_user->ID, \'following\', $followers );
echo mbt_news_feed_button($user_id, true);
exit;
}
function mbt_news_feed_button($user_id, $follow=true) {
$class = \'unfollow\';
$label = __(\'Unfollow\',\'newsfeed\');
if (true === $follow) {
$class = \'follow\';
$label = __(\'Follow\',\'newsfeed\');
}
return "<a href=\'#mbt-news-feed\' class=\'button {$class}\' data-user_id=\'{$user_id}\'>{$label}</a>";
}
function mbt_news_feed_valid_actions() {
return array(
\'mbt_follow\',
\'mbt_unfollow\',
);
}
function mbt_news_feed_enqueue_scripts() {
if (is_user_logged_in()) {
wp_enqueue_script(\'jquery\');
wp_localize_script(\'jquery\', \'admin_ajax\', array(
\'url\' => admin_url(\'admin-ajax.php\'),
\'nonce\' => wp_create_nonce(\'mbtNewsFeed\'),
));
wp_enqueue_script( \'mbt-news-feed\', plugins_url(\'newsfeed.js\', __FILE__), array(\'jquery\'), NULL, true);
wp_enqueue_style( \'mbt-news-feed-css\', plugins_url(\'newsfeed.css\', __FILE__) );
}
}
function mbt_news_feed_wp_footer() {
if (is_user_logged_in()) {
$render_button = false;
$user_id = 0;
if (is_singular()) {
$render_button = true;
$post_id = get_queried_object_id();
$user_id = get_post_field( \'post_author\', $post_id );
}
if (is_author()) {
$render_button = true;
$user_id = get_queried_object_id();
}
if (true === $render_button && $user_id > 0) {
$follow = mbt_news_feed_is_following($user_id);
echo "<div id=\'mbt-news-feed\'>";
echo mbt_news_feed_button($user_id, !$follow);
echo "</div>";
}
}
}
if (is_admin()){
foreach (mbt_news_feed_valid_actions() as $action) {
add_action(\'wp_ajax_\'.$action, $action);
}
}
add_action( \'init\', \'mbt_news_feed_init\');
add_action( \'wp_enqueue_scripts\', \'mbt_news_feed_enqueue_scripts\');
add_action( \'pre_get_posts\', \'mbt_news_feed_pre_get_posts\');
add_action( \'wp_footer\', \'mbt_news_feed_wp_footer\');
newsfeed.js
jQuery(document).ready(function($) {
$(\'body\').on(\'click\', \'#mbt-news-feed .follow, #mbt-news-feed .unfollow\', function(e) {
e.preventDefault();
var $me = $(this),
action = \'mbt_follow\';
if ($me.hasClass(\'unfollow\')) action = \'mbt_unfollow\';
var data = $.extend(true, $me.data(), {
action: action,
_ajax_nonce: admin_ajax.nonce
});
$.post(admin_ajax.url, data, function(response) {
if(response == \'0\' || response == \'-1\'){
} else {
$($me).parent().empty().html(response);
}
});
});
});
newsfeed.css
#mbt-news-feed {
display: block;
position: fixed;
bottom: 20px;
bottom: 3.125vw;
right: 20px;
right: 3.125vw;
}
#mbt-news-feed a.button{
display: block;
border-radius: 2px;
border-radius: 0.625vw;
padding: 5px 10px;
padding: 1.5625vw 3.125vw;
color: #fff;
background-color: #333;
background-color: rgba(51,51,51,.8);
opacity: .5;
}
#mbt-news-feed a.button:hover{
opacity: 1;
}