/**
	 * Given a list of fields defining numeric values, it will return a Piwik_DataTable_Array
	 * ordered by idsite
	 *
	 * @param array|string $fields array( fieldName1, fieldName2, ...)  Names of the mysql table fields to load
	 * @return Piwik_DataTable_Array
	 */
	public function getDataTableFromNumeric( $fields )
	{
		$tableArray = $this->getNewDataTableArray();
		if ($this->getFirstArchive() instanceof Piwik_Archive_Single)
		{
			$values = $this->getValues($fields);
			foreach($this->archives as $idSite => $archive)
			{
				$table = new Piwik_DataTable_Simple();
				if (array_key_exists($idSite, $values))
				{
					$table->addRowsFromArray($values[$idSite]);
				}
				$tableArray->addTable($table, $idSite);
			}
		}
		elseif ($this->getFirstArchive() instanceof Piwik_Archive_Array)
		{
			foreach($this->archives as $idSite => $archive)
			{
				$tableArray->addTable($archive->getDataTableFromNumeric($fields), $idSite);
			}
		}
		
		return $tableArray;
	}
Example #2
0
 /**
  * Enhance $simpleDataTable using metadata :
  *
  * - remove metrics based on $reportMetadata['metrics']
  * - add 0 valued metrics if $simpleDataTable doesn't provide all $reportMetadata['metrics']
  * - format metric values to a 'human readable' format
  * - extract row metadata to a separate Piwik_DataTable_Simple $rowsMetadata
  *
  * @param int $idSite enables monetary value formatting based on site currency
  * @param Piwik_DataTable_Simple $simpleDataTable
  * @param array $metadataColumns
  * @param boolean $hasDimension
  * @return array Piwik_DataTable $enhancedDataTable filtered metrics with human readable format & Piwik_DataTable_Simple $rowsMetadata
  */
 private function handleSimpleDataTable($idSite, $simpleDataTable, $metadataColumns, $hasDimension)
 {
     // new DataTable to store metadata
     $rowsMetadata = new Piwik_DataTable();
     // new DataTable to store 'human readable' values
     if ($hasDimension) {
         $enhancedDataTable = new Piwik_DataTable();
     } else {
         $enhancedDataTable = new Piwik_DataTable_Simple();
     }
     // add missing metrics
     foreach ($simpleDataTable->getRows() as $row) {
         $rowMetrics = $row->getColumns();
         foreach ($metadataColumns as $id => $name) {
             if (!isset($rowMetrics[$id])) {
                 $row->addColumn($id, 0);
             }
         }
     }
     foreach ($simpleDataTable->getRows() as $row) {
         $enhancedRow = new Piwik_DataTable_Row();
         $enhancedDataTable->addRow($enhancedRow);
         $rowMetrics = $row->getColumns();
         foreach ($rowMetrics as $columnName => $columnValue) {
             // filter metrics according to metadata definition
             if (isset($metadataColumns[$columnName])) {
                 // generate 'human readable' metric values
                 $prettyValue = Piwik::getPrettyValue($idSite, $columnName, $columnValue, false, false);
                 $enhancedRow->addColumn($columnName, $prettyValue);
             }
         }
         // If report has a dimension, extract metadata into a distinct DataTable
         if ($hasDimension) {
             $rowMetadata = $row->getMetadata();
             $idSubDataTable = $row->getIdSubDataTable();
             // Create a row metadata only if there are metadata to insert
             if (count($rowMetadata) > 0 || !is_null($idSubDataTable)) {
                 $metadataRow = new Piwik_DataTable_Row();
                 $rowsMetadata->addRow($metadataRow);
                 foreach ($rowMetadata as $metadataKey => $metadataValue) {
                     $metadataRow->addColumn($metadataKey, $metadataValue);
                 }
                 if (!is_null($idSubDataTable)) {
                     $metadataRow->addColumn('idsubdatatable', $idSubDataTable);
                 }
             }
         }
     }
     return array($enhancedDataTable, $rowsMetadata);
 }
Example #3
0
 /**
  * Given a list of fields defining numeric values, it will return a Piwik_DataTable_Simple
  * containing one row per field name.
  *
  * For example $fields = array(    'max_actions',
  *                        'nb_uniq_visitors',
  *                        'nb_visits',
  *                        'nb_actions',
  *                        'sum_visit_length',
  *                        'bounce_count',
  *                        'nb_visits_converted'
  *                    );
  *
  * @param string|array $fields Name or array of names of Archive fields
  *
  * @return Piwik_DataTable_Simple
  */
 public function getDataTableFromNumeric($fields)
 {
     if (!is_array($fields)) {
         $fields = array($fields);
     }
     $values = array();
     foreach ($fields as $field) {
         $values[$field] = $this->getNumeric($field);
     }
     $table = new Piwik_DataTable_Simple();
     $table->addRowsFromArray($values);
     return $table;
 }
Example #4
0
 protected function _getDataTableSimpleOneRowArrayTest()
 {
     $array1 = array('nb_visits' => 14.0);
     $table1 = new Piwik_DataTable_Simple();
     $table1->addRowsFromArray($array1);
     $array2 = array('nb_visits' => 15.0);
     $table2 = new Piwik_DataTable_Simple();
     $table2->addRowsFromArray($array2);
     $table3 = new Piwik_DataTable_Simple();
     $table = new Piwik_DataTable_Array();
     $table->setKeyName('testKey');
     $table->addTable($table1, 'row1');
     $table->addTable($table2, 'row2');
     $table->addTable($table3, 'row3');
     return $table;
 }
	protected function handleScalar($scalar)
	{
		$dataTable = new Piwik_DataTable_Simple();
		$dataTable->addRowsFromArray( array($scalar) );
		return $this->getRenderedDataTable($dataTable);
	}
Example #6
0
 /**
  * Converts the simple data table to an array
  *
  * @param Piwik_DataTable_Simple  $table
  * @return array
  */
 protected function renderSimpleTable($table)
 {
     $array = array();
     $row = $table->getFirstRow();
     if ($row === false) {
         return $array;
     }
     foreach ($row->getColumns() as $columnName => $columnValue) {
         $array[$columnName] = $columnValue;
     }
     return $array;
 }
Example #7
0
 /**
  * Returns a DataTable_Array containing values 
  * of the element $name from the archives in this Archive_Array.
  *
  * The value to be returned are blob values (stored in the archive_numeric_* tables in the DB).	 * 
  * It can return anything from strings, to serialized PHP arrays or PHP objects, etc.
  *
  * @param string  $name  Name of the mysql table field to load eg. Referers_keywordBySearchEngine
  * @return Piwik_DataTable_Array  containing the requested blob values for each Archive
  */
 public function getBlob($name)
 {
     $table = $this->getNewDataTableArray();
     foreach ($this->archives as $archive) {
         $blob = $archive->getBlob($name);
         $subTable = new Piwik_DataTable_Simple();
         $subTable->addRowsFromArray(array('blob' => $blob));
         $table->addTable($subTable, $this->getDataTableLabelValue($archive));
         $this->loadMetadata($table, $archive);
     }
     return $table;
 }
Example #8
0
 /**
  * Convert a dimension-less report to a multi-row two-column data table
  *
  * @static
  * @param  $reportMetadata array
  * @param  $report Piwik_DataTable
  * @param  $reportColumns array
  * @return array Piwik_DataTable $report & array $columns
  */
 protected static function processTableFormat($reportMetadata, $report, $reportColumns)
 {
     $finalReport = $report;
     if (empty($reportMetadata['dimension'])) {
         //			var_dump($report);
         $simpleReportMetrics = $report->getFirstRow();
         if ($simpleReportMetrics) {
             $finalReport = new Piwik_DataTable_Simple();
             foreach ($simpleReportMetrics->getColumns() as $metricId => $metric) {
                 $newRow = new Piwik_DataTable_Row();
                 $newRow->addColumn("label", $reportColumns[$metricId]);
                 $newRow->addColumn("value", $metric);
                 $finalReport->addRow($newRow);
             }
         }
         $reportColumns = array('label' => Piwik_Translate('General_Name'), 'value' => Piwik_Translate('General_Value'));
     }
     return array($finalReport, $reportColumns);
 }
Example #9
0
 /**
  * Converts the output of the given simple data table
  *
  * @param Piwik_DataTable_Simple  $table
  * @param array                   $allColumns
  * @return string
  */
 protected function renderDataTable($table, &$allColumns = array())
 {
     if ($table instanceof Piwik_DataTable_Simple) {
         $row = $table->getFirstRow();
         if ($row !== false) {
             $columnNameToValue = $row->getColumns();
             if (count($columnNameToValue) == 1) {
                 // simple tables should only have one column, the value
                 $allColumns['value'] = true;
                 $value = array_values($columnNameToValue);
                 $str = 'value' . $this->lineEnd . $this->formatValue($value[0]);
                 return $str;
             }
         }
     }
     $csv = array();
     foreach ($table->getRows() as $row) {
         $csvRow = array();
         $columns = $row->getColumns();
         foreach ($columns as $name => $value) {
             //goals => array( 'idgoal=1' =>array(..), 'idgoal=2' => array(..))
             if (is_array($value)) {
                 foreach ($value as $key => $subValues) {
                     if (is_array($subValues)) {
                         foreach ($subValues as $subKey => $subValue) {
                             if ($this->translateColumnNames) {
                                 $subName = $name != 'goals' ? $name . ' ' . $key : Piwik_Translate('Goals_GoalX', $key);
                                 $columnName = $this->translateColumnName($subKey) . ' (' . $subName . ')';
                             } else {
                                 // goals_idgoal=1
                                 $columnName = $name . "_" . $key . "_" . $subKey;
                             }
                             $allColumns[$columnName] = true;
                             $csvRow[$columnName] = $subValue;
                         }
                     }
                 }
             } else {
                 $allColumns[$name] = true;
                 $csvRow[$name] = $value;
             }
         }
         if ($this->exportMetadata) {
             $metadata = $row->getMetadata();
             foreach ($metadata as $name => $value) {
                 if ($name == 'idsubdatatable_in_db') {
                     continue;
                 }
                 //if a metadata and a column have the same name make sure they dont overwrite
                 if ($this->translateColumnNames) {
                     $name = Piwik_Translate('General_Metadata') . ': ' . $name;
                 } else {
                     $name = 'metadata_' . $name;
                 }
                 $allColumns[$name] = true;
                 $csvRow[$name] = $value;
             }
         }
         if ($this->exportIdSubtable) {
             $idsubdatatable = $row->getIdSubDataTable();
             if ($idsubdatatable !== false && $this->hideIdSubDatatable === false) {
                 $csvRow['idsubdatatable'] = $idsubdatatable;
             }
         }
         $csv[] = $csvRow;
     }
     // now we make sure that all the rows in the CSV array have all the columns
     foreach ($csv as &$row) {
         foreach ($allColumns as $columnName => $true) {
             if (!isset($row[$columnName])) {
                 $row[$columnName] = '';
             }
         }
     }
     $str = '';
     // specific case, we have only one column and this column wasn't named properly (indexed by a number)
     // we don't print anything in the CSV file => an empty line
     if (sizeof($allColumns) == 1 && reset($allColumns) && !is_string(key($allColumns))) {
         $str .= '';
     } else {
         // render row names
         $str .= $this->getHeaderLine(array_keys($allColumns)) . $this->lineEnd;
     }
     // we render the CSV
     foreach ($csv as $theRow) {
         $rowStr = '';
         foreach ($allColumns as $columnName => $true) {
             $rowStr .= $this->formatValue($theRow[$columnName]) . $this->separator;
         }
         // remove the last separator
         $rowStr = substr_replace($rowStr, "", -strlen($this->separator));
         $str .= $rowStr . $this->lineEnd;
     }
     $str = substr($str, 0, -strlen($this->lineEnd));
     return $str;
 }
Example #10
0
 /**
  * Adds the given data table to the table structure array
  *
  * @param Piwik_DataTable_Simple  $table
  * @param null|string             $columnToAdd
  * @param null|string             $valueToAdd
  * @throws Exception
  */
 protected function buildTableStructure($table, $columnToAdd = null, $valueToAdd = null)
 {
     $i = $this->i;
     $someMetadata = false;
     $someIdSubTable = false;
     /*
      * table = array
      * ROW1 = col1 | col2 | col3 | metadata | idSubTable
      * ROW2 = col1 | col2 (no value but appears) | col3 | metadata | idSubTable
      */
     if (!$table instanceof Piwik_DataTable) {
         throw new Exception("HTML Renderer does not work with this combination of parameters");
     }
     foreach ($table->getRows() as $row) {
         if (isset($columnToAdd) && isset($valueToAdd)) {
             $this->allColumns[$columnToAdd] = true;
             $this->tableStructure[$i][$columnToAdd] = $valueToAdd;
         }
         foreach ($row->getColumns() as $column => $value) {
             $this->allColumns[$column] = true;
             $this->tableStructure[$i][$column] = $value;
         }
         $metadata = array();
         foreach ($row->getMetadata() as $name => $value) {
             if (is_string($value)) {
                 $value = "'{$value}'";
             }
             $metadata[] = "'{$name}' => {$value}";
         }
         if (count($metadata) != 0) {
             $someMetadata = true;
             $metadata = implode("<br />", $metadata);
             $this->tableStructure[$i]['_metadata'] = $metadata;
         }
         $idSubtable = $row->getIdSubDataTable();
         if (!is_null($idSubtable)) {
             $someIdSubTable = true;
             $this->tableStructure[$i]['_idSubtable'] = $idSubtable;
         }
         $i++;
     }
     $this->i = $i;
     $this->allColumns['_metadata'] = $someMetadata;
     $this->allColumns['_idSubtable'] = $someIdSubTable;
 }
Example #11
0
 /**
  * This method post processes the data resulting from the API call.
  * 
  * - If the data resulted from the API call is a Piwik_DataTable then 
  * 		- we apply the standard filters if the parameters have been found
  * 		  in the URL. For example to offset,limit the Table you can add the following parameters to any API
  *  	  call that returns a DataTable: filter_limit=10&filter_offset=20
  * 		- we apply the filters that have been previously queued on the DataTable
  *        @see Piwik_DataTable::queueFilter()
  * 		- we apply the renderer that generate the DataTable in a given format (XML, PHP, HTML, JSON, etc.) 
  * 		  the format can be changed using the 'format' parameter in the request.
  *        Example: format=xml
  * 
  * - If there is nothing returned (void) we display a standard success message
  * 
  * - If there is a PHP array returned, we try to convert it to a dataTable 
  *   It is then possible to convert this datatable to any requested format (xml/etc)
  * 
  * - If a bool is returned we convert to a string (true is displayed as 'true' false as 'false')
  * 
  * - If an integer / float is returned, we simply return it
  * 
  * @throws Exception If an object/resource is returned, if any of conversion fails, etc. 
  * 
  * @param mixed The initial returned value, before post process
  * @return mixed Usually a string, but can still be a PHP data structure if the format requested is 'original'
  */
 protected function handleReturnedValue($returnedValue)
 {
     $toReturn = $returnedValue;
     // If the returned value is an object DataTable we
     // apply the set of generic filters if asked in the URL
     // and we render the DataTable according to the format specified in the URL
     if ($returnedValue instanceof Piwik_DataTable || $returnedValue instanceof Piwik_DataTable_Array) {
         if ($returnedValue instanceof Piwik_DataTable) {
             $this->applyDataTableGenericFilters($returnedValue);
         } elseif ($returnedValue instanceof Piwik_DataTable_Array) {
             $tables = $returnedValue->getArray();
             foreach ($tables as $table) {
                 $this->applyDataTableGenericFilters($table);
             }
         }
         // if the flag disable_queued_filters is defined we skip the filters that were queued
         // useful in some very rare cases but better to use this than a bad hack on the data returned...
         if (Piwik_Common::getRequestVar('disable_queued_filters', 'false', 'string', $this->requestToUse) == 'false') {
             $returnedValue->applyQueuedFilters();
         }
         $toReturn = $this->getRenderedDataTable($returnedValue);
     } elseif (!isset($toReturn)) {
         $toReturn = $this->getStandardSuccessOutput($this->outputFormatRequested);
     } elseif (is_array($toReturn)) {
         if ($this->outputFormatRequested == 'original') {
             // we handle the serialization. Because some php array have a very special structure that
             // couldn't be converted with the automatic DataTable->loadFromSimpleArray
             // the user may want to request the original PHP data structure serialized by the API
             // in case he has to setup serialize=1 in the URL
             if ($this->caseRendererPHPSerialize($defaultSerialize = 0)) {
                 $toReturn = serialize($toReturn);
             }
         } else {
             $dataTable = new Piwik_DataTable();
             $dataTable->loadFromSimpleArray($toReturn);
             $toReturn = $this->getRenderedDataTable($dataTable);
         }
     } else {
         // original data structure requested, we return without process
         if ($this->outputFormatRequested == 'original') {
             return $toReturn;
         }
         if ($toReturn === true) {
             $toReturn = 'true';
         } elseif ($toReturn === false) {
             $toReturn = 'false';
         } elseif (is_object($toReturn) || is_resource($toReturn)) {
             return $this->getExceptionOutput(' The API cannot handle this data structure. You can get the data internally by directly using the class.', $this->outputFormatRequested);
         }
         require_once "DataTable/Simple.php";
         $dataTable = new Piwik_DataTable_Simple();
         $dataTable->loadFromArray(array($toReturn));
         $toReturn = $this->getRenderedDataTable($dataTable);
     }
     return $toReturn;
 }
Example #12
0
 /**
  * Returns a DataTable_Simple with one row per field from $fields array names.
  *
  * @param string|array $fields Name or array of names of Archive fields 
  * 
  * @return Piwik_DataTable_Simple
  */
 public function getDataTableFromNumeric($fields)
 {
     require_once "DataTable/Simple.php";
     if (!is_array($fields)) {
         $fields = array($fields);
     }
     $values = array();
     foreach ($fields as $field) {
         $values[$field] = $this->getNumeric($field);
     }
     $table = new Piwik_DataTable_Simple();
     $table->loadFromArray($values);
     return $table;
 }