Drupal 7.23: 함수 drupal_alter() 주석

32310 단어 drupal
  1 /**
  2  * Passes alterable variables to specific hook_TYPE_alter() implementations.
  3  *
  4  * This dispatch function hands off the passed-in variables to type-specific
  5  * hook_TYPE_alter() implementations in modules. It ensures a consistent
  6  * interface for all altering operations.
  7  *
  8  * A maximum of 2 alterable arguments is supported (a third is supported for
  9  * legacy reasons, but should not be used in new code). In case more arguments
 10  * need to be passed and alterable, modules provide additional variables
 11  * assigned by reference in the last $context argument:
 12  * @code
 13  *   $context = array(
 14  *     'alterable' => &$alterable,
 15  *     'unalterable' => $unalterable,
 16  *     'foo' => 'bar',
 17  *   );
 18  *   drupal_alter('mymodule_data', $alterable1, $alterable2, $context);
 19  * @endcode
 20  *
 21  * Note that objects are always passed by reference in PHP5. If it is absolutely
 22  * required that no implementation alters a passed object in $context, then an
 23  * object needs to be cloned:
 24  * @code
 25  *   $context = array(
 26  *     'unalterable_object' => clone $object,
 27  *   );
 28  *   drupal_alter('mymodule_data', $data, $context);
 29  * @endcode
 30  *
 31  * @param $type
 32  *   A string describing the type of the alterable $data. 'form', 'links',
 33  *   'node_content', and so on are several examples. Alternatively can be an
 34  *   array, in which case hook_TYPE_alter() is invoked for each value in the
 35  *   array, ordered first by module, and then for each module, in the order of
 36  *   values in $type. For example, when Form API is using drupal_alter() to
 37  *   execute both hook_form_alter() and hook_form_FORM_ID_alter()
 38  *   implementations, it passes array('form', 'form_' . $form_id) for $type.
 39  * @param $data
 40  *   The variable that will be passed to hook_TYPE_alter() implementations to be
 41  *   altered. The type of this variable depends on the value of the $type
 42  *   argument. For example, when altering a 'form', $data will be a structured
 43  *   array. When altering a 'profile', $data will be an object.
 44  * @param $context1
 45  *   (optional) An additional variable that is passed by reference.
 46  * @param $context2
 47  *   (optional) An additional variable that is passed by reference. If more
 48  *   context needs to be provided to implementations, then this should be an
 49  *   associative array as described above.
 50  * @param $context3
 51  *   (optional) An additional variable that is passed by reference. This
 52  *   parameter is deprecated and will not exist in Drupal 8; consequently, it
 53  *   should not be used for new Drupal 7 code either. It is here only for
 54  *   backwards compatibility with older code that passed additional arguments
 55  *   to drupal_alter().
 56  */
 57 function drupal_alter($type, &$data, &$context1 = NULL, &$context2 = NULL, &$context3 = NULL) {
 58   // Use the advanced drupal_static() pattern, since this is called very often.
 59   static $drupal_static_fast;
 60   if (!isset($drupal_static_fast)) {
 61     $drupal_static_fast['functions'] = &drupal_static(__FUNCTION__);
 62   }
 63   $functions = &$drupal_static_fast['functions'];
 64 
 65   // Most of the time, $type is passed as a string, so for performance,
 66   // normalize it to that. When passed as an array, usually the first item in
 67   // the array is a generic type, and additional items in the array are more
 68   // specific variants of it, as in the case of array('form', 'form_FORM_ID').
 69   if (is_array($type)) {
 70     $cid = implode(',', $type);
 71     $extra_types = $type;
 72     $type = array_shift($extra_types);
 73     // Allow if statements in this function to use the faster isset() rather
 74     // than !empty() both when $type is passed as a string, or as an array with
 75     // one item.
 76     if (empty($extra_types)) {
 77       unset($extra_types);
 78     }
 79   }
 80   else {
 81     $cid = $type;
 82   }
 83 
 84   // Some alter hooks are invoked many times per page request, so statically
 85   // cache the list of functions to call, and on subsequent calls, iterate
 86   // through them quickly.
 87   if (!isset($functions[$cid])) {
 88     $functions[$cid] = array();
 89     $hook = $type . '_alter';
 90     $modules = module_implements($hook);
 91     if (!isset($extra_types)) {
 92       // For the more common case of a single hook, we do not need to call
 93       // function_exists(), since module_implements() returns only modules with
 94       // implementations.
 95       foreach ($modules as $module) {
 96         $functions[$cid][] = $module . '_' . $hook;
 97       }
 98     }
 99     else {
100       // For multiple hooks, we need $modules to contain every module that
101       // implements at least one of them.
102       $extra_modules = array();
103       foreach ($extra_types as $extra_type) {
104         $extra_modules = array_merge($extra_modules, module_implements($extra_type . '_alter'));
105       }
106       // If any modules implement one of the extra hooks that do not implement
107       // the primary hook, we need to add them to the $modules array in their
108       // appropriate order. module_implements() can only return ordered
109       // implementations of a single hook. To get the ordered implementations
110       // of multiple hooks, we mimic the module_implements() logic of first
111       // ordering by module_list(), and then calling
112       // drupal_alter('module_implements').
113       if (array_diff($extra_modules, $modules)) {
114         // Merge the arrays and order by module_list().
115         $modules = array_intersect(module_list(), array_merge($modules, $extra_modules));
116         // Since module_implements() already took care of loading the necessary
117         // include files, we can safely pass FALSE for the array values.
118         $implementations = array_fill_keys($modules, FALSE);
119         // Let modules adjust the order solely based on the primary hook. This
120         // ensures the same module order regardless of whether this if block
121         // runs. Calling drupal_alter() recursively in this way does not result
122         // in an infinite loop, because this call is for a single $type, so we
123         // won't end up in this code block again.
124         drupal_alter('module_implements', $implementations, $hook);
125         $modules = array_keys($implementations);
126       }
127       foreach ($modules as $module) {
128         // Since $modules is a merged array, for any given module, we do not
129         // know whether it has any particular implementation, so we need a
130         // function_exists().
131         $function = $module . '_' . $hook;
132         if (function_exists($function)) {
133           $functions[$cid][] = $function;
134         }
135         foreach ($extra_types as $extra_type) {
136           $function = $module . '_' . $extra_type . '_alter';
137           if (function_exists($function)) {
138             $functions[$cid][] = $function;
139           }
140         }
141       }
142     }
143     // Allow the theme to alter variables after the theme system has been
144     // initialized.
145     global $theme, $base_theme_info;
146     if (isset($theme)) {
147       $theme_keys = array();
148       foreach ($base_theme_info as $base) {
149         $theme_keys[] = $base->name;
150       }
151       $theme_keys[] = $theme;
152       foreach ($theme_keys as $theme_key) {
153         $function = $theme_key . '_' . $hook;
154         if (function_exists($function)) {
155           $functions[$cid][] = $function;
156         }
157         if (isset($extra_types)) {
158           foreach ($extra_types as $extra_type) {
159             $function = $theme_key . '_' . $extra_type . '_alter';
160             if (function_exists($function)) {
161               $functions[$cid][] = $function;
162             }
163           }
164         }
165       }
166     }
167   }
168 
169   foreach ($functions[$cid] as $function) {
170     $function($data, $context1, $context2, $context3);
171   }
172 }

 
drupal_alter () 함수는 갈고리 시스템에 대한 호출을 제공하여 시스템 변수에 대한 사용자 정의 수정을 실현합니다.예를 들어 시스템이 유지보수 상태에 있을 때 사이트는 관리자만 접근할 수 있도록 해야 한다. 일반 방문자들은'시스템이 유지보수 상태에 있다'는 알림 정보만 볼 수 있다.일반 방문자가 사이트를 방문할 때 유지보수 상태를 변경하기 전에 사이트에 로그인하면user 모듈은 갈고리를 제공하여 방문자의 자동 로그아웃을 실현한다.
// menu.inc 501-508 
$site_status = variable_get('maintenance_mode') ? MENU_SITE_OFFLINE : MENU_SITE_ONLINE;
drupal_alter('menu_site_status', $site_status , $_GET['q']);

drupal_alter()는 hook_와 같이 호출됩니다TYPE_alter 같은 갈고리, 이 예에서user 모듈의user_menu_site_status_alter () 함수:
// user.module 1834-1874 
function user_menu_site_status_alter(&$menu_site_status, $path) {
  if ($menu_site_status == MENU_SITE_OFFLINE) {
    // If the site is offline, log out unprivileged users.
    if (user_is_logged_in() && !user_access('access site in maintenance mode')) {
      module_load_include('pages.inc', 'user', 'user');
      user_logout();
    }

    ... ...
  }

  ...
}

 
57줄: 매개 변수 $data를 주의하십시오. 인용 정의입니다. 주소로 이해할 수도 있습니다.다시 한 번 user_menu_site_status_alter () 갈고리의 매개 변수, 여기 $menu_site_status도 인용 정의입니다. $data와 맞습니다.즉, user_menu_site_status_alter()에서 $menu_ 수정site_status의 값, 즉 $data의 값을 수정하는 것입니다.이를테면 drupal_alter () 는 세 개의context 매개 변수를 정의하고 모두 인용하여 정의합니다.따라서 갈고리 함수에서 필요하면 이 세 context 매개 변수의 값을 수정할 수 있습니다.
function hook_menu_site_status_alter(&$menu_site_status, &$context1, &$context2, &$context3) {
  $context1 = 'new value';
  ... ...
}

 
143-144행:drupal_alter () 가 호출되었을 때, theme 시스템은 준비가 되었을 수도 있고, 아직 준비가 되지 않았을 수도 있습니다.전역 변수 $theme를 통해 theme 시스템의 준비 여부를 판단할 수 있습니다.
global $theme;
if (isset($theme)) {
  // theme 
} else {
  // theme 
}

 
module에서 갈고리 (예: module_TYPE_alter) 를 사용하여 변수 값을 수정할 수 있는 것 외에 theme도 갈고리 (형식: theme_TYPE_alter) 를 사용하여 변수 값을 수정할 수 있습니다.따라서drupal은 모듈과 테마의 이름을 유일하게 요구해야 합니다.

좋은 웹페이지 즐겨찾기