| [ Index ] |
PHP Cross Reference of Drupal 6 (yi-drupal) |
[Summary view] [Print] [Text view]
1 <?php 2 3 /** 4 * @file 5 * Module builder code processing code. 6 * 7 * Turns downloaded data and shipped templates into data about hooks. 8 */ 9 10 /** 11 * Get stored hook declarations, keyed by hook name, with destination. 12 * 13 * @return 14 * An array of the form: 15 * [hook_action_info] => 16 * 'declaration' => function hook_action_info() 17 * 'destination' => function hook_action_info() 18 */ 19 function module_builder_get_hook_declarations($dir = NULL) { 20 $data = module_builder_get_hook_data($dir); 21 22 foreach ($data as $group => $hooks) { 23 foreach ($hooks as $key => $hook) { 24 $return[$hook['name']] = array( 25 'declaration' => $hook['definition'], 26 'destination' => $hook['destination'], 27 ); 28 } 29 } 30 31 return $return; 32 } 33 34 /** 35 * Get just hook declarations, keyed by hook name. 36 * 37 * @return 38 * An array of the form: 39 * [hook_action_info] => function hook_action_info() 40 */ 41 function module_builder_get_hook_declarations_plain($dir = NULL) { 42 $data = module_builder_get_hook_data($dir); 43 44 foreach ($data as $group => $hooks) { 45 foreach ($hooks as $key => $hook) { 46 $return[$hook['name']] = $hook['definition']; 47 } 48 } 49 50 return $return; 51 } 52 53 /** 54 * Get just hook names. 55 * 56 * @param $short 57 * Whether to return hook names as just 'init' or 'hook_init'. 58 * Might as well call like this: module_builder_get_hook_names('short') for clarity. 59 * @return 60 * A flat array of strings. 61 */ 62 function module_builder_get_hook_names($dir = NULL, $short = FALSE) { 63 $data = module_builder_get_hook_data_flat($dir); 64 $names = array_keys($data); 65 66 if ($short) { 67 foreach ($names as $key => $hook_name) { 68 $names[$key] = str_replace('hook_', '', $hook_name); 69 } 70 } 71 72 return $names; 73 } 74 75 76 /** 77 * Helper for API functions that don't care about file grouping. 78 */ 79 function module_builder_get_hook_data_flat($dir = NULL) { 80 $data = module_builder_get_hook_data($dir); 81 82 foreach ($data as $group => $hooks) { 83 foreach ($hooks as $key => $hook) { 84 $return[$hook['name']] = $hook; 85 } 86 } 87 return $return; 88 } 89 90 /** 91 * Retrieve hook data from storage file. 92 */ 93 function module_builder_get_hook_data($directory = NULL) { 94 if (!isset($directory)) { 95 //$directory = file_create_path(variable_get('module_builder_hooks_directory', 'hooks')); 96 $directory = _module_builder_get_hooks_directory(); 97 } 98 99 $hooks_file = "$directory/hooks_processed.php"; 100 if (file_exists($hooks_file)) { 101 return unserialize(file_get_contents($hooks_file)); 102 } 103 } 104 105 /** 106 * Get the timestamp of the processed file. 107 */ 108 function module_builder_get_hook_data_last_updated($directory = NULL) { 109 if (!isset($directory)) { 110 $directory = _module_builder_get_hooks_directory(); 111 } 112 $hooks_file = "$directory/hooks_processed.php"; 113 if (file_exists($hooks_file)) { 114 $timestamp = filemtime($hooks_file); 115 return format_date($timestamp, 'large'); 116 } 117 } 118 119 /** 120 * Builds complete hook data array from downloaded files and stores in a file. 121 * 122 * @param hook_file_data 123 * An array of data about the files to process, keyed by (safe) filename: 124 [MODULE.FILENAME] => Array // eg system.core.php 125 [path] => full path to the file 126 [destination] => %module.module 127 [group] => GROUP // eg core 128 [hook_destinations] => array(%module.foo => hook_foo, etc) 129 * This is the same format as returned by update.inc. 130 * @return 131 * An array keyed by originating file of the following form: 132 * [GROUP] => array( // grouping for UI. 133 [{i}] => array( 134 [name] => hook_foo 135 [definition] => function hook_foo($node, $teaser = FALSE, $page = FALSE) 136 [description] => Description. 137 [destination] => Destination module file for hook code from this file. 138 */ 139 function module_builder_process_hook_data($hook_file_data) { 140 /* 141 // Get list of hook documentation files 142 $files = module_builder_get_doc_files($directory); 143 if (!isset($files)) { 144 return NULL; 145 } 146 */ 147 148 //print_r($hook_file_data); 149 150 // check file_exists? 151 152 // Build list of hooks 153 $hook_groups = array(); 154 foreach ($hook_file_data as $file => $file_data) { 155 $hook_data_raw = _module_builder_process_hook_file($file_data['path']); 156 157 $file_name = basename($file, '.php'); 158 $group = $file_data['group']; 159 160 // Create an array in the form of: 161 // array( 162 // 'filename' => array( 163 // array('hook' => 'hook_foo', 'description' => 'hook_foo description'), 164 // ... 165 // ), 166 // ... 167 // ); 168 foreach ($hook_data_raw['names'] as $key => $hook) { 169 // The destination is possibly specified per-hook; if not, then given 170 // for the whole file. 171 if (isset($file_data['hook_destinations'][$hook])) { 172 $destination = $file_data['hook_destinations'][$hook]; 173 } 174 else { 175 $destination = $file_data['destination']; 176 } 177 178 $hook_groups[$group][$key] = array( 179 'name' => $hook, 180 'definition' => $hook_data_raw['definitions'][$key], 181 'description' => $hook_data_raw['descriptions'][$key], 182 'destination' => $destination, 183 ); 184 //dsm($hook_groups); 185 186 } // foreach hook_data 187 } // foreach files 188 189 //dsm($hook_groups); 190 //print_r($hook_groups); 191 192 // Write the processed data to a file. 193 $directory = _module_builder_get_hooks_directory(); 194 file_put_contents("$directory/hooks_processed.php", serialize($hook_groups)); 195 196 return $hook_groups; 197 } 198 199 /** 200 * Retrieve list of documentation files containing hook definitions. 201 * 202 * @return array 203 * Array of files 204 */ 205 function module_builder_get_doc_files() { 206 $dir = _module_builder_get_hooks_directory(); 207 208 if (!$dir) { 209 drupal_set_message(t('Please configure the hook documentation path in <a href="!settings">module builder settings</a>.', array('!settings' => url('admin/settings/module_builder'))), 'error'); 210 return NULL; 211 } 212 213 $files = array(); 214 215 if (is_dir($dir)) { 216 if ($dh = opendir($dir)) { 217 while (($file = readdir($dh)) !== FALSE) { 218 // Ignore files that don't make sense to include 219 // TODO: replace all the .foo with one of the arcane PHP string checking functions 220 if (!in_array($file, array('.', '..', '.DS_Store', 'CVS', 'hooks_processed.php'))) { 221 $files[] = $file; 222 } 223 } 224 closedir($dh); 225 } 226 else { 227 drupal_set_message(t('There was an error opening the hook documentation path. Please try again.'), 'error'); 228 return NULL; 229 } 230 } 231 else { 232 drupal_set_message(t('Hook documentation path is invalid. Please return to the <a href="!settings">module builder settings</a> page to try again.', array('!settings' => url('admin/settings/module_builder'))), 'error'); 233 return NULL; 234 } 235 236 return $files; 237 } 238 239 /** 240 * Extracts raw hook data from downloaded hook documentation files. 241 * 242 * @param string $path 243 * Path to hook file 244 * @param string $file 245 * Name of hook file 246 * @return array 247 * Array of hook data: 248 * [0]: Each hook's user-friendly description 249 * [1]: Each hook's entire function declaration: "function name($params)" 250 * [2]: Name of each hook 251 */ 252 function _module_builder_process_hook_file($filepath) { 253 254 $contents = file_get_contents("$filepath"); 255 256 // The pattern for extracting function data: capture first line of doc, 257 // function declaration, and hook name. 258 $pattern = '[ 259 / \* \* \n # start phpdoc 260 \ \* \ ( .* ) \n # first line of phpdoc: capture the text 261 (?: \ \* .* \n )* # lines of phpdoc 262 \ \* / \n # end phpdoc 263 ( function \ ( hook_\w* ) .* ) \ { # function declaration: capture both entire declaration and name 264 ]mx'; 265 266 preg_match_all($pattern, $contents, $matches); 267 268 // We don't care about the full matches. 269 //array_shift($matches); 270 271 $data = array( 272 'descriptions' => $matches[1], 273 'definitions' => $matches[2], 274 'names' => $matches[3], 275 ); 276 277 return $data; 278 } 279 280 /** 281 * Parse a module_builder template file. 282 * 283 * Template files are composed of several sections in the form of: 284 * 285 * == START [title of template section] == 286 * [the body of the template section] 287 * == END == 288 * 289 * @param string $file 290 * The template file to parse 291 * @return Array 292 * Return array keyed by hook name, whose values are of the form: 293 * array('template' => TEMPLATE BODY) 294 */ 295 function module_builder_parse_template($file) { 296 $data = array(); 297 298 // Captures a template name and body from a template file. 299 $pattern = '#== START (.*?) ==(.*?)== END ==#ms'; 300 preg_match_all($pattern, $file, $matches); 301 $count = count($matches[0]); 302 for ($i = 0; $i < $count; $i++) { 303 $data[$matches[1][$i]] = array( 304 #'title' => $matches[1][$i], 305 'template' => $matches[2][$i] 306 ); 307 /* 308 $hook_custom_declarations[] = array( 309 'title' => $matches[1][$i], 310 'data' => $matches[2][$i] 311 ); 312 */ 313 } 314 return $data; 315 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Mon Jul 9 18:01:44 2012 | Cross-referenced by PHPXref 0.7 |