You are here

function coder_upgrade_convert_theme_callback in Coder 7

Same name and namespace in other branches
  1. 7.2 coder_upgrade/conversions/function.inc \coder_upgrade_convert_theme_callback()

Updates theme_xxx() functions.

Parameters are arrayitized.

Parameters

PGPNode $node: A node object containing a PGPClass (or function) item.

1 call to coder_upgrade_convert_theme_callback()
coder_upgrade_upgrade_hook_alter in coder_upgrade/conversions/function.inc
Implements hook_upgrade_hook_alter().

File

coder_upgrade/conversions/function.inc, line 155
Provides conversion routines applied to functions (or hooks).

Code

function coder_upgrade_convert_theme_callback(&$node) {
  global $_coder_upgrade_theme_registry;

  // Create helper objects.
  $editor = PGPEditor::getInstance();

  // Changes: drupal_render_children, theme_changes
  $item =& $node->data;
  $body =& $item->body;

  // Save the parameters for later.
  $parameters = array();
  for ($i = 0; $i < $item
    ->parameterCount(); $i++) {

    // Allow for default values, e.g. $var = NULL.
    if ($temp = $item
      ->getParameterVariable($i)) {

      // The parameter includes a variable; save the variable.
      $parameters[] = $temp
        ->toString();
    }
    else {

      // The parameter has no variable.
      // Example: function foo(/*$form = NULL*/, , 'xxx') {}
      $parameters[] = '$xx_missing_xx';
    }
  }

  // Delete the current parameters.
  $item->parameters
    ->clear();

  // Case 1: Theme function with no parameters
  // - leave the new function with no parameters
  // Case 2: Theme function whose signature omits some or all of the parameters
  // declared in the module's hook_theme()
  // - replace the function parameters with $variable
  // - insert assignment statements for each of the declared parameters
  // - log an error message about the missing signature parameters
  // Reassign function parameters to corresponding $variables array key.
  $theme_name = substr($item->name, strpos($item->name, "theme_") + 6);
  if (isset($_coder_upgrade_theme_registry[$theme_name])) {
    $hook = $_coder_upgrade_theme_registry[$theme_name];
    if (isset($hook['render element'])) {

      // In coder_upgrade_cache_info_hooks(), $hook key === 'variables'
      // for a theme defined by the module being upgraded, Thus, this
      // condition is not hit.
      // Replace the parameters by $variable, an array.
      $editor
        ->setParameter($item, 0, '$variables');
      if (!isset($parameters[0])) {
        clp('ERROR: No parameter in signature of theme_' . $theme_name . '()');
        return;
      }
      $string = $parameters[0] . ' = $variables[\'' . $hook['render element'] . '\']';
      $body
        ->insertFirst($editor
        ->textToStatements($string)
        ->getElement(0));
    }
    elseif (isset($hook['variables'])) {
      if (count($parameters) != count($hook['variables'])) {

        // The number of parameters to this theme function differs from the
        // number of variables parameters defined in hook_theme.
        clp("ERROR: Number of parameters in theme funcion '{$theme_name}' does not match number of parameters found in hook_theme");
        $body
          ->insertFirst($editor
          ->commentToStatement('// TODO Number of parameters in this theme funcion does not match number of parameters found in hook_theme.'), 'comment');

        //         return;
      }
      if (empty($hook['variables'])) {

        // New function should also have no parameters.
        clp('INFO: hook_theme() for theme ' . $theme_name . ' has no parameters');
        return;
      }

      // Replace the parameters by $variable, an array.
      $editor
        ->setParameter($item, 0, '$variables');
      $empty = FALSE;
      if (!($sentinel = $body
        ->get(0))) {

        // Add a sentinel -- a marker for insertion.
        $sentinel = $body
          ->insertFirst(NULL, 'sentinel');
        $empty = TRUE;
      }

      // Add an assignment statement for each of the previous function parameters.
      $i = 0;
      foreach ($hook['variables'] as $key => $value) {
        if (!isset($parameters[$i])) {
          clp('ERROR: No parameter ' . $i . ' in signature of theme_' . $theme_name . '()');
          break;
        }
        if ($parameters[$i] == '$xx_missing_xx') {
          $body
            ->insertBefore($sentinel, $editor
            ->commentToStatement('// TODO: Name this variable which was missing in the old function signature.'));
        }
        $string = $parameters[$i] . ' = $variables[\'' . $key . "'];\n";
        $body
          ->insertBefore($sentinel, $editor
          ->textToStatements($string)
          ->getElement(0));
        $i++;
      }
      if ($empty) {
        $body
          ->delete($sentinel);
      }
    }
  }

  // If theme function calls drupal_render, make sure last call is to drupal_render_children
  // to avoid endless loops: http://drupal.org/node/224333#drupal_render_children
  if ($statement = $body
    ->searchBackward('PGPFunctionCall', 'name', 'value', 'drupal_render')) {
    $statement->name['value'] = 'drupal_render_children';
  }
}