web-dev-qa-db-fra.com

Ajouter un nombre de nouveaux messages (post_status = en attente) au menu d'administration

Ce que j'ai: Un type de message personnalisé. Un formulaire de publication frontale qui crée de nouvelles publications avec post_status = pending jusqu'à ce qu'elles soient révisées manuellement et que leur statut soit modifié.

Ce dont j'ai besoin: Bien que je puisse aller à la liste de messages et voir s'il y en a avec "En attente" d'autoriser; Ce que je veux, c’est d’ajouter une icône ronde avec un nombre à l’intérieur, comme ce que fait WordPress lorsqu’il y a de nouveaux commentaires. Je peux écrire le code pour extraire le nombre de messages en attente, mais je ne sais pas comment l'insérer dans le menu admin.

C'est le code créé par wp quand un nouveau commentaire est ajouté:

<span class="awaiting-mod count-6"><span class="pending-count">1</span></span>

Une capture d’écran qui montre un nouveau commentaire, j’ai besoin de la même chose dans Items.

Je cherche une solution à cela depuis un moment et je ne la trouve nulle part; Mon prochain arrêt, si personne ne peut me répondre ici, est de démonter le WP noyau et de voir comment il le fait ici.

2
Ronnieinspain

Normalement, tout ce qui est contenu dans l'argument $labels['menu_name'] de l'enregistrement cpt est imprimé dans le menu. Le bon endroit où placer le nombre span est là mais il y a 2 problèmes:

  1. Vous devez compter de manière dinamonique, vous ne pouvez donc pas simplement écrire le code HTML
  2. Même si vous insérez le code HTML dans l'option ou le code $labels['menu_name'], la plage est supprimée, car avant d'imprimer le menu, la valeur du paramètre est encapsulée dans esc_attr.

Le deuxième "problème" n’est pas un problème réel, c’est la solution!

En fait, la fonction esc_attr déclenche un hook de filtre attribute_escape que nous pouvons utiliser pour calculer le nombre de messages en attente, puis générer le code html non échappé de droite.

Nous devons faire très attention si nous supprimons la fonctionnalité de désinfection de esc_attr car il s’agit d’une fonction utilisée très souvent dans WP et d’une fonction liée à la sécurité. Nous devons donc isoler le comportement uniquement dans le menu administrateur et uniquement dans des cas spécifiques.

De plus, nous pouvons ajouter un filtre une fois que le travail est terminé. Ainsi, il n'est supprimé qu'une seule fois.

Le seul problème maintenant est de savoir quel est le bon élément de menu pour lequel supprimer le filtre et ajouter le nombre.

La seule chance que nous ayons, c’est d’insérer une sorte de espace réservé qui nous permet de reconnaître l’élément de menu. En d'autres termes, lorsque vous enregistrez votre cpt, vous devez ajouter une chaîne uncommon à $labels['menu_name']:

$labels = array(
  /** This do the magic ;) ! */
  'menu_name' => _x('My CPT %%PENDING_COUNT%%', 'My CPT post type label menu_name', 'mytextdomain'),

  'name' => _x('My CPT','My CPT label name','mytextdomain'),
  'singular_name' => _x('My CPT','My CPT label singular_name','mytextdomain'),
  'all_items' => _x('All My CPT','My CPT label all_items','mytextdomain'),
  'add_new' => _x('Add New','My CPT label add_new','mytextdomain'),
  'add_new_item' => _x('Add New My CPT','My CPT label add_new_item','mytextdomain'),
  'edit_item' => _x('Edit My CPT','My CPT label edit_item','mytextdomain'),
  'new_item' => _x('New My CPT','My CPT label new_item','mytextdomain'),
  'view_item' => _x('View My CPT','My CPTlabel view_item','mytextdomain'),
  'search_items' => _x('Search My CPT','My CPT label search_items','mytextdomain'),
  'not_found' => _x('My CPT not found','My CPT label not_found','mytextdomain'),
  'not_found_in_trash' => _x('My CPT not found in trash','My CPT label not_found_in_trash','mytextdomain'),
  'parent_item_colon' => _x('Parent:','My CPT label parent_item_colon','mytextdomain')
);
$args = array(
  'labels' => $labels,
  ... other args here
)
register_post_type( 'my_cpt', $args );

Une fois que le %%PENDING_COUNT%% est ajouté, lorsque le esc_attr est appelé pour une chaîne contenant ce texte, nous exécutons notre travail:

add_action('auth_redirect', 'add_pending_count_filter'); // modify esc_attr on auth_redirect
add_action('admin_menu', 'esc_attr_restore'); // restore on admin_menu (very soon)

function add_pending_count_filter() {
  add_filter('attribute_escape', 'remove_esc_attr_and_count', 20, 2);
}

function esc_attr_restore() {
  remove_filter('attribute_escape', 'remove_esc_attr_and_count', 20, 2);
}

function remove_esc_attr_and_count( $safe_text = '', $text = '' ) {
  if ( substr_count($text, '%%PENDING_COUNT%%') ) {
    $text = trim( str_replace('%%PENDING_COUNT%%', '', $text) );
    // run only once!
    remove_filter('attribute_escape', 'remove_esc_attr_and_count', 20, 2);
    $safe_text = esc_attr($text);
    // remember to set the right cpt name below
    $count = (int)wp_count_posts( 'my_cpt',  'readable' )->pending;
    if ( $count > 0 ) {
      // we have pending, add the count
      $text = esc_attr($text) . '<span class="awaiting-mod count-' . $count . '"><span class="pending-count">' . $count . '</span></span>';
      return $text;
    } 
  }
  return $safe_text;
}

C'est tout et ça marche!

enter image description here

Il n’ya qu’un petit problème: si un article en attente est publié via l’édition rapide , le compte en attente n’est pas mis à jour, car l’édition rapide utilise ajax, et pour mettre à jour le numéro, vous devez utiliser des js. Travaillez-y si vous voulez.

6
gmazzap