示例#1
0
 /**
  * Singleton, returns instance
  *
  * @return Piwik_API_Proxy
  */
 public static function getInstance()
 {
     if (self::$instance == null) {
         self::$instance = new self();
     }
     return self::$instance;
 }
示例#2
0
 /**
  * Singleton, returns instance
  *
  * @return Piwik_API_Proxy
  */
 public static function getInstance()
 {
     if (self::$instance == null) {
         $c = __CLASS__;
         self::$instance = new $c();
     }
     return self::$instance;
 }
示例#3
0
 public function listAllAPI()
 {
     $view = Piwik_View::factory("listAllAPI");
     $this->setGeneralVariablesView($view);
     $ApiDocumentation = new Piwik_API_DocumentationGenerator();
     $view->countLoadedAPI = Piwik_API_Proxy::getInstance()->getCountRegisteredClasses();
     $view->list_api_methods_with_links = $ApiDocumentation->getAllInterfaceString();
     echo $view->render();
 }
 function getAllRequestsWithParameters()
 {
     $requestUrls = array();
     $parametersToSet = array('idSite' => '1', 'period' => 'week', 'date' => 'today', 'expanded' => '1');
     foreach (Piwik_API_Proxy::getInstance()->getMetadata() as $class => $info) {
         $moduleName = Piwik_API_Proxy::getInstance()->getModuleNameFromClassName($class);
         foreach ($info as $methodName => $infoMethod) {
             $params = $this->getStrListParameters($class, $methodName);
             $exampleUrl = $this->getExampleUrl($class, $methodName, $parametersToSet);
             if ($exampleUrl !== false) {
                 $requestUrls[] = $exampleUrl;
             }
         }
     }
     return $requestUrls;
 }
示例#5
0
 /** 
  * Get a combined report of the *.get API methods. 
  */
 public function get($idSite, $period, $date, $segment = false, $columns = false)
 {
     $columns = Piwik::getArrayFromApiParameter($columns);
     // build columns map for faster checks later on
     $columnsMap = array();
     foreach ($columns as $column) {
         $columnsMap[$column] = true;
     }
     // find out which columns belong to which plugin
     $columnsByPlugin = array();
     $meta = Piwik_API_API::getInstance()->getReportMetadata($idSite, $period, $date);
     foreach ($meta as $reportMeta) {
         // scan all *.get reports
         if ($reportMeta['action'] == 'get' && !isset($reportMeta['parameters']) && $reportMeta['module'] != 'API') {
             $plugin = $reportMeta['module'];
             foreach ($reportMeta['metrics'] as $column => $columnTranslation) {
                 // a metric from this report has been requested
                 if (isset($columnsMap[$column]) || empty($columnsMap)) {
                     $columnsByPlugin[$plugin][] = $column;
                 }
             }
         }
     }
     krsort($columnsByPlugin);
     $mergedDataTable = false;
     $params = compact('idSite', 'period', 'date', 'segment', 'idGoal');
     foreach ($columnsByPlugin as $plugin => $columns) {
         // load the data
         $className = 'Piwik_' . $plugin . '_API';
         $params['columns'] = implode(',', $columns);
         $dataTable = Piwik_API_Proxy::getInstance()->call($className, 'get', $params);
         // make sure the table has all columns
         $array = $dataTable instanceof Piwik_DataTable_Array ? $dataTable->getArray() : array($dataTable);
         foreach ($array as $table) {
             // we don't support idSites=all&date=DATE1,DATE2
             if ($table instanceof Piwik_DataTable) {
                 $firstRow = $table->getFirstRow();
                 if (!$firstRow) {
                     $firstRow = new Piwik_DataTable_Row();
                     $table->addRow($firstRow);
                 }
                 foreach ($columns as $column) {
                     if ($firstRow->getColumn($column) === false) {
                         $firstRow->setColumn($column, 0);
                     }
                 }
             }
         }
         // merge reports
         if ($mergedDataTable === false) {
             $mergedDataTable = $dataTable;
         } else {
             $this->mergeDataTables($mergedDataTable, $dataTable);
         }
     }
     return $mergedDataTable;
 }
	/**
	 * Returns the methods $class.$name parameters (and default value if provided) as a string.
	 * 
	 * @param string The class name
	 * @param string The method name
	 * @return string For example "(idSite, period, date = 'today')"
	 */
	public function getParametersString($class, $name)
	{
		$aParameters = Piwik_API_Proxy::getInstance()->getParametersList($class, $name);
		$asParameters = array();
		foreach($aParameters as $nameVariable=> $defaultValue)
		{
			// Do not show API parameters starting with _ 
			// They are supposed to be used only in internal API calls
			if(strpos($nameVariable, '_') === 0)
			{
				continue;
			}
			$str = $nameVariable;
			if(!($defaultValue instanceof Piwik_API_Proxy_NoDefaultValue))
			{
				$str .= " = '$defaultValue'";
			}
			$asParameters[] = $str;
		}
		$sParameters = implode(", ", $asParameters);
		return "($sParameters)";
	}	
 /**
  * Returns the methods $class.$name parameters (and default value if provided) as a string.
  * 
  * @param string The class name
  * @param string The method name
  * @return string For example "(idSite, period, date = 'today')"
  */
 protected function getStrListParameters($class, $name)
 {
     $aParameters = Piwik_API_Proxy::getInstance()->getParametersList($class, $name);
     $asParameters = array();
     foreach ($aParameters as $nameVariable => $defaultValue) {
         $str = $nameVariable;
         if (!$defaultValue instanceof Piwik_API_Proxy_NoDefaultValue) {
             $str .= " = '{$defaultValue}'";
         }
         $asParameters[] = $str;
     }
     $sParameters = implode(", ", $asParameters);
     return "({$sParameters})";
 }
示例#8
0
	/**
	 * Handles the request to the API.
	 * It first checks that the method called (parameter 'method') is available in the module (it means that the method exists and is public)
	 * It then reads the parameters from the request string and throws an exception if there are missing parameters.
	 * It then calls the API Proxy which will call the requested method.
	 * 
	 * @return mixed The data resulting from the API call  
	 */
	public function process()
	{
		// read the format requested for the output data
		$outputFormat = strtolower(Piwik_Common::getRequestVar('format', 'xml', 'string', $this->request));
		
		// create the response
		$response = new Piwik_API_ResponseBuilder($outputFormat, $this->request);
		
		try {
			// read parameters
			$moduleMethod = Piwik_Common::getRequestVar('method', null, null, $this->request);
			
			list($module, $method) = $this->extractModuleAndMethod($moduleMethod); 
			
			if(!Piwik_PluginsManager::getInstance()->isPluginActivated($module))
			{
				throw new Piwik_FrontController_PluginDeactivatedException($module);
			}
			$module = "Piwik_" . $module . "_API";

			self::reloadAuthUsingTokenAuth($this->request);
			
			// call the method 
			$returnedValue = Piwik_API_Proxy::getInstance()->call($module, $method, $this->request);
			
			$toReturn = $response->getResponse($returnedValue);
		} catch(Exception $e ) {
			$toReturn = $response->getResponseException( $e );
		}
		return $toReturn;
	}
 /**
  * Method for the recursive descend
  * @return Piwik_DataTable_Row | false
  */
 protected function doFilterRecursiveDescend($labelParts, $dataTable, $date = false)
 {
     if (!$dataTable instanceof Piwik_DataTable) {
         throw new Exception("Using the label filter is not supported for DataTable " . get_class($dataTable));
     }
     // search for the first part of the tree search
     $labelPart = array_shift($labelParts);
     foreach ($this->getLabelVariations($labelPart) as $labelPart) {
         $row = $dataTable->getRowFromLabel($labelPart);
         if ($row !== false) {
             break;
         }
     }
     if ($row === false) {
         // not found
         return false;
     }
     // end of tree search reached
     if (count($labelParts) == 0) {
         return $row;
     }
     // match found on this level and more levels remaining: go deeper
     $request = $this->request;
     // this is why the filter does not work with expanded=1:
     // if the entire table is loaded, the id of sub-datatable has a different semantic.
     $idSubTable = $row->getIdSubDataTable();
     $request['idSubtable'] = $idSubTable;
     if ($date) {
         $request['date'] = $date;
     }
     $class = 'Piwik_' . $this->apiModule . '_API';
     $method = $this->getApiMethodForSubtable();
     // Clean up request for Piwik_API_ResponseBuilder to behave correctly
     unset($request['label']);
     $request['serialize'] = 0;
     $dataTable = Piwik_API_Proxy::getInstance()->call($class, $method, $request);
     $response = new Piwik_API_ResponseBuilder($format = 'original', $request);
     $dataTable = $response->getResponse($dataTable);
     return $this->doFilterRecursiveDescend($labelParts, $dataTable, $date);
 }
 /**
  * Given a list of default parameters to set, returns the URLs of APIs to call
  * If any API was specified in setApiToCall() we ensure only these are tested.
  * If any API is set as excluded (see list below) then it will be ignored.
  *
  * @param array       $parametersToSet Parameters to set in api call
  * @param array       $formats         Array of 'format' to fetch from API
  * @param array       $periods         Array of 'period' to query API
  * @param bool        $supertableApi
  * @param bool        $setDateLastN    If set to true, the 'date' parameter will be rewritten to query instead a range of dates, rather than one period only.
  * @param bool|string $language        2 letter language code, defaults to default piwik language
  * @param bool|string $segment
  * @param bool|string $fileExtension
  *
  * @throws Exception
  * @return array of API URLs query strings
  */
 protected function generateUrlsApi($parametersToSet, $formats, $periods, $supertableApi = false, $setDateLastN = false, $language = false, $segment = false, $fileExtension = false)
 {
     // Get the URLs to query against the API for all functions starting with get*
     $skipped = $requestUrls = array();
     $apiMetadata = new Piwik_API_DocumentationGenerator();
     foreach (Piwik_API_Proxy::getInstance()->getMetadata() as $class => $info) {
         $moduleName = Piwik_API_Proxy::getInstance()->getModuleNameFromClassName($class);
         foreach ($info as $methodName => $infoMethod) {
             $apiId = $moduleName . '.' . $methodName;
             // If Api to test were set, we only test these
             if (!empty(self::$apiToCall) && in_array($moduleName, self::$apiToCall) === false && in_array($apiId, self::$apiToCall) === false) {
                 $skipped[] = $apiId;
                 continue;
             } elseif (strpos($methodName, 'get') !== 0 && $methodName != 'generateReport' || in_array($moduleName, self::$apiNotToCall) === true || in_array($apiId, self::$apiNotToCall) === true || $methodName == 'getLogoUrl' || $methodName == 'getHeaderLogoUrl') {
                 $skipped[] = $apiId;
                 continue;
             }
             foreach ($periods as $period) {
                 $parametersToSet['period'] = $period;
                 // If date must be a date range, we process this date range by adding 6 periods to it
                 if ($setDateLastN) {
                     if (!isset($parametersToSet['dateRewriteBackup'])) {
                         $parametersToSet['dateRewriteBackup'] = $parametersToSet['date'];
                     }
                     $lastCount = (int) $setDateLastN;
                     if ($setDateLastN === true) {
                         $lastCount = 6;
                     }
                     $firstDate = $parametersToSet['dateRewriteBackup'];
                     $secondDate = date('Y-m-d', strtotime("+{$lastCount} " . $period . "s", strtotime($firstDate)));
                     $parametersToSet['date'] = $firstDate . ',' . $secondDate;
                 }
                 // Set response language
                 if ($language !== false) {
                     $parametersToSet['language'] = $language;
                 }
                 // set idSubtable if subtable API is set
                 if ($supertableApi !== false) {
                     $request = new Piwik_API_Request(array('module' => 'API', 'method' => $supertableApi, 'idSite' => $parametersToSet['idSite'], 'period' => $parametersToSet['period'], 'date' => $parametersToSet['date'], 'format' => 'php', 'serialize' => 0));
                     // find first row w/ subtable
                     foreach ($request->process() as $row) {
                         if (isset($row['idsubdatatable'])) {
                             $parametersToSet['idSubtable'] = $row['idsubdatatable'];
                             break;
                         }
                     }
                     // if no subtable found, throw
                     if (!isset($parametersToSet['idSubtable'])) {
                         throw new Exception("Cannot find subtable to load for {$apiId} in {$supertableApi}.");
                     }
                 }
                 // Generate for each specified format
                 foreach ($formats as $format) {
                     $parametersToSet['format'] = $format;
                     $parametersToSet['hideIdSubDatable'] = 1;
                     $parametersToSet['serialize'] = 1;
                     $exampleUrl = $apiMetadata->getExampleUrl($class, $methodName, $parametersToSet);
                     if ($exampleUrl === false) {
                         $skipped[] = $apiId;
                         continue;
                     }
                     // Remove the first ? in the query string
                     $exampleUrl = substr($exampleUrl, 1);
                     $apiRequestId = $apiId;
                     if (strpos($exampleUrl, 'period=') !== false) {
                         $apiRequestId .= '_' . $period;
                     }
                     $apiRequestId .= '.' . $format;
                     if ($fileExtension) {
                         $apiRequestId .= '.' . $fileExtension;
                     }
                     $requestUrls[$apiRequestId] = $exampleUrl;
                 }
             }
         }
     }
     return $requestUrls;
 }
 public function tearDown()
 {
     parent::tearDown();
     // reset that value after the test
     Piwik_API_Proxy::getInstance()->setHideIgnoredFunctions(true);
 }
示例#12
0
 /**
  * Load the subtable for a row.
  * Returns null if none is found.
  *
  * @param Piwik_Datatable_Row  $row
  * @param bool|string          $date
  * @throws Exception
  * @return Piwik_DataTable
  */
 protected function loadSubtable($row, $date = false)
 {
     if (!($this->apiModule && $this->apiMethod && count($this->request))) {
         return null;
     }
     $request = $this->request;
     // loading subtables doesn't work if expanded=1 because when the entire table is loaded,
     // the ids of sub-datatables have a different semantic.
     if (Piwik_Common::getRequestVar('expanded', false, 'int', $this->request)) {
         throw new Exception('Cannot load subtable if expanded=1 is set.');
     }
     $idSubTable = $row->getIdSubDataTable();
     if ($idSubTable === null) {
         return null;
     }
     $request['idSubtable'] = $idSubTable;
     if ($date) {
         $request['date'] = $date;
     }
     $class = 'Piwik_' . $this->apiModule . '_API';
     $method = $this->getApiMethodForSubtable();
     $this->manipulateSubtableRequest($request);
     $request['serialize'] = 0;
     $dataTable = Piwik_API_Proxy::getInstance()->call($class, $method, $request);
     $response = new Piwik_API_ResponseBuilder($format = 'original', $request);
     $dataTable = $response->getResponse($dataTable);
     if (method_exists($dataTable, 'applyQueuedFilters')) {
         $dataTable->applyQueuedFilters();
     }
     return $dataTable;
 }
示例#13
0
 /**
  * Handles the request to the API.
  * It first checks that the method called (parameter 'method') is available in the module (it means that the method exists and is public)
  * It then reads the parameters from the request string and throws an exception if there are missing parameters.
  * It then calls the API Proxy which will call the requested method.
  * 
  * @return mixed The data resulting from the API call  
  */
 public function process()
 {
     // read the format requested for the output data
     $outputFormat = strtolower(Piwik_Common::getRequestVar('format', 'xml', 'string', $this->request));
     // create the response
     $response = new Piwik_API_ResponseBuilder($this->request, $outputFormat);
     try {
         // read parameters
         $moduleMethod = Piwik_Common::getRequestVar('method', null, null, $this->request);
         list($module, $method) = $this->extractModuleAndMethod($moduleMethod);
         if (!Piwik_PluginsManager::getInstance()->isPluginActivated($module)) {
             throw new Piwik_FrontController_PluginDeactivatedException($module);
         }
         $module = "Piwik_" . $module . "_API";
         // if a token_auth is specified in the API request, we load the right permissions
         $token_auth = Piwik_Common::getRequestVar('token_auth', '', 'string', $this->request);
         if ($token_auth) {
             Piwik_PostEvent('API.Request.authenticate', $token_auth);
             Zend_Registry::get('access')->reloadAccess();
         }
         // call the method
         $returnedValue = Piwik_API_Proxy::getInstance()->call($module, $method, $this->request);
         $toReturn = $response->getResponse($returnedValue);
     } catch (Exception $e) {
         $toReturn = $response->getResponseException($e);
     }
     return $toReturn;
 }
 /**
  * The main test case. Runs API & Controller tests.
  *
  * This can be overriden to add more testing logic (or a new test case
  * can be added).
  */
 public function test_RunAllTests()
 {
     $this->trackVisits();
     // From Piwik 1.5, we hide Goals.getConversions and other get* methods via @ignore, but we ensure that they still work
     // This hack allows the API proxy to let us generate example URLs for the ignored functions
     Piwik_API_Proxy::getInstance()->hideIgnoredFunctions = false;
     $this->runApiTests();
     $this->runControllerTests();
 }
示例#15
0
 /**
  * Method always called when making an API request.
  * It checks several things before actually calling the real method on the given module.
  * 
  * 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)
  * 
  * @param string The method name
  * @param array The parameters
  * 
  * @throws Piwik_Access_NoAccessException 
  */
 public function __call($methodName, $parameterValues)
 {
     $returnedValue = null;
     try {
         $this->registerClass(self::$classCalled);
         $className = $this->getClassNameFromModule(self::$classCalled);
         // instanciate the object
         $object = call_user_func(array($className, "getInstance"));
         // check method exists
         $this->checkMethodExists($className, $methodName);
         // first check number of parameters do match
         $this->checkNumberOfParametersMatch($className, $methodName, $parameterValues);
         // start the timer
         $timer = new Piwik_Timer();
         // call the method
         $returnedValue = call_user_func_array(array($object, $methodName), $parameterValues);
         // log the API Call
         $parameterNamesDefaultValues = $this->getParametersList($className, $methodName);
         Zend_Registry::get('logger_api_call')->log(self::$classCalled, $methodName, $parameterNamesDefaultValues, $parameterValues, $timer->getTimeMs(), $returnedValue);
     } catch (Piwik_Access_NoAccessException $e) {
         throw $e;
     }
     self::$classCalled = null;
     return $returnedValue;
 }
 public function tearDown()
 {
     Piwik_API_Proxy::getInstance()->setHideIgnoredFunctions(true);
 }