PageRenderTime 38ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/core/ViewDataTable/Config.php

https://github.com/CodeYellowBV/piwik
PHP | 633 lines | 187 code | 72 blank | 374 comment | 16 complexity | 7beb0f5771f54a4ad372c7c400d1f22f 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\ViewDataTable;
  10. use Piwik\API\Request as ApiRequest;
  11. use Piwik\Metrics;
  12. use Piwik\Plugins\API\API;
  13. /**
  14. * Contains base display properties for {@link Piwik\Plugin\ViewDataTable}s. Manipulating these
  15. * properties in a ViewDataTable instance will change how its report will be displayed.
  16. *
  17. * <a name="client-side-properties-desc"></a>
  18. * **Client Side Properties**
  19. *
  20. * Client side properties are properties that should be passed on to the browser so
  21. * client side JavaScript can use them. Only affects ViewDataTables that output HTML.
  22. *
  23. * <a name="overridable-properties-desc"></a>
  24. * **Overridable Properties**
  25. *
  26. * Overridable properties are properties that can be set via the query string.
  27. * If a request has a query parameter that matches an overridable property, the property
  28. * will be set to the query parameter value.
  29. *
  30. * **Reusing base properties**
  31. *
  32. * Many of the properties in this class only have meaning for the {@link Piwik\Plugin\Visualization}
  33. * class, but can be set for other visualizations that extend {@link Piwik\Plugin\ViewDataTable}
  34. * directly.
  35. *
  36. * Visualizations that extend {@link Piwik\Plugin\ViewDataTable} directly and want to re-use these
  37. * properties must make sure the properties are used in the exact same way they are used in
  38. * {@link Piwik\Plugin\Visualization}.
  39. *
  40. * **Defining new display properties**
  41. *
  42. * If you are creating your own visualization and want to add new display properties for
  43. * it, extend this class and add your properties as fields.
  44. *
  45. * Properties are marked as client side properties by calling the
  46. * {@link addPropertiesThatShouldBeAvailableClientSide()} method.
  47. *
  48. * Properties are marked as overridable by calling the
  49. * {@link addPropertiesThatCanBeOverwrittenByQueryParams()} method.
  50. *
  51. * ### Example
  52. *
  53. * **Defining new display properties**
  54. *
  55. * class MyCustomVizConfig extends Config
  56. * {
  57. * /**
  58. * * My custom property. It is overridable.
  59. * *\/
  60. * public $my_custom_property = false;
  61. *
  62. * /**
  63. * * Another custom property. It is available client side.
  64. * *\/
  65. * public $another_custom_property = true;
  66. *
  67. * public function __construct()
  68. * {
  69. * parent::__construct();
  70. *
  71. * $this->addPropertiesThatShouldBeAvailableClientSide(array('another_custom_property'));
  72. * $this->addPropertiesThatCanBeOverwrittenByQueryParams(array('my_custom_property'));
  73. * }
  74. * }
  75. *
  76. * @api
  77. */
  78. class Config
  79. {
  80. /**
  81. * The list of ViewDataTable properties that are 'Client Side Properties'.
  82. */
  83. public $clientSideProperties = array(
  84. 'show_limit_control'
  85. );
  86. /**
  87. * The list of ViewDataTable properties that can be overriden by query parameters.
  88. */
  89. public $overridableProperties = array(
  90. 'show_goals',
  91. 'show_exclude_low_population',
  92. 'show_flatten_table',
  93. 'show_table',
  94. 'show_table_all_columns',
  95. 'show_footer',
  96. 'show_footer_icons',
  97. 'show_all_views_icons',
  98. 'show_active_view_icon',
  99. 'show_related_reports',
  100. 'show_limit_control',
  101. 'show_search',
  102. 'enable_sort',
  103. 'show_bar_chart',
  104. 'show_pie_chart',
  105. 'show_tag_cloud',
  106. 'show_export_as_rss_feed',
  107. 'show_ecommerce',
  108. 'search_recursive',
  109. 'show_export_as_image_icon',
  110. 'show_pagination_control',
  111. 'show_offset_information',
  112. 'hide_annotations_view',
  113. 'export_limit'
  114. );
  115. /**
  116. * Controls what footer icons are displayed on the bottom left of the DataTable view.
  117. * The value of this property must be an array of footer icon groups. Footer icon groups
  118. * have set of properties, including an array of arrays describing footer icons. For
  119. * example:
  120. *
  121. * array(
  122. * array( // footer icon group 1
  123. * 'class' => 'footerIconGroup1CssClass',
  124. * 'buttons' => array(
  125. * 'id' => 'myid',
  126. * 'title' => 'My Tooltip',
  127. * 'icon' => 'path/to/my/icon.png'
  128. * )
  129. * ),
  130. * array( // footer icon group 2
  131. * 'class' => 'footerIconGroup2CssClass',
  132. * 'buttons' => array(...)
  133. * )
  134. * )
  135. *
  136. * By default, when a user clicks on a footer icon, Piwik will assume the 'id' is
  137. * a viewDataTable ID and try to reload the DataTable w/ the new viewDataTable. You
  138. * can provide your own footer icon behavior by adding an appropriate handler via
  139. * DataTable.registerFooterIconHandler in your JavaScript code.
  140. *
  141. * The default value of this property is not set here and will show the 'Normal Table'
  142. * icon, the 'All Columns' icon, the 'Goals Columns' icon and all jqPlot graph columns,
  143. * unless other properties tell the view to exclude them.
  144. */
  145. public $footer_icons = false;
  146. /**
  147. * Controls whether the buttons and UI controls around the visualization or shown or
  148. * if just the visualization alone is shown.
  149. */
  150. public $show_visualization_only = false;
  151. /**
  152. * Controls whether the goals footer icon is shown.
  153. */
  154. public $show_goals = false;
  155. /**
  156. * Array property mapping DataTable column names with their internationalized names.
  157. *
  158. * The default value for this property is set elsewhere. It will contain translations
  159. * of common metrics.
  160. */
  161. public $translations = array();
  162. /**
  163. * Controls whether the 'Exclude Low Population' option (visible in the popup that displays after
  164. * clicking the 'cog' icon) is shown.
  165. */
  166. public $show_exclude_low_population = true;
  167. /**
  168. * Whether to show the 'Flatten' option (visible in the popup that displays after clicking the
  169. * 'cog' icon).
  170. */
  171. public $show_flatten_table = true;
  172. /**
  173. * Controls whether the footer icon that allows users to switch to the 'normal' DataTable view
  174. * is shown.
  175. */
  176. public $show_table = true;
  177. /**
  178. * Controls whether the 'All Columns' footer icon is shown.
  179. */
  180. public $show_table_all_columns = true;
  181. /**
  182. * Controls whether the entire view footer is shown.
  183. */
  184. public $show_footer = true;
  185. /**
  186. * Controls whether the row that contains all footer icons & the limit selector is shown.
  187. */
  188. public $show_footer_icons = true;
  189. /**
  190. * Array property that determines which columns will be shown. Columns not in this array
  191. * should not appear in ViewDataTable visualizations.
  192. *
  193. * Example: `array('label', 'nb_visits', 'nb_uniq_visitors')`
  194. *
  195. * If this value is empty it will be defaulted to `array('label', 'nb_visits')` or
  196. * `array('label', 'nb_uniq_visitors')` if the report contains a nb_uniq_visitors column
  197. * after data is loaded.
  198. */
  199. public $columns_to_display = array();
  200. /**
  201. * Controls whether graph and non core viewDataTable footer icons are shown or not.
  202. */
  203. public $show_all_views_icons = true;
  204. /**
  205. * Controls whether to display a tiny upside-down caret over the currently active view icon.
  206. */
  207. public $show_active_view_icon = true;
  208. /**
  209. * Related reports are listed below a datatable view. When clicked, the original report will
  210. * change to the clicked report and the list will change so the original report can be
  211. * navigated back to.
  212. */
  213. public $related_reports = array();
  214. /**
  215. * "Related Reports" is displayed by default before listing the Related reports,
  216. * The string can be changed.
  217. */
  218. public $related_reports_title;
  219. /**
  220. * The report title. Used with related reports so report headings can be changed when switching
  221. * reports.
  222. *
  223. * This must be set if related reports are added.
  224. */
  225. public $title = '';
  226. /**
  227. * Controls whether a report's related reports are listed with the view or not.
  228. */
  229. public $show_related_reports = true;
  230. /**
  231. * Contains the documentation for a report.
  232. */
  233. public $documentation = false;
  234. /**
  235. * Array property containing custom data to be saved in JSON in the data-params HTML attribute
  236. * of a data table div. This data can be used by JavaScript DataTable classes.
  237. *
  238. * e.g. array('typeReferrer' => ...)
  239. *
  240. * It can then be accessed in the twig templates by clientSideParameters.typeReferrer
  241. */
  242. public $custom_parameters = array();
  243. /**
  244. * Controls whether the limit dropdown (which allows users to change the number of data shown)
  245. * is always shown or not.
  246. *
  247. * Normally shown only if pagination is enabled.
  248. */
  249. public $show_limit_control = true;
  250. /**
  251. * Controls whether the search box under the datatable is shown.
  252. */
  253. public $show_search = true;
  254. /**
  255. * Controls whether the user can sort DataTables by clicking on table column headings.
  256. */
  257. public $enable_sort = true;
  258. /**
  259. * Controls whether the footer icon that allows users to view data as a bar chart is shown.
  260. */
  261. public $show_bar_chart = true;
  262. /**
  263. * Controls whether the footer icon that allows users to view data as a pie chart is shown.
  264. */
  265. public $show_pie_chart = true;
  266. /**
  267. * Controls whether the footer icon that allows users to view data as a tag cloud is shown.
  268. */
  269. public $show_tag_cloud = true;
  270. /**
  271. * Controls whether the user is allowed to export data as an RSS feed or not.
  272. */
  273. public $show_export_as_rss_feed = true;
  274. /**
  275. * Controls whether the 'Ecoommerce Orders'/'Abandoned Cart' footer icons are shown or not.
  276. */
  277. public $show_ecommerce = false;
  278. /**
  279. * Stores an HTML message (if any) to display under the datatable view.
  280. */
  281. public $show_footer_message = false;
  282. /**
  283. * Array property that stores documentation for individual metrics.
  284. *
  285. * E.g. `array('nb_visits' => '...', ...)`
  286. *
  287. * By default this is set to values retrieved from report metadata (via API.getReportMetadata API method).
  288. */
  289. public $metrics_documentation = array();
  290. /**
  291. * Row metadata name that contains the tooltip for the specific row.
  292. */
  293. public $tooltip_metadata_name = false;
  294. /**
  295. * The URL to the report the view is displaying. Modifying this means clicking back to this report
  296. * from a Related Report will go to a different URL. Can be used to load an entire page instead
  297. * of a single report when going back to the original report.
  298. *
  299. * The URL used to request the report without generic filters.
  300. */
  301. public $self_url = '';
  302. /**
  303. * CSS class to use in the output HTML div. This is added in addition to the visualization CSS
  304. * class.
  305. */
  306. public $datatable_css_class = false;
  307. /**
  308. * The JavaScript class to instantiate after the result HTML is obtained. This class handles all
  309. * interactive behavior for the DataTable view.
  310. */
  311. public $datatable_js_type = 'DataTable';
  312. /**
  313. * If true, searching through the DataTable will search through all subtables.
  314. */
  315. public $search_recursive = false;
  316. /**
  317. * The unit of the displayed column. Valid if only one non-label column is displayed.
  318. */
  319. public $y_axis_unit = false;
  320. /**
  321. * Controls whether to show the 'Export as Image' footer icon.
  322. */
  323. public $show_export_as_image_icon = false;
  324. /**
  325. * Array of DataTable filters that should be run before displaying a DataTable. Elements
  326. * of this array can either be a closure or an array with at most three elements, including:
  327. * - the filter name (or a closure)
  328. * - an array of filter parameters
  329. * - a boolean indicating if the filter is a priority filter or not
  330. *
  331. * Priority filters are run before queued filters. These filters should be filters that
  332. * add/delete rows.
  333. *
  334. * If a closure is used, the view is appended as a parameter.
  335. */
  336. public $filters = array();
  337. /**
  338. * Contains the controller action to call when requesting subtables of the current report.
  339. *
  340. * By default, this is set to the controller action used to request the report.
  341. */
  342. public $subtable_controller_action = '';
  343. /**
  344. * Controls whether the 'prev'/'next' links are shown in the DataTable footer. These links
  345. * change the 'filter_offset' query parameter, thus allowing pagination.
  346. */
  347. public $show_pagination_control = true;
  348. /**
  349. * Controls whether offset information (ie, '5-10 of 20') is shown under the datatable.
  350. */
  351. public $show_offset_information = true;
  352. /**
  353. * Controls whether annotations are shown or not.
  354. */
  355. public $hide_annotations_view = true;
  356. /**
  357. * The filter_limit query parameter value to use in export links.
  358. *
  359. * Defaulted to the value of the `[General] API_datatable_default_limit` INI config option.
  360. */
  361. public $export_limit = '';
  362. /**
  363. * @ignore
  364. */
  365. public $report_id = '';
  366. /**
  367. * @ignore
  368. */
  369. public $controllerName;
  370. /**
  371. * @ignore
  372. */
  373. public $controllerAction;
  374. /**
  375. * Constructor.
  376. */
  377. public function __construct()
  378. {
  379. $this->export_limit = \Piwik\Config::getInstance()->General['API_datatable_default_limit'];
  380. $this->translations = array_merge(
  381. Metrics::getDefaultMetrics(),
  382. Metrics::getDefaultProcessedMetrics()
  383. );
  384. }
  385. /**
  386. * @ignore
  387. */
  388. public function setController($controllerName, $controllerAction)
  389. {
  390. $this->controllerName = $controllerName;
  391. $this->controllerAction = $controllerAction;
  392. $this->report_id = $controllerName . '.' . $controllerAction;
  393. $this->loadDocumentation();
  394. }
  395. /** Load documentation from the API */
  396. private function loadDocumentation()
  397. {
  398. $this->metrics_documentation = array();
  399. $report = API::getInstance()->getMetadata(0, $this->controllerName, $this->controllerAction);
  400. $report = $report[0];
  401. if (isset($report['metricsDocumentation'])) {
  402. $this->metrics_documentation = $report['metricsDocumentation'];
  403. }
  404. if (isset($report['documentation'])) {
  405. $this->documentation = $report['documentation'];
  406. }
  407. }
  408. /**
  409. * Marks display properties as client side properties. [Read this](#client-side-properties-desc)
  410. * to learn more.
  411. *
  412. * @param array $propertyNames List of property names, eg, `array('show_limit_control', 'show_goals')`.
  413. */
  414. public function addPropertiesThatShouldBeAvailableClientSide(array $propertyNames)
  415. {
  416. foreach ($propertyNames as $propertyName) {
  417. $this->clientSideProperties[] = $propertyName;
  418. }
  419. }
  420. /**
  421. * Marks display properties as overridable. [Read this](#overridable-properties-desc) to
  422. * learn more.
  423. *
  424. * @param array $propertyNames List of property names, eg, `array('show_limit_control', 'show_goals')`.
  425. */
  426. public function addPropertiesThatCanBeOverwrittenByQueryParams(array $propertyNames)
  427. {
  428. foreach ($propertyNames as $propertyName) {
  429. $this->overridableProperties[] = $propertyName;
  430. }
  431. }
  432. /**
  433. * Returns array of all property values in this config object. Property values are mapped
  434. * by name.
  435. *
  436. * @return array eg, `array('show_limit_control' => 0, 'show_goals' => 1, ...)`
  437. */
  438. public function getProperties()
  439. {
  440. return get_object_vars($this);
  441. }
  442. /**
  443. * @ignore
  444. */
  445. public function setDefaultColumnsToDisplay($columns, $hasNbVisits, $hasNbUniqVisitors)
  446. {
  447. if ($hasNbVisits || $hasNbUniqVisitors) {
  448. $columnsToDisplay = array('label');
  449. // if unique visitors data is available, show it, otherwise just visits
  450. if ($hasNbUniqVisitors) {
  451. $columnsToDisplay[] = 'nb_uniq_visitors';
  452. } else {
  453. $columnsToDisplay[] = 'nb_visits';
  454. }
  455. } else {
  456. $columnsToDisplay = $columns;
  457. }
  458. $this->columns_to_display = array_filter($columnsToDisplay);
  459. }
  460. /**
  461. * @ignore
  462. */
  463. public function getFiltersToRun()
  464. {
  465. $priorityFilters = array();
  466. $presentationFilters = array();
  467. foreach ($this->filters as $filterInfo) {
  468. if ($filterInfo instanceof \Closure) {
  469. $nameOrClosure = $filterInfo;
  470. $parameters = array();
  471. $priority = false;
  472. } else {
  473. @list($nameOrClosure, $parameters, $priority) = $filterInfo;
  474. }
  475. if ($priority) {
  476. $priorityFilters[] = array($nameOrClosure, $parameters);
  477. } else {
  478. $presentationFilters[] = array($nameOrClosure, $parameters);
  479. }
  480. }
  481. return array($priorityFilters, $presentationFilters);
  482. }
  483. /**
  484. * Adds a related report to the {@link $related_reports} property. If the report
  485. * references the one that is currently being displayed, it will not be added to the related
  486. * report list.
  487. *
  488. * @param string $relatedReport The plugin and method of the report, eg, `'UserSettings.getBrowser'`.
  489. * @param string $title The report's display name, eg, `'Browsers'`.
  490. * @param array $queryParams Any extra query parameters to set in releated report's URL, eg,
  491. * `array('idGoal' => 'ecommerceOrder')`.
  492. */
  493. public function addRelatedReport($relatedReport, $title, $queryParams = array())
  494. {
  495. list($module, $action) = explode('.', $relatedReport);
  496. // don't add the related report if it references this report
  497. if ($this->controllerName == $module
  498. && $this->controllerAction == $action) {
  499. if(empty($queryParams)) {
  500. return;
  501. }
  502. }
  503. $url = ApiRequest::getBaseReportUrl($module, $action, $queryParams);
  504. $this->related_reports[$url] = $title;
  505. }
  506. /**
  507. * Adds several related reports to the {@link $related_reports} property. If
  508. * any of the reports references the report that is currently being displayed, it will not
  509. * be added to the list. All other reports will still be added though.
  510. *
  511. * If you need to make sure the related report URL has some extra query parameters,
  512. * use {@link addRelatedReport()}.
  513. *
  514. * @param array $relatedReports Array mapping report IDs with their internationalized display
  515. * titles, eg,
  516. * ```
  517. * array(
  518. * 'UserSettings.getBrowser' => 'Browsers',
  519. * 'UserSettings.getConfiguration' => 'Configurations'
  520. * )
  521. * ```
  522. */
  523. public function addRelatedReports($relatedReports)
  524. {
  525. foreach ($relatedReports as $report => $title) {
  526. $this->addRelatedReport($report, $title);
  527. }
  528. }
  529. /**
  530. * Associates internationalized text with a metric. Overwrites existing mappings.
  531. *
  532. * See {@link $translations}.
  533. *
  534. * @param string $columnName The name of a column in the report data, eg, `'nb_visits'` or
  535. * `'goal_1_nb_conversions'`.
  536. * @param string $translation The internationalized text, eg, `'Visits'` or `"Conversions for 'My Goal'"`.
  537. */
  538. public function addTranslation($columnName, $translation)
  539. {
  540. $this->translations[$columnName] = $translation;
  541. }
  542. /**
  543. * Associates multiple translations with metrics.
  544. *
  545. * See {@link $translations} and {@link addTranslation()}.
  546. *
  547. * @param array $translations An array of column name => text mappings, eg,
  548. * ```
  549. * array(
  550. * 'nb_visits' => 'Visits',
  551. * 'goal_1_nb_conversions' => "Conversions for 'My Goal'"
  552. * )
  553. * ```
  554. */
  555. public function addTranslations($translations)
  556. {
  557. foreach ($translations as $key => $translation) {
  558. $this->addTranslation($key, $translation);
  559. }
  560. }
  561. }