Teknik is a suite of services with attractive and functional interfaces. https://www.teknik.io/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Flattener.php 4.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  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\API\DataTableManipulator;
  10. use Piwik\API\DataTableManipulator;
  11. use Piwik\Common;
  12. use Piwik\DataTable;
  13. use Piwik\DataTable\Row;
  14. /**
  15. * This class is responsible for flattening data tables.
  16. *
  17. * It loads subtables and combines them into a single table by concatenating the labels.
  18. * This manipulator is triggered by using flat=1 in the API request.
  19. */
  20. class Flattener extends DataTableManipulator
  21. {
  22. private $includeAggregateRows = false;
  23. /**
  24. * If the flattener is used after calling this method, aggregate rows will
  25. * be included in the result. This can be useful when they contain data that
  26. * the leafs don't have (e.g. conversion stats in some cases).
  27. */
  28. public function includeAggregateRows()
  29. {
  30. $this->includeAggregateRows = true;
  31. }
  32. /**
  33. * Separator for building recursive labels (or paths)
  34. * @var string
  35. */
  36. public $recursiveLabelSeparator = ' - ';
  37. /**
  38. * @param DataTable $dataTable
  39. * @return DataTable|DataTable\Map
  40. */
  41. public function flatten($dataTable)
  42. {
  43. if ($this->apiModule == 'Actions' || $this->apiMethod == 'getWebsites') {
  44. $this->recursiveLabelSeparator = '/';
  45. }
  46. return $this->manipulate($dataTable);
  47. }
  48. /**
  49. * Template method called from self::manipulate.
  50. * Flatten each data table.
  51. *
  52. * @param DataTable $dataTable
  53. * @return DataTable
  54. */
  55. protected function manipulateDataTable($dataTable)
  56. {
  57. // apply filters now since subtables have their filters applied before generic filters. if we don't do this
  58. // now, we'll try to apply filters to rows that have already been manipulated. this results in errors like
  59. // 'column ... already exists'.
  60. $keepFilters = true;
  61. if (Common::getRequestVar('disable_queued_filters', 0, 'int', $this->request) == 0) {
  62. $dataTable->applyQueuedFilters();
  63. $keepFilters = false;
  64. }
  65. $newDataTable = $dataTable->getEmptyClone($keepFilters);
  66. foreach ($dataTable->getRows() as $row) {
  67. $this->flattenRow($row, $newDataTable);
  68. }
  69. return $newDataTable;
  70. }
  71. /**
  72. * @param Row $row
  73. * @param DataTable $dataTable
  74. * @param string $labelPrefix
  75. * @param bool $parentLogo
  76. */
  77. private function flattenRow(Row $row, DataTable $dataTable,
  78. $labelPrefix = '', $parentLogo = false)
  79. {
  80. $label = $row->getColumn('label');
  81. if ($label !== false) {
  82. $label = trim($label);
  83. if (substr($label, 0, 1) == '/' && $this->recursiveLabelSeparator == '/') {
  84. $label = substr($label, 1);
  85. }
  86. $label = $labelPrefix . $label;
  87. $row->setColumn('label', $label);
  88. }
  89. $logo = $row->getMetadata('logo');
  90. if ($logo === false && $parentLogo !== false) {
  91. $logo = $parentLogo;
  92. $row->setMetadata('logo', $logo);
  93. }
  94. $subTable = $this->loadSubtable($dataTable, $row);
  95. $row->removeSubtable();
  96. if ($subTable === null) {
  97. if ($this->includeAggregateRows) {
  98. $row->setMetadata('is_aggregate', 0);
  99. }
  100. $dataTable->addRow($row);
  101. } else {
  102. if ($this->includeAggregateRows) {
  103. $row->setMetadata('is_aggregate', 1);
  104. $dataTable->addRow($row);
  105. }
  106. $prefix = $label . $this->recursiveLabelSeparator;
  107. foreach ($subTable->getRows() as $row) {
  108. $this->flattenRow($row, $dataTable, $prefix, $logo);
  109. }
  110. }
  111. }
  112. /**
  113. * Remove the flat parameter from the subtable request
  114. *
  115. * @param array $request
  116. */
  117. protected function manipulateSubtableRequest($request)
  118. {
  119. unset($request['flat']);
  120. return $request;
  121. }
  122. }