Piwik\API\Proxy::call PHP Method

call() public method

It also logs the API calls, with the parameters values, the returned value, the performance, etc. You can enable logging in config/global.ini.php (log_api_call)
public call ( string $className, string $methodName, array $parametersRequest ) : mixed | null
$className string The class name (eg. API)
$methodName string The method name
$parametersRequest array The parameters pairs (name=>value)
return mixed | null
    public function call($className, $methodName, $parametersRequest)
    {
        $returnedValue = null;
        // Temporarily sets the Request array to this API call context
        $saveGET = $_GET;
        $saveQUERY_STRING = @$_SERVER['QUERY_STRING'];
        foreach ($parametersRequest as $param => $value) {
            $_GET[$param] = $value;
        }
        try {
            $this->registerClass($className);
            // instanciate the object
            $object = $className::getInstance();
            // check method exists
            $this->checkMethodExists($className, $methodName);
            // get the list of parameters required by the method
            $parameterNamesDefaultValues = $this->getParametersList($className, $methodName);
            // load parameters in the right order, etc.
            $finalParameters = $this->getRequestParametersArray($parameterNamesDefaultValues, $parametersRequest);
            // allow plugins to manipulate the value
            $pluginName = $this->getModuleNameFromClassName($className);
            /**
             * Triggered before an API request is dispatched.
             *
             * This event can be used to modify the arguments passed to one or more API methods.
             *
             * **Example**
             *
             *     Piwik::addAction('API.Request.dispatch', function (&$parameters, $pluginName, $methodName) {
             *         if ($pluginName == 'Actions') {
             *             if ($methodName == 'getPageUrls') {
             *                 // ... do something ...
             *             } else {
             *                 // ... do something else ...
             *             }
             *         }
             *     });
             *
             * @param array &$finalParameters List of parameters that will be passed to the API method.
             * @param string $pluginName The name of the plugin the API method belongs to.
             * @param string $methodName The name of the API method that will be called.
             */
            Piwik::postEvent('API.Request.dispatch', array(&$finalParameters, $pluginName, $methodName));
            /**
             * Triggered before an API request is dispatched.
             *
             * This event exists for convenience and is triggered directly after the {@hook API.Request.dispatch}
             * event is triggered. It can be used to modify the arguments passed to a **single** API method.
             *
             * _Note: This is can be accomplished with the {@hook API.Request.dispatch} event as well, however
             * event handlers for that event will have to do more work._
             *
             * **Example**
             *
             *     Piwik::addAction('API.Actions.getPageUrls', function (&$parameters) {
             *         // force use of a single website. for some reason.
             *         $parameters['idSite'] = 1;
             *     });
             *
             * @param array &$finalParameters List of parameters that will be passed to the API method.
             */
            Piwik::postEvent(sprintf('API.%s.%s', $pluginName, $methodName), array(&$finalParameters));
            $apiParametersInCorrectOrder = array();
            foreach ($parameterNamesDefaultValues as $name => $defaultValue) {
                if (isset($finalParameters[$name]) || array_key_exists($name, $finalParameters)) {
                    $apiParametersInCorrectOrder[] = $finalParameters[$name];
                }
            }
            // call the method
            $returnedValue = call_user_func_array(array($object, $methodName), $apiParametersInCorrectOrder);
            $endHookParams = array(&$returnedValue, array('className' => $className, 'module' => $pluginName, 'action' => $methodName, 'parameters' => $finalParameters));
            /**
             * Triggered directly after an API request is dispatched.
             *
             * This event exists for convenience and is triggered immediately before the
             * {@hook API.Request.dispatch.end} event. It can be used to modify the output of a **single**
             * API method.
             *
             * _Note: This can be accomplished with the {@hook API.Request.dispatch.end} event as well,
             * however event handlers for that event will have to do more work._
             *
             * **Example**
             *
             *     // append (0 hits) to the end of row labels whose row has 0 hits
             *     Piwik::addAction('API.Actions.getPageUrls', function (&$returnValue, $info)) {
             *         $returnValue->filter('ColumnCallbackReplace', 'label', function ($label, $hits) {
             *             if ($hits === 0) {
             *                 return $label . " (0 hits)";
             *             } else {
             *                 return $label;
             *             }
             *         }, null, array('nb_hits'));
             *     }
             *
             * @param mixed &$returnedValue The API method's return value. Can be an object, such as a
             *                              {@link Piwik\DataTable DataTable} instance.
             *                              could be a {@link Piwik\DataTable DataTable}.
             * @param array $extraInfo An array holding information regarding the API request. Will
             *                         contain the following data:
             *
             *                         - **className**: The namespace-d class name of the API instance
             *                                          that's being called.
             *                         - **module**: The name of the plugin the API request was
             *                                       dispatched to.
             *                         - **action**: The name of the API method that was executed.
             *                         - **parameters**: The array of parameters passed to the API
             *                                           method.
             */
            Piwik::postEvent(sprintf('API.%s.%s.end', $pluginName, $methodName), $endHookParams);
            /**
             * Triggered directly after an API request is dispatched.
             *
             * This event can be used to modify the output of any API method.
             *
             * **Example**
             *
             *     // append (0 hits) to the end of row labels whose row has 0 hits for any report that has the 'nb_hits' metric
             *     Piwik::addAction('API.Actions.getPageUrls.end', function (&$returnValue, $info)) {
             *         // don't process non-DataTable reports and reports that don't have the nb_hits column
             *         if (!($returnValue instanceof DataTableInterface)
             *             || in_array('nb_hits', $returnValue->getColumns())
             *         ) {
             *             return;
             *         }
             *
             *         $returnValue->filter('ColumnCallbackReplace', 'label', function ($label, $hits) {
             *             if ($hits === 0) {
             *                 return $label . " (0 hits)";
             *             } else {
             *                 return $label;
             *             }
             *         }, null, array('nb_hits'));
             *     }
             *
             * @param mixed &$returnedValue The API method's return value. Can be an object, such as a
             *                              {@link Piwik\DataTable DataTable} instance.
             * @param array $extraInfo An array holding information regarding the API request. Will
             *                         contain the following data:
             *
             *                         - **className**: The namespace-d class name of the API instance
             *                                          that's being called.
             *                         - **module**: The name of the plugin the API request was
             *                                       dispatched to.
             *                         - **action**: The name of the API method that was executed.
             *                         - **parameters**: The array of parameters passed to the API
             *                                           method.
             */
            Piwik::postEvent('API.Request.dispatch.end', $endHookParams);
            // Restore the request
            $_GET = $saveGET;
            $_SERVER['QUERY_STRING'] = $saveQUERY_STRING;
        } catch (Exception $e) {
            $_GET = $saveGET;
            throw $e;
        }
        return $returnedValue;
    }

Usage Example

Example #1
0
 public function test_generateReport_CatchesIndividualReportProcessExceptions_WithoutFailingToGenerateWholeReport()
 {
     $realProxy = new Proxy();
     $mockProxy = $this->getMock('Piwik\\API\\Proxy', array('call'));
     $mockProxy->expects($this->any())->method('call')->willReturnCallback(function ($className, $methodName, $parametersRequest) use($realProxy) {
         switch ($className) {
             case '\\Piwik\\Plugins\\VisitsSummary\\API':
                 $result = new DataTable();
                 $result->addRowFromSimpleArray(array('label' => 'visits label', 'nb_visits' => 1));
                 return $result;
             case '\\Piwik\\Plugins\\UserCountry\\API':
                 throw new \Exception("error");
             case '\\Piwik\\Plugins\\Referrers\\API':
                 $result = new DataTable();
                 $result->addRowFromSimpleArray(array('label' => 'referrers label', 'nb_visits' => 1));
                 return $result;
             case '\\Piwik\\Plugins\\API\\API':
                 return $realProxy->call($className, $methodName, $parametersRequest);
             default:
                 throw new \Exception("Unexpected method {$className}::{$methodName}.");
         }
     });
     Proxy::setSingletonInstance($mockProxy);
     $idReport = APIScheduledReports::getInstance()->addReport(1, '', Schedule::PERIOD_DAY, 0, ScheduledReports::EMAIL_TYPE, ReportRenderer::HTML_FORMAT, array('VisitsSummary_get', 'UserCountry_getCountry', 'Referrers_getWebsites'), array(ScheduledReports::DISPLAY_FORMAT_PARAMETER => ScheduledReports::DISPLAY_FORMAT_TABLES_ONLY));
     ob_start();
     $result = APIScheduledReports::getInstance()->generateReport($idReport, Date::factory('now')->toString(), $language = false, $outputType = APIScheduledReports::OUTPUT_RETURN);
     ob_end_clean();
     $this->assertContains('id="VisitsSummary_get"', $result);
     $this->assertContains('id="Referrers_getWebsites"', $result);
     $this->assertNotContains('id="UserCountry_getCountry"', $result);
 }