diff options
author | Thomas Steur <thomas.steur@googlemail.com> | 2014-08-26 18:35:55 +0400 |
---|---|---|
committer | Thomas Steur <thomas.steur@googlemail.com> | 2014-08-26 18:35:55 +0400 |
commit | 18e7b5688e7ae40a24801e2f3bd9eec867ba8c16 (patch) | |
tree | d16eb49ed135da66b687f286c5d078cbec3c1161 /plugins/Contents | |
parent | 24b470b815d648ca1be2a366da08b672dc46bdbb (diff) |
refs #4996 archiving of impressions should work now, displaying impressions should work (contentName => contentPiece and contentPiece => contentName). Next step: Matching interactions with impressions then this part is nearly done hopefully
Diffstat (limited to 'plugins/Contents')
-rw-r--r-- | plugins/Contents/API.php | 45 | ||||
-rw-r--r-- | plugins/Contents/Archiver.php | 82 | ||||
-rw-r--r-- | plugins/Contents/Contents.php | 2 | ||||
-rw-r--r-- | plugins/Contents/Controller.php | 56 | ||||
-rw-r--r-- | plugins/Contents/DataArray.php | 11 | ||||
-rw-r--r-- | plugins/Contents/Dimensions.php | 90 | ||||
-rw-r--r-- | plugins/Contents/Menu.php | 24 | ||||
-rw-r--r-- | plugins/Contents/Reports/Base.php | 17 | ||||
-rw-r--r-- | plugins/Contents/Reports/GetContentNames.php | 36 | ||||
-rw-r--r-- | plugins/Contents/Reports/GetContentPieces.php | 37 | ||||
-rw-r--r-- | plugins/Contents/Reports/GetContents.php | 67 | ||||
-rw-r--r-- | plugins/Contents/lang/en.json | 2 |
12 files changed, 341 insertions, 128 deletions
diff --git a/plugins/Contents/API.php b/plugins/Contents/API.php index f9c2b8d9ab..15cd14179e 100644 --- a/plugins/Contents/API.php +++ b/plugins/Contents/API.php @@ -21,54 +21,37 @@ use Piwik\Piwik; */ class API extends \Piwik\Plugin\API { + public function getContentNames($idSite, $period, $date, $segment = false, $idSubtable = false, $secondaryDimension = false) + { + return $this->getDataTable(__FUNCTION__, $idSite, $period, $date, $segment, false, $idSubtable, $secondaryDimension); + } - protected $mappingApiToRecord = array( - 'getContents' => Archiver::CONTENTS_NAME_RECORD_NAME - ); - - /** - * Another example method that returns a data table. - * @param int $idSite - * @param string $period - * @param string $date - * @param bool|string $segment - * @return DataTable - */ - public function getContents($idSite, $period, $date, $segment = false) + public function getContentPieces($idSite, $period, $date, $segment = false, $idSubtable = false, $secondaryDimension = false) { - return $this->getDataTable(__FUNCTION__, $idSite, $period, $date, $segment); + return $this->getDataTable(__FUNCTION__, $idSite, $period, $date, $segment, false, $idSubtable, $secondaryDimension); } - protected function getDataTable($name, $idSite, $period, $date, $segment) + private function getDataTable($name, $idSite, $period, $date, $segment, $expanded, $idSubtable, $secondaryDimension) { Piwik::checkUserHasViewAccess($idSite); - $recordName = $this->getRecordNameForAction($name); - $dataTable = Archive::getDataTableFromArchive($recordName, $idSite, $period, $date, $segment, false); + Dimensions::checkSecondaryDimension($name, $secondaryDimension); + $recordName = Dimensions::getRecordNameForAction($name, $secondaryDimension); + $dataTable = Archive::getDataTableFromArchive($recordName, $idSite, $period, $date, $segment, $expanded, $idSubtable); $this->filterDataTable($dataTable); return $dataTable; } - protected function getRecordNameForAction($apiMethod, $secondaryDimension = false) - { - return $this->mappingApiToRecord[$apiMethod]; - } - /** * @param DataTable $dataTable */ - protected function filterDataTable($dataTable) + private function filterDataTable($dataTable) { $dataTable->filter('Sort', array(Metrics::INDEX_NB_VISITS)); + $dataTable->queueFilter('ReplaceColumnNames'); $dataTable->queueFilter('ReplaceSummaryRowLabel'); - $dataTable->filter(function (DataTable $table) { - $row = $table->getRowFromLabel(Archiver::CONTENT_TARGET_NOT_SET); - if ($row) { - $row->setColumn('label', Piwik::translate('General_NotDefined', Piwik::translate('Contents_ContentTarget'))); - } - }); - // Content conversion rate = conversions / impressions - $dataTable->queueFilter('ColumnCallbackAddColumnPercentage', array('conversion_rate', 'nb_conversions', 'nb_impressions', $precision = 2)); + // Content interaction rate = interactions / impressions + $dataTable->queueFilter('ColumnCallbackAddColumnPercentage', array('interaction_rate', 'nb_interactions', 'nb_impressions', $precision = 2)); } } diff --git a/plugins/Contents/Archiver.php b/plugins/Contents/Archiver.php index 81abbe75d6..2af8c5ae63 100644 --- a/plugins/Contents/Archiver.php +++ b/plugins/Contents/Archiver.php @@ -15,21 +15,20 @@ use Piwik\RankingQuery; /** * Processing reports for Contents - */ class Archiver extends \Piwik\Plugin\Archiver { - const CONTENTS_PIECE_RECORD_NAME = 'Contents_piece'; - const CONTENTS_TARGET_RECORD_NAME = 'Contents_target'; - const CONTENTS_NAME_RECORD_NAME = 'Contents_name'; - const CONTENT_TARGET_NOT_SET = 'Piwik_ContentNameNotSet'; + const CONTENTS_PIECE_NAME_RECORD_NAME = 'Contents_piece_name'; + const CONTENTS_NAME_PIECE_RECORD_NAME = 'Contents_name_piece'; + const CONTENT_TARGET_NOT_SET = 'Piwik_ContentTargetNotSet'; /** * @var DataArray[] */ - protected $arrays = array(); + protected $arrays = array(); + protected $metadata = array(); - function __construct($processor) + public function __construct($processor) { parent::__construct($processor); $this->columnToSortByBeforeTruncation = Metrics::INDEX_NB_VISITS; @@ -37,12 +36,11 @@ class Archiver extends \Piwik\Plugin\Archiver $this->maximumRowsInSubDataTable = ArchivingHelper::$maximumRowsInSubDataTable; } - protected function getRecordToDimensions() + private function getRecordToDimensions() { return array( - self::CONTENTS_PIECE_RECORD_NAME => array('contentPiece'), - self::CONTENTS_TARGET_RECORD_NAME => array('contentTarget'), - self::CONTENTS_NAME_RECORD_NAME => array('contentName') + self::CONTENTS_PIECE_NAME_RECORD_NAME => array('contentPiece', 'contentName'), + self::CONTENTS_NAME_PIECE_RECORD_NAME => array('contentName', 'contentPiece') ); } @@ -52,7 +50,7 @@ class Archiver extends \Piwik\Plugin\Archiver $this->getProcessor()->aggregateDataTableRecords($dataTableToSum, $this->maximumRowsInDataTable, $this->maximumRowsInSubDataTable, $this->columnToSortByBeforeTruncation); } - protected function getRecordNames() + private function getRecordNames() { $mapping = $this->getRecordToDimensions(); return array_keys($mapping); @@ -64,7 +62,7 @@ class Archiver extends \Piwik\Plugin\Archiver $this->insertDayReports(); } - protected function aggregateDayContents() + private function aggregateDayContents() { $select = " log_action_content_piece.name as contentPiece, @@ -119,7 +117,7 @@ class Archiver extends \Piwik\Plugin\Archiver $this->archiveDayQueryProcess($select, $from, $where, $orderBy, $groupBy, $rankingQuery); } - protected function archiveDayQueryProcess($select, $from, $where, $orderBy, $groupBy, RankingQuery $rankingQuery) + private function archiveDayQueryProcess($select, $from, $where, $orderBy, $groupBy, RankingQuery $rankingQuery) { // get query with segmentation $query = $this->getLogAggregator()->generateQuery($select, $from, $where, $groupBy, $orderBy); @@ -144,10 +142,22 @@ class Archiver extends \Piwik\Plugin\Archiver /** * Records the daily datatables */ - protected function insertDayReports() + private function insertDayReports() { foreach ($this->arrays as $recordName => $dataArray) { + $dataTable = $dataArray->asDataTable(); + + foreach ($dataTable->getRows() as $row) { + $label = $row->getColumn('label'); + + if (!empty($this->metadata[$label])) { + foreach ($this->metadata[$label] as $name => $value) { + $row->addMetadata($name, $value); + } + } + + } $blob = $dataTable->getSerialized( $this->maximumRowsInDataTable, $this->maximumRowsInSubDataTable, @@ -160,29 +170,53 @@ class Archiver extends \Piwik\Plugin\Archiver * @param string $name * @return DataArray */ - protected function getDataArray($name) + private function getDataArray($name) { - if(empty($this->arrays[$name])) { + if (empty($this->arrays[$name])) { $this->arrays[$name] = new DataArray(); } + return $this->arrays[$name]; } - protected function aggregateContentRow($row) + private function aggregateContentRow($row) { foreach ($this->getRecordToDimensions() as $record => $dimensions) { $dataArray = $this->getDataArray($record); $mainDimension = $dimensions[0]; - $mainLabel = $row[$mainDimension]; + $mainLabel = $row[$mainDimension]; - // Content target is optional - if ($mainDimension == 'contentTarget' - && empty($mainLabel)) { - $mainLabel = self::CONTENT_TARGET_NOT_SET; - } $dataArray->sumMetricsContents($mainLabel, $row); + $this->rememberMetadataForRow($row, $mainLabel, $mainDimension); + + $subDimension = $dimensions[1]; + $subLabel = $row[$subDimension]; + + if (empty($subLabel)) { + continue; + } + + $dataArray->sumMetricsContentsPivot($mainLabel, $subLabel, $row); + } + } + + private function rememberMetadataForRow($row, $mainLabel, $mainDimension) + { + $this->metadata[$mainLabel] = array(); + + if ($mainDimension === 'contentPiece') { + $this->metadata[$mainLabel]['contentName'] = $row['contentName']; + } elseif ($mainDimension === 'contentName') { + $this->metadata[$mainLabel]['contentPiece'] = $row['contentPiece']; } + + $target = $row['contentTarget']; + if (empty($target)) { + $target = Archiver::CONTENT_TARGET_NOT_SET; + } + + $this->metadata[$mainLabel]['contentTarget'] = $target; } } diff --git a/plugins/Contents/Contents.php b/plugins/Contents/Contents.php index df54017d68..5a81979ed3 100644 --- a/plugins/Contents/Contents.php +++ b/plugins/Contents/Contents.php @@ -23,6 +23,8 @@ class Contents extends \Piwik\Plugin public function addMetricTranslations(&$translations) { $translations['nb_impressions'] = 'Contents_Impressions'; + $translations['nb_interactions'] = 'Contents_Interactions'; + $translations['interaction_rate'] = 'Contents_InteractionRate'; } } diff --git a/plugins/Contents/Controller.php b/plugins/Contents/Controller.php new file mode 100644 index 0000000000..d7cde20a24 --- /dev/null +++ b/plugins/Contents/Controller.php @@ -0,0 +1,56 @@ +<?php +/** + * Piwik - free/libre analytics platform + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + * + */ +namespace Piwik\Plugins\Contents; + +use Piwik\Plugin\Report; +use Piwik\Plugins\Contents\Reports\GetContentNames; +use Piwik\Plugins\Contents\Reports\GetContentPieces; +use Piwik\View; + +class Controller extends \Piwik\Plugin\Controller +{ + + public function index() + { + $reportsView = new View\ReportsByDimension('Contents'); + + /** @var \Piwik\Plugin\Report[] $reports */ + $reports = array(new GetContentNames(), new GetContentPieces()); + + foreach($reports as $report) { + $params = array( + 'secondaryDimension' => Dimensions::getDefaultSecondaryDimension($report->getAction()) + ); + + $reportsView->addReport( + $report->getCategory(), + $report->getName(), + 'Contents.menu' . ucfirst($report->getAction()), + $params + ); + } + + return $reportsView->render(); + } + + public function menuGetContentNames() + { + $report = new GetContentNames(); + + return View::singleReport($report->getName(), $report->render()); + } + + public function menuGetContentPieces() + { + $report = new GetContentPieces(); + + return View::singleReport($report->getName(), $report->render()); + } + +} diff --git a/plugins/Contents/DataArray.php b/plugins/Contents/DataArray.php index d506567513..f83f06f624 100644 --- a/plugins/Contents/DataArray.php +++ b/plugins/Contents/DataArray.php @@ -8,8 +8,6 @@ */ namespace Piwik\Plugins\Contents; -use Exception; -use Piwik\Tracker\GoalManager; use Piwik\Metrics; /** @@ -32,9 +30,10 @@ class DataArray extends \Piwik\DataArray protected static function makeEmptyContentsRow() { return array( - Metrics::INDEX_NB_UNIQ_VISITORS => 0, - Metrics::INDEX_NB_VISITS => 0, - Metrics::INDEX_CONTENT_NB_IMPRESSIONS => 0 + Metrics::INDEX_NB_UNIQ_VISITORS => 0, + Metrics::INDEX_NB_VISITS => 0, + Metrics::INDEX_CONTENT_NB_IMPRESSIONS => 0, + Metrics::INDEX_CONTENT_NB_INTERACTIONS => 0 ); } @@ -53,7 +52,7 @@ class DataArray extends \Piwik\DataArray public function sumMetricsContentsPivot($parentLabel, $label, $row) { if (!isset($this->dataTwoLevels[$parentLabel][$label])) { - $this->dataTwoLevels[$parentLabel][$label] = $this->makeEmptyEventRow(); + $this->dataTwoLevels[$parentLabel][$label] = $this->makeEmptyContentsRow(); } $this->doSumContentsMetrics($row, $this->dataTwoLevels[$parentLabel][$label]); } diff --git a/plugins/Contents/Dimensions.php b/plugins/Contents/Dimensions.php new file mode 100644 index 0000000000..aab79450ca --- /dev/null +++ b/plugins/Contents/Dimensions.php @@ -0,0 +1,90 @@ +<?php +/** + * Piwik - free/libre analytics platform + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + * + */ +namespace Piwik\Plugins\Contents; + +class Dimensions +{ + + private static $defaultMappingApiToSecondaryDimension = array( + 'getContentNames' => 'getContentPieces', + 'getContentPieces' => 'getContentNames' + ); + + private static $mappingApiToRecord = array( + 'getContentNames' => array( + 'getContentPieces' => Archiver::CONTENTS_NAME_PIECE_RECORD_NAME + ), + 'getContentPieces' => array( + 'getContentNames' => Archiver::CONTENTS_PIECE_NAME_RECORD_NAME, + ) + ); + + public static function getDefaultSecondaryDimension($apiMethod) + { + if (isset(self::$defaultMappingApiToSecondaryDimension[$apiMethod])) { + return self::$defaultMappingApiToSecondaryDimension[$apiMethod]; + } + + return false; + } + + public static function getRecordNameForAction($apiMethod, $secondaryDimension = false) + { + if (empty($secondaryDimension)) { + $secondaryDimension = self::getDefaultSecondaryDimension($apiMethod); + } + + $record = self::$mappingApiToRecord[$apiMethod]; + if (!is_array($record)) { + return $record; + } + + // when secondaryDimension is incorrectly set + if (empty($record[$secondaryDimension])) { + return key($record); + } + + return $record[$secondaryDimension]; + } + + /** + * @ignore + * @param $apiMethod + * @return array + */ + public static function getSecondaryDimensions($apiMethod) + { + $records = self::$mappingApiToRecord[$apiMethod]; + + if(!is_array($records)) { + return false; + } + + return array_keys($records); + } + + public static function checkSecondaryDimension($apiMethod, $secondaryDimension) + { + if (empty($secondaryDimension)) { + return; + } + + $isSecondaryDimensionValid = + isset(self::$mappingApiToRecord[$apiMethod]) + && isset(self::$mappingApiToRecord[$apiMethod][$secondaryDimension]); + + if (!$isSecondaryDimensionValid) { + throw new \Exception( + "Secondary dimension '$secondaryDimension' is not valid for the API $apiMethod. ". + "Use one of: " . implode(", ", self::getSecondaryDimensions($apiMethod)) + ); + } + } + +} diff --git a/plugins/Contents/Menu.php b/plugins/Contents/Menu.php new file mode 100644 index 0000000000..e8c05222e8 --- /dev/null +++ b/plugins/Contents/Menu.php @@ -0,0 +1,24 @@ +<?php +/** + * Piwik - free/libre analytics platform + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + * + */ +namespace Piwik\Plugins\Contents; + +use Piwik\Menu\MenuReporting; + +/** + * This class allows you to add, remove or rename menu items. + * To configure a menu (such as Admin Menu, Reporting Menu, User Menu...) simply call the corresponding methods as + * described in the API-Reference http://developer.piwik.org/api-reference/Piwik/Menu/MenuAbstract + */ +class Menu extends \Piwik\Plugin\Menu +{ + public function configureReportingMenu(MenuReporting $menu) + { + $menu->addActionsItem('Contents_Contents', array('module' => 'Contents', 'action' => 'index'), $orderId = 30); + } +} diff --git a/plugins/Contents/Reports/Base.php b/plugins/Contents/Reports/Base.php index 84540699f9..e972078eee 100644 --- a/plugins/Contents/Reports/Base.php +++ b/plugins/Contents/Reports/Base.php @@ -9,6 +9,7 @@ namespace Piwik\Plugins\Contents\Reports; use Piwik\Plugin\Report; +use Piwik\Plugin\ViewDataTable; abstract class Base extends Report { @@ -16,4 +17,20 @@ abstract class Base extends Report { $this->category = 'General_Actions'; } + + /** + * Here you can configure how your report should be displayed. For instance whether your report supports a search + * etc. You can also change the default request config. For instance change how many rows are displayed by default. + * + * @param ViewDataTable $view + */ + public function configureView(ViewDataTable $view) + { + if (!empty($this->dimension)) { + $view->config->addTranslations(array('label' => $this->dimension->getName())); + } + + $view->config->columns_to_display = array_merge(array('label'), $this->metrics); + $view->requestConfig->filter_sort_column = 'nb_impressions'; + } } diff --git a/plugins/Contents/Reports/GetContentNames.php b/plugins/Contents/Reports/GetContentNames.php new file mode 100644 index 0000000000..011581025f --- /dev/null +++ b/plugins/Contents/Reports/GetContentNames.php @@ -0,0 +1,36 @@ +<?php +/** + * Piwik - free/libre analytics platform + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + * + */ +namespace Piwik\Plugins\Contents\Reports; + +use Piwik\Piwik; +use Piwik\Plugin\Report; +use Piwik\Plugins\Contents\Columns\ContentName; +use Piwik\View; + +/** + * This class defines a new report. + * + * See {@link http://developer.piwik.org/api-reference/Piwik/Plugin/Report} for more information. + */ +class GetContentNames extends Base +{ + protected function init() + { + parent::init(); + + $this->name = Piwik::translate('Contents_ContentName'); + $this->dimension = null; + // TODO $this->documentation = Piwik::translate('ContentsDocumentation'); + $this->dimension = new ContentName(); + $this->order = 35; + + $this->widgetTitle = 'Contents_ContentName'; + $this->metrics = array('nb_impressions', 'nb_interactions', 'interaction_rate'); + } +} diff --git a/plugins/Contents/Reports/GetContentPieces.php b/plugins/Contents/Reports/GetContentPieces.php new file mode 100644 index 0000000000..a9beda66cf --- /dev/null +++ b/plugins/Contents/Reports/GetContentPieces.php @@ -0,0 +1,37 @@ +<?php +/** + * Piwik - free/libre analytics platform + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + * + */ +namespace Piwik\Plugins\Contents\Reports; + +use Piwik\Piwik; +use Piwik\Plugin\Report; +use Piwik\Plugins\Contents\Columns\ContentPiece; +use Piwik\View; + +/** + * This class defines a new report. + * + * See {@link http://developer.piwik.org/api-reference/Piwik/Plugin/Report} for more information. + */ +class GetContentPieces extends Base +{ + protected function init() + { + parent::init(); + + $this->name = Piwik::translate('Contents_ContentPiece'); + $this->dimension = null; + // TODO $this->documentation = Piwik::translate('ContentsDocumentation'); + $this->dimension = new ContentPiece(); + $this->order = 36; + + $this->widgetTitle = 'Contents_ContentPiece'; + + $this->metrics = array('nb_impressions', 'nb_interactions', 'interaction_rate'); + } +} diff --git a/plugins/Contents/Reports/GetContents.php b/plugins/Contents/Reports/GetContents.php deleted file mode 100644 index 1d4205d956..0000000000 --- a/plugins/Contents/Reports/GetContents.php +++ /dev/null @@ -1,67 +0,0 @@ -<?php -/** - * Piwik - free/libre analytics platform - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later - * - */ -namespace Piwik\Plugins\Contents\Reports; - -use Piwik\Piwik; -use Piwik\Plugin\Report; -use Piwik\Plugin\ViewDataTable; - -use Piwik\Plugins\Contents\Columns\ContentName; -use Piwik\View; - -/** - * This class defines a new report. - * - * See {@link http://developer.piwik.org/api-reference/Piwik/Plugin/Report} for more information. - */ -class GetContents extends Base -{ - protected function init() - { - parent::init(); - - $this->name = Piwik::translate('ContentsName'); - $this->dimension = null; - $this->documentation = Piwik::translate('ContentsDocumentation'); - $this->dimension = new ContentName(); - $this->order = 35; - - $this->menuTitle = 'Contents_Contents'; - $this->widgetTitle = $this->menuTitle; - - $this->metrics = array('nb_impressions', 'nb_conversions', 'conversion_rate'); - } - - /** - * Here you can configure how your report should be displayed. For instance whether your report supports a search - * etc. You can also change the default request config. For instance change how many rows are displayed by default. - * - * @param ViewDataTable $view - */ - public function configureView(ViewDataTable $view) - { - if (!empty($this->dimension)) { - $view->config->addTranslations(array('label' => $this->dimension->getName())); - } - - $view->config->columns_to_display = array_merge(array('label'), $this->metrics); - $view->requestConfig->filter_sort_column = 'nb_impressions'; - } - - /** - * Here you can define related reports that will be shown below the reports. Just return an array of related - * report instances if there are any. - * - * @return \Piwik\Plugin\Report[] - */ - public function getRelatedReports() - { - return array(); // eg return array(new XyzReport()); - } -} diff --git a/plugins/Contents/lang/en.json b/plugins/Contents/lang/en.json index 33f9434073..37acf673d4 100644 --- a/plugins/Contents/lang/en.json +++ b/plugins/Contents/lang/en.json @@ -1,6 +1,8 @@ { "Contents":{ "Impressions":"Impressions", + "Interactions":"Interactions", + "InteractionRate":"Interaction Rate", "ContentName":"Content Name", "ContentPiece":"Content Piece", "ContentTarget":"Content Target", |