Source of file ElementalArea.php
Size: 8,175 Bytes - Last Modified: 2021-12-24T06:44:48+00:00
/var/www/docs.ssmods.com/process/src/src/Models/ElementalArea.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306 | <?php namespace DNADesign\Elemental\Models; use DNADesign\Elemental\Extensions\ElementalAreasExtension; use SilverStripe\Core\ClassInfo; use SilverStripe\Core\Extensible; use SilverStripe\Core\Injector\Injector; use SilverStripe\Dev\TestOnly; use SilverStripe\ORM\ArrayList; use SilverStripe\ORM\DataObject; use SilverStripe\ORM\FieldType\DBField; use SilverStripe\ORM\FieldType\DBHTMLText; use SilverStripe\ORM\HasManyList; use SilverStripe\ORM\UnsavedRelationList; use SilverStripe\Versioned\Versioned; /** * Class ElementalArea * @package DNADesign\Elemental\Models * * @property string $OwnerClassName * * @mixin Versioned */ class ElementalArea extends DataObject { private static $db = [ 'OwnerClassName' => 'Varchar(255)', ]; private static $has_many = [ 'Elements' => BaseElement::class, ]; private static $extensions = [ Versioned::class, ]; private static $owns = [ 'Elements', ]; private static $cascade_deletes = [ 'Elements', ]; private static $cascade_duplicates = [ 'Elements', ]; private static $summary_fields = [ 'Title' => 'Title', ]; private static $table_name = 'ElementalArea'; /** * Don't show this model in campaign admin as part of implicit change sets * * @config * @var bool */ private static $hide_in_campaigns = true; /** * Cache various data to improve CMS load time * * @internal * @var array */ protected $cacheData = []; /** * @return array */ public function supportedPageTypes() { $elementalClasses = []; foreach (ClassInfo::getValidSubClasses(DataObject::class) as $class) { if (Extensible::has_extension($class, ElementalAreasExtension::class)) { $elementalClasses[] = $class; } } return $elementalClasses; } /** * @return DBHTMLText */ public function forTemplate() { return $this->renderWith(static::class); } /** * @param ArrayList $elements * @return $this */ public function setElementsCached(ArrayList $elements) { $this->cacheData['elements'] = $elements; return $this; } /** * @param DataObject $page * @return $this */ public function setOwnerPageCached(DataObject $page) { $this->cacheData['owner_page'] = $page; return $this; } /** * A cache-aware accessor for the elements * @return ArrayList|HasManyList|BaseElement[] */ public function Elements() { if (isset($this->cacheData['elements'])) { return $this->cacheData['elements']; } return parent::Elements(); } /** * Necessary to display results in CMS site search. * * @return DBField */ public function Breadcrumbs() { $ownerClassName = $this->OwnerClassName; if ($owner = $ownerClassName::get()->filter('ElementalAreaID', $this->ID)->first()) { return DBField::create_field('HTMLText', sprintf( '<a href="%s">%s</a>', $owner->CMSEditLink(), $owner->Title )); } return null; } /** * Used in template instead of {@link Elements()} to wrap each element in * its' controller, making it easier to access and process form logic and * actions stored in {@link ElementController}. * * @return ArrayList * @throws \Exception */ public function ElementControllers() { // Don't try and process unsaved lists if ($this->Elements() instanceof UnsavedRelationList) { return ArrayList::create(); } $controllers = ArrayList::create(); $items = $this->Elements()->filterByCallback(function (BaseElement $item) { return $item->canView(); }); if (!is_null($items)) { foreach ($items as $element) { $controller = $element->getController(); $controllers->push($controller); } } return $controllers; } /** * @return null|DataObject * @throws \Psr\Container\NotFoundExceptionInterface * @throws \SilverStripe\ORM\ValidationException */ public function getOwnerPage() { // You can't find the owner page of a area that hasn't been save yet if (!$this->isInDB()) { return null; } // Allow for repeated calls to read from cache if (isset($this->cacheData['owner_page'])) { return $this->cacheData['owner_page']; } if ($this->OwnerClassName && ClassInfo::exists($this->OwnerClassName)) { $class = $this->OwnerClassName; $instance = Injector::inst()->get($class); if (!ClassInfo::hasMethod($instance, 'getElementalRelations')) { return null; } $elementalAreaRelations = $instance->getElementalRelations(); foreach ($elementalAreaRelations as $eaRelationship) { $areaID = $eaRelationship . 'ID'; $table = DataObject::getSchema()->tableForField($class, $areaID); $baseTable = DataObject::getSchema()->baseDataTable($class); $page = DataObject::get_one($class, [ "\"{$table}\".\"{$areaID}\" = ?" => $this->ID, "\"{$baseTable}\".\"ClassName\" = ?" => $class ]); if ($page) { $this->setOwnerPageCached($page); return $page; } } } foreach ($this->supportedPageTypes() as $class) { $instance = Injector::inst()->get($class); if (!ClassInfo::hasMethod($instance, 'getElementalRelations')) { return null; } $areaIDFilters = []; foreach ($instance->getElementalRelations() as $eaRelationship) { $areaIDFilters[$eaRelationship . 'ID'] = $this->ID; } try { $page = Versioned::get_by_stage($class, Versioned::DRAFT)->filterAny($areaIDFilters)->first(); } catch (\Exception $ex) { // Usually this is catching cases where test stubs from other modules are trying to be loaded // and failing in unit tests. if (in_array(TestOnly::class, class_implements($class))) { continue; } // Continue as normal... throw $ex; } if ($page) { if ($this->OwnerClassName !== $class) { $this->OwnerClassName = $class; // Avoid recursion: only write if it's already in the database if ($this->isInDB()) { $this->write(); } } $this->cacheData['area_relation_name'] = $page; return $page; } } return null; } /** * @param null $member * @return bool * @throws \Psr\Container\NotFoundExceptionInterface * @throws \SilverStripe\ORM\ValidationException */ public function canEdit($member = null) { if (parent::canEdit($member)) { return true; } $ownerPage = $this->getOwnerPage(); if ($ownerPage !== null) { return $this->getOwnerPage()->canEdit($member); } return false; } /** * @param null $member * @return bool * @throws \Psr\Container\NotFoundExceptionInterface * @throws \SilverStripe\ORM\ValidationException */ public function canView($member = null) { if (parent::canEdit($member)) { return true; } $ownerPage = $this->getOwnerPage(); if ($ownerPage !== null) { return $this->getOwnerPage()->canView($member); } return false; } } |