web-dev-qa-db-fra.com

Modification du formulaire d'administration / de contenu

Après avoir ajouté un "modifié par" sur les nœuds je dois maintenant afficher l'utilisateur qui a modifié chaque nœud sur le node_admin_content formulaire (à admin/content) juste à côté de la colonne "Auteur".

J'ai réussi à résoudre facilement cela en modifiant node.admin.inc et en ajoutant seulement 2 lignes de code:

...
'changed_by' => t('Changed By'),
...

...
'changed_by' => theme('username', array('account' => user_load($node->changed_by))),
...

Bien sûr, ce n'est pas une bonne solution car cela modifie le noyau.

J'ai donc essayé de modifier le formulaire via:

function hook_form_node_admin_content_alter(&$form, &$form_state, $form_id) { 
  $form['admin']['nodes']['#header']['changed_by'] = t('Changed By');
  // ... ?
}

En utilisant dpm je peux voir que le formulaire a les nœuds dans les options. Le problème est que cela résulte du rendu des nœuds en tant qu'options de table. Je n'ai pas accès aux nœuds d'origine et je ne souhaite pas réexécuter la requête d'extraction de nœud afin d'obtenir les informations "modifiées par". Je suppose que faire cela dans le crochet de formulaire ne le résoudrait pas dans la bonne couche. Ou est-ce?

Alors, quelle est la bonne façon de modifier le node_admin_content formulaire pour ajouter plus de données qui existent sur les nœuds?

8
cherouvim

La mauvaise nouvelle, c'est qu'après avoir inspecté le code, la couche alter form est le seul endroit pour vraiment faire cela; votre approche est à peu près parfaite.

La bonne nouvelle est que, Drupal implémente toutes sortes de mise en cache statique tout au long du chargement de la page, ce qui minimise le besoin de revenir dans la base de données. Ainsi, tout en modifiant la table de contenu peut sembler lourd, vous êtes ne prend pas réellement un coup de performance notable.

Le code suivant (ou similaire) devrait fonctionner; voir les commentaires pour plus d'informations sur le problème de mise en cache:

function MYMODULE_form_node_admin_content_alter(&$form, &$form_state, $form_id) {
  // Load the nodes. This incurrs very little overhead as 
  // "$nodes = node_load_multiple($nids);" has already been run on these
  // nids in node_admin_nodes(). The static cache will be used instead of
  // another db query being invoked
  $nodes = node_load_multiple(array_keys($form['admin']['nodes']['#options']));

  // Grab a list of all user ids that have been responsible for changing the node
  $uids = array();
  foreach ($nodes as $node) {
    $uids[] = $node->changed_by;
  }

  // Filter out duplicates (one user may have been the last to change more than one node)
  $uids = array_unique($uids);

  // Load a list of all involved users in one go. This is about as performant
  // as this is going to get, as you're going to need the user objects one
  // way or the other for the call to theme_username
  $users = user_load_multiple($uids);

  // Add another column to the table header
  $form['admin']['nodes']['#header']['changed_by'] = array('data' => t('Changed by'));

  // Loop through the rows in the table and add the changed by column
  foreach ($form['admin']['nodes']['#options'] as $nid => $row) {
    // Grab the user related to this node.
    $this_user = $users[$nodes[$nid]->changed_by];

    // Add data for the new column
    $form['admin']['nodes']['#options'][$nid]['changed_by'] = theme('username', array('account' => $this_user));
  }
}

Le code ci-dessus produit une nouvelle colonne brillante comme celle-ci sur la page d'administration de contenu:

enter image description here

18
Clive

Remplacez simplement admin/content par une vue, puis ajoutez les champs que vous souhaitez. Vues Admin le fera même pour vous.

3
Bojan Zivanovic

Un peu hors sujet, mais cette réponse montre comment vous pouvez le faire par programme (par exemple en l'ajoutant en tant que mise à jour de module dans le fichier MY_MODULE.install.)

Vous aurez besoin d'un peu plus de travail si vous souhaitez ajouter votre nouveau champ avant le dernier champ existant. Fusionnez-le avant la fin du tableau $ view-> display ['default'] -> display_options ['fields'].

    function MY_MODULE_update_7101(){
        // update the admin/content view, need to do it manually because it's
        // set by admin_views module
        $view_name = 'admin_views_node';
        $view = views_get_view($view_name, TRUE);

        //  add the relationship
        $view->display['default']->display_options['relationships']['uid_1']['id'] = 'uid_1';
        $view->display['default']->display_options['relationships']['uid_1']['table'] = 'node_revision';
        $view->display['default']->display_options['relationships']['uid_1']['field'] = 'uid';
        $view->display['default']->display_options['relationships']['uid_1']['label'] = 'Revision User';
        // new column settings
        $new_column = array(
            'name_1' => array(
                'id' => 'name_1',
                'table' => 'users',
                'field' => 'name',
                'relationship' => 'uid_1',
                'label' => 'Updated By',
            )
        );
        // need to use this because array_splice by itself resets 'name_1' key to '0'
        // see http://php.net/manual/en/function.array-splice.php#56794
        $temp_array = array_splice( $view->display['default']->display_options['fields'] , 0, 7);
        $view->display['default']->display_options['fields'] = array_merge($temp_array , $new_column, $view->display['default']->display_options['fields']);

        views_save_view($view);
    }
0
reedbert