PageRenderTime 36ms CodeModel.GetById 1ms RepoModel.GetById 1ms app.codeStats 0ms

/modules/report/lib/visualconstructor/handler/basereport.php

https://gitlab.com/alexprowars/bitrix
PHP | 535 lines | 353 code | 58 blank | 124 comment | 16 complexity | e4cba97bf1a4df902b893b652c9169d9 MD5 | raw file
  1. <?php
  2. namespace Bitrix\Report\VisualConstructor\Handler;
  3. use Bitrix\Main\Localization\Loc;
  4. use Bitrix\Report\VisualConstructor\Config\Common;
  5. use Bitrix\Report\VisualConstructor\Entity\Report;
  6. use Bitrix\Report\VisualConstructor\Fields\Base as BaseFormField;
  7. use Bitrix\Report\VisualConstructor\Fields\Div;
  8. use Bitrix\Report\VisualConstructor\Fields\Valuable\CustomDropDown;
  9. use Bitrix\Report\VisualConstructor\Fields\Valuable\BaseValuable;
  10. use Bitrix\Report\VisualConstructor\Fields\Valuable\DropDown;
  11. use Bitrix\Report\VisualConstructor\Fields\Valuable\IValuable;
  12. use Bitrix\Report\VisualConstructor\Helper\Category;
  13. use Bitrix\Report\VisualConstructor\IReportData;
  14. use Bitrix\Report\VisualConstructor\RuntimeProvider\CategoryProvider;
  15. use Bitrix\Report\VisualConstructor\RuntimeProvider\ReportProvider;
  16. use Bitrix\Report\VisualConstructor\RuntimeProvider\ViewProvider;
  17. use Bitrix\Report\VisualConstructor\Handler\Base as BaseHandler;
  18. /**
  19. * Class BaseReport
  20. * @property mixed category
  21. * @property void unit
  22. * @package Bitrix\Report\VisualConstructor
  23. */
  24. abstract class BaseReport extends BaseHandler implements IReportData
  25. {
  26. private $title;
  27. private $categoryKey;
  28. private $unitKey;
  29. private $weight = 0;
  30. private $report;
  31. private $calculatedData;
  32. private $widgetHandler;
  33. /**
  34. * BaseReport constructor.
  35. */
  36. public function __construct()
  37. {
  38. $report = new Report();
  39. $report->setReportHandler($this);
  40. $this->setReport($report);
  41. $this->setTitle(Loc::getMessage('WITHOUT_DATA'));
  42. }
  43. /**
  44. * @return \Bitrix\Report\VisualConstructor\Fields\Base[]
  45. */
  46. public function getCollectedFormElements()
  47. {
  48. parent::getCollectedFormElements();
  49. $this->getView()->collectReportHandlerFormElements($this);
  50. return $this->getFormElements();
  51. }
  52. /**
  53. * Collecting form elements for configuration form.
  54. *
  55. * @return void
  56. */
  57. protected function collectFormElements()
  58. {
  59. $mainContainer = new Div();
  60. $mainContainer->setKey('main_container');
  61. if ($this->getConfiguration('color'))
  62. {
  63. $mainContainer->addInlineStyle('background-color', $this->getConfiguration('color')->getValue() . '5f');
  64. }
  65. else
  66. {
  67. $reportHandlersCount = count($this->getWidgetHandler()->getReportHandlers());
  68. $mainContainer->addInlineStyle('background-color', $this->getView()->getReportDefaultColor($reportHandlersCount) . '5f');
  69. }
  70. $mainContainer->addClass('report-configuration-main');
  71. $mainContainer->addAssets(array(
  72. 'css' => array('/bitrix/js/report/css/visualconstructor/configmain.css')
  73. ));
  74. $this->addFormElement($mainContainer->start());
  75. $fieldListContainer = new Div();
  76. $fieldListContainer->setKey('field_list_container');
  77. $fieldListContainer->addClass('report-configuration-field-list');
  78. $this->addFormElement($fieldListContainer->start());
  79. $reportHandlerSelectContainer = new Div();
  80. $reportHandlerSelectContainer->setKey('report_handler_select_container');
  81. $reportHandlerSelectContainer->addClass('report-configuration-row');
  82. $reportHandlerSelectContainer->addClass('report-configuration-no-padding-bottom');
  83. $categorySelectField = $this->getReportHandlerCategoryField();
  84. $reportHandlerSelectField = $this->getReportHandlerSelectField($categorySelectField->getValue());
  85. $reportHandlerSelectField->addJsEventListener($categorySelectField, $categorySelectField::JS_EVENT_ON_CHANGE, array(
  86. 'class' => 'BX.Report.VisualConstructor.FieldEventHandlers.ReportHandlerSelect',
  87. 'action' => 'categorySelected'
  88. ));
  89. $reportHandlerSelectField->addAssets(array(
  90. 'js' => array('/bitrix/js/report/js/visualconstructor/fields/reporthandlerselect.js')
  91. ));
  92. $this->addFormElement($reportHandlerSelectContainer->start());
  93. $this->addFormElement($categorySelectField);
  94. $this->addFormElement($reportHandlerSelectField);
  95. $whatWillCalculateField = $this->getCalculateField();
  96. $viewCompatibleDataType = $this->getView()->getCompatibleDataType();
  97. if (in_array($viewCompatibleDataType, array(
  98. Common::MULTIPLE_REPORT_TYPE,
  99. Common::MULTIPLE_GROUPED_REPORT_TYPE,
  100. Common::MULTIPLE_BI_GROUPED_REPORT_TYPE,
  101. )))
  102. {
  103. $groupingField = $this->getGroupingField($whatWillCalculateField);
  104. $this->addFormElement($groupingField);
  105. $widgetHandler = $this->getWidgetHandler();
  106. $previewBlock = $widgetHandler->getFormElement('view_type');
  107. $previewBlock->addJsEventListener($groupingField, $groupingField::JS_EVENT_ON_CHANGE, array(
  108. 'class' => 'BX.Report.VisualConstructor.FieldEventHandlers.PreviewBlock',
  109. 'action' => 'reloadWidgetPreview'
  110. ));
  111. }
  112. $this->addFormElement($reportHandlerSelectContainer->end());
  113. $selectListContainer = new Div();
  114. $selectListContainer->setKey('report_configuration_select_list');
  115. $selectListContainer->addClass('report-configuration-row');
  116. $selectListContainer->addClass('report-configuration-row-list');
  117. $this->addFormElement($selectListContainer->start());
  118. $this->addFormElement($whatWillCalculateField);
  119. $this->addFormElement($selectListContainer->end());
  120. $this->addFormElement($fieldListContainer->end());
  121. $this->addFormElement($mainContainer->end());
  122. }
  123. /**
  124. * @return DropDown
  125. */
  126. public function getCalculateField()
  127. {
  128. $whatWillCalculate = new DropDown('calculate');
  129. $whatWillCalculate->setLabel(Loc::getMessage('BASE_REPORT_HANDLER_WHAT_WILL_CALCULATE'));
  130. $whatWillCalculate->addOptions($this->getWhatWillCalculateOptions());
  131. return $whatWillCalculate;
  132. }
  133. /**
  134. * @param DropDown $whatWillCalculateField What will calculate field.
  135. * @return DropDown
  136. */
  137. public function getGroupingField(DropDown $whatWillCalculateField)
  138. {
  139. $groupingField = new CustomDropDown('groupingBy');
  140. $groupingField->setLabel(Loc::getMessage('BASE_REPORT_HANDLER_GROUPING'));
  141. $groupingField->addOptions($this->getGroupByOptions());
  142. $whatWillCalculateField->addJsEventListener($groupingField, $groupingField::JS_EVENT_ON_CHANGE, array(
  143. 'class' => 'BX.Report.VisualConstructor.FieldEventHandlers.WhatWillCalculate',
  144. 'action' => 'reloadCompatibleCalculatedTypes',
  145. ));
  146. $whatWillCalculateField->addAssets(array(
  147. 'js' => array('/bitrix/js/report/js/visualconstructor/fields/whatwillcalculate.js')
  148. ));
  149. return $groupingField;
  150. }
  151. /**
  152. * @return array
  153. */
  154. protected function getGroupByOptions()
  155. {
  156. return array();
  157. }
  158. /**
  159. * @return BaseFormField[]
  160. */
  161. public function getFormElements()
  162. {
  163. $pseudoReportId = '_pseudo' . randString(4);
  164. $result = array();
  165. foreach ($this->formElementsList as $key => $element)
  166. {
  167. $viewModesWhereFieldAvailable = $element->getCompatibleViewTypes();
  168. if ($viewModesWhereFieldAvailable != null)
  169. {
  170. $viewKey = $this->getView()->getKey();
  171. $viewProvider = new ViewProvider();
  172. $viewProvider->addFilter('primary', $viewKey);
  173. $viewProvider->addFilter('dataType', $viewModesWhereFieldAvailable);
  174. $views = $viewProvider->execute()->getResults();
  175. if (!empty($views))
  176. {
  177. $result[$key] = $element;
  178. }
  179. }
  180. else
  181. {
  182. $result[$key] = $element;
  183. }
  184. if ($element instanceof BaseValuable)
  185. {
  186. $element->setName($this->getNameForFormElement($element, $pseudoReportId));
  187. }
  188. }
  189. return $result;
  190. }
  191. /**
  192. * @param BaseValuable $element Element for which construct name.
  193. * @param string $pseudoReportId pseudo report id is report not exist.
  194. * @return string
  195. */
  196. protected function getNameForFormElement(BaseValuable $element, $pseudoReportId = '')
  197. {
  198. $name = '';
  199. if ($this->getWidgetHandler() && $this->getReport())
  200. {
  201. $name = 'widget[' .
  202. $this->getWidgetHandler()->getWidget()->getGId() .
  203. '][reports][' .
  204. $this->getReport()->getGId() .
  205. ']';
  206. }
  207. elseif(!$this->getReport())
  208. {
  209. $name = 'widget[' .
  210. $this->getWidgetHandler()->getWidget()->getGId() .
  211. '][reports][' .
  212. $pseudoReportId .
  213. ']';
  214. }
  215. $name .= parent::getNameForFormElement($element);
  216. return $name;
  217. }
  218. /**
  219. * @return string
  220. */
  221. public function getTitle()
  222. {
  223. return $this->title;
  224. }
  225. /**
  226. * @param string $title Title of report handler.
  227. * @return void
  228. */
  229. public function setTitle($title)
  230. {
  231. $this->title = $title;
  232. }
  233. /**
  234. * @return mixed
  235. */
  236. public function getWeight()
  237. {
  238. return $this->weight;
  239. }
  240. /**
  241. * @param mixed $weight Weight value for sorting.
  242. * @return void
  243. */
  244. public function setWeight($weight)
  245. {
  246. $this->weight = $weight;
  247. }
  248. /**
  249. * @return Report
  250. */
  251. public function getReport()
  252. {
  253. return $this->report;
  254. }
  255. /**
  256. * @param Report $report Report entity.
  257. * @return void
  258. */
  259. public function setReport($report)
  260. {
  261. $this->report = $report;
  262. }
  263. /**
  264. * @return mixed
  265. */
  266. public function getCalculatedData()
  267. {
  268. return $this->calculatedData;
  269. }
  270. /**
  271. * @param mixed $calculatedData Report handler calculated data.
  272. * @return void
  273. */
  274. public function setCalculatedData($calculatedData)
  275. {
  276. $this->calculatedData = $calculatedData;
  277. }
  278. /**
  279. * Fill report handler properties from Report entity.
  280. *
  281. * @param Report $report Report entity.
  282. * @return void
  283. */
  284. public function fillReport(Report $report)
  285. {
  286. $viewHandler = $this->getView();
  287. if ($viewHandler)
  288. {
  289. $this->setView($viewHandler);
  290. }
  291. $this->setReport($report);
  292. $this->setConfigurations($report->getConfigurations());
  293. $this->getCollectedFormElements();
  294. $this->fillFormElementsValues();
  295. }
  296. private function fillFormElementsValues()
  297. {
  298. $formElements = $this->getFormElements();
  299. $configurations = $this->getConfigurations();
  300. if (!empty($configurations))
  301. {
  302. foreach ($configurations as $configuration)
  303. {
  304. if (isset($formElements[$configuration->getKey()]) && ($formElements[$configuration->getKey()] instanceof BaseValuable))
  305. {
  306. /** @var BaseValuable[] $formElements */
  307. $formElements[$configuration->getKey()]->setValue($configuration->getValue());
  308. }
  309. }
  310. }
  311. }
  312. /**
  313. * @return string
  314. */
  315. public function getCategoryKey()
  316. {
  317. return $this->categoryKey;
  318. }
  319. /**
  320. * Attach report handler to category.
  321. *
  322. * @param string $categoryKey Category key.
  323. * @return void
  324. */
  325. protected function setCategoryKey($categoryKey)
  326. {
  327. $this->categoryKey = $categoryKey;
  328. }
  329. /**
  330. * @return string
  331. */
  332. public function getUnitKey()
  333. {
  334. return $this->unitKey;
  335. }
  336. /**
  337. * @param string $unitKey Unit measurement key.
  338. * @return void
  339. */
  340. protected function setUnitKey($unitKey)
  341. {
  342. $this->unitKey = $unitKey;
  343. }
  344. /**
  345. * Field for selecting category.
  346. *
  347. * @return DropDown
  348. */
  349. private function getReportHandlerCategoryField()
  350. {
  351. $selectField = new CustomDropDown('reportCategory');
  352. $selectField->setLabel(Loc::getMessage('SELECT_REPORT_HANDLER_CATEGORY'));
  353. $categories = new CategoryProvider();
  354. $categories->addFilter('parent_keys', 'main');
  355. $categories->addRelation('children');
  356. $categories->addRelation('parent');
  357. $categories = $categories->execute()->getResults();
  358. $options = Category::getOptionsTree($categories);
  359. $selectField->addOptions($options);
  360. $selectField->setValue($this->getCategoryKey());
  361. return $selectField;
  362. }
  363. /**
  364. * Build report handler select drop down.
  365. * Collect all report handler sin selected category.
  366. *
  367. * @param string $categoryKey Category key.
  368. * @return CustomDropDown
  369. */
  370. private function getReportHandlerSelectField($categoryKey = '__')
  371. {
  372. $selectField = new CustomDropDown('reportHandler');
  373. $selectField->addDataAttribute('field-type', 'report-handler-class');
  374. $selectField->setLabel(Loc::getMessage('SELECT_DATA_PROVIDER'));
  375. $selectField->addJsEventListener($selectField, $selectField::JS_EVENT_ON_CHANGE, array(
  376. 'class' => 'BX.Report.VisualConstructor.FieldEventHandlers.ReportHandlerSelect',
  377. 'action' => 'reportHandlerSelected',
  378. ));
  379. $selectField->addAssets(array(
  380. 'js' => array('/bitrix/js/report/js/visualconstructor/fields/reporthandlerselect.js')
  381. ));
  382. $reports = new ReportProvider();
  383. $reports->addFilter('dataType', $this->getView()->getCompatibleDataType());
  384. if (!empty($categoryKey) && $categoryKey !== '__')
  385. {
  386. $reports->addFilter('categories', array($categoryKey));
  387. }
  388. $reports->execute();
  389. /** @var BaseReport[] $reportHandlers */
  390. $reportHandlers = $reports->getResults();
  391. foreach ($reportHandlers as $report)
  392. {
  393. $selectField->addOption($report::getClassName(), $report->getTitle());
  394. }
  395. $selectField->setDefaultValue($this::getClassName());
  396. return $selectField;
  397. }
  398. /**
  399. * @return array
  400. */
  401. public function getReportImplementedDataTypes()
  402. {
  403. $dataTypeMap = Common::$reportImplementationTypesMap;
  404. $class = get_class($this);
  405. $implementedInterfaceList = class_implements($class);
  406. $implementedInterfaceList = array_values($implementedInterfaceList);
  407. $result = array();
  408. foreach ($dataTypeMap as $reportTypeKey => $settings)
  409. {
  410. if (in_array($settings['interface'], $implementedInterfaceList))
  411. {
  412. $result[] = $reportTypeKey;
  413. }
  414. }
  415. return $result;
  416. }
  417. /**
  418. * @return BaseWidget|null
  419. */
  420. public function getWidgetHandler()
  421. {
  422. if ($this->getReport()->getWidget())
  423. {
  424. return $this->getReport()->getWidget()->getWidgetHandler();
  425. }
  426. elseif ($this->widgetHandler)
  427. {
  428. return $this->widgetHandler;
  429. }
  430. else
  431. {
  432. return null;
  433. }
  434. }
  435. /**
  436. * Attach report handler to widget handler.
  437. *
  438. * @param BaseWidget $widgetHandler Widget handler.
  439. * @return void
  440. */
  441. public function setWidgetHandler(BaseWidget $widgetHandler)
  442. {
  443. $this->widgetHandler = $widgetHandler;
  444. }
  445. /**
  446. * In cloning of entity clone nested entities too.(configurations, form elements list).
  447. * @return void
  448. */
  449. public function __clone()
  450. {
  451. foreach ($this->configurations as $key => $configuration)
  452. {
  453. $this->configurations[$key] = clone $configuration;
  454. }
  455. foreach ($this->formElementsList as $key => $formElement)
  456. {
  457. $this->formElementsList[$key] = clone $formElement;
  458. }
  459. }
  460. /**
  461. *
  462. * @param null $groupingValue Grouping field value.
  463. * @return array
  464. */
  465. public function getWhatWillCalculateOptions($groupingValue = null)
  466. {
  467. return array();
  468. }
  469. /**
  470. * In some case, need to dynamically disable some report handler
  471. * @return bool
  472. */
  473. public function isEnabled()
  474. {
  475. return true;
  476. }
  477. }