Das ist eine wirklich coole Idee.
Ich denke nicht, dass Teil 2 in WordPress behandelt werden sollte: Es gibt viele RSS für E-Mail-Anbieter. Sie werden darin viel besser sein als ein Plugin (oder Thema) wahrscheinlich.
ABER wir können RSS-Feeds erstellen.
Schritt eins: Richten Sie eine Klasse ein, um alles zusammenzufassen.
Hier gibt es einige Klassenkonstanten und -variablen - wir werden sie später verwenden. Nur ein Singleton-Muster.
<?php
class Per_User_Feeds
{
// Where we'll store the user cats
const META_KEY = '_per_user_feeds_cats';
// Nonce for the form fields
const NONCE = '_user_user_feeds_nonce';
// Taxonomy to use
const TAX = 'category';
// The query variable for the rewrite
const Q_VAR = 'puf_feed';
// container for the instance of this class
private static $ins = null;
// container for the terms allowed for this plugin
private static $terms = null;
public static function init()
{
add_action('plugins_loaded', array(__CLASS__, 'instance'));
}
public static function instance()
{
is_null(self::$ins) && self::$ins = new self;
return self::$ins;
}
}
Schritt zwei: Fügen Sie den Benutzerprofilseiten ein Feld hinzu (und speichern Sie es).
Sie müssen sich einhaken show_user_profile
und dies edit_user_profile
tun. Spucken Sie eine Nonce, ein Etikett und das Feld aus. show_user_profile
Wird ausgelöst, wenn Benutzer ihr Profil im Administratorbereich anzeigen. edit_user_profile
Wird ausgelöst, wenn das Profil eines anderen Benutzers bearbeitet wird. So wird Ihr Administrator in die Kategorien eines Bearbeitungsbenutzers eingeordnet.
<?php
class Per_User_Feeds
{
// snip snip
protected function __construct()
{
add_action('show_user_profile', array($this, 'field'));
add_action('edit_user_profile', array($this, 'field'));
}
public function field($user)
{
wp_nonce_field(self::NONCE . $user->ID, self::NONCE, false);
echo '<h4>', esc_html__('Feed Categories', 'per-user-feed'), '</h4>';
if($terms = self::get_terms())
{
$val = self::get_user_terms($user->ID);
printf('<select name="%1$s[]" id="%1$s" multiple="multiple">', esc_attr(self::META_KEY));
echo '<option value="">', esc_html__('None', 'per-user-feed'), '</option>';
foreach($terms as $t)
{
printf(
'<option value="%1$s" %3$s>%2$s</option>',
esc_attr($t->term_id),
esc_html($t->name),
in_array($t->term_id, $val) ? 'selected="selected"' : ''
);
}
echo '</select>';
}
}
}
Damit werden auch unsere ersten beiden Hilfsmethoden vorgestellt:
get_user_terms
, ein einfacher Wraper get_user_meta
mit einem Aufruf an apply_filters
- lassen Sie andere Dinge ändern, wenn sie wollen!
get_terms
ein Wrapper get_terms
mit einem Anruf an apply_filters
.
Beides sind nur Annehmlichkeiten. Sie bieten auch Möglichkeiten für andere Plugins / Themes, Dinge einzubinden und zu ändern.
<?php
/**
* Get the categories available for use with this plugin.
*
* @uses get_terms
* @uses apply_filters
* @return array The categories for use
*/
public static function get_terms()
{
if(is_null(self::$terms))
self::$terms = get_terms(self::TAX, array('hide_empty' => false));
return apply_filters('per_user_feeds_terms', self::$terms);
}
/**
* Get the feed terms for a given user.
*
* @param int $user_id The user for which to fetch terms
* @uses get_user_meta
* @uses apply_filters
* @return mixed The array of allowed term IDs or an empty string
*/
public static function get_user_terms($user_id)
{
return apply_filters('per_user_feeds_user_terms',
get_user_meta($user_id, self::META_KEY, true), $user_id);
}
Um die Felder zu speichern, klicken Sie auf personal_options_update
(wird ausgelöst, wenn der Benutzer sein eigenes Profil speichert) und edit_user_profile_update
(wird ausgelöst, wenn das Profil eines anderen Benutzers gespeichert wird).
<?php
class Per_User_Feeds
{
// snip snip
protected function __construct()
{
add_action('show_user_profile', array($this, 'field'));
add_action('edit_user_profile', array($this, 'field'));
add_action('personal_options_update', array($this, 'save'));
add_action('edit_user_profile_update', array($this, 'save'));
}
// snip snip
public function save($user_id)
{
if(
!isset($_POST[self::NONCE]) ||
!wp_verify_nonce($_POST[self::NONCE], self::NONCE . $user_id)
) return;
if(!current_user_can('edit_user', $user_id))
return;
if(!empty($_POST[self::META_KEY]))
{
$allowed = array_map(function($t) {
return $t->term_id;
}, self::get_terms());
// PHP > 5.3: Make sure the items are in our allowed terms.
$res = array_filter(
(array)$_POST[self::META_KEY],
function($i) use ($allowed) {
return in_array($i, $allowed);
}
);
update_user_meta($user_id, self::META_KEY, array_map('absint', $res));
}
else
{
delete_user_meta($user_id, self::META_KEY);
}
}
}
Schritt drei: Geben Sie einen Feed ein
Da es sich um einen benutzerdefinierten Feed handelt, möchten wir keine Autoren-Feeds entführen, um dies zu erreichen (obwohl dies eine Option ist!). Fügen wir stattdessen ein Umschreiben hinzu: yoursite.com/user-feed/{{user_id}}
Rendert den personalisierten Benutzer-Feed.
Um das Umschreiben hinzuzufügen, müssen wir uns einhaken init
und verwenden add_rewrite_rule
. Da dies eine benutzerdefinierte Abfragevariable verwendet, um zu erkennen, wann wir uns in einem personalisierten Benutzer-Feed befinden, müssen wir uns auch in query_vars
unsere benutzerdefinierte Variable einbinden, damit WordPress sie nicht ignoriert.
<?php
class Per_User_Feeds
{
// snip snip
protected function __construct()
{
add_action('show_user_profile', array($this, 'field'));
add_action('edit_user_profile', array($this, 'field'));
add_action('personal_options_update', array($this, 'save'));
add_action('edit_user_profile_update', array($this, 'save'));
add_action('init', array($this, 'rewrite'));
add_filter('query_vars', array($this, 'query_var'));
}
// snip snip
public function rewrite()
{
add_rewrite_rule(
'^user-feed/(\d+)/?$',
'index.php?' . self::Q_VAR . '=$matches[1]',
'top'
);
}
public function query_var($v)
{
$v[] = self::Q_VAR;
return $v;
}
}
Um den Feed tatsächlich zu rendern, werden wir uns anschließen template_redirect
, nach unserer benutzerdefinierten Abfragevariablen suchen (Kaution, wenn wir sie nicht finden) und die globale $wp_query
mit einer personalisierten Version entführen .
Ich habe mich auch daran gewöhnt wp_title_rss
, den RSS-Titel zu ändern, was etwas seltsam war: Er hat die erste Kategorie erfasst und den Feed-Titel so angezeigt, als würde er eine einzelne Kategorie betrachten.
<?php
class Per_User_Feeds
{
// snip snip
protected function __construct()
{
add_action('show_user_profile', array($this, 'field'));
add_action('edit_user_profile', array($this, 'field'));
add_action('personal_options_update', array($this, 'save'));
add_action('edit_user_profile_update', array($this, 'save'));
add_action('init', array($this, 'rewrite'));
add_filter('query_vars', array($this, 'query_var'));
add_action('template_redirect', array($this, 'catch_feed'));
}
// snip snip
public function catch_feed()
{
$user_id = get_query_var(self::Q_VAR);
if(!$user_id)
return;
if($q = self::get_user_query($user_id))
{
global $wp_query;
$wp_query = $q;
// kind of lame: anon function on a filter...
add_filter('wp_title_rss', function($title) use ($user_id) {
$title = ' - ' . __('User Feed', 'per-user-feed');
if($user = get_user_by('id', $user_id))
$title .= ': ' . $user->display_name;
return $title;
});
}
// maybe want to handle the "else" here?
// see do_feed_rss2
load_template( ABSPATH . WPINC . '/feed-rss2.php' );
exit;
}
}
Um den Feed tatsächlich zu rendern, verlassen wir uns darauf wp-includes/feed-rss2.php
. Sie könnten dies durch etwas Benutzerdefinierteres ersetzen, aber warum nicht faul sein?
Hier gibt es auch eine dritte Hilfsmethode : get_user_query
. Dieselbe Idee wie die oben genannten Helfer - abstrahieren Sie einige wiederverwendbare Funktionen und stellen Sie Hooks bereit.
<?php
/**
* Get a WP_Query object for a given user.
*
* @acces public
* @uses WP_Query
* @return object WP_Query
*/
public static function get_user_query($user_id)
{
$terms = self::get_user_terms($user_id);
if(!$terms)
return apply_filters('per_user_feeds_query_args', false, $terms, $user_id);
$args = apply_filters('per_user_feeds_query_args', array(
'tax_query' => array(
array(
'taxonomy' => self::TAX,
'terms' => $terms,
'field' => 'id',
'operator' => 'IN',
),
),
), $terms, $user_id);
return new WP_Query($args);
}
Hier ist alles oben als Plugin . Das Plugin (und anschließend diese Antwort) benötigt aufgrund der Verwendung anonymer Funktionen PHP 5.3+.