Source of file BlocksSiteTreeExtension.php
Size: 9,990 Bytes - Last Modified: 2021-12-23T10:20:13+00:00
/var/www/docs.ssmods.com/process/src/src/extensions/BlocksSiteTreeExtension.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348 | <?php namespace SheaDawson\Blocks\Extensions; use SheaDawson\Blocks\Model\Block; use SheaDawson\Blocks\Model\Blockset; use SheaDawson\Blocks\BlockManager; use SheaDawson\Blocks\Forms\GridFieldConfigBlockManager; use SilverStripe\CMS\Model\SiteTreeExtension; use SilverStripe\Forms\ReadonlyField; use SilverStripe\Forms\CheckboxField; use SilverStripe\Forms\FieldList; use SilverStripe\Forms\LiteralField; use SilverStripe\Forms\ListboxField; use SilverStripe\Forms\Tab; use SilverStripe\Forms\GridField\GridField; use SilverStripe\View\SSViewer; use SilverStripe\ORM\ArrayList; use SilverStripe\Security\Permission; use SilverStripe\Control\Controller; use SilverStripeAustralia\GridFieldExtensions\GridFieldOrderableRows; /** * BlocksSiteTreeExtension. * * @author Shea Dawson <shea@silverstripe.com.au> */ class BlocksSiteTreeExtension extends SiteTreeExtension { private static $db = [ 'InheritBlockSets' => 'Boolean', ]; private static $many_many = [ "Blocks" => Block::class, "DisabledBlocks" => Block::class, ]; public static $many_many_extraFields = [ 'Blocks' => [ 'Sort' => 'Int', 'BlockArea' => 'Varchar', ], ]; private static $defaults = [ 'InheritBlockSets' => 1, ]; private static $dependencies = [ 'blockManager' => '%$blockManager', ]; public $blockManager; /** * Check if the Blocks CMSFields should be displayed for this Page * * @return boolean **/ public function showBlocksFields() { $whiteList = $this->blockManager->getWhiteListedPageTypes(); $blackList = $this->blockManager->getBlackListedPageTypes(); if (in_array($this->owner->ClassName, $blackList)) { return false; } if (count($whiteList) && !in_array($this->owner->ClassName, $whiteList)) { return false; } if (!Permission::check('BLOCK_EDIT')) { return false; } return true; } /** * Block manager for Pages. * */ public function updateCMSFields(FieldList $fields) { if ($fields->fieldByName('Root.Blocks') || !$this->showBlocksFields()) { return; } $areas = $this->blockManager->getAreasForPageType($this->owner->ClassName); if ($areas && count($areas)) { $fields->addFieldToTab('Root', new Tab('Blocks', _t('Block.PLURALNAME', 'Blocks'))); if (BlockManager::config()->get('block_area_preview')) { $fields->addFieldToTab('Root.Blocks', LiteralField::create('PreviewLink', $this->areasPreviewButton())); } // Blocks related directly to this Page $gridConfig = GridFieldConfigBlockManager::create(true, true, true, true) ->addExisting($this->owner->class) //->addBulkEditing() // ->addComponent(new GridFieldOrderableRows()) // Comment until below TODO is complete. ; // TODO it seems this sort is not being applied... $gridSource = $this->owner->Blocks(); // ->sort(array( // "FIELD(SiteTree_Blocks.BlockArea, '" . implode("','", array_keys($areas)) . "')" => '', // 'SiteTree_Blocks.Sort' => 'ASC', // 'Name' => 'ASC' // )); $fields->addFieldToTab('Root.Blocks', GridField::create('Blocks', _t('Block.PLURALNAME', 'Blocks'), $gridSource, $gridConfig)); // Blocks inherited from BlockSets if ($this->blockManager->getUseBlockSets()) { $inheritedBlocks = $this->getBlocksFromAppliedBlockSets(null, true); if ($inheritedBlocks->count()) { $activeInherited = $this->getBlocksFromAppliedBlockSets(null, false); if ($activeInherited->count()) { $fields->addFieldsToTab('Root.Blocks', [ GridField::create('InheritedBlockList', _t('BlocksSiteTreeExtension.BlocksInheritedFromBlockSets', 'Blocks Inherited from Block Sets'), $activeInherited, GridFieldConfigBlockManager::create(false, false, false)), LiteralField::create('InheritedBlockListTip', "<p class='message'>"._t('BlocksSiteTreeExtension.InheritedBlocksEditLink', 'Tip: Inherited blocks can be edited in the {link_start}Block Admin area{link_end}', '', ['link_start' => '<a href="admin/block-admin">', 'link_end' => '</a>']).'<p>'), ]); } $fields->addFieldToTab('Root.Blocks', ListboxField::create('DisabledBlocks', _t('BlocksSiteTreeExtension.DisableInheritedBlocks', 'Disable Inherited Blocks'), $inheritedBlocks->map('ID', 'Title'), null, null, true) ->setDescription(_t('BlocksSiteTreeExtension.DisableInheritedBlocksDescription', 'Select any inherited blocks that you would not like displayed on this page.')) ); } else { $fields->addFieldToTab('Root.Blocks', ReadonlyField::create('DisabledBlocksReadOnly', _t('BlocksSiteTreeExtension.DisableInheritedBlocks', 'Disable Inherited Blocks'), _t('BlocksSiteTreeExtension.NoInheritedBlocksToDisable','This page has no inherited blocks to disable.'))); } $fields->addFieldToTab('Root.Blocks', CheckboxField::create('InheritBlockSets', _t('BlocksSiteTreeExtension.InheritBlocksFromBlockSets', 'Inherit Blocks from Block Sets'))); } } } /** * Called from templates to get rendered blocks for the given area. * * @param string $area * @param int $limit Limit the items to this number, or null for no limit */ public function BlockArea($area, $limit = null) { if ($this->owner->ID <= 0) { return; } // blocks break on fake pages ie Security/login $list = $this->getBlockList($area); foreach ($list as $block) { if (!$block->canView()) { $list->remove($block); } } if ($limit !== null) { $list = $list->limit($limit); } $data = []; $data['HasBlockArea'] = ($this->owner->canEdit() && isset($_REQUEST['block_preview']) && $_REQUEST['block_preview']) || $list->Count() > 0; $data['BlockArea'] = $list; $data['AreaID'] = $area; $data = $this->owner->customise($data); $template = ['BlockArea_'.$area]; if (SSViewer::hasTemplate($template)) { return $data->renderWith($template); } else { return $data->renderWith('BlockArea'); } } public function HasBlockArea($area) { if ($this->owner->canEdit() && isset($_REQUEST['block_preview']) && $_REQUEST['block_preview']) { return true; } $list = $this->getBlockList($area); foreach ($list as $block) { if (!$block->canView()) { $list->remove($block); } } return $list->Count() > 0; } /** * Get a merged list of all blocks on this page and ones inherited from BlockSets. * * @param string|null $area filter by block area * @param bool $includeDisabled Include blocks that have been explicitly excluded from this page * i.e. blocks from block sets added to the "disable inherited blocks" list * * @return ArrayList * */ public function getBlockList($area = null, $includeDisabled = false) { $includeSets = $this->blockManager->getUseBlockSets() && $this->owner->InheritBlockSets; $blocks = ArrayList::create(); // get blocks directly linked to this page $nativeBlocks = $this->owner->Blocks()->sort('Sort'); if ($area) { $nativeBlocks = $nativeBlocks->filter('BlockArea', $area); } if ($nativeBlocks->count()) { foreach ($nativeBlocks as $block) { $blocks->add($block); } } // get blocks from BlockSets if ($includeSets) { $blocksFromSets = $this->getBlocksFromAppliedBlockSets($area, $includeDisabled); if ($blocksFromSets->count()) { // merge set sources foreach ($blocksFromSets as $block) { if (!$blocks->find('ID', $block->ID)) { if ($block->AboveOrBelow == 'Above') { $blocks->unshift($block); } else { $blocks->push($block); } } } } } return $blocks; } /** * Get Any BlockSets that apply to this page. * * @return ArrayList * */ public function getAppliedSets() { $list = ArrayList::create(); if (!$this->owner->InheritBlockSets) { return $list; } $sets = BlockSet::get()->where("(PageTypesValue IS NULL) OR (PageTypesValue LIKE '%:\"{$this->owner->ClassName}%')"); $ancestors = $this->owner->getAncestors()->column('ID'); foreach ($sets as $set) { $restrictedToParerentIDs = $set->PageParents()->column('ID'); if (count($restrictedToParerentIDs)) { // check whether the set should include selected parent, in which case check whether // it was in the restricted parents list. If it's not, or if include parentpage // wasn't selected, we check the ancestors of this page. if ($set->IncludePageParent && in_array($this->owner->ID, $restrictedToParerentIDs)) { $list->add($set); } else { if (count($ancestors)) { foreach ($ancestors as $ancestor) { if (in_array($ancestor, $restrictedToParerentIDs)) { $list->add($set); continue; } } } } } else { $list->add($set); } } return $list; } /** * Get all Blocks from BlockSets that apply to this page. * * @return ArrayList * */ public function getBlocksFromAppliedBlockSets($area = null, $includeDisabled = false) { $blocks = ArrayList::create(); $sets = $this->getAppliedSets(); if (!$sets->count()) { return $blocks; } foreach ($sets as $set) { $setBlocks = $set->Blocks()->sort('Sort DESC'); if (!$includeDisabled) { $setBlocks = $setBlocks->exclude('ID', $this->owner->DisabledBlocks()->column('ID')); } if ($area) { $setBlocks = $setBlocks->filter('BlockArea', $area); } $blocks->merge($setBlocks); } $blocks->removeDuplicates(); return $blocks; } /** * Get's the link for a block area preview button. * * @return string * */ public function areasPreviewLink() { return Controller::join_links($this->owner->Link(), '?block_preview=1'); } /** * Get's html for a block area preview button. * * @return string * */ public function areasPreviewButton() { return "<a class='btn btn-primary' style='font-style:normal;' href='".$this->areasPreviewLink()."' target='_blank'>"._t('BlocksSiteTreeExtension.PreviewBlockAreasLink', 'Preview Block Areas for this page').'</a>'; } } |