[ Mini Kiebo ]
Server: Windows NT DESKTOP-5B8S0D4 6.2 build 9200 (Windows 8 Professional Edition) i586
Path:
D:
/
Backup
/
05122024
/
htdocs
/
jurnal-kesmas
/
lib
/
pkp
/
classes
/
controllers
/
grid
/
[
Home
]
File: CategoryGridHandler.php
<?php /** * @file classes/controllers/grid/CategoryGridHandler.php * * Copyright (c) 2014-2021 Simon Fraser University * Copyright (c) 2000-2021 John Willinsky * Distributed under the GNU GPL v3. For full terms see the file docs/COPYING. * * @class CategoryGridHandler * * @ingroup controllers_grid * * @brief Class defining basic operations for handling HTML grids with categories. */ namespace PKP\controllers\grid; use APP\template\TemplateManager; use Illuminate\Support\LazyCollection; use PKP\core\JSONMessage; use PKP\core\PKPRequest; class CategoryGridHandler extends GridHandler { /** @var string empty category row locale key */ public $_emptyCategoryRowText = 'grid.noItems'; /** @var array The category grid's data source. */ public $_categoryData; /** @var ?int The category id that this grid is currently rendering. */ public $_currentCategoryId = null; /** * Constructor. * * @param null|mixed $dataProvider */ public function __construct($dataProvider = null) { parent::__construct($dataProvider); $this->addColumn(new GridColumn( 'indent', null, null, null, new NullGridCellProvider(), ['indent' => true, 'width' => 2] )); } // // Getters and setters. // /** * Get the empty rows text for a category. * * @return string */ public function getEmptyCategoryRowText() { return $this->_emptyCategoryRowText; } /** * Set the empty rows text for a category. * * @param string $translationKey */ public function setEmptyCategoryRowText($translationKey) { $this->_emptyCategoryRowText = $translationKey; } /** * Get the category id that this grid is currently rendering. * * @return int */ public function getCurrentCategoryId() { return $this->_currentCategoryId; } /** * Override to return the data element sequence value * inside the passed category, if needed. * * @param int $categoryId The data element category id. * @param mixed $gridDataElement The element to return the * sequence. * * @return int */ public function getDataElementInCategorySequence($categoryId, &$gridDataElement) { assert(false); } /** * Override to set the data element new sequence inside * the passed category, if needed. * * @param int $categoryId The data element category id. * @param mixed $gridDataElement The element to set the * new sequence. * @param int $newSequence The new sequence value. */ public function setDataElementInCategorySequence($categoryId, &$gridDataElement, $newSequence) { assert(false); } /** * Override to define whether the data element inside the passed * category is selected or not. * * @param int $categoryId */ public function isDataElementInCategorySelected($categoryId, &$gridDataElement) { assert(false); } /** * Get the grid category data. * * @param PKPRequest $request * @param mixed $categoryElement The category element. * * @return array */ public function &getGridCategoryDataElements($request, $categoryElement) { $filter = $this->getFilterSelectionData($request); // Get the category element id. $categories = $this->getGridDataElements($request); $categoryElementId = array_search($categoryElement, $categories); assert($categoryElementId !== false); // Try to load data if it has not yet been loaded. if (!is_array($this->_categoryData) || !array_key_exists($categoryElementId, $this->_categoryData)) { $data = $this->loadCategoryData($request, $categoryElement, $filter); if (is_null($data)) { // Initialize data to an empty array. $data = []; } $this->setGridCategoryDataElements($request, $categoryElementId, $data); } return $this->_categoryData[$categoryElementId]; } /** * Check whether the passed category has grid rows. * * @param mixed $categoryElement The category data element * that will be checked. * @param PKPRequest $request * * @return bool */ public function hasGridDataElementsInCategory($categoryElement, $request) { $data = & $this->getGridCategoryDataElements($request, $categoryElement); assert(is_array($data)); return (bool) count($data); } /** * Get the number of elements inside the passed category element. * * @param PKPRequest $request * * @return int */ public function getCategoryItemsCount($categoryElement, $request) { $data = $this->getGridCategoryDataElements($request, $categoryElement); assert(is_array($data)); return count($data); } /** * Set the grid category data. * * @param string $categoryElementId The category element id. * @param mixed $data an array or ItemIterator with category elements data. */ public function setGridCategoryDataElements($request, $categoryElementId, $data) { // Make sure we have an array to store all categories elements data. if (!is_array($this->_categoryData)) { $this->_categoryData = []; } // FIXME: We go to arrays for all types of iterators because // iterators cannot be re-used, see #6498. if (is_array($data)) { $this->_categoryData[$categoryElementId] = $data; } elseif ($data instanceof \PKP\db\DAOResultFactory) { $this->_categoryData[$categoryElementId] = $data->toAssociativeArray(); } elseif ($data instanceof \PKP\core\ItemIterator) { $this->_categoryData[$categoryElementId] = $data->toArray(); } elseif ($data instanceof LazyCollection) { $this->_categoryData[$categoryElementId] = iterator_to_array($data); } else { assert(false); } } // // Public handler methods // /** * Render a category with all the rows inside of it. * * @param array $args * @param PKPRequest $request * * @return string the serialized row JSON message or a flag * that indicates that the row has not been found. */ public function fetchCategory($args, $request) { // Instantiate the requested row (includes a // validity check on the row id). $row = $this->getRequestedCategoryRow($request, $args); $json = new JSONMessage(true); if (is_null($row)) { // Inform the client that the category does no longer exist. $json->setAdditionalAttributes(['elementNotFound' => (int)$args['rowId']]); } else { // Render the requested category $this->setFirstDataColumn(); $json->setContent($this->_renderCategoryInternally($request, $row)); } return $json; } // // Extended methods from GridHandler // /** * @copydoc GridHandler::initialize() * * @param null|mixed $args */ public function initialize($request, $args = null) { parent::initialize($request, $args); if (!is_null($request->getUserVar('rowCategoryId'))) { $this->_currentCategoryId = (string) $request->getUserVar('rowCategoryId'); } } /** * @see GridHandler::getRequestArgs() */ public function getRequestArgs() { $args = parent::getRequestArgs(); // If grid is rendering grid rows inside category, // add current category id value so rows will also know // their parent category. if (!is_null($this->_currentCategoryId)) { if ($this->getCategoryRowIdParameterName()) { $args[$this->getCategoryRowIdParameterName()] = $this->_currentCategoryId; } } return $args; } /** * @copydoc GridHandler::getJSHandler() */ public function getJSHandler() { return '$.pkp.controllers.grid.CategoryGridHandler'; } /** * @copydoc GridHandler::setUrls() */ public function setUrls($request, $extraUrls = []) { $router = $request->getRouter(); $extraUrls['fetchCategoryUrl'] = $router->url($request, null, null, 'fetchCategory', null, $this->getRequestArgs()); parent::setUrls($request, $extraUrls); } /** * @copydoc GridHandler::getRowsSequence() */ protected function getRowsSequence($request) { $categories = $this->getGridDataElements($request); $categoryElement = $categories[$this->getCurrentCategoryId()]; return array_keys($this->getGridCategoryDataElements($request, $categoryElement)); } /** * @see GridHandler::doSpecificFetchGridActions() */ protected function doSpecificFetchGridActions($args, $request, $templateMgr) { // Render the body elements (category groupings + rows inside a <tbody>) $gridBodyParts = $this->_renderCategoriesInternally($request); $templateMgr->assign('gridBodyParts', $gridBodyParts); } /** * @copydoc GridHandler::getRowDataElement() */ protected function getRowDataElement($request, &$rowId) { $rowData = parent::getRowDataElement($request, $rowId); $rowCategoryId = $request->getUserVar('rowCategoryId'); if (is_null($rowData) && !is_null($rowCategoryId)) { // Try to get row data inside category. $categoryRowData = parent::getRowDataElement($request, $rowCategoryId); if (!is_null($categoryRowData)) { $categoryElements = $this->getGridCategoryDataElements($request, $categoryRowData); assert(is_array($categoryElements)); if (!isset($categoryElements[$rowId])) { return null; } // Let grid (and also rows) knowing the current category id. // This value will be published by the getRequestArgs method. $this->_currentCategoryId = $rowCategoryId; return $categoryElements[$rowId]; } } else { return $rowData; } } /** * @see GridHandler::setFirstDataColumn() */ protected function setFirstDataColumn() { $columns = & $this->getColumns(); reset($columns); // Category grids will always have indent column firstly, // so we need to consider the first column the second one. $secondColumn = next($columns); /** @var GridColumn $secondColumn */ $secondColumn->addFlag('firstColumn', true); } /** * @see GridHandler::renderRowInternally() */ protected function renderRowInternally($request, $row) { if ($this->getCategoryRowIdParameterName()) { $param = $this->getRequestArg($this->getCategoryRowIdParameterName()); $templateMgr = TemplateManager::getManager($request); $templateMgr->assign('categoryId', $param); } return parent::renderRowInternally($request, $row); } /** * Tries to identify the data element in the grids * data source that corresponds to the requested row id. * Raises a fatal error if such an element cannot be * found. * * @param PKPRequest $request * @param array $args * * @return GridRow the requested grid row, already * configured with id and data or null if the row * could not been found. */ protected function getRequestedCategoryRow($request, $args) { if (isset($args['rowId'])) { // A row ID was specified. Fetch it $elementId = $args['rowId']; // Retrieve row data for the requested row id // (we can use the default getRowData element, works for category grids as well). $dataElement = $this->getRowDataElement($request, $elementId); if (is_null($dataElement)) { // If the row doesn't exist then // return null. It may be that the // row has been deleted in the meantime // and the client does not yet know about this. $nullVar = null; return $nullVar; } } // Instantiate a new row return $this->_getInitializedCategoryRowInstance($request, $elementId, $dataElement); } // // Protected methods to be overridden/used by subclasses // /** * Get a new instance of a category grid row. May be * overridden by subclasses if they want to * provide a custom row definition. * * @return CategoryGridRow */ protected function getCategoryRowInstance() { //provide a sensible default category row definition return new GridCategoryRow(); } /** * Get the category row id parameter name. * * @return string */ protected function getCategoryRowIdParameterName() { // Must be implemented by subclasses. return null; } /** * Implement this method to load category data into the grid. * * @param PKPRequest $request * @param null|mixed $filter * * @return array */ protected function loadCategoryData($request, &$categoryDataElement, $filter = null) { $gridData = []; $dataProvider = $this->getDataProvider(); if ($dataProvider instanceof \PKP\controllers\grid\CategoryGridDataProvider) { // Populate the grid with data from the // data provider. $gridData = $dataProvider->loadCategoryData($request, $categoryDataElement, $filter); } return $gridData; } // // Private helper methods // /** * Instantiate a new row. * * @param PKPRequest $request * @param string $elementId * * @return GridRow */ private function _getInitializedCategoryRowInstance($request, $elementId, $element) { // Instantiate a new row $row = $this->getCategoryRowInstance(); $row->setGridId($this->getId()); $row->setId($elementId); $row->setData($element); $row->setRequestArgs($this->getRequestArgs()); // Initialize the row before we render it $row->initialize($request); $this->callFeaturesHook( 'getInitializedCategoryRowInstance', ['request' => $request, 'grid' => $this, 'categoryId' => $this->_currentCategoryId, 'row' => $row] ); return $row; } /** * Render all the categories internally * * @param PKPRequest $request */ private function _renderCategoriesInternally($request) { // Iterate through the rows and render them according // to the row definition. $renderedCategories = []; $elements = $this->getGridDataElements($request); foreach ($elements as $key => $element) { // Instantiate a new row $categoryRow = $this->_getInitializedCategoryRowInstance($request, $key, $element); // Render the row $renderedCategories[] = $this->_renderCategoryInternally($request, $categoryRow); } return $renderedCategories; } /** * Render a category row and its data. * * @param PKPRequest $request * @param GridCategoryRow $categoryRow * * @return string HTML for all the rows (including category) */ private function _renderCategoryInternally($request, $categoryRow) { // Prepare the template to render the category. $templateMgr = TemplateManager::getManager($request); $templateMgr->assign('grid', $this); $columns = $this->getColumns(); $templateMgr->assign('columns', $columns); $categoryDataElement = $categoryRow->getData(); $rowData = $this->getGridCategoryDataElements($request, $categoryDataElement); // Render the data rows $templateMgr->assign('categoryRow', $categoryRow); // Let grid (and also rows) knowing the current category id. // This value will be published by the getRequestArgs method. $this->_currentCategoryId = $categoryRow->getId(); $renderedRows = $this->renderRowsInternally($request, $rowData); $templateMgr->assign('rows', $renderedRows); $renderedCategoryRow = $this->renderRowInternally($request, $categoryRow); // Finished working with this category, erase the current id value. $this->_currentCategoryId = null; $templateMgr->assign('renderedCategoryRow', $renderedCategoryRow); return $templateMgr->fetch('controllers/grid/gridBodyPartWithCategory.tpl'); } } if (!PKP_STRICT_MODE) { class_alias('\PKP\controllers\grid\CategoryGridHandler', '\CategoryGridHandler'); }