/[drupal]/contributions/modules/deadwood/deadwood.conversions.inc
ViewVC logotype

Contents of /contributions/modules/deadwood/deadwood.conversions.inc

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.19 - (show annotations) (download) (as text)
Thu Aug 6 20:57:58 2009 UTC (3 months, 3 weeks ago) by solotandem
Branch: MAIN
CVS Tags: DRUPAL-6--1-6, HEAD
Changes since 1.18: +15 -7 lines
File MIME type: text/x-php
Replace messages to screen with writes to a log file; Add .test as a file extension to convert and sort all extensions; Rename 'files' key to to 'deadwood_files' in hook_requirements(); Removing trailing spaces in all files.
1 <?php
2 // $Id: deadwood.conversions.inc,v 1.17 2009/03/28 20:26:56 solotandem Exp $
3
4 /**
5 * @file
6 * Generate version upgrade code from 5.x to 6.x.
7 *
8 * The functions in this file match up with the 80 topics in the roadmap at
9 * http://drupal.org/node/114774. As the topics sometimes overlap, there is
10 * a corresponding redundancy in the functions. The hope for the 7.x version
11 * of this module is that the 7.x roadmap will be written without any
12 * overlap in topics.
13 *
14 * This includes 6 topics in the menu API roadmap at
15 * http://drupal.org/node/103114.
16 *
17 * Copyright 2008 by Jim Berry ("solotandem", http://drupal.org/user/240748)
18 */
19
20 module_load_include('inc', 'deadwood', 'deadwood.formapi');
21 module_load_include('inc', 'deadwood', 'deadwood.schemaapi');
22 module_load_include('inc', 'deadwood', 'deadwood.notifies');
23
24 /**
25 * Convert files in a directory.
26 *
27 * @param string $dirname Module input directory containing the code files to be updated.
28 * @param string $newdirname Module output directory where the converted code files will be written.
29 * @param array $params Keyed array with run-time parameters. Should contain
30 * these keys:
31 * 'extensions' => array() // The file types to convert based on extension
32 * 'conversions' => array() // The conversions to apply
33 * @param boolean $recursive Indicates whether to recurse the subdirectories of $dirname.
34 */
35 function deadwood_convert_dir($dirname, $newdirname, $params = array(), $recursive = TRUE) {
36 // Declare global variables.
37 global $debug;
38 global $_deadwood_filename;
39 static $ignore = array('.', '..', 'CVS', '.svn');
40
41 $debug = TRUE;
42 // Clear the debug log file.
43 if ($debug) {
44 file_put_contents(deadwood_log_path(), '');
45 }
46
47 // Create an output directory we can write to.
48 if (!is_dir($newdirname)) {
49 mkdir($newdirname);
50 }
51 else {
52 deadwood_clean_directory($newdirname);
53 }
54
55 // Extract the file types to convert based on extension.
56 $extensions = array();
57 if (isset($params) && count($params) && array_key_exists('extensions', $params)) {
58 $extensions = $params['extensions'];
59 }
60
61 $dir = opendir($dirname);
62 while ($filename = readdir($dir)) {
63 $_deadwood_filename = $filename;
64 if (!in_array($filename, $ignore)) {
65 if (is_dir($dirname . '/' . $filename)) {
66 $newfilename = $filename;
67 // Handle conversion item #79.
68 if ($filename == 'po') {
69 $newfilename = 'translations';
70 }
71 if ($recursive) {
72 deadwood_convert_dir($dirname . '/' . $filename, $newdirname . '/' . $newfilename, $params, $recursive);
73 }
74 }
75 elseif (in_array(pathinfo($filename, PATHINFO_EXTENSION), $extensions)) {
76 copy($dirname . '/' . $filename, $newdirname . '/' . $filename);
77 deadwood_debug_print('Converting the file => ' . $filename);
78 deadwood_convert_file($newdirname . '/' . $filename, $params);
79 }
80 else {
81 copy($dirname . '/' . $filename, $newdirname . '/' . $filename);
82 }
83 }
84 }
85 }
86
87 /**
88 * Convert a file.
89 *
90 * @param string $filename The name of the file to convert.
91 * @param array $params Keyed array with run-time parameters. Should contain
92 * these keys:
93 * 'extensions' => array() // The file types to convert based on extension
94 * 'conversions' => array() // The conversions to apply
95 */
96 function deadwood_convert_file($filename, $params = array()) {
97 if (!file_exists($filename)) {
98 return FALSE;
99 }
100
101 // Read the file and copy the contents.
102 $cur = file_get_contents($filename);
103 $new = $cur;
104
105 // Extract the conversions to apply.
106 $conversions = array();
107 if (isset($params) && count($params) && array_key_exists('conversions', $params)) {
108 $conversions = $params['conversions'];
109 }
110
111 // Process conversions on file.
112 $is_info_file = pathinfo($filename, PATHINFO_EXTENSION) == 'info';
113 $is_schema_file = pathinfo($filename, PATHINFO_EXTENSION) == 'install';
114 foreach ($conversions as $conversion) {
115 if (function_exists($function = 'deadwood_convert_' . $conversion)) {
116 $is_format_conversion = strpos($conversion, 'format') === 0;
117 $is_info_conversion = strpos($conversion, 'info') === 0;
118 $is_schema_conversion = in_array($conversion, array('hook_schema', 'hook_install', 'hook_uninstall', 'hook_update'));
119 // Only run info changes on info files
120 // Only run install changes on install files
121 if ((!$is_info_file && !$is_info_conversion && !$is_schema_file && !$is_schema_conversion) ||
122 ($is_info_file && $is_info_conversion) ||
123 ($is_schema_file && $is_schema_conversion) ||
124 ($is_format_conversion)) {
125 call_user_func_array($function, array(&$new));
126 }
127 }
128 }
129
130 // Write the new file.
131 if ($new != $cur) {
132 if (file_put_contents($filename, $new) === FALSE) {
133 deadwood_debug_print('File could not be written');
134 }
135 deadwood_debug_print('Replaced the file');
136 }
137 }
138
139 /**
140 * Find the text of a particular function.
141 *
142 * @param string $hook
143 * By default, the suffix of the function name to find.
144 * Example: passing $hook = 'menu' will find a function whose name ends in '_menu'.
145 * When $hook_is_suffix = FALSE, then $hook is the entire function name to find.
146 * @param string $file The file to search.
147 * @param boolean $match_all When TRUE, find all functions with $hook in the name.
148 * @param boolean $hook_is_suffix The $hook is only the suffix of the function name.
149 * @return string The function text.
150 */
151 function deadwood_find_hook($hook, $file, $match_all = FALSE, $hook_is_suffix = TRUE) {
152 // Construct pattern based on function parameters.
153 $prefix = $hook_is_suffix ? '\w+_' : '';
154 $pattern = '/^function\s*';
155 // $pattern .= $hook_is_suffix ? '\w+_' : '';
156 $pattern .= $prefix . $hook . '\s*\(.*?(?=(\/\*\*|^function|\z))/ms';
157
158 if ($match_all) {
159 preg_match_all($pattern, $file, $matches, PREG_PATTERN_ORDER);
160 // This block should be unnecessary with the changes to pattern above.
161 if (!isset($matches[0][0])) {
162 // Check to see if the function name exists.
163 $pattern = '/^function\s*' . $prefix . $hook . '\s*\(/m';
164 preg_match($pattern, $file, $matches);
165 if (!isset($matches[0])) {
166 return array();
167 }
168 // Find last function in file.
169 $pattern = '/^function\s*' . $prefix . $hook . '.*\z/ms';
170 preg_match_all($pattern, $file, $matches, PREG_PATTERN_ORDER);
171 deadwood_debug_print('Primary search failed to find function text for _' . $hook .'. Resorting to secondary pattern to find function.');
172 }
173 return isset($matches[0]) ? $matches[0] : array();
174 }
175 else {
176 preg_match($pattern, $file, $matches);
177 // This block should be unnecessary with the changes to pattern above.
178 if (!isset($matches[0])) {
179 // Check to see if the function name exists.
180 $pattern = '/^function\s*' . $prefix . $hook . '\s*\(/m';
181 preg_match($pattern, $file, $matches);
182 if (!isset($matches[0])) {
183 return '';
184 }
185 // Find last function in file.
186 $pattern = '/^function\s*' . $prefix . $hook . '.*\z/ms';
187 preg_match($pattern, $file, $matches);
188 deadwood_debug_print('Primary search failed to find function text for _' . $hook .'. Resorting to secondary pattern to find function.');
189 }
190 return isset($matches[0]) ? $matches[0] : '';
191 }
192 }
193
194 /**
195 * Loop on from and to arrays, converting the text of the subject string.
196 *
197 * @param string $from The pattern to search for.
198 * @param string $to The string to replace the pattern with.
199 * @param string $subject The string to search and replace.
200 */
201 function deadwood_do_conversions($from, $to, &$subject) {
202 for ($i = 0; $i < count($from); $i++) {
203 $subject = preg_replace($from[$i], $to[$i], $subject);
204 }
205 }
206
207 /**
208 * Save the changes back to the file.
209 *
210 * @param string $cur The string to search for in $file.
211 * @param string $new The replacement string.
212 * @param string $file The text being replaced (all of or part of a file).
213 * @param string $hook The hook being modified.
214 */
215 function deadwood_save_changes($cur, $new, &$file, $hook) {
216 if ($new != $cur) {
217 $file = str_replace($cur, $new, $file);
218 deadwood_debug_print('Completed conversions for ' . $hook);
219 }
220 }
221
222 /**
223 * Convert menu function.
224 * See: http://drupal.org/node/103114.
225 *
226 * @param string $file The file to convert.
227 */
228 function deadwood_convert_menu(&$file) {
229 $hook = 'menu';
230 $cur = deadwood_find_hook($hook, $file);
231 $new = $cur;
232
233 $msg1 = "/* TODO\n" .
234 " Non menu code that was placed in hook_menu under the '!\$may_cache' block\n" .
235 " so that it could be run during initialization, should now be moved to hook_init.\n" .
236 " Previously we called hook_init twice, once early in the bootstrap process, second\n" .
237 " just after the bootstrap has finished. The first instance is now called boot\n" .
238 " instead of init.\n" .
239 " \n" .
240 " In Drupal 6, there are now two hooks that can be used by modules to execute code\n" .
241 " at the beginning of a page request. hook_boot() replaces hook_init() in Drupal 5\n" .
242 " and runs on each page request, even for cached pages. hook_init() now only runs\n" .
243 " for non-cached pages and thus can be used for code that was previously placed in\n" .
244 " hook_menu() with \$may_cache = FALSE:\n" .
245 " \n" .
246 " Dynamic menu items under a '!\$may_cache' block can often be simplified\n" .
247 " to remove references to arg(n) and use of '%<function-name>' to check\n" .
248 " conditions. See http://drupal.org/node/103114.\n" .
249 " \n" .
250 " The title and description arguments should not have strings wrapped in t(),\n" .
251 " because translation of these happen in a later stage in the menu system.\n" .
252 "*/\n";
253
254 $from = array();
255 $to = array();
256 // hook_menu() no longer takes any parameters (remove $may_cache).
257 $from[] = '/_menu\(\$may_cache/m';
258 $to[] = '_menu(';
259 $from[] = '/^(.*?if \((!|)\$may_cache\).*)$/m';
260 $to[] = "$msg1$1";
261 // callback becomes page callback.
262 $from[] = '/\'callback\'/m';
263 $to[] = '\'page callback\'';
264 // callback arguments becomes page arguments.
265 $from[] = '/\'callback arguments\'/m';
266 $to[] = '\'page arguments\'';
267 // access becomes access callback and access arguments.
268 $from[] = '/\'access\'\s*=>\s*user_access/m';
269 $to[] = '\'access arguments\' => array';
270 $from[] = '/\'access\'\s*=>\s*TRUE/m';
271 $to[] = '\'access arguments\' => array(\'access content\')';
272 $from[] = '/\'access\'/m';
273 $to[] = '\'access arguments\'';
274 $from[] = '/=\s*user_access\s*\(\'/m';
275 $to[] = '= array(\'';
276 // title and description arguments should not have strings wrapped in t().
277 // $from[] = '/\'title\' => t\(\'(.*)\'\)([|,])$/m';
278 // $to[] = '\'title\' => \'$1\'$2';
279 // $from[] = '/\'description\' => t\(\'(.*)\'\)([|,])$/m';
280 // $to[] = '\'description\' => \'$1\'$2';
281 // There may be other t() references on these lines. Add a message?
282 // t\((('|)(\w+)('|))\)
283 // $from[] = '/(\'title\' =>.*\W)t\(((\'|)([\w ]+)(\'|))\)/';
284 $from[] = '/(\'title\' =>.*\W)t\((.*)\)/';
285 $to[] = '$1$2';
286 $from[] = '/(\'description\' =>.*\W)t\((.*)\)/';
287 $to[] = '$1$2';
288 // Repeat these as they may occur multiple times on a line (probably a way to do this with one call).
289 // $from[] = '/(\'title\' =>.*\W)t\(((\'|)([\w ]+)(\'|))\)/';
290 $from[] = '/(\'title\'\s*=>.*\W)t\((.*)\)/';
291 $to[] = '$1$2';
292 $from[] = '/(\'description\'\s*=>.*)\Wt\((.*)\)/';
293 $to[] = '$1$2';
294 // Menu index strings with wildcards may be simplified
295 $from[] = '/(\'path\'\s*=>.*)arg\(\d+\)(.*)$/m'; // '/(\'path\' =>.*)\..*arg\(\d+\).*\.(.*)$/m';
296 $to[] = '$1\'%\'$2';
297 // value of path is the new index for $items. Do last due to above search for 'path.'
298 // Some code the 'path' to start on the line after 'array('; others on the same line.
299 // Same inconsistency exists in the database table statements where some put the first
300 // field on the 'CREATE TABLE' line.
301 $from[] = '/^(\s*)\$items\[\]\s*=\s*array\s*\(\s*\'path\'\s*=>\s*(.+),\s*(\n\s*)/m';
302 $to[] = '$1$items[$2] = array($3';
303
304 deadwood_do_conversions($from, $to, $new);
305 deadwood_save_changes($cur, $new, $file, $hook);
306 }
307
308 /**
309 * Convert calls to url() and l().
310 *
311 * See: http://drupal.org/node/114774#url.
312 * Adapted from the script at http://drupal.org/files/issues/replace.php_.txt.
313 *
314 * @param string $file The file to convert.
315 */
316 function deadwood_convert_url(&$file) {
317 $hook = 'url';
318 $msg = "/* TODO\n" .
319 " Please manually fix the parameters on the l() or url() function on the next line.\n" .
320 " Typically, this was not changed because of a function call inside an array call like\n" .
321 " array('title' => t('View user profile.'))." .
322 "*/\n";
323
324 $callbacks = array('deadwood_fix_l', 'deadwood_fix_url');
325 foreach ($callbacks as $callback) {
326 $cur = $file;
327 $new = '';
328
329 // Process file in chunks to avoid PCRE bug?
330 $pattern = $callback == 'deadwood_fix_l' ? '/(?=(?<!ion )(?<![a-zA-Z_\'\"])l\()/' : '/(?=(?<!ion )(?<![a-zA-Z_\'\"])url\()/';
331 $chunks = preg_split($pattern, $cur);
332
333 $search = $callback == 'deadwood_fix_l' ? '@(?<!ion )(?<![a-zA-Z_\'\"])l\((([^()]*|\((?2)?\))+)\)@' : '@(?<!ion )(?<![a-zA-Z_\'\"])url\((([^()]*|\((?2)?\))+)\)@';
334
335 foreach ($chunks as $chunk) {
336 $chg = preg_replace_callback($search, $callback, $chunk);
337 $new .= $chg != '' ? $chg : $msg . $chunk;
338 }
339
340 deadwood_save_changes($cur, $new, $file, $hook);
341 }
342 }
343
344 /**
345 * Callback function for converting l() references.
346 *
347 * @param array $matches Function arguments.
348 * @return Text of converted function call.
349 */
350 function deadwood_fix_l($matches) {
351 $args = deadwwod_get_args($matches[1]);
352
353 // Two arguments, no change.
354 if (count($args) <= 2) {
355 return $matches[0];
356 }
357
358 $options = "array(";
359 if (isset($args[2]) && $args[2][1] != 'array()' && $args[2][1] != 'NULL') {
360 $options .= "'attributes' => " . $args[2][1] . ', ';
361 }
362 if (isset($args[3]) && $args[3][1] != "''" && $args[3][1] != '""' && $args[3][1] != 'NULL') {
363 $options .= "'query' => " . $args[3][1] . ', ';
364 }
365 if (isset($args[4]) && $args[4][1] != "''" && $args[4][1] != '""' && $args[4][1] != 'NULL') {
366 $options .= "'fragment' => " . $args[4][1] . ', ';
367 }
368 if (isset($args[5]) && $args[5][1] != "FALSE") {
369 $options .= "'absolute' => TRUE, ";
370 }
371 if (isset($args[6]) && $args[6][1] != "FALSE") {
372 $options .= "'html' => TRUE, ";
373 }
374 $options = rtrim($options, ', ');
375
376 $return = 'l('. $args[0][1] . ', ' . $args[1][1] . ', ' . $options . '))';
377 return $return;
378 }
379
380 /**
381 * Callback function for converting url() references.
382 *
383 * @param array $matches Function arguments.
384 * @return Text of converted function call.
385 */
386 function deadwood_fix_url($matches) {
387 $args = deadwwod_get_args($matches[1]);
388
389 // One argument, no change.
390 if (count($args) <= 1) {
391 return $matches[0];
392 }
393
394 // Ignore the url() call from l().
395 if ($args[1][1] == '$options') return $matches[0];
396
397 $options = "array(";
398 if (isset($args[1]) && $args[1][1] != "''" && $args[1][1] != '""' && $args[1][1] != 'NULL') {
399 $options .= "'query' => " . $args[1][1] . ', ';
400 }
401 if (isset($args[2]) && $args[2][1] != "''" && $args[2][1] != '""' && $args[2][1] != 'NULL') {
402 $options .= "'fragment' => " . $args[2][1] . ', ';
403 }
404 if (isset($args[3]) && $args[3][1] != "FALSE") {
405 $options .= "'absolute' => TRUE, ";
406 }
407 $options = rtrim($options, ', ');
408
409 $return = 'url(' . $args[0][1] . ', ' . $options . '))';
410 return $return;
411 }
412
413 /**
414 * Helper function for parsing arguments.
415 *
416 * @param array $matches Function arguments.
417 * @return Text of converted function call.
418 */
419 function deadwwod_get_args($string) {
420 preg_match_all('` *(([^(),]+|\((([^()]*|\((?3)?\))+)\))+) *(,|$)`', $string, $matches, PREG_SET_ORDER);
421 return $matches;
422 }
423
424 /**
425 * Convert calls to taxonomy_node_get_terms(), taxonomy_node_get_terms_by_vocabulary(),
426 * taxonomy_node_save and taxonomy_node_delete().
427 *
428 * @param string $file The file to convert.
429 */
430 function deadwood_convert_taxonomy(&$file) {
431 $hook = 'taxonomy';
432 $cur = $file;
433 $new = $cur;
434
435 $from = array();
436 $to = array();
437 /*
438 * TODO Add this text if table name is found.
439 * The {term_node} table now has a vid (version id) column, and (tid, nid, vid) is now the primary key.
440 * Any direct queries against {term_node} should be checked, and probably modified to use the node
441 * revision (vid) field instead of nid.
442 *
443 */
444 // taxonomy_node_get_terms() now takes a full $node object, not just a nid (node id).
445 $from[] = '/taxonomy_node_get_terms\s*\(\$(nid|node->nid)/';
446 $to[] = 'taxonomy_node_get_terms($node';
447 // $from[] = '/taxonomy_node_get_terms\(([^\$node]+)/m';
448 // $to[] = '_menu(';
449 // taxonomy_node_get_terms_by_vocabulary() now takes a full $node object, not just a nid (node id).
450 $from[] = '/taxonomy_node_get_terms_by_vocabulary\s*\(\$(nid|node->nid)/m';
451 $to[] = 'taxonomy_node_get_terms_by_vocabulary($node';
452 // taxonomy_node_save() now takes a full $node object, not just a nid (node id).
453 $from[] = '/taxonomy_node_save\s*\(\$(nid|node->nid)/m';
454 $to[] = 'taxonomy_node_save($node';
455 // taxonomy_node_delete() now takes a full $node object, not just a nid (node id).
456 $from[] = '/taxonomy_node_delete\s*\(\$(nid|node->nid)/m';
457 $to[] = 'taxonomy_node_delete($node';
458 // taxonomy_node_delete_revision() has been added to delete all taxonomy terms from the current revision of the given $node object.
459
460 deadwood_do_conversions($from, $to, $new);
461 deadwood_save_changes($cur, $new, $file, $hook);
462 }
463
464 /**
465 * Convert module loads to use new module_load_include().
466 *
467 * @param string $file The file to convert.
468 */
469 function deadwood_convert_module_load(&$file) {
470 $hook = 'module_load';
471 $cur = $file;
472 $new = $cur;
473
474 $callback = 'deadwood_fix_module_load';
475 $functions = array('require_once', 'require', 'include_once', 'include');
476 foreach ($functions as $function) {
477 // replace function calls using drupal_get_path including those prefixed with './'.
478 $search = "/$function\s*(\(|)\s*'\.\/'.*?drupal_get_path\s*\((.+),\s*(.+)\)\s*\.\s*(.+?)(\)|);/";
479 $chg = preg_replace_callback($search, $callback, $new);
480 $new = $chg != '' ? $chg : $new;
481 // replace function calls using drupal_get_path.
482 $search = "/$function\s*(\(|)drupal_get_path\s*\((.+),\s*(.+)\)\s*\.\s*(.+?)(\)|);/";
483 $chg = preg_replace_callback($search, $callback, $new);
484 $new = $chg != '' ? $chg : $new;
485 // replace function calls not using drupal_get_path.
486 // Example: require_once("$path/file_name.inc");
487 $search = "/$function\s*(\(|)(\'|\")(.+?)(\'|\")(\)|);/";
488 $chg = preg_replace_callback($search, $callback . '2', $new);
489 $new = $chg != '' ? $chg : $new;
490 // Example: include_once(PATH_CONSTANT .'/file_name.inc');
491 // This uses an opportunistic 'inc' as extension.
492 $search = "/^\s*$function\s*(\(|)(.+?)\s*\.\s*(.+?)(\)|);/m"; // $search = "/$function\s*(\(|)(\'|\"|)(.+?)(\'|\"|)\s*\.\s*(\'|\")(.+?)(\'|\")(\)|);/";
493 $chg = preg_replace_callback($search, $callback, $new);
494 $new = $chg != '' ? $chg : $new;
495 }
496
497 $from = array();
498 $to = array();
499 // remove '_xx' from function name.
500 $from[] = '/module_load_include_xx/';
501 $to[] = 'module_load_include';
502
503 deadwood_do_conversions($from, $to, $new);
504 deadwood_save_changes($cur, $new, $file, $hook);
505 }
506
507 /**
508 * Callback function for converting module loads.
509 * $function(drupal_get_path('module', 'module_name') .'/file_name.inc');
510 * $function(PATH_CONSTANT .'/file_name.inc');
511 *
512 * @param array $matches Function arguments.
513 * @return Text of converted function call.
514 */
515 function deadwood_fix_module_load($matches) {
516 // If not 5 or 6 arguments, no change.
517 if (count($matches) <= 4) {
518 return $matches[0];
519 }
520
521 $all = trim($matches[count($matches) - 2], "'/);");
522 $ext = substr($all, strpos($all, '.') + 1);
523 $name = substr($all, 0, strpos($all, '.'));
524 $module = trim($matches[3], "'");
525 if (count($matches) == 5) {
526 global $_deadwood_filename;
527 $module = pathinfo($_deadwood_filename, PATHINFO_FILENAME);
528 }
529 $new = "module_load_include_xx('$ext', '$module', '$name');";
530
531 return $new;
532 }
533
534 /**
535 * Callback function for converting module loads.
536 * $function("$path/file_name.inc");
537 *
538 * @param array $matches Function arguments.
539 * @return Text of converted function call.
540 */
541 function deadwood_fix_module_load2($matches) {
542 // If not 6 arguments, no change.
543 if (count($matches) <= 5) {
544 return $matches[0];
545 }
546
547 $all = trim($matches[count($matches) - 3], "');");
548 $ext = substr($all, strpos($all, '.') + 1);
549 $name = substr($all, strpos($all, '/') + 1);
550 $name = substr($name, 0, strpos($name, '.'));
551 $module = substr($all, 0, strpos($all, '/'));
552 // if (count($matches) == 6) {
553 global $_deadwood_filename;
554 $module = pathinfo($_deadwood_filename, PATHINFO_FILENAME);
555 // }
556 $new = "module_load_include_xx('$ext', '$module', '$name');";
557
558 return $new;
559 }
560
561 /**
562 * Convert calls to hook_form_alter() for parameter changes.
563 *
564 * @param string $file The file to convert.
565 */
566 function deadwood_convert_form_alter(&$file) {
567 /*
568 * TODO These module functions could have added additional parameters from the core signature.
569 * We need to append any additional parameters to the end of the required parameters.
570 * Should we search for the string '_form_alter' and place a notification message?
571 * This might be present if the module called the hook itself.
572 * Are there variables inside this function we could/should rename?
573 */
574 $hook = 'form_alter';
575 $pattern = '/(?<!hook)_form_alter\s*(\(.*\))/';
576 // No need for preg_match_all as a module should only define this function once?
577 if (!preg_match($pattern, $file, $matches)) {
578 return;
579 }
580 $cur = $matches[0];
581 $new = $cur;
582
583 $search = $matches[1];
584 $replace = '(&$form, &$form_state, $form_id)';
585 $new = str_replace($search, $replace, $new);
586
587 deadwood_save_changes($cur, $new, $file, $hook);
588 }
589
590 /**
591 * Convert calls to hook_link_alter() for parameter changes.
592 *
593 * @param string $file The file to convert.
594 */
595 function deadwood_convert_link_alter(&$file) {
596 /*
597 * TODO These module functions could have added additional parameters from the core signature.
598 * We need to append any additional parameters to the end of the required parameters.
599 * Should we search for the string '_link_alter' and place a notification message?
600 * This might be present if the module called the hook itself.
601 */
602 $hook = 'link_alter';
603 $pattern = '/_link_alter\s*(\(.*\))/';
604 // No need for preg_match_all as a module should only define this function once?
605 if (!preg_match($pattern, $file, $matches)) {
606 return;
607 }
608 $cur = $matches[0];
609 $new = $cur;
610
611 $search = $matches[1];
612 $replace = '(&$links, $node)';
613 $new = str_replace($search, $replace, $new);
614
615 deadwood_save_changes($cur, $new, $file, $hook);
616 }
617
618 /**
619 * Convert calls to hook_profile_alter() for parameter changes.
620 *
621 * @param string $file The file to convert.
622 */
623 function deadwood_convert_profile_alter(&$file) {
624 /*
625 * TODO These module functions could have added additional parameters from the core signature.
626 * We need to append any additional parameters to the end of the required parameters.
627 * Should we search for the string '_profile_alter' and place a notification message?
628 * This might be present if the module called the hook itself.
629 */
630 $hook = 'profile_alter';
631 $cur = deadwood_find_hook($hook, $file);
632 $new = $cur;
633
634 $from = array();
635 $to = array();
636 // Change function paramters.
637 $from[] = '/_profile_alter\s*(\(.*\))/';
638 $to[] = '_profile_alter(&$account)';
639 // Change variable references.
640 $from[] = '/\$fields\[/';
641 $to[] = '$account->content[';
642
643 deadwood_do_conversions($from, $to, $new);
644 deadwood_save_changes($cur, $new, $file, $hook);
645 }
646
647 /**
648 * Convert calls to hook_mail_alter() for parameter changes.
649 *
650 * @param string $file The file to convert.
651 */
652 function deadwood_convert_mail_alter(&$file) {
653 /*
654 * TODO These module functions could have added additional parameters from the core signature.
655 * We need to append any additional parameters to the end of the required parameters.
656 * Should we search for the string '_mail_alter' and place a notification message?
657 * This might be present if the module called the hook itself.
658 */
659 $hook = 'mail_alter';
660 $cur = deadwood_find_hook($hook, $file);
661 $new = $cur;
662
663 $from = array();
664 $to = array();
665 // Change function paramters.
666 $from[] = '/_mail_alter\s*(\(.*\))/';
667 $to[] = '_mail_alter(&$message)';
668 // Change variable references.
669 $from[] = '/([^&])\$(mailkey|to|subject|body|from|headers)/';
670 $to[] = '$1$message[\'$2\']';
671
672 deadwood_do_conversions($from, $to, $new);
673 deadwood_save_changes($cur, $new, $file, $hook);
674 }
675
676 /**
677 * Add note about need to register theme functions in hook_theme().
678 * Create entries to register theme functions in hook_theme().
679 * These will need to be manually combined from all project files.
680 *
681 * @param string $file The file to convert.
682 */
683 function deadwood_convert_theme(&$file) {
684 $hook = 'theme';
685 $cur = $file;
686 $new = $cur;
687
688 global $_deadwood_filename;
689
690 $name = pathinfo($_deadwood_filename, PATHINFO_FILENAME);
691 $msg =
692 "/* TODO Implement the hook_theme registry. Combine all theme registry entries
693 into one hook_theme function in each corresponding module file.
694 function $name" . "_theme() {
695 return array(";
696
697 // Find all theme functions and add to hook_theme.
698 $search = '/^function\s*theme_(\w+)\s*\((.*?)\s*\)\s*{$/ms';
699 preg_match_all($search, $new, $matches, PREG_SET_ORDER);
700 $text = $msg . "\n";
701 foreach ($matches as $match) {
702 $text .= " '$match[1]' => array(\n";
703 $text .= " 'file' => '$_deadwood_filename',\n";
704 $text .= " 'arguments' => array(\n";
705 $text .= deadwood_get_theme_params($match[2]);
706 $text .= " ),\n";
707 $text .= " ),\n";
708 }
709 $text .= " );\n";
710 $text .= "} */";
711
712 // Create function body and add theme entries. Write at top of file.
713 $from[] = '/^(\/\/ \$Id.*\$\s*$)/m';
714 $to[] = "$1\n$text\n";
715
716 deadwood_do_conversions($from, $to, $new);
717 deadwood_save_changes($cur, $new, $file, $hook);
718 }
719
720 /**
721 * Callback function for writing theme registry entries.
722 *
723 * @param array $matches Function arguments.
724 * @return Text of converted function call.
725 */
726 function deadwood_get_theme_params($matches) {
727 $new = array();
728 $params = explode(',', $matches);
729 foreach ($params as $param) {
730 $tokens = explode('=', $param);
731 $new[] = " '" . trim($tokens[0], '$ ') . "' => " . (isset($tokens[1]) ? trim($tokens[1]) : 'NULL') . ",\n";
732 }
733 $new = implode("", $new);
734 return $new;
735 }
736
737 /**
738 * Convert calls to watchdog() for parameter changes.
739 *
740 * @param string $file The file to convert.
741 */
742 function deadwood_convert_watchdog(&$file) {
743 $hook = 'watchdog';
744 $cur = $file;
745 $new = $cur;
746
747 $from = array();
748 $to = array();
749 // Parameters of watchdog() changed
750 // remove the t(.., array(.., function())) reference inside the watchdog() call
751 $from[] = '/(watchdog\(.*),\s*t\((.*array.*?\)\))\)/';
752 $to[] = "\$1, $2"; // TODO Are the '\' characters intended or leftover from above???
753 // remove the t(.., array()) reference inside the watchdog() call
754 $from[] = '/(watchdog\(.*),\s*t\((.*array.*?\))\)/';
755 $to[] = "\$1, $2";
756 // remove the t() reference inside the watchdog() call
757 $from[] = '/(watchdog\(.*),\s*t\((.*?)\)/';
758 $to[] = "\$1, $2";
759
760 deadwood_do_conversions($from, $to, $new);
761 deadwood_save_changes($cur, $new, $file, $hook);
762 }
763
764 /**
765 * Convert syntax for .info files.
766 *
767 * @param string $file The file to convert.
768 */
769 function deadwood_convert_info1(&$file) {
770 $hook = 'info1';
771 $cur = $file;
772 $new = $cur;
773
774 // New syntax for .info files
775 $search = '/(dependencies)\s*=\s*(.+)/';
776 $callback = 'deadwood_fix_dependencies';
777 $chg = preg_replace_callback($search, $callback, $new);
778 $new = $chg != '' ? $chg : $new;
779
780 deadwood_save_changes($cur, $new, $file, $hook);
781 }
782
783 /**
784 * Specify core compatibility in .info files.
785 *
786 * @param string $file The file to convert.
787 */
788 function deadwood_convert_info2(&$file) {
789 $hook = 'info2';
790 $cur = $file;
791 $new = $cur;
792
793 $from = array();
794 $to = array();
795 // Core compatibility now specified in .info files
796 $from[] = '/\z/';
797 $to[] = "\ncore = 6.x";
798
799 deadwood_do_conversions($from, $to, $new);
800 deadwood_save_changes($cur, $new, $file, $hook);
801 }
802
803 /**
804 * Callback function for converting dependencies.
805 *
806 * @param array $matches Function arguments.
807 * @return Text of converted function call.
808 */
809 function deadwood_fix_dependencies($matches) {
810 // Two arguments, no change.
811 if (count($matches) <= 2) {
812 return $matches[0];
813 }
814
815 $deps = explode(' ', $matches[2]);
816 $new = array();
817 foreach ($deps as $dep) {
818 $new[] = $matches[1] . '[] = ' . $dep;
819 }
820 $new = implode("\n", $new);
821 return $new;
822 }
823
824 /**
825 * Convert calls to cache_set() for parameter changes.
826 *
827 * @param string $file The file to convert.
828 */
829 function deadwood_convert_cache1(&$file) {
830 $hook = 'cache1';
831 $cur = $file;
832 $new = $cur;
833
834 $from = array();
835 $to = array();
836 // Changes to cache_set parameter order
837 // remove a serialize() reference inside the cache_set() call
838 // switch order of parameters 2 and 3
839 $from[] = '/cache_set\s*\(\s*(.+),\s*(.+),\s*(serialize\s*\(|)(.+)(\)|)\)/';
840 $to[] = "cache_set($1, $4, $2)";
841 // remove 'cache' as the table parameter since it is defaulted
842 $from[] = '/cache_set\s*\(\s*(.+),\s*(.+),\s*(\'cache\')\)/';
843 $to[] = "cache_set($1, $2)";
844
845 deadwood_do_conversions($from, $to, $new);
846 deadwood_save_changes($cur, $new, $file, $hook);
847 }
848
849 /**
850 * Remove (un)serialize calls with cache_get() and cache_set().
851 * This is not a perfect split on the conversion since we remove
852 * the serialize reference in cache1 above.
853 *
854 * @param string $file The file to convert.
855 */
856 function deadwood_convert_cache2(&$file) {
857 $hook = 'cache2';
858 $cur = $file;
859 $new = $cur;
860
861 $from = array();
862 $to = array();
863 // Cache set and get automatically (un)serialize complex data types
864 $from[] = '/unserialize\s*\(\s*cache_get/';
865 $to[] = "cache_get";
866
867 deadwood_do_conversions($from, $to, $new);
868 deadwood_save_changes($cur, $new, $file, $hook);
869 }
870
871 /**
872 * Replace calls to $_SERVER['REMOTE_ADDR'] with new function.
873 *
874 * @param string $file The file to convert.
875 */
876 function deadwood_convert_ip_address(&$file) {
877 $hook = 'ip_address';
878 $cur = $file;
879 $new = $cur;
880
881 $from = array();
882 $to = array();
883 // New ip_address() function when working behind proxies
884 $from[] = '/\$_SERVER\[\'REMOTE_ADDR\'\]/';
885 $to[] = "ip_address()";
886
887 deadwood_do_conversions($from, $to, $new);
888 deadwood_save_changes($cur, $new, $file, $hook);
889 }
890
891 /**
892 * Replace references to file_check_upload().
893 *
894 * @param string $file The file to convert.
895 */
896 function deadwood_convert_upload1(&$file) {
897 $hook = 'upload1';
898 $cur = $file;
899 $new = $cur;
900
901 $msg =
902 "/* TODO Modify the validators array to suit your needs.
903 This array is used in the revised file_save_upload */
904 \$validators = array(
905 'file_validate_is_image' => array(),
906 'file_validate_image_resolution' => array('85x85')),
907 'file_validate_size' => array(30 * 1024),
908 );";
909
910 $from = array();
911 $to = array();
912 // file_check_upload() merged into file_save_upload()
913 // file_save_upload() has new parameter
914 $from[] = '/^(.*)(file_check_upload)\s*\((.*)\)/m';
915 $to[] = "$msg\n\n$1file_save_upload($2, \$validators)";
916
917 deadwood_do_conversions($from, $to, $new);
918 deadwood_save_changes($cur, $new, $file, $hook);
919 }
920
921 /**
922 * Replace references to {file_revisions} table.
923 *
924 * @param string $file The file to convert.
925 */
926 function deadwood_convert_upload2(&$file) {
927 $hook = 'upload2';
928 $cur = $file;
929 $new = $cur;
930
931 $from = array();
932 $to = array();
933 // The {file_revisions} table is now {upload}
934 $from[] = '/{file_revisions}/';
935 $to[] = "{upload}";
936
937 deadwood_do_conversions($from, $to, $new);
938 deadwood_save_changes($cur, $new, $file, $hook);
939 }
940
941 /**
942 * Replace references to custom_url_rewrite with new functions.
943 *
944 * @param string $file The file to convert.
945 */
946 function deadwood_convert_custom_url(&$file) {
947 $hook = 'custom_url';
948 $cur = $file;
949 $new = $cur;
950
951 $from = array();
952 $to = array();
953 // custom_url_rewrite('alias', ..) is now custom_url_rewrite_outbound
954 // Change function_exists calls.
955 $from[] = "/^(\s*if.*?exists)(\('custom_url_rewrite'\))(.*?\('alias.*?;)/m";
956 $to[] = "$1('custom_url_rewrite_outbound')$3";
957 // Change function calls.
958 $from[] = "/(custom_url_rewrite)(\('alias', )/";
959 $to[] = "$1_outbound(";
960 // custom_url_rewrite('source', ..) is now custom_url_rewrite_inbound
961 // Change function_exists calls.
962 $from[] = "/^(\s*if.*?exists)(\('custom_url_rewrite'\))(.*\('source.*?;)/m";
963 $to[] = "$1('custom_url_rewrite_inbound')$3";
964 // Change function calls.
965 $from[] = "/(custom_url_rewrite)(\('source', )/";
966 $to[] = "$1_inbound(";
967
968 deadwood_do_conversions($from, $to, $new);
969 deadwood_save_changes($cur, $new, $file, $hook);
970 }
971
972 /**
973 * Replace paramters for hook_help.
974 *
975 * @param string $file The file to convert.
976 */
977 function deadwood_convert_hook_help(&$file) {
978 $hook = 'help';
979 $cur = deadwood_find_hook($hook, $file);
980 $new = $cur;
981 $hook = 'hook_help';
982
983 $from = array();
984 $to = array();
985
986 // Save the parameter name to use in next search.
987 $old_param = '$section';
988 $pattern = "/_help\s*\(\s*(.+?)(\s*=.+?|\s*)\)/";
989 preg_match($pattern, $cur, $matches);
990 if (isset($matches[1])) {
991 $old_param = $matches[1];
992 }
993 // hook_help() parameters are changed
994 // Change function parameter signature.
995 $from[] = "/_help\s*\(\s*(.+?)(\s*=.+?|\s*)\)/";
996 $to[] = "_help(\$path$2, \$arg)";
997 // Change function body.
998 $from[] = "/\\$old_param/";
999 $to[] = "\$path";
1000
1001 deadwood_do_conversions($from, $to, $new);
1002 deadwood_save_changes($cur, $new, $file, $hook);
1003 }
1004
1005 /**
1006 * Replace references to taxonomy_get_vocabulary with taxonomy_vocabulary_load.
1007 *
1008 * @param string $file The file to convert.
1009 */
1010 function deadwood_convert_taxonomy_vocabulary(&$file) {
1011 $hook = 'taxonomy_vocabulary';
1012 $cur = $file;
1013 $new = $cur;
1014
1015 $from = array();
1016 $to = array();
1017
1018 // taxonomy_get_vocabulary() changed to taxonomy_vocabulary_load().
1019 $from[] = '/taxonomy_get_vocabulary\s*\(/';
1020 $to[] = 'taxonomy_vocabulary_load(';
1021
1022 deadwood_do_conversions($from, $to, $new);
1023 deadwood_save_changes($cur, $new, $file, $hook);
1024 }
1025
1026 /**
1027 * Replace references to hook_init with hook_boot.
1028 *
1029 * @param string $file The file to convert.
1030 */
1031 function deadwood_convert_hook_init(&$file) {
1032 $hook = 'hook_init';
1033 $cur = $file;
1034 $new = $cur;
1035
1036 $from = array();
1037 $to = array();
1038
1039 // hook_init() changed to hook_boot().
1040 $from[] = '/hook_init\s*\(/';
1041 $to[] = 'hook_boot(';
1042 // Added a message to deadwood_convert_menu about new hook_init.
1043
1044 deadwood_do_conversions($from, $to, $new);
1045 deadwood_save_changes($cur, $new, $file, $hook);
1046 }
1047
1048 /**
1049 * Replace references to global comment variables with per node type references.
1050 *
1051 * @param string $file The file to convert.
1052 */
1053 function deadwood_convert_comment_settings(&$file) {
1054 $hook = 'comment_settings';
1055 $cur = $file;
1056 $new = $cur;
1057
1058 $from = array();
1059 $to = array();
1060
1061 // Add node type when setting comment variables.
1062
1063 // Because there is no easy way of knowing all the node types,
1064 // you need to add to this list any node types referenced in your code.
1065 $from[] = "/variable_([s|g])et\s*\(\s*'comment_(article|page|story)'/";
1066 $to[] = "variable_$1et('commentxxx_$2'";
1067 // Do the rest.
1068 $from[] = "/variable_([s|g])et\s*\(\s*'comment_(.*?)'/";
1069 $to[] = "variable_$1et('comment_$2_' . \$node->type";
1070 // Revert these.
1071 $from[] = "/variable_([s|g])et\s*\(\s*'commentxxx_(article|page|story)'/";
1072 $to[] = "variable_$1et('comment_$2'";
1073
1074 deadwood_do_conversions($from, $to, $new);
1075 deadwood_save_changes($cur, $new, $file, $hook);
1076 }
1077
1078 /**
1079 * Comment out references to dangerous_skip_check form property.
1080 *
1081 * @param string $file The file to convert.
1082 */
1083 function deadwood_convert_dangerous_skip_check(&$file) {
1084 $hook = 'dangerous_skip_check';
1085 $cur = $file;
1086 $new = $cur;
1087
1088 $from = array();
1089 $to = array();
1090
1091 // Comment out this parameter.
1092 $from[] = "/^(.*'#DANGEROUS_SKIP_CHECK'.*)$/m";
1093 $to[] = "//$1 // This property has been removed from core.";
1094
1095 deadwood_do_conversions($from, $to, $new);
1096 deadwood_save_changes($cur, $new, $file, $hook);
1097 }
1098
1099 /**
1100 * Replace references to access_control with permissions.
1101 *
1102 * @param string $file The file to convert.
1103 */
1104 function deadwood_convert_access_control(&$file) {
1105 $hook = 'access_control';
1106 $cur = $file;
1107 $new = $cur;
1108
1109 $from = array();
1110 $to = array();
1111
1112 // Access control renamed to permissions.
1113 $from[] = '/(user_access\s*\(.*)administer access control/';
1114 $to[] = "$1administer permissions";
1115
1116 deadwood_do_conversions($from, $to, $new);
1117 deadwood_save_changes($cur, $new, $file, $hook);
1118 }
1119
1120 /**
1121 * Replace references to locale_refresh_cache with cache_clear_all.
1122 *
1123 * @param string $file The file to convert.
1124 */
1125 function deadwood_convert_locale_cache(&$file) {
1126 $hook = 'locale_cache';
1127 $cur = $file;
1128 $new = $cur;
1129
1130 $from = array();
1131 $to = array();
1132
1133 // Access control renamed to permissions.
1134 $from[] = '/locale_refresh_cache\s*\(\)/';
1135 $to[] = "cache_clear_all('locale:', 'cache', TRUE)";
1136
1137 deadwood_do_conversions($from, $to, $new);
1138 deadwood_save_changes($cur, $new, $file, $hook);
1139 }
1140
1141 /**
1142 * Replace references to admin/logs with admin/reports.
1143 *
1144 * @param string $file The file to convert.
1145 */
1146 function deadwood_convert_admin_logs(&$file) {
1147 $hook = 'admin_logs';
1148 $cur = $file;
1149 $new = $cur;
1150
1151 $from = array();
1152 $to = array();
1153
1154 // admin/logs renamed to admin/reports.
1155 $from[] = '/admin\/logs/';
1156 $to[] = "admin/reports";
1157
1158 deadwood_do_conversions($from, $to, $new);
1159 deadwood_save_changes($cur, $new, $file, $hook);
1160 }
1161
1162 /**
1163 * Convert parameters in references to drupal_mail.
1164 *
1165 * @param string $file The file to convert.
1166 */
1167 function deadwood_convert_drupal_mail(&$file) {
1168 $hook = 'drupal_mail';
1169 $cur = $file;
1170 $new = $cur;
1171
1172 // convert parameters in references to drupal_mail.
1173 $callback = 'deadwood_fix_drupal_mail';
1174 $search = "/^((.*)(drupal_mail)\s*\((.+?),\s*(.+?),\s*(.+?),\s*(.+?)(,\s*([^,]*?)|)(,\s*(.*?)|)\))(.*?)$/m";
1175 $chg = preg_replace_callback($search, $callback, $new);
1176 $new = $chg != '' ? $chg : $new;
1177
1178 deadwood_save_changes($cur, $new, $file, $hook);
1179 }
1180
1181 /**
1182 * Callback function for converting drupal_mail parameters.
1183 *
1184 * @param array $matches Function arguments.
1185 * @return Text of converted function call.
1186 */
1187 function deadwood_fix_drupal_mail($matches) {
1188 // If not 5 arguments, then error.
1189 if (count($matches) < 5) {
1190 return $matches[0];
1191 }
1192
1193 $cur = $matches[0];
1194 $beg = $matches[2];
1195 $function = $matches[3];
1196 $key = $matches[4];
1197 $to = $matches[5];
1198 $subject = $matches[6];
1199 $body = $matches[7];
1200 $from = $matches[9];
1201 $headers = $matches[11];
1202 $end = $matches[12];
1203
1204 $msg =
1205 "$beg/* TODO Create a hook_mail(\$key, &\$message, \$params) function to generate
1206 $beg" . "the message body when called by drupal_mail. */
1207 $beg\$account = array(); // Set this as needed
1208 $beg\$language = user_preferred_language(\$account);
1209 $beg\$object = array(); // Replace this as needed
1210 $beg\$context['subject'] = \$subject;
1211 $beg\$context['body'] = \$body;";
1212
1213 if ($headers != '') {
1214 $msg .= "\n$beg\$context['headers'] = $headers;";
1215 }
1216 $msg .= "\n$beg\$params = array('account' => \$account, 'object' => \$object, 'context' => \$context);";
1217
1218 global $_deadwood_filename;
1219 $module = pathinfo($_deadwood_filename, PATHINFO_FILENAME);
1220
1221 if ($from != '') {
1222 $new = "//$cur\n$msg\n$beg$function('$module', $key, $to, \$language, \$params, $from);";
1223 }
1224 else {
1225 $new = "//$cur\n$msg\n$beg$function('$module', $key, $to, \$language, \$params);";
1226 }
1227
1228 return