web-dev-qa-db-ja.com

管理/コンテンツフォームの変更

ノードに 「changed by」を追加した後 次に、各ノードを変更したユーザーをnode_admin_contentフォームに表示する必要があります(admin/content)[著者]列のすぐ横。

node.admin.inc を変更してコードを2行追加するだけで、これを簡単に解決できました。

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

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

もちろん、コアを変更するため、これは適切なソリューションではありません。

だから私はそれからフォームを変更しようとしました:

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

dpmを使用すると、フォームにオプションのノードがあることがわかります。問題は、これがノードをテーブルオプションとしてレンダリングした結果であるということです。元のノードにアクセスできません。また、「変更者」情報を取得するためにノードフェッチクエリを再実行しません。フォームフックでこれを行うと、正しいレイヤーでそれを解決できないと思います。またはそれは?

では、node_admin_contentフォームを変更して、ノードに存在するデータをさらに追加するための良い方法は何ですか?

8
cherouvim

悪いニュースは、コードを検査した後、フォーム変更レイヤーが実際にこれを行う唯一の場所であることです。あなたのアプローチはかなり適切です。

Drupalは、ページの読み込み全体であらゆる種類の静的キャッシュを実装するため、データベースに戻る必要性が最小限に抑えられます。そのため、コンテンツテーブルの変更が煩雑に見える場合がありますが、実際には目立ったパフォーマンスの打撃を受けていません。

次のコード(または類似のコード)が機能するはずです。キャッシュの問題の詳細については、コメントを参照してください。

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));
  }
}

上記のコードは、コンテンツ管理ページに次のような素晴らしい光沢のある新しい列を生成します。

enter image description here

18
Clive

Admin/contentをViewに置き換え、必要なフィールドを追加します。 Admin Views はあなたのためにそれをします。

3
Bojan Zivanovic

少しずれていますが、- この答え は、これをプログラムで行う方法を示しています(たとえば、MY_MODULE.installファイルにモジュールの更新として追加することによって)。

最後の既存のフィールドの前に新しいフィールドを追加する場合は、もう少し作業が必要になります。 $ 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