Source of file GridFieldLimitItems.php
Size: 6,567 Bytes - Last Modified: 2021-12-23T10:09:46+00:00
/var/www/docs.ssmods.com/process/src/code/GridFieldLimitItems.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200 | <?php /** * Simple component which enables you to easily limit the maximum number of items that are setup in a relation that is * being managed by a GridField instance. * * @author Patrick Nelson, pat@catchyour.com * @since 2016-02-24 */ class GridFieldLimitItems implements GridField_HTMLProvider, GridField_DataManipulator { /** @var int */ protected $maxItems; /** @var bool */ protected $removeButton = true; /** @var string */ protected $noteLocation = 'before'; /** @var bool */ protected $removeFromTop = false; /** @var callable */ protected $onBeforeManipulate; /** @var callable */ protected $onAfterManipulate; /** * @param int $maxItems The maximum number of items you wish to allow in this grid field. */ public function __construct($maxItems) { $this->setMaxItems($maxItems); } /** * The maximum number of items you wish to allow in this grid field. * * @param int $maxItems */ public function setMaxItems($maxItems) { if ($maxItems < 1) throw new InvalidArgumentException('Maximum items must be at least 1 or greater.'); $this->maxItems = (int) $maxItems; } /** * Indicates that the 'Add New [x]' button should be removed once we reach our limit. * * @param $removeButton */ public function setRemoveButton($removeButton) { $this->removeButton = (bool) $removeButton; } /** * Indicate the position of the note. Either above or below the grid field. * * @return GridFieldLimitItems */ public function setNoteAbove() { $this->noteLocation = 'before'; return $this; } /** * Indicate the position of the note. Either above or below the grid field. * * @return GridFieldLimitItems */ public function setNoteBelow() { $this->noteLocation = 'after'; return $this; } /** * By default, items are removed from the bottom of the list, but this allows you to configure it to remove from * the top instead. * * @param bool $removeFromTop * @return GridFieldLimitItems */ public function setRemoveFromTop($removeFromTop) { $this->removeFromTop = (bool) $removeFromTop; return $this; } /** * Allows you to perform some sort of action BEFORE any sort of manipulation is performed. * * @param callable $callback(GridField $grid, SS_List $list): bool * * The callback can accept a GridField and SS_List instance. You can also return false from * your callback to prevent any sort of manipulation from taking place! * * @return GridFieldLimitItems */ public function onBeforeManipulate(callable $callback) { $this->onBeforeManipulate = $callback; return $this; } /** * Allows you to perform some sort of action AFTER any sort of manipulation is performed. * * @param callable $callback(GridField $grid, SS_List $list) * * The callback can accept a GridField and SS_List instance. * * @return GridFieldLimitItems */ public function onAfterManipulate(callable $callback) { $this->onAfterManipulate = $callback; return $this; } /** * Generates HTML responsible for note above/below the grid field. * * @return array */ public function getHTMLFragments($gridField) { return [ $this->noteLocation => "<p style='margin-top: 16px;'><strong>Note:</strong> This grid is limited to a maximum of $this->maxItems items.</p>", ]; } /** * Manipulate the {@link DataList} as needed by this grid modifier. * * @param GridField * @param SS_List * @return DataList|SS_List */ public function getManipulatedData(GridField $gridField, SS_List $dataList) { // Allow custom action prior to manipulation and, if false is returned, avoid doing anything at all. if (isset($this->onBeforeManipulate)) { $result = call_user_func($this->onBeforeManipulate, $gridField, $dataList); if ($result === false) return $dataList; } // Can't do anything to unsaved relation lists. if(($dataList instanceof UnsavedRelationList)) return $dataList; // Not compatible with paginator. if ($gridField->getConfig()->getComponentByType('GridFieldPaginator')) { $this->debug('GridFieldLimitItems is not compatible with GridFieldPaginator.'); return $dataList; } // See if any action needs to be taken... $total = $dataList->count(); if ($total > $this->maxItems) { $index = 0; $lowerLimit = ($total - $this->maxItems); $this->debug("List of $total is beyond threshold of $this->maxItems."); $this->debug("Lower limit is: $lowerLimit"); foreach($dataList as $item) { // Remove items beyond threshold. $index++; $itemName = "item #$index"; if (is_object($item) && isset($item->ID)) $itemName = "item ID #$item->ID"; if ($this->removeFromTop) { if ($index <= $lowerLimit) { $this->debug("Removed item $itemName from top."); $dataList->remove($item); } } else { if ($index > $this->maxItems) { $this->debug("Removed item $itemName from bottom."); $dataList->remove($item); } } } } // Also remove the 'Add [item]' button, if it exists. if ($this->removeButton && $total >= $this->maxItems) { // ... obviously shouldn't be null, but just in case. $gridConfig = $gridField->getConfig(); if ($gridConfig) $gridConfig->removeComponentsByType('GridFieldAddNewButton'); } // Allow custom action after manipulation. if (isset($this->onAfterManipulate)) call_user_func($this->onAfterManipulate, $gridField, $dataList); return $dataList; } /** * For internal debug use only. * * @param mixed $message */ protected function debug($message) { SS_Log::log(print_r($message, true), SS_Log::DEBUG); } } |