update Piwik to version 2.16 (fixes #91)
This commit is contained in:
parent
9abe039dc8
commit
47263617c5
51 changed files with 418860 additions and 226988 deletions
74
www/analytics/plugins/Contents/API.php
Normal file
74
www/analytics/plugins/Contents/API.php
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
<?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\Archive;
|
||||
use Piwik\DataTable;
|
||||
use Piwik\DataTable\Row;
|
||||
use Piwik\Metrics;
|
||||
use Piwik\Piwik;
|
||||
use Piwik\Plugins\Contents\Archiver;
|
||||
|
||||
/**
|
||||
* API for plugin Contents
|
||||
*
|
||||
* @method static \Piwik\Plugins\Contents\API getInstance()
|
||||
*/
|
||||
class API extends \Piwik\Plugin\API
|
||||
{
|
||||
public function getContentNames($idSite, $period, $date, $segment = false, $idSubtable = false)
|
||||
{
|
||||
return $this->getDataTable(__FUNCTION__, $idSite, $period, $date, $segment, false, $idSubtable);
|
||||
}
|
||||
|
||||
public function getContentPieces($idSite, $period, $date, $segment = false, $idSubtable = false)
|
||||
{
|
||||
return $this->getDataTable(__FUNCTION__, $idSite, $period, $date, $segment, false, $idSubtable);
|
||||
}
|
||||
|
||||
private function getDataTable($name, $idSite, $period, $date, $segment, $expanded, $idSubtable)
|
||||
{
|
||||
Piwik::checkUserHasViewAccess($idSite);
|
||||
$recordName = Dimensions::getRecordNameForAction($name);
|
||||
$dataTable = Archive::getDataTableFromArchive($recordName, $idSite, $period, $date, $segment, $expanded, $idSubtable);
|
||||
|
||||
if (empty($idSubtable)) {
|
||||
$dataTable->filter('AddSegmentValue', array(function ($label) {
|
||||
if ($label === Archiver::CONTENT_PIECE_NOT_SET) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $label;
|
||||
}));
|
||||
}
|
||||
|
||||
$this->filterDataTable($dataTable);
|
||||
return $dataTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DataTable $dataTable
|
||||
*/
|
||||
private function filterDataTable($dataTable)
|
||||
{
|
||||
$dataTable->queueFilter('ReplaceColumnNames');
|
||||
$dataTable->queueFilter('ReplaceSummaryRowLabel');
|
||||
$dataTable->filter(function (DataTable $table) {
|
||||
$row = $table->getRowFromLabel(Archiver::CONTENT_PIECE_NOT_SET);
|
||||
if ($row) {
|
||||
$row->setColumn('label', Piwik::translate('General_NotDefined', Piwik::translate('Contents_ContentPiece')));
|
||||
}
|
||||
foreach ($table->getRows() as $row) {
|
||||
if ($row->getMetadata('contentTarget') === Archiver::CONTENT_TARGET_NOT_SET) {
|
||||
$row->setMetadata('contentTarget', '');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
54
www/analytics/plugins/Contents/Actions/ActionContent.php
Normal file
54
www/analytics/plugins/Contents/Actions/ActionContent.php
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
<?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\Actions;
|
||||
|
||||
use Piwik\Tracker\Action;
|
||||
use Piwik\Tracker\Request;
|
||||
use Piwik\Tracker;
|
||||
|
||||
/**
|
||||
* A content is composed of a name, an actual piece of content, and optionally a target.
|
||||
*/
|
||||
class ActionContent extends Action
|
||||
{
|
||||
public function __construct(Request $request)
|
||||
{
|
||||
parent::__construct(Action::TYPE_CONTENT, $request);
|
||||
|
||||
$url = $request->getParam('url');
|
||||
$this->setActionUrl($url);
|
||||
}
|
||||
|
||||
public static function shouldHandle(Request $request)
|
||||
{
|
||||
$name = $request->getParam('c_n');
|
||||
|
||||
return !empty($name);
|
||||
}
|
||||
|
||||
protected function getActionsToLookup()
|
||||
{
|
||||
return array(
|
||||
'idaction_url' => array($this->getActionUrl(), $this->getActionType())
|
||||
);
|
||||
}
|
||||
|
||||
// Do not track this Event URL as Entry/Exit Page URL (leave the existing entry/exit)
|
||||
public function getIdActionUrlForEntryAndExitIds()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Do not track this Event Name as Entry/Exit Page Title (leave the existing entry/exit)
|
||||
public function getIdActionNameForEntryAndExitIds()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
320
www/analytics/plugins/Contents/Archiver.php
Normal file
320
www/analytics/plugins/Contents/Archiver.php
Normal file
|
|
@ -0,0 +1,320 @@
|
|||
<?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\DataTable;
|
||||
use Piwik\Metrics;
|
||||
use Piwik\Plugins\Actions\ArchivingHelper;
|
||||
use Piwik\RankingQuery;
|
||||
|
||||
/**
|
||||
* Processing reports for Contents
|
||||
*/
|
||||
class Archiver extends \Piwik\Plugin\Archiver
|
||||
{
|
||||
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';
|
||||
const CONTENT_PIECE_NOT_SET = 'Piwik_ContentPieceNotSet';
|
||||
|
||||
/**
|
||||
* @var DataArray[]
|
||||
*/
|
||||
protected $arrays = array();
|
||||
protected $metadata = array();
|
||||
|
||||
public function __construct($processor)
|
||||
{
|
||||
parent::__construct($processor);
|
||||
$this->columnToSortByBeforeTruncation = Metrics::INDEX_NB_VISITS;
|
||||
$this->maximumRowsInDataTable = ArchivingHelper::$maximumRowsInDataTableLevelZero;
|
||||
$this->maximumRowsInSubDataTable = ArchivingHelper::$maximumRowsInSubDataTable;
|
||||
}
|
||||
|
||||
private function getRecordToDimensions()
|
||||
{
|
||||
return array(
|
||||
self::CONTENTS_PIECE_NAME_RECORD_NAME => array('contentPiece', 'contentName'),
|
||||
self::CONTENTS_NAME_PIECE_RECORD_NAME => array('contentName', 'contentPiece')
|
||||
);
|
||||
}
|
||||
|
||||
public function aggregateMultipleReports()
|
||||
{
|
||||
$dataTableToSum = $this->getRecordNames();
|
||||
$columnsAggregationOperation = null;
|
||||
$this->getProcessor()->aggregateDataTableRecords(
|
||||
$dataTableToSum,
|
||||
$this->maximumRowsInDataTable,
|
||||
$this->maximumRowsInSubDataTable,
|
||||
$this->columnToSortByBeforeTruncation,
|
||||
$columnsAggregationOperation,
|
||||
$columnsToRenameAfterAggregation = null,
|
||||
$countRowsRecursive = array());
|
||||
}
|
||||
|
||||
private function getRecordNames()
|
||||
{
|
||||
$mapping = $this->getRecordToDimensions();
|
||||
return array_keys($mapping);
|
||||
}
|
||||
|
||||
public function aggregateDayReport()
|
||||
{
|
||||
$this->aggregateDayImpressions();
|
||||
$this->aggregateDayInteractions();
|
||||
$this->insertDayReports();
|
||||
}
|
||||
|
||||
private function aggregateDayImpressions()
|
||||
{
|
||||
$select = "
|
||||
log_action_content_piece.name as contentPiece,
|
||||
log_action_content_target.name as contentTarget,
|
||||
log_action_content_name.name as contentName,
|
||||
|
||||
count(distinct log_link_visit_action.idvisit) as `" . Metrics::INDEX_NB_VISITS . "`,
|
||||
count(distinct log_link_visit_action.idvisitor) as `" . Metrics::INDEX_NB_UNIQ_VISITORS . "`,
|
||||
count(*) as `" . Metrics::INDEX_CONTENT_NB_IMPRESSIONS . "`
|
||||
";
|
||||
|
||||
$from = array(
|
||||
"log_link_visit_action",
|
||||
array(
|
||||
"table" => "log_action",
|
||||
"tableAlias" => "log_action_content_piece",
|
||||
"joinOn" => "log_link_visit_action.idaction_content_piece = log_action_content_piece.idaction"
|
||||
),
|
||||
array(
|
||||
"table" => "log_action",
|
||||
"tableAlias" => "log_action_content_target",
|
||||
"joinOn" => "log_link_visit_action.idaction_content_target = log_action_content_target.idaction"
|
||||
),
|
||||
array(
|
||||
"table" => "log_action",
|
||||
"tableAlias" => "log_action_content_name",
|
||||
"joinOn" => "log_link_visit_action.idaction_content_name = log_action_content_name.idaction"
|
||||
)
|
||||
);
|
||||
|
||||
$where = "log_link_visit_action.server_time >= ?
|
||||
AND log_link_visit_action.server_time <= ?
|
||||
AND log_link_visit_action.idsite = ?
|
||||
AND log_link_visit_action.idaction_content_name IS NOT NULL
|
||||
AND log_link_visit_action.idaction_content_interaction IS NULL";
|
||||
|
||||
$groupBy = "log_action_content_piece.idaction,
|
||||
log_action_content_target.idaction,
|
||||
log_action_content_name.idaction";
|
||||
|
||||
$orderBy = "`" . Metrics::INDEX_NB_VISITS . "` DESC";
|
||||
|
||||
$rankingQueryLimit = ArchivingHelper::getRankingQueryLimit();
|
||||
$rankingQuery = null;
|
||||
if ($rankingQueryLimit > 0) {
|
||||
$rankingQuery = new RankingQuery($rankingQueryLimit);
|
||||
$rankingQuery->setOthersLabel(DataTable::LABEL_SUMMARY_ROW);
|
||||
$rankingQuery->addLabelColumn(array('contentPiece', 'contentTarget', 'contentName'));
|
||||
$rankingQuery->addColumn(array(Metrics::INDEX_NB_UNIQ_VISITORS));
|
||||
$rankingQuery->addColumn(array(Metrics::INDEX_CONTENT_NB_IMPRESSIONS, Metrics::INDEX_NB_VISITS), 'sum');
|
||||
}
|
||||
|
||||
$resultSet = $this->archiveDayQueryProcess($select, $from, $where, $groupBy, $orderBy, $rankingQuery);
|
||||
|
||||
while ($row = $resultSet->fetch()) {
|
||||
$this->aggregateImpressionRow($row);
|
||||
}
|
||||
}
|
||||
|
||||
private function aggregateDayInteractions()
|
||||
{
|
||||
$select = "
|
||||
log_action_content_name.name as contentName,
|
||||
log_action_content_interaction.name as contentInteraction,
|
||||
log_action_content_piece.name as contentPiece,
|
||||
|
||||
count(*) as `" . Metrics::INDEX_CONTENT_NB_INTERACTIONS . "`
|
||||
";
|
||||
|
||||
$from = array(
|
||||
"log_link_visit_action",
|
||||
array(
|
||||
"table" => "log_action",
|
||||
"tableAlias" => "log_action_content_piece",
|
||||
"joinOn" => "log_link_visit_action.idaction_content_piece = log_action_content_piece.idaction"
|
||||
),
|
||||
array(
|
||||
"table" => "log_action",
|
||||
"tableAlias" => "log_action_content_interaction",
|
||||
"joinOn" => "log_link_visit_action.idaction_content_interaction = log_action_content_interaction.idaction"
|
||||
),
|
||||
array(
|
||||
"table" => "log_action",
|
||||
"tableAlias" => "log_action_content_name",
|
||||
"joinOn" => "log_link_visit_action.idaction_content_name = log_action_content_name.idaction"
|
||||
)
|
||||
);
|
||||
|
||||
$where = "log_link_visit_action.server_time >= ?
|
||||
AND log_link_visit_action.server_time <= ?
|
||||
AND log_link_visit_action.idsite = ?
|
||||
AND log_link_visit_action.idaction_content_name IS NOT NULL
|
||||
AND log_link_visit_action.idaction_content_interaction IS NOT NULL";
|
||||
|
||||
$groupBy = "log_action_content_piece.idaction,
|
||||
log_action_content_interaction.idaction,
|
||||
log_action_content_name.idaction";
|
||||
|
||||
$orderBy = "`" . Metrics::INDEX_CONTENT_NB_INTERACTIONS . "` DESC";
|
||||
|
||||
$rankingQueryLimit = ArchivingHelper::getRankingQueryLimit();
|
||||
$rankingQuery = null;
|
||||
if ($rankingQueryLimit > 0) {
|
||||
$rankingQuery = new RankingQuery($rankingQueryLimit);
|
||||
$rankingQuery->setOthersLabel(DataTable::LABEL_SUMMARY_ROW);
|
||||
$rankingQuery->addLabelColumn(array('contentPiece', 'contentInteraction', 'contentName'));
|
||||
$rankingQuery->addColumn(array(Metrics::INDEX_CONTENT_NB_INTERACTIONS), 'sum');
|
||||
}
|
||||
|
||||
$resultSet = $this->archiveDayQueryProcess($select, $from, $where, $groupBy, $orderBy, $rankingQuery);
|
||||
|
||||
while ($row = $resultSet->fetch()) {
|
||||
$this->aggregateInteractionRow($row);
|
||||
}
|
||||
}
|
||||
|
||||
private function archiveDayQueryProcess($select, $from, $where, $groupBy, $orderBy, RankingQuery $rankingQuery)
|
||||
{
|
||||
// get query with segmentation
|
||||
$query = $this->getLogAggregator()->generateQuery($select, $from, $where, $groupBy, $orderBy);
|
||||
|
||||
// apply ranking query
|
||||
if ($rankingQuery) {
|
||||
$query['sql'] = $rankingQuery->generateRankingQuery($query['sql']);
|
||||
}
|
||||
|
||||
// get result
|
||||
$resultSet = $this->getLogAggregator()->getDb()->query($query['sql'], $query['bind']);
|
||||
|
||||
if ($resultSet === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
return $resultSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Records the daily datatables
|
||||
*/
|
||||
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,
|
||||
$this->columnToSortByBeforeTruncation);
|
||||
$this->getProcessor()->insertBlobRecord($recordName, $blob);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @return DataArray
|
||||
*/
|
||||
private function getDataArray($name)
|
||||
{
|
||||
if (empty($this->arrays[$name])) {
|
||||
$this->arrays[$name] = new DataArray();
|
||||
}
|
||||
|
||||
return $this->arrays[$name];
|
||||
}
|
||||
|
||||
private function aggregateImpressionRow($row)
|
||||
{
|
||||
foreach ($this->getRecordToDimensions() as $record => $dimensions) {
|
||||
$dataArray = $this->getDataArray($record);
|
||||
|
||||
$mainDimension = $dimensions[0];
|
||||
$mainLabel = $row[$mainDimension];
|
||||
|
||||
// content piece is optional
|
||||
if ($mainDimension == 'contentPiece'
|
||||
&& empty($mainLabel)) {
|
||||
$mainLabel = self::CONTENT_PIECE_NOT_SET;
|
||||
}
|
||||
|
||||
$dataArray->sumMetricsImpressions($mainLabel, $row);
|
||||
$this->rememberMetadataForRow($row, $mainLabel);
|
||||
|
||||
$subDimension = $dimensions[1];
|
||||
$subLabel = $row[$subDimension];
|
||||
|
||||
if (empty($subLabel)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// content piece is optional
|
||||
if ($subDimension == 'contentPiece'
|
||||
&& empty($subLabel)) {
|
||||
$subLabel = self::CONTENT_PIECE_NOT_SET;
|
||||
}
|
||||
|
||||
$dataArray->sumMetricsContentsImpressionPivot($mainLabel, $subLabel, $row);
|
||||
}
|
||||
}
|
||||
|
||||
private function aggregateInteractionRow($row)
|
||||
{
|
||||
foreach ($this->getRecordToDimensions() as $record => $dimensions) {
|
||||
$dataArray = $this->getDataArray($record);
|
||||
|
||||
$mainDimension = $dimensions[0];
|
||||
$mainLabel = $row[$mainDimension];
|
||||
|
||||
$dataArray->sumMetricsInteractions($mainLabel, $row);
|
||||
|
||||
$subDimension = $dimensions[1];
|
||||
$subLabel = $row[$subDimension];
|
||||
|
||||
if (empty($subLabel)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$dataArray->sumMetricsContentsInteractionPivot($mainLabel, $subLabel, $row);
|
||||
}
|
||||
}
|
||||
|
||||
private function rememberMetadataForRow($row, $mainLabel)
|
||||
{
|
||||
$this->metadata[$mainLabel] = array();
|
||||
|
||||
$target = $row['contentTarget'];
|
||||
if (empty($target)) {
|
||||
$target = Archiver::CONTENT_TARGET_NOT_SET;
|
||||
}
|
||||
|
||||
// there can be many different targets
|
||||
$this->metadata[$mainLabel]['contentTarget'] = $target;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
<?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\Columns;
|
||||
|
||||
use Piwik\Piwik;
|
||||
use Piwik\Plugin\Dimension\ActionDimension;
|
||||
use Piwik\Plugins\Actions\Segment;
|
||||
use Piwik\Tracker\Action;
|
||||
use Piwik\Tracker\Request;
|
||||
|
||||
class ContentInteraction extends ActionDimension
|
||||
{
|
||||
protected $columnName = 'idaction_content_interaction';
|
||||
protected $columnType = 'INTEGER(10) UNSIGNED DEFAULT NULL';
|
||||
|
||||
protected function configureSegments()
|
||||
{
|
||||
$segment = new Segment();
|
||||
$segment->setSegment('contentInteraction');
|
||||
$segment->setName('Contents_Interaction');
|
||||
$segment->setAcceptedValues('The type of interaction with the content. For instance "click" or "submit".');
|
||||
$this->addSegment($segment);
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return Piwik::translate('Contents_Interaction');
|
||||
}
|
||||
|
||||
public function getActionId()
|
||||
{
|
||||
return Action::TYPE_CONTENT_INTERACTION;
|
||||
}
|
||||
|
||||
public function onLookupAction(Request $request, Action $action)
|
||||
{
|
||||
$interaction = $request->getParam('c_i');
|
||||
|
||||
if (empty($interaction)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$interaction = trim($interaction);
|
||||
|
||||
if (strlen($interaction) > 0) {
|
||||
return $interaction;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
57
www/analytics/plugins/Contents/Columns/ContentName.php
Normal file
57
www/analytics/plugins/Contents/Columns/ContentName.php
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
<?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\Columns;
|
||||
|
||||
use Piwik\Piwik;
|
||||
use Piwik\Plugin\Dimension\ActionDimension;
|
||||
use Piwik\Plugins\Actions\Segment;
|
||||
use Piwik\Tracker\Action;
|
||||
use Piwik\Tracker\Request;
|
||||
|
||||
class ContentName extends ActionDimension
|
||||
{
|
||||
protected $columnName = 'idaction_content_name';
|
||||
protected $columnType = 'INTEGER(10) UNSIGNED DEFAULT NULL';
|
||||
|
||||
protected function configureSegments()
|
||||
{
|
||||
$segment = new Segment();
|
||||
$segment->setSegment('contentName');
|
||||
$segment->setName('Contents_ContentName');
|
||||
$segment->setAcceptedValues('The name of a content block, for instance "Ad Sale"');
|
||||
$this->addSegment($segment);
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return Piwik::translate('Contents_ContentName');
|
||||
}
|
||||
|
||||
public function getActionId()
|
||||
{
|
||||
return Action::TYPE_CONTENT_NAME;
|
||||
}
|
||||
|
||||
public function onLookupAction(Request $request, Action $action)
|
||||
{
|
||||
$contentName = $request->getParam('c_n');
|
||||
|
||||
if (empty($contentName)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$contentName = trim($contentName);
|
||||
|
||||
if (strlen($contentName) > 0) {
|
||||
return $contentName;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
57
www/analytics/plugins/Contents/Columns/ContentPiece.php
Normal file
57
www/analytics/plugins/Contents/Columns/ContentPiece.php
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
<?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\Columns;
|
||||
|
||||
use Piwik\Piwik;
|
||||
use Piwik\Plugin\Dimension\ActionDimension;
|
||||
use Piwik\Plugins\Actions\Segment;
|
||||
use Piwik\Tracker\Action;
|
||||
use Piwik\Tracker\Request;
|
||||
|
||||
class ContentPiece extends ActionDimension
|
||||
{
|
||||
protected $columnName = 'idaction_content_piece';
|
||||
protected $columnType = 'INTEGER(10) UNSIGNED DEFAULT NULL';
|
||||
|
||||
protected function configureSegments()
|
||||
{
|
||||
$segment = new Segment();
|
||||
$segment->setSegment('contentPiece');
|
||||
$segment->setName('Contents_ContentPiece');
|
||||
$segment->setAcceptedValues('The actual content. For instance "ad.jpg" or "My text ad"');
|
||||
$this->addSegment($segment);
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return Piwik::translate('Contents_ContentPiece');
|
||||
}
|
||||
|
||||
public function getActionId()
|
||||
{
|
||||
return Action::TYPE_CONTENT_PIECE;
|
||||
}
|
||||
|
||||
public function onLookupAction(Request $request, Action $action)
|
||||
{
|
||||
$contentPiece = $request->getParam('c_p');
|
||||
|
||||
if (empty($contentPiece)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$contentPiece = trim($contentPiece);
|
||||
|
||||
if (strlen($contentPiece) > 0) {
|
||||
return $contentPiece;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
52
www/analytics/plugins/Contents/Columns/ContentTarget.php
Normal file
52
www/analytics/plugins/Contents/Columns/ContentTarget.php
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
<?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\Columns;
|
||||
|
||||
use Piwik\Piwik;
|
||||
use Piwik\Plugin\Dimension\ActionDimension;
|
||||
use Piwik\Plugins\Actions\Segment;
|
||||
use Piwik\Tracker\Action;
|
||||
use Piwik\Tracker\Request;
|
||||
|
||||
class ContentTarget extends ActionDimension
|
||||
{
|
||||
protected $columnName = 'idaction_content_target';
|
||||
protected $columnType = 'INTEGER(10) UNSIGNED DEFAULT NULL';
|
||||
|
||||
protected function configureSegments()
|
||||
{
|
||||
$segment = new Segment();
|
||||
$segment->setSegment('contentTarget');
|
||||
$segment->setName('Contents_ContentTarget');
|
||||
$segment->setAcceptedValues('For instance the URL of a landing page: "http://landingpage.example.com"');
|
||||
$this->addSegment($segment);
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return Piwik::translate('Contents_ContentTarget');
|
||||
}
|
||||
|
||||
public function getActionId()
|
||||
{
|
||||
return Action::TYPE_CONTENT_TARGET;
|
||||
}
|
||||
|
||||
public function onLookupAction(Request $request, Action $action)
|
||||
{
|
||||
$contentTarget = $request->getParam('c_t');
|
||||
$contentTarget = trim($contentTarget);
|
||||
|
||||
if (strlen($contentTarget) > 0) {
|
||||
return $contentTarget;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
<?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\Columns\Metrics;
|
||||
|
||||
use Piwik\DataTable\Row;
|
||||
use Piwik\Metrics\Formatter;
|
||||
use Piwik\Piwik;
|
||||
use Piwik\Plugin\ProcessedMetric;
|
||||
|
||||
/**
|
||||
* The content interaction rate. Calculated as:
|
||||
*
|
||||
* nb_interactions / nb_impressions
|
||||
*
|
||||
* nb_interactions & nb_impressions are calculated by the Contents archiver.
|
||||
*/
|
||||
class InteractionRate extends ProcessedMetric
|
||||
{
|
||||
public function getName()
|
||||
{
|
||||
return 'interaction_rate';
|
||||
}
|
||||
|
||||
public function getTranslatedName()
|
||||
{
|
||||
return Piwik::translate('Contents_InteractionRate');
|
||||
}
|
||||
|
||||
public function getDocumentation()
|
||||
{
|
||||
return Piwik::translate('Contents_InteractionRateMetricDocumentation');
|
||||
}
|
||||
|
||||
public function compute(Row $row)
|
||||
{
|
||||
$interactions = $this->getMetric($row, 'nb_interactions');
|
||||
$impressions = $this->getMetric($row, 'nb_impressions');
|
||||
|
||||
return Piwik::getQuotientSafe($interactions, $impressions, $precision = 4);
|
||||
}
|
||||
|
||||
public function format($value, Formatter $formatter)
|
||||
{
|
||||
return $formatter->getPrettyPercentFromQuotient($value);
|
||||
}
|
||||
|
||||
public function getDependentMetrics()
|
||||
{
|
||||
return array('nb_interactions', 'nb_impressions');
|
||||
}
|
||||
}
|
||||
50
www/analytics/plugins/Contents/Contents.php
Normal file
50
www/analytics/plugins/Contents/Contents.php
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
<?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\Piwik;
|
||||
|
||||
class Contents extends \Piwik\Plugin
|
||||
{
|
||||
/**
|
||||
* @see Piwik\Plugin::registerEvents
|
||||
*/
|
||||
public function registerEvents()
|
||||
{
|
||||
return array(
|
||||
'Metrics.getDefaultMetricTranslations' => 'addMetricTranslations',
|
||||
'Metrics.getDefaultMetricDocumentationTranslations' => 'addMetricDocumentationTranslations',
|
||||
'AssetManager.getJavaScriptFiles' => 'getJsFiles',
|
||||
'AssetManager.getStylesheetFiles' => 'getStylesheetFiles',
|
||||
);
|
||||
}
|
||||
|
||||
public function addMetricTranslations(&$translations)
|
||||
{
|
||||
$translations['nb_impressions'] = 'Contents_Impressions';
|
||||
$translations['nb_interactions'] = 'Contents_Interactions';
|
||||
$translations['interaction_rate'] = 'Contents_InteractionRate';
|
||||
}
|
||||
|
||||
public function getJsFiles(&$jsFiles)
|
||||
{
|
||||
$jsFiles[] = "plugins/Contents/javascripts/contentsDataTable.js";
|
||||
}
|
||||
|
||||
public function getStylesheetFiles(&$stylesheets)
|
||||
{
|
||||
$stylesheets[] = "plugins/Contents/stylesheets/datatable.less";
|
||||
}
|
||||
|
||||
public function addMetricDocumentationTranslations(&$translations)
|
||||
{
|
||||
$translations['nb_impressions'] = Piwik::translate('Contents_ImpressionsMetricDocumentation');
|
||||
$translations['nb_interactions'] = Piwik::translate('Contents_InteractionsMetricDocumentation');
|
||||
}
|
||||
}
|
||||
51
www/analytics/plugins/Contents/Controller.php
Normal file
51
www/analytics/plugins/Contents/Controller.php
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
<?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\View;
|
||||
|
||||
class Controller extends \Piwik\Plugin\Controller
|
||||
{
|
||||
|
||||
public function index()
|
||||
{
|
||||
$reportsView = new View\ReportsByDimension('Contents');
|
||||
|
||||
/** @var \Piwik\Plugin\Report[] $reports */
|
||||
$contentNames = Report::factory($this->pluginName, 'getContentNames');
|
||||
$contentPieces = Report::factory($this->pluginName, 'getContentPieces');
|
||||
$reports = array($contentNames, $contentPieces);
|
||||
|
||||
foreach($reports as $report) {
|
||||
$reportsView->addReport(
|
||||
$report->getCategory(),
|
||||
$report->getName(),
|
||||
'Contents.' . Report::PREFIX_ACTION_IN_MENU . ucfirst($report->getAction())
|
||||
);
|
||||
}
|
||||
|
||||
return $reportsView->render();
|
||||
}
|
||||
|
||||
public function menuGetContentNames()
|
||||
{
|
||||
$report = Report::factory($this->pluginName, 'getContentNames');
|
||||
|
||||
return View::singleReport($report->getName(), $report->render());
|
||||
}
|
||||
|
||||
public function menuGetContentPieces()
|
||||
{
|
||||
$report = Report::factory($this->pluginName, 'getContentPieces');
|
||||
|
||||
return View::singleReport($report->getName(), $report->render());
|
||||
}
|
||||
|
||||
}
|
||||
76
www/analytics/plugins/Contents/DataArray.php
Normal file
76
www/analytics/plugins/Contents/DataArray.php
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
<?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\Metrics;
|
||||
|
||||
/**
|
||||
* The DataArray is a data structure used to aggregate datasets,
|
||||
* ie. sum arrays made of rows made of columns,
|
||||
* data from the logs is stored in a DataArray before being converted in a DataTable
|
||||
*
|
||||
*/
|
||||
|
||||
class DataArray extends \Piwik\DataArray
|
||||
{
|
||||
public function sumMetricsImpressions($label, $row)
|
||||
{
|
||||
if (!isset($this->data[$label])) {
|
||||
$this->data[$label] = self::makeEmptyContentsRow();
|
||||
}
|
||||
$this->doSumContentsImpressionMetrics($row, $this->data[$label]);
|
||||
}
|
||||
|
||||
public function sumMetricsInteractions($label, $row)
|
||||
{
|
||||
if (!isset($this->data[$label])) {
|
||||
return; // do igonre interactions that do not have an impression
|
||||
}
|
||||
$this->doSumContentsInteractionMetrics($row, $this->data[$label]);
|
||||
}
|
||||
|
||||
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_CONTENT_NB_INTERACTIONS => 0
|
||||
);
|
||||
}
|
||||
|
||||
protected function doSumContentsImpressionMetrics($newRowToAdd, &$oldRowToUpdate)
|
||||
{
|
||||
$oldRowToUpdate[Metrics::INDEX_NB_VISITS] += $newRowToAdd[Metrics::INDEX_NB_VISITS];
|
||||
$oldRowToUpdate[Metrics::INDEX_NB_UNIQ_VISITORS] += $newRowToAdd[Metrics::INDEX_NB_UNIQ_VISITORS];
|
||||
$oldRowToUpdate[Metrics::INDEX_CONTENT_NB_IMPRESSIONS] += $newRowToAdd[Metrics::INDEX_CONTENT_NB_IMPRESSIONS];
|
||||
}
|
||||
|
||||
protected function doSumContentsInteractionMetrics($newRowToAdd, &$oldRowToUpdate)
|
||||
{
|
||||
$oldRowToUpdate[Metrics::INDEX_CONTENT_NB_INTERACTIONS] += $newRowToAdd[Metrics::INDEX_CONTENT_NB_INTERACTIONS];
|
||||
}
|
||||
|
||||
public function sumMetricsContentsImpressionPivot($parentLabel, $label, $row)
|
||||
{
|
||||
if (!isset($this->dataTwoLevels[$parentLabel][$label])) {
|
||||
$this->dataTwoLevels[$parentLabel][$label] = $this->makeEmptyContentsRow();
|
||||
}
|
||||
$this->doSumContentsImpressionMetrics($row, $this->dataTwoLevels[$parentLabel][$label]);
|
||||
}
|
||||
|
||||
public function sumMetricsContentsInteractionPivot($parentLabel, $label, $row)
|
||||
{
|
||||
if (!isset($this->dataTwoLevels[$parentLabel][$label])) {
|
||||
return; // do igonre interactions that do not have an impression
|
||||
}
|
||||
$this->doSumContentsInteractionMetrics($row, $this->dataTwoLevels[$parentLabel][$label]);
|
||||
}
|
||||
|
||||
}
|
||||
33
www/analytics/plugins/Contents/Dimensions.php
Normal file
33
www/analytics/plugins/Contents/Dimensions.php
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
<?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
|
||||
{
|
||||
public static function getRecordNameForAction($apiMethod)
|
||||
{
|
||||
$apiToRecord = array(
|
||||
'getContentNames' => Archiver::CONTENTS_NAME_PIECE_RECORD_NAME,
|
||||
'getContentPieces' => Archiver::CONTENTS_PIECE_NAME_RECORD_NAME
|
||||
);
|
||||
|
||||
return $apiToRecord[$apiMethod];
|
||||
}
|
||||
|
||||
public static function getSubtableLabelForApiMethod($apiMethod)
|
||||
{
|
||||
$labelToMethod = array(
|
||||
'getContentNames' => 'Contents_ContentPiece',
|
||||
'getContentPieces' => 'Contents_ContentName'
|
||||
);
|
||||
|
||||
return $labelToMethod[$apiMethod];
|
||||
}
|
||||
|
||||
}
|
||||
24
www/analytics/plugins/Contents/Menu.php
Normal file
24
www/analytics/plugins/Contents/Menu.php
Normal file
|
|
@ -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 = 40);
|
||||
}
|
||||
}
|
||||
18
www/analytics/plugins/Contents/README.md
Normal file
18
www/analytics/plugins/Contents/README.md
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
# Piwik Contents Plugin
|
||||
|
||||
## Description
|
||||
|
||||
Add your plugin description here.
|
||||
|
||||
## FAQ
|
||||
|
||||
__My question?__
|
||||
My answer
|
||||
|
||||
## Changelog
|
||||
|
||||
Here goes the changelog text.
|
||||
|
||||
## Support
|
||||
|
||||
Please direct any feedback to ...
|
||||
60
www/analytics/plugins/Contents/Reports/Base.php
Normal file
60
www/analytics/plugins/Contents/Reports/Base.php
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
<?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\Common;
|
||||
use Piwik\Piwik;
|
||||
use Piwik\Plugin\Report;
|
||||
use Piwik\Plugin\ViewDataTable;
|
||||
use Piwik\Plugins\Contents\Dimensions;
|
||||
|
||||
abstract class Base extends Report
|
||||
{
|
||||
protected function init()
|
||||
{
|
||||
$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)
|
||||
{
|
||||
$view->config->datatable_js_type = 'ContentsDataTable';
|
||||
$view->config->datatable_css_class = 'ContentsDataTable';
|
||||
|
||||
if (!empty($this->dimension)) {
|
||||
$view->config->addTranslations(array('label' => $this->dimension->getName()));
|
||||
}
|
||||
|
||||
$view->config->columns_to_display = array_merge(
|
||||
array('label'),
|
||||
array_keys($this->getMetrics()),
|
||||
array_keys($this->getProcessedMetrics())
|
||||
);
|
||||
|
||||
$view->requestConfig->filter_sort_column = 'nb_impressions';
|
||||
|
||||
if ($this->hasSubtableId()) {
|
||||
$apiMethod = $view->requestConfig->getApiMethodToRequest();
|
||||
$label = Dimensions::getSubtableLabelForApiMethod($apiMethod);
|
||||
$view->config->addTranslation('label', Piwik::translate($label));
|
||||
}
|
||||
}
|
||||
|
||||
private function hasSubtableId()
|
||||
{
|
||||
$subtable = Common::getRequestVar('idSubtable', false, 'integer');
|
||||
|
||||
return !empty($subtable);
|
||||
}
|
||||
}
|
||||
39
www/analytics/plugins/Contents/Reports/GetContentNames.php
Normal file
39
www/analytics/plugins/Contents/Reports/GetContentNames.php
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
<?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\Plugins\Contents\Columns\Metrics\InteractionRate;
|
||||
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->actionToLoadSubTables = 'getContentNames';
|
||||
|
||||
$this->widgetTitle = 'Contents_ContentName';
|
||||
$this->metrics = array('nb_impressions', 'nb_interactions');
|
||||
$this->processedMetrics = array(new InteractionRate());
|
||||
}
|
||||
}
|
||||
40
www/analytics/plugins/Contents/Reports/GetContentPieces.php
Normal file
40
www/analytics/plugins/Contents/Reports/GetContentPieces.php
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
<?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\Plugins\Contents\Columns\Metrics\InteractionRate;
|
||||
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->actionToLoadSubTables = 'getContentPieces';
|
||||
|
||||
$this->widgetTitle = 'Contents_ContentPiece';
|
||||
|
||||
$this->metrics = array('nb_impressions', 'nb_interactions');
|
||||
$this->processedMetrics = array(new InteractionRate());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
/*!
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
|
||||
(function ($, require) {
|
||||
|
||||
var exports = require('piwik/UI'),
|
||||
DataTable = exports.DataTable,
|
||||
dataTablePrototype = DataTable.prototype;
|
||||
|
||||
/**
|
||||
* UI control that handles extra functionality for Actions datatables.
|
||||
*
|
||||
* @constructor
|
||||
*/
|
||||
exports.ContentsDataTable = function (element) {
|
||||
DataTable.call(this, element);
|
||||
};
|
||||
|
||||
$.extend(exports.ContentsDataTable.prototype, dataTablePrototype, {
|
||||
|
||||
//see dataTable::bindEventsAndApplyStyle
|
||||
_init: function (domElem) {
|
||||
domElem.find('table > tbody > tr').each(function (index, tr) {
|
||||
var $tr = $(tr);
|
||||
var $td = $tr.find('.label .value');
|
||||
var text = $td.text().trim();
|
||||
|
||||
if (text.search('^https?:\/\/[^\/]+') !== -1) {
|
||||
if (text.match(/(.jpg|.gif|.png|.svg)$/)) {
|
||||
if (window.encodeURI) {
|
||||
text = window.encodeURI(text);
|
||||
}
|
||||
$td.tooltip({
|
||||
track: true,
|
||||
items: 'span',
|
||||
content: '<p><img style="max-width: 150px;max-height:150px;" src="' + text + '"/><br />' + text + '</p>',
|
||||
tooltipClass: 'rowActionTooltip',
|
||||
show: false,
|
||||
hide: false
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
})(jQuery, require);
|
||||
9
www/analytics/plugins/Contents/lang/ar.json
Normal file
9
www/analytics/plugins/Contents/lang/ar.json
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"Contents": {
|
||||
"Impressions": "طباعة",
|
||||
"Interaction": "المعاملة",
|
||||
"InteractionRate": "نسبة المشاركة",
|
||||
"ContentPiece": "جزء من المحتوى",
|
||||
"Contents": "عنوان المحتوى"
|
||||
}
|
||||
}
|
||||
11
www/analytics/plugins/Contents/lang/bg.json
Normal file
11
www/analytics/plugins/Contents/lang/bg.json
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"Contents": {
|
||||
"Impressions": "Импресии",
|
||||
"Interactions": "Взаимодействия",
|
||||
"Interaction": "Взаимодействие",
|
||||
"InteractionRate": "Честота на взаимодействие",
|
||||
"ContentName": "Име на съдържанието",
|
||||
"ContentTarget": "Целево съдържание",
|
||||
"Contents": "Съдържание"
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue