You are here

function moopapi_wrap in Module Object Oriented Programming API 7.2

Same name and namespace in other branches
  1. 6.2 moopapi.module \moopapi_wrap()
  2. 6 moopapi.module \moopapi_wrap()
  3. 7 moopapi.module \moopapi_wrap()

Api function that will create function wrapper to a class method

Parameters

string $app:

string $method:

array $decorators:

2 calls to moopapi_wrap()
MoopapiWebTestCase::testWrap in tests/moopapi.test
moopapi_init in ./moopapi.module
Implements of hook_init().

File

./moopapi.module, line 69

Code

function moopapi_wrap($app, $method, array $decorators = array()) {

  /**
   * We can't pass an array to defined as text function - so use
   * this workaround with setting a variable, which is going to
   * be read during function evaluation.
   * @see moopapi_object()
   */
  global $conf;
  $app_lower = strtolower($app);
  $conf["{$app_lower}_decorators"] = serialize($decorators);
  $function_name = "{$app}_{$method}";
  if (in_array($method, moopapi_hook_ignore_list())) {

    /**
     * I am assuming that developer wants this method to be executed
     * Because developer explicitly implemented this hook both in function and in method.
     *
     * WARNING: we cannot predict the type of arguments to be passed here. so we pass none.
     * This limitation is to the developer to figure out how to bypass
     */
    moopapi_object($app)
      ->{$method}();
    return;
  }
  elseif (function_exists($function_name) && !in_array($function_name, unserialize(variable_get('moopapi_functions_overridden', serialize(array()))))) {

    /**
     * This could mean that developer chose to create function on his own, so we respect his wishes and skip re-implementing it
     * If in this step function does not exist it means that it was not created by the developer or previously by us.
     * lets create it.
     */
    return;

    // do not create it again
  }

  /**
   * In order to enable passing proper parameters (and parameters by reference)
   * we must use PHP Reflection ( Ref: http://us.php.net/language.oop5.reflection )
   * to auto-discover certain properties, in this case number of arguments
   * a method expects.
   */
  $ref_method = new ReflectionMethod($app, $method);
  $parameters = $ref_method
    ->getParameters();

  // Determine whether to create or replace.
  if (Patchwork\Utils\callbackTargetDefined($function_name)) {

    // Use replaceLater as it allows not yet defined functions.
    Patchwork\replaceLater($function_name, function () {

      // To pass additional params that are not declared.
      $full_args = func_get_args();
      foreach ($parameters as $number => $parameter) {
        $var_name = $parameter
          ->getName();
        if ($parameter
          ->isPassedByReference()) {

          // Right part is a reference to a variable, which is called \$var_name.
          $full_args[$number] =& ${$var_name};
        }
      }
      $application = moopapi_object($app);
      return call_user_func_array(array(
        $application,
        $method,
      ), $full_args);
    });
  }
  else {
    $args = moopapi_create_args($parameters);
    $function = <<<END
function {<span class="php-variable">$function_name</span>}({<span class="php-variable">$args</span>}) {
  // To pass additional params that are not declared.
  \$full_args = func_get_args();
  \$ref_method = new ReflectionMethod('{<span class="php-variable">$app</span>}', '{<span class="php-variable">$method</span>}');
  \$parameters = \$ref_method->getParameters();
  foreach (\$parameters as \$number => \$parameter) {
    \$var_name = \$parameter->getName();
    if (\$parameter->isPassedByReference()) {
      // Right part is a reference to a variable, which is called \$var_name.
      \$full_args[\$number] = &\$\$var_name;
    }
  }
  \$application = moopapi_object('{<span class="php-variable">$app</span>}');
  return call_user_func_array(array(\$application, '{<span class="php-variable">$method</span>}'), \$full_args);
}
END;

    // This is what makes the magic possible create function in runtime that calls
    // our objects.
    eval($function);
  }
}