function coder_upgrade_convert_filter in Coder 7.2
Same name and namespace in other branches
- 7 coder_upgrade/conversions/function.inc \coder_upgrade_convert_filter()
Updates hook_filter().
hook_filter() and hook_filter_tips() replaced by hook_filter_info().
@todo Integrate hook_filter_tips() code with this function. @todo Allow for other code styles, e.g. if block instead of switch. How similar is this use case to convert_return or convert_op?
Parameters
PGPNode $node: A node object containing a PGPClass (or function) item.
1 call to coder_upgrade_convert_filter()
- coder_upgrade_upgrade_hook_filter_alter in coder_upgrade/
conversions/ function.inc - Implements hook_upgrade_hook_filter_alter().
File
- coder_upgrade/
conversions/ function.inc, line 631 - Provides conversion routines applied to functions (or hooks).
Code
function coder_upgrade_convert_filter(&$node, &$reader) {
// DONE
cdp("inside " . __FUNCTION__);
$item =& $node->data;
global $_coder_upgrade_module_name;
$tips = array();
$editor = PGPEditor::getInstance();
// Find the hook_filter_tips function object.
$function_node = $editor
->findFunction($reader
->getFunctions(), $_coder_upgrade_module_name . '_filter_tips', 'node');
if (!is_null($function_node)) {
$tips = coder_upgrade_convert_filter_tips($function_node);
cdp($tips, '$tips');
}
// Rename function.
$item->name .= '_XXX';
// $item->name = $_coder_upgrade_module_name . '_filter_info';
// Update document comment.
// $item->comment = preg_replace('@hook_filter@', "hook_filter_info", $item->comment);
// Restructure the triggers array.
$body =& $item->body;
if (!($switch1 = $body
->find(T_SWITCH))) {
clp("ERROR: switch statement not found in hook_filter");
return;
}
// $value = &$switch1['value'];
/*
* Compare first parameter to first switch condition (s/b $op)
* Compare second parameter to second switch condition (s/b $delta)
*
* Read $op case block: case operand gives the key for array
* Read $delta case block: case operand gives the key for array
* Return value gives the array value for above keys
* Build array internally, then write it out.
*
* On the callback items, we only want the callback function name, not the
* parameters. If there is not a function name (e.g. the filter module had
* case 'process': case 4: return trim(check_plain($text));),
* then make a new function with the return value as its body.
* For this example, core created _filter_html_escape($text).
*
* Look for a hook_filter_tips($delta, $format, $long = false).
* If present:
* - if multiple $delta bodies, then create new callback functions using
* $delta as part of the function name
* - else if one, then create new callback function
* - remove the $delta parameter
* - add tips_callback parameters to filter_info array items
*/
// Get the operation variable from the function parameter [at index $op_index].
// This function removes any default value assignment (e.g. $op = 'list') or
// inline comments included in the parameter expression.
$op_index = 0;
if (!($variable = $item
->getParameterVariable($op_index))) {
clp("ERROR: Variable not found in hook(\$op) parameter {$op_index}");
return;
}
$op = $variable
->toString();
// Get the first condition. (With a switch there should only be one condition.)
$condition1 = $switch1->conditions
->getElement()
->findNode('operand')
->stripComments();
$operand1 = $condition1
->toString();
if ($operand1 != $op) {
clp('ERROR: switch statement operand does not match first function parameter in hook_filter');
return;
}
$filters = array();
// Get list of case statements.
$cases1 = $switch1->body;
$current1 = $cases1
->first();
while ($current1->next != NULL) {
$case1 = $current1->data;
if (!$case1 instanceof PGPCase || $case1->type == T_DEFAULT) {
$current1 = $current1->next;
continue;
}
$key1 = trim($case1->case
->stripComments()
->toString(), "'\"");
cdp("key1 = {$key1}");
// TODO Convert key2 to new key: Ex. 'process' becomes 'process callback'
$key1 = coder_upgrade_callback_filter($key1);
cdp("new key1 = {$key1}");
$body1 = $case1->body
->getElement();
if ($body1 && get_class($body1) == 'PGPFunctionCall') {
// Use case 1: returns an array.
cdp("body1 is an array");
if ($key1 != 'name') {
clp("ERROR: key is not 'list' in hook_filter");
return;
}
if ($body1->type != T_RETURN) {
clp("ERROR: switch statement body for 'list' key does not return an array in hook_filter");
return;
}
$value1 = $body1
->getParameter()
->getElement();
if ($value1 && get_class($value1) == 'PGPArray') {
$node_x = $value1->values
->first();
while ($node_x->next != NULL) {
$data = $node_x->data;
if ($node_x->type == 'key') {
$key2 = $data
->toString();
// Should be an integer = $delta
}
elseif ($node_x->type == 'value') {
$filters[$key2][$key1] = $data
->toString();
}
$node_x = $node_x->next;
}
}
}
elseif ($body1 && get_class($body1) == 'PGPConditional' && $body1->type == T_SWITCH) {
// Use case 2: switch statement on $delta.
$switch2 =& $body1;
$operand2 = $switch2->conditions
->toString();
if ($operand2 != $item
->getParameterVariable(1)
->toString()) {
clp("ERROR: switch statement operand does not match second function parameter in hook_filter");
return;
}
// Get list of case statements.
$cases2 = $switch2->body;
$current2 = $cases2
->first();
while ($current2->next != NULL) {
$case2 = $current2->data;
if (!$case2 instanceof PGPCase || $case2->type == T_DEFAULT) {
$current2 = $current2->next;
continue;
}
$key2 = trim($case2->case
->stripComments()
->toString(), "'\"");
cdp("key2 = {$key2}");
$body2 = $case2->body
->getElement();
if ($body2 && get_class($body2) == 'PGPFunctionCall') {
// Use case 2: returns an array.
if ($body2->type != T_RETURN) {
clp("ERROR: switch statement operand does not match first function parameter in hook_filter");
return;
}
$value2 = $body2
->getParameter();
if (get_class($value2) == 'PGPExpression') {
// TODO On the callback items only want the callback function name, not the parameters!!!
$filters[$key2][$key1] = $value2
->toString();
cdp($value2, '$value2');
}
if ($key1 == 'process callback' || $key1 == 'settings callback') {
if ($value2
->isType(T_FUNCTION_CALL)) {
// For $value2 = trim(check_plain($text)), this will grab trim.
// The user needs to define a callback function to do both.
$call =& $value2
->findNode('operand');
if (is_array($call->name)) {
// Name could be T_STRING or T_VARIABLE.
$name = $call->name['value'];
if ($call->name['type'] == T_STRING) {
$name = "'{$name}'";
}
}
else {
// An object expression (should be unlikely).
$name = $call->name
->toString();
}
$filters[$key2][$key1] = $name;
}
}
// else {
// $filters[$key2][$key1] = $value2->toString();
// }
}
$current2 = $current2->next;
}
}
$current1 = $current1->next;
}
foreach ($tips as $key2 => $callback) {
$filters[$key2]['tips callback'] = "'{$callback}'";
}
$hook = '_filter_info';
coder_upgrade_new_filter_hook($node, $hook, $filters);
// Delete the function body.
$item->body
->clear();
}