PageRenderTime 61ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 0ms

/plugins/Goals/API.php

https://github.com/CodeYellowBV/piwik
PHP | 567 lines | 337 code | 52 blank | 178 comment | 40 complexity | e9beeb06d3ca510be3f7ba6b7ad6cf8d MD5 | raw file
Possible License(s): LGPL-3.0, JSON, MIT, GPL-3.0, LGPL-2.1, GPL-2.0, AGPL-1.0, BSD-2-Clause, BSD-3-Clause
  1. <?php
  2. /**
  3. * Piwik - free/libre analytics platform
  4. *
  5. * @link http://piwik.org
  6. * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
  7. *
  8. */
  9. namespace Piwik\Plugins\Goals;
  10. use Exception;
  11. use Piwik\Archive;
  12. use Piwik\Common;
  13. use Piwik\DataTable;
  14. use Piwik\Db;
  15. use Piwik\Metrics;
  16. use Piwik\Piwik;
  17. use Piwik\Site;
  18. use Piwik\Tracker\Cache;
  19. use Piwik\Tracker\GoalManager;
  20. /**
  21. * Goals API lets you Manage existing goals, via "updateGoal" and "deleteGoal", create new Goals via "addGoal",
  22. * or list existing Goals for one or several websites via "getGoals"
  23. *
  24. * If you are <a href='http://piwik.org/docs/ecommerce-analytics/' target='_blank'>tracking Ecommerce orders and products</a> on your site, the functions "getItemsSku", "getItemsName" and "getItemsCategory"
  25. * will return the list of products purchased on your site, either grouped by Product SKU, Product Name or Product Category. For each name, SKU or category, the following
  26. * metrics are returned: Total revenue, Total quantity, average price, average quantity, number of orders (or abandoned carts) containing this product, number of visits on the Product page,
  27. * Conversion rate.
  28. *
  29. * By default, these functions return the 'Products purchased'. These functions also accept an optional parameter &abandonedCarts=1.
  30. * If the parameter is set, it will instead return the metrics for products that were left in an abandoned cart therefore not purchased.
  31. *
  32. * The API also lets you request overall Goal metrics via the method "get": Conversions, Visits with at least one conversion, Conversion rate and Revenue.
  33. * If you wish to request specific metrics about Ecommerce goals, you can set the parameter &idGoal=ecommerceAbandonedCart to get metrics about abandoned carts (including Lost revenue, and number of items left in the cart)
  34. * or &idGoal=ecommerceOrder to get metrics about Ecommerce orders (number of orders, visits with an order, subtotal, tax, shipping, discount, revenue, items ordered)
  35. *
  36. * See also the documentation about <a href='http://piwik.org/docs/tracking-goals-web-analytics/' target='_blank'>Tracking Goals</a> in Piwik.
  37. *
  38. * @method static \Piwik\Plugins\Goals\API getInstance()
  39. */
  40. class API extends \Piwik\Plugin\API
  41. {
  42. const AVG_PRICE_VIEWED = 'avg_price_viewed';
  43. /**
  44. * Returns all Goals for a given website, or list of websites
  45. *
  46. * @param string|array $idSite Array or Comma separated list of website IDs to request the goals for
  47. * @return array Array of Goal attributes
  48. */
  49. public function getGoals($idSite)
  50. {
  51. //TODO calls to this function could be cached as static
  52. // would help UI at least, since some UI requests would call this 2-3 times..
  53. $idSite = Site::getIdSitesFromIdSitesString($idSite);
  54. if (empty($idSite)) {
  55. return array();
  56. }
  57. Piwik::checkUserHasViewAccess($idSite);
  58. $goals = Db::fetchAll("SELECT *
  59. FROM " . Common::prefixTable('goal') . "
  60. WHERE idsite IN (" . implode(", ", $idSite) . ")
  61. AND deleted = 0");
  62. $cleanedGoals = array();
  63. foreach ($goals as &$goal) {
  64. if ($goal['match_attribute'] == 'manually') {
  65. unset($goal['pattern']);
  66. unset($goal['pattern_type']);
  67. unset($goal['case_sensitive']);
  68. }
  69. $cleanedGoals[$goal['idgoal']] = $goal;
  70. }
  71. return $cleanedGoals;
  72. }
  73. /**
  74. * Creates a Goal for a given website.
  75. *
  76. * @param int $idSite
  77. * @param string $name
  78. * @param string $matchAttribute 'url', 'title', 'file', 'external_website' or 'manually'
  79. * @param string $pattern eg. purchase-confirmation.htm
  80. * @param string $patternType 'regex', 'contains', 'exact'
  81. * @param bool $caseSensitive
  82. * @param bool|float $revenue If set, default revenue to assign to conversions
  83. * @param bool $allowMultipleConversionsPerVisit By default, multiple conversions in the same visit will only record the first conversion.
  84. * If set to true, multiple conversions will all be recorded within a visit (useful for Ecommerce goals)
  85. * @return int ID of the new goal
  86. */
  87. public function addGoal($idSite, $name, $matchAttribute, $pattern, $patternType, $caseSensitive = false, $revenue = false, $allowMultipleConversionsPerVisit = false)
  88. {
  89. Piwik::checkUserHasAdminAccess($idSite);
  90. $this->checkPatternIsValid($patternType, $pattern);
  91. $name = $this->checkName($name);
  92. $pattern = $this->checkPattern($pattern);
  93. // save in db
  94. $db = Db::get();
  95. $idGoal = $db->fetchOne("SELECT max(idgoal) + 1
  96. FROM " . Common::prefixTable('goal') . "
  97. WHERE idsite = ?", $idSite);
  98. if ($idGoal == false) {
  99. $idGoal = 1;
  100. }
  101. $db->insert(Common::prefixTable('goal'),
  102. array(
  103. 'idsite' => $idSite,
  104. 'idgoal' => $idGoal,
  105. 'name' => $name,
  106. 'match_attribute' => $matchAttribute,
  107. 'pattern' => $pattern,
  108. 'pattern_type' => $patternType,
  109. 'case_sensitive' => (int)$caseSensitive,
  110. 'allow_multiple' => (int)$allowMultipleConversionsPerVisit,
  111. 'revenue' => (float)$revenue,
  112. 'deleted' => 0,
  113. ));
  114. Cache::regenerateCacheWebsiteAttributes($idSite);
  115. return $idGoal;
  116. }
  117. /**
  118. * Updates a Goal description.
  119. * Will not update or re-process the conversions already recorded
  120. *
  121. * @see addGoal() for parameters description
  122. * @param int $idSite
  123. * @param int $idGoal
  124. * @param $name
  125. * @param $matchAttribute
  126. * @param string $pattern
  127. * @param string $patternType
  128. * @param bool $caseSensitive
  129. * @param bool|float $revenue
  130. * @param bool $allowMultipleConversionsPerVisit
  131. * @return void
  132. */
  133. public function updateGoal($idSite, $idGoal, $name, $matchAttribute, $pattern, $patternType, $caseSensitive = false, $revenue = false, $allowMultipleConversionsPerVisit = false)
  134. {
  135. Piwik::checkUserHasAdminAccess($idSite);
  136. $name = $this->checkName($name);
  137. $pattern = $this->checkPattern($pattern);
  138. $this->checkPatternIsValid($patternType, $pattern);
  139. Db::get()->update(Common::prefixTable('goal'),
  140. array(
  141. 'name' => $name,
  142. 'match_attribute' => $matchAttribute,
  143. 'pattern' => $pattern,
  144. 'pattern_type' => $patternType,
  145. 'case_sensitive' => (int)$caseSensitive,
  146. 'allow_multiple' => (int)$allowMultipleConversionsPerVisit,
  147. 'revenue' => (float)$revenue,
  148. ),
  149. "idsite = '$idSite' AND idgoal = '$idGoal'"
  150. );
  151. Cache::regenerateCacheWebsiteAttributes($idSite);
  152. }
  153. private function checkPatternIsValid($patternType, $pattern)
  154. {
  155. if ($patternType == 'exact'
  156. && substr($pattern, 0, 4) != 'http'
  157. ) {
  158. throw new Exception(Piwik::translate('Goals_ExceptionInvalidMatchingString', array("http:// or https://", "http://www.yourwebsite.com/newsletter/subscribed.html")));
  159. }
  160. }
  161. private function checkName($name)
  162. {
  163. return urldecode($name);
  164. }
  165. private function checkPattern($pattern)
  166. {
  167. return urldecode($pattern);
  168. }
  169. /**
  170. * Soft deletes a given Goal.
  171. * Stats data in the archives will still be recorded, but not displayed.
  172. *
  173. * @param int $idSite
  174. * @param int $idGoal
  175. * @return void
  176. */
  177. public function deleteGoal($idSite, $idGoal)
  178. {
  179. Piwik::checkUserHasAdminAccess($idSite);
  180. Db::query("UPDATE " . Common::prefixTable('goal') . "
  181. SET deleted = 1
  182. WHERE idsite = ?
  183. AND idgoal = ?",
  184. array($idSite, $idGoal));
  185. Db::deleteAllRows(Common::prefixTable("log_conversion"), "WHERE idgoal = ? AND idsite = ?", "idvisit", 100000, array($idGoal, $idSite));
  186. Cache::regenerateCacheWebsiteAttributes($idSite);
  187. }
  188. /**
  189. * Returns a datatable of Items SKU/name or categories and their metrics
  190. * If $abandonedCarts set to 1, will return items abandoned in carts. If set to 0, will return items ordered
  191. */
  192. protected function getItems($recordName, $idSite, $period, $date, $abandonedCarts, $segment)
  193. {
  194. Piwik::checkUserHasViewAccess($idSite);
  195. $recordNameFinal = $recordName;
  196. if ($abandonedCarts) {
  197. $recordNameFinal = Archiver::getItemRecordNameAbandonedCart($recordName);
  198. }
  199. $archive = Archive::build($idSite, $period, $date, $segment);
  200. $dataTable = $archive->getDataTable($recordNameFinal);
  201. $dataTable->filter('Sort', array(Metrics::INDEX_ECOMMERCE_ITEM_REVENUE));
  202. $this->enrichItemsTableWithViewMetrics($dataTable, $recordName, $idSite, $period, $date, $segment);
  203. // First rename the avg_price_viewed column
  204. $renameColumn = array(self::AVG_PRICE_VIEWED => 'avg_price');
  205. $dataTable->queueFilter('ReplaceColumnNames', array($renameColumn));
  206. $dataTable->queueFilter('ReplaceColumnNames');
  207. $dataTable->queueFilter('ReplaceSummaryRowLabel');
  208. $ordersColumn = 'orders';
  209. if ($abandonedCarts) {
  210. $ordersColumn = 'abandoned_carts';
  211. $dataTable->renameColumn(Metrics::INDEX_ECOMMERCE_ORDERS, $ordersColumn);
  212. }
  213. // Average price = sum product revenue / quantity
  214. $dataTable->queueFilter('ColumnCallbackAddColumnQuotient', array('avg_price', 'price', $ordersColumn, GoalManager::REVENUE_PRECISION));
  215. // Average quantity = sum product quantity / abandoned carts
  216. $dataTable->queueFilter('ColumnCallbackAddColumnQuotient',
  217. array('avg_quantity', 'quantity', $ordersColumn, $precision = 1));
  218. $dataTable->queueFilter('ColumnDelete', array('price'));
  219. // Product conversion rate = orders / visits
  220. $dataTable->queueFilter('ColumnCallbackAddColumnPercentage', array('conversion_rate', $ordersColumn, 'nb_visits', GoalManager::REVENUE_PRECISION));
  221. return $dataTable;
  222. }
  223. protected function renameNotDefinedRow($dataTable, $notDefinedStringPretty)
  224. {
  225. if ($dataTable instanceof DataTable\Map) {
  226. foreach ($dataTable->getDataTables() as $table) {
  227. $this->renameNotDefinedRow($table, $notDefinedStringPretty);
  228. }
  229. return;
  230. }
  231. $rowNotDefined = $dataTable->getRowFromLabel(\Piwik\Plugins\CustomVariables\Archiver::LABEL_CUSTOM_VALUE_NOT_DEFINED);
  232. if ($rowNotDefined) {
  233. $rowNotDefined->setColumn('label', $notDefinedStringPretty);
  234. }
  235. }
  236. protected function enrichItemsDataTableWithItemsViewMetrics($dataTable, $idSite, $period, $date, $segment, $idSubtable)
  237. {
  238. $ecommerceViews = \Piwik\Plugins\CustomVariables\API::getInstance()->getCustomVariablesValuesFromNameId($idSite, $period, $date, $idSubtable, $segment, $_leavePriceViewedColumn = true);
  239. // For Product names and SKU reports, and for Category report
  240. // Use the Price (tracked on page views)
  241. // ONLY when the price sold in conversions is not found (ie. product viewed but not sold)
  242. foreach ($ecommerceViews->getRows() as $rowView) {
  243. // If there is not already a 'sum price' for this product
  244. $rowFound = $dataTable->getRowFromLabel($rowView->getColumn('label'));
  245. $price = $rowFound
  246. ? $rowFound->getColumn(Metrics::INDEX_ECOMMERCE_ITEM_PRICE)
  247. : false;
  248. if (empty($price)) {
  249. // If a price was tracked on the product page
  250. if ($rowView->getColumn(Metrics::INDEX_ECOMMERCE_ITEM_PRICE_VIEWED)) {
  251. $rowView->renameColumn(Metrics::INDEX_ECOMMERCE_ITEM_PRICE_VIEWED, self::AVG_PRICE_VIEWED);
  252. }
  253. }
  254. $rowView->deleteColumn(Metrics::INDEX_ECOMMERCE_ITEM_PRICE_VIEWED);
  255. }
  256. $dataTable->addDataTable($ecommerceViews);
  257. }
  258. public function getItemsSku($idSite, $period, $date, $abandonedCarts = false, $segment = false)
  259. {
  260. return $this->getItems('Goals_ItemsSku', $idSite, $period, $date, $abandonedCarts, $segment);
  261. }
  262. public function getItemsName($idSite, $period, $date, $abandonedCarts = false, $segment = false)
  263. {
  264. return $this->getItems('Goals_ItemsName', $idSite, $period, $date, $abandonedCarts, $segment);
  265. }
  266. public function getItemsCategory($idSite, $period, $date, $abandonedCarts = false, $segment = false)
  267. {
  268. return $this->getItems('Goals_ItemsCategory', $idSite, $period, $date, $abandonedCarts, $segment);
  269. }
  270. /**
  271. * Helper function that checks for special string goal IDs and converts them to
  272. * their integer equivalents.
  273. *
  274. * Checks for the following values:
  275. * Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_ORDER
  276. * Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_CART
  277. *
  278. * @param string|int $idGoal The goal id as an integer or a special string.
  279. * @return int The numeric goal id.
  280. */
  281. protected static function convertSpecialGoalIds($idGoal)
  282. {
  283. if ($idGoal == Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_ORDER) {
  284. return GoalManager::IDGOAL_ORDER;
  285. } else if ($idGoal == Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_CART) {
  286. return GoalManager::IDGOAL_CART;
  287. } else {
  288. return $idGoal;
  289. }
  290. }
  291. /**
  292. * Returns Goals data
  293. *
  294. * @param int $idSite
  295. * @param string $period
  296. * @param string $date
  297. * @param bool $segment
  298. * @param bool|int $idGoal
  299. * @param array $columns Array of metrics to fetch: nb_conversions, conversion_rate, revenue
  300. * @return DataTable
  301. */
  302. public function get($idSite, $period, $date, $segment = false, $idGoal = false, $columns = array())
  303. {
  304. Piwik::checkUserHasViewAccess($idSite);
  305. $archive = Archive::build($idSite, $period, $date, $segment);
  306. $columns = Piwik::getArrayFromApiParameter($columns);
  307. // Mapping string idGoal to internal ID
  308. $idGoal = self::convertSpecialGoalIds($idGoal);
  309. if (empty($columns)) {
  310. $columns = Goals::getGoalColumns($idGoal);
  311. if ($idGoal == Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_ORDER) {
  312. $columns[] = 'avg_order_revenue';
  313. }
  314. }
  315. if (in_array('avg_order_revenue', $columns)
  316. && $idGoal == Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_ORDER
  317. ) {
  318. $columns[] = 'nb_conversions';
  319. $columns[] = 'revenue';
  320. $columns = array_values(array_unique($columns));
  321. }
  322. $columnsToSelect = array();
  323. foreach ($columns as &$columnName) {
  324. $columnsToSelect[] = Archiver::getRecordName($columnName, $idGoal);
  325. }
  326. $dataTable = $archive->getDataTableFromNumeric($columnsToSelect);
  327. // Rewrite column names as we expect them
  328. foreach ($columnsToSelect as $id => $oldName) {
  329. $dataTable->renameColumn($oldName, $columns[$id]);
  330. }
  331. if ($idGoal == Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_ORDER) {
  332. if ($dataTable instanceof DataTable\Map) {
  333. foreach ($dataTable->getDataTables() as $row) {
  334. $this->enrichTable($row);
  335. }
  336. } else {
  337. $this->enrichTable($dataTable);
  338. }
  339. }
  340. return $dataTable;
  341. }
  342. protected function enrichTable($table)
  343. {
  344. $row = $table->getFirstRow();
  345. if (!$row) {
  346. return;
  347. }
  348. // AVG order per visit
  349. if (false !== $table->getColumn('avg_order_revenue')) {
  350. $conversions = $row->getColumn('nb_conversions');
  351. if ($conversions) {
  352. $row->setColumn('avg_order_revenue', round($row->getColumn('revenue') / $conversions, 2));
  353. }
  354. }
  355. }
  356. protected function getNumeric($idSite, $period, $date, $segment, $toFetch)
  357. {
  358. Piwik::checkUserHasViewAccess($idSite);
  359. $archive = Archive::build($idSite, $period, $date, $segment);
  360. $dataTable = $archive->getDataTableFromNumeric($toFetch);
  361. return $dataTable;
  362. }
  363. /**
  364. * @ignore
  365. */
  366. public function getConversions($idSite, $period, $date, $segment = false, $idGoal = false)
  367. {
  368. return $this->getNumeric($idSite, $period, $date, $segment, Archiver::getRecordName('nb_conversions', $idGoal));
  369. }
  370. /**
  371. * @ignore
  372. */
  373. public function getNbVisitsConverted($idSite, $period, $date, $segment = false, $idGoal = false)
  374. {
  375. return $this->getNumeric($idSite, $period, $date, $segment, Archiver::getRecordName('nb_visits_converted', $idGoal));
  376. }
  377. /**
  378. * @ignore
  379. */
  380. public function getConversionRate($idSite, $period, $date, $segment = false, $idGoal = false)
  381. {
  382. return $this->getNumeric($idSite, $period, $date, $segment, Archiver::getRecordName('conversion_rate', $idGoal));
  383. }
  384. /**
  385. * @ignore
  386. */
  387. public function getRevenue($idSite, $period, $date, $segment = false, $idGoal = false)
  388. {
  389. return $this->getNumeric($idSite, $period, $date, $segment, Archiver::getRecordName('revenue', $idGoal));
  390. }
  391. /**
  392. * Utility method that retrieve an archived DataTable for a specific site, date range,
  393. * segment and goal. If not goal is specified, this method will retrieve and sum the
  394. * data for every goal.
  395. *
  396. * @param string $recordName The archive entry name.
  397. * @param int|string $idSite The site(s) to select data for.
  398. * @param string $period The period type.
  399. * @param string $date The date type.
  400. * @param string $segment The segment.
  401. * @param int|bool $idGoal The id of the goal to get data for. If this is set to false,
  402. * data for every goal that belongs to $idSite is returned.
  403. * @return false|DataTable
  404. */
  405. protected function getGoalSpecificDataTable($recordName, $idSite, $period, $date, $segment, $idGoal)
  406. {
  407. Piwik::checkUserHasViewAccess($idSite);
  408. $archive = Archive::build($idSite, $period, $date, $segment);
  409. // check for the special goal ids
  410. $realGoalId = $idGoal != true ? false : self::convertSpecialGoalIds($idGoal);
  411. // get the data table
  412. $dataTable = $archive->getDataTable(Archiver::getRecordName($recordName, $realGoalId), $idSubtable = null);
  413. $dataTable->queueFilter('ReplaceColumnNames');
  414. return $dataTable;
  415. }
  416. /**
  417. * Gets a DataTable that maps ranges of days to the number of conversions that occurred
  418. * within those ranges, for the specified site, date range, segment and goal.
  419. *
  420. * @param int $idSite The site to select data from.
  421. * @param string $period The period type.
  422. * @param string $date The date type.
  423. * @param string|bool $segment The segment.
  424. * @param int|bool $idGoal The id of the goal to get data for. If this is set to false,
  425. * data for every goal that belongs to $idSite is returned.
  426. * @return false|DataTable
  427. */
  428. public function getDaysToConversion($idSite, $period, $date, $segment = false, $idGoal = false)
  429. {
  430. $dataTable = $this->getGoalSpecificDataTable(
  431. Archiver::DAYS_UNTIL_CONV_RECORD_NAME, $idSite, $period, $date, $segment, $idGoal);
  432. $dataTable->queueFilter('Sort', array('label', 'asc', true));
  433. $dataTable->queueFilter(
  434. 'BeautifyRangeLabels', array(Piwik::translate('General_OneDay'), Piwik::translate('General_NDays')));
  435. return $dataTable;
  436. }
  437. /**
  438. * Gets a DataTable that maps ranges of visit counts to the number of conversions that
  439. * occurred on those visits for the specified site, date range, segment and goal.
  440. *
  441. * @param int $idSite The site to select data from.
  442. * @param string $period The period type.
  443. * @param string $date The date type.
  444. * @param string|bool $segment The segment.
  445. * @param int|bool $idGoal The id of the goal to get data for. If this is set to false,
  446. * data for every goal that belongs to $idSite is returned.
  447. * @return bool|DataTable
  448. */
  449. public function getVisitsUntilConversion($idSite, $period, $date, $segment = false, $idGoal = false)
  450. {
  451. $dataTable = $this->getGoalSpecificDataTable(
  452. Archiver::VISITS_UNTIL_RECORD_NAME, $idSite, $period, $date, $segment, $idGoal);
  453. $dataTable->queueFilter('Sort', array('label', 'asc', true));
  454. $dataTable->queueFilter(
  455. 'BeautifyRangeLabels', array(Piwik::translate('General_OneVisit'), Piwik::translate('General_NVisits')));
  456. return $dataTable;
  457. }
  458. /**
  459. * Enhances the dataTable with Items attributes found in the Custom Variables report.
  460. *
  461. * @param $dataTable
  462. * @param $recordName
  463. * @param $idSite
  464. * @param $period
  465. * @param $date
  466. * @param $segment
  467. */
  468. protected function enrichItemsTableWithViewMetrics($dataTable, $recordName, $idSite, $period, $date, $segment)
  469. {
  470. // Enrich the datatable with Product/Categories views, and conversion rates
  471. $customVariables = \Piwik\Plugins\CustomVariables\API::getInstance()->getCustomVariables($idSite, $period, $date, $segment, $expanded = false,
  472. $_leavePiwikCoreVariables = true);
  473. $mapping = array(
  474. 'Goals_ItemsSku' => '_pks',
  475. 'Goals_ItemsName' => '_pkn',
  476. 'Goals_ItemsCategory' => '_pkc',
  477. );
  478. $reportToNotDefinedString = array(
  479. 'Goals_ItemsSku' => Piwik::translate('General_NotDefined', Piwik::translate('Goals_ProductSKU')), // Note: this should never happen
  480. 'Goals_ItemsName' => Piwik::translate('General_NotDefined', Piwik::translate('Goals_ProductName')),
  481. 'Goals_ItemsCategory' => Piwik::translate('General_NotDefined', Piwik::translate('Goals_ProductCategory'))
  482. );
  483. $notDefinedStringPretty = $reportToNotDefinedString[$recordName];
  484. $customVarNameToLookFor = $mapping[$recordName];
  485. // Handle case where date=last30&period=day
  486. if ($customVariables instanceof DataTable\Map) {
  487. $customVariableDatatables = $customVariables->getDataTables();
  488. $dataTables = $dataTable->getDataTables();
  489. foreach ($customVariableDatatables as $key => $customVariableTableForDate) {
  490. $dataTableForDate = isset($dataTables[$key]) ? $dataTables[$key] : new DataTable();
  491. // we do not enter the IF
  492. // if case idSite=1,3 AND period=day&date=datefrom,dateto,
  493. if ($customVariableTableForDate instanceof DataTable
  494. && $customVariableTableForDate->getMetadata(Archive\DataTableFactory::TABLE_METADATA_PERIOD_INDEX)
  495. ) {
  496. $dateRewrite = $customVariableTableForDate->getMetadata(Archive\DataTableFactory::TABLE_METADATA_PERIOD_INDEX)->getDateStart()->toString();
  497. $row = $customVariableTableForDate->getRowFromLabel($customVarNameToLookFor);
  498. if ($row) {
  499. $idSubtable = $row->getIdSubDataTable();
  500. $this->enrichItemsDataTableWithItemsViewMetrics($dataTableForDate, $idSite, $period, $dateRewrite, $segment, $idSubtable);
  501. }
  502. $dataTable->addTable($dataTableForDate, $key);
  503. }
  504. $this->renameNotDefinedRow($dataTableForDate, $notDefinedStringPretty);
  505. }
  506. } elseif ($customVariables instanceof DataTable) {
  507. $row = $customVariables->getRowFromLabel($customVarNameToLookFor);
  508. if ($row) {
  509. $idSubtable = $row->getIdSubDataTable();
  510. $this->enrichItemsDataTableWithItemsViewMetrics($dataTable, $idSite, $period, $date, $segment, $idSubtable);
  511. }
  512. $this->renameNotDefinedRow($dataTable, $notDefinedStringPretty);
  513. }
  514. }
  515. }