Source of file PageRow.php
Size: 26,007 Bytes - Last Modified: 2021-12-23T10:42:24+00:00
/var/www/docs.ssmods.com/process/src/code/model/PageRow.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927 | <?php class PageRow extends DataObject { /** * * @var string */ private static $bg_image_prefix = ''; /** * * @var string */ private static $bg_image_postfix = ''; /** * * @var array */ private static $background_image_options = []; /** * * @var array */ private static $background_style_options = []; /** * * @var int */ private static $max_number_of_pages_for_tree_selector = 500; ####################### ### Names Section ####################### private static $singular_name = 'Content Block'; public function i18n_singular_name() { return _t('PageRows.SINGULAR_NAME', 'Content Block'); } private static $plural_name = 'PageRows'; public function i18n_plural_name() { return _t('PageRows.PLURAL_NAME', 'Content Blocks'); } ####################### ### Model Section ####################### private static $db = [ 'ReadyForPublication' => 'Boolean', 'Code' => 'Varchar(7)', 'Title' => 'Varchar(255)', 'BackgroundImage' => 'Varchar(255)', 'BackgroundStyle' => 'Varchar(100)' ]; private static $belongs_many_many = [ 'Pages' => 'Page' ]; ####################### ### Further DB Field Details ####################### private static $indexes = [ 'Created' => true, 'Code' => true, 'ReadyForPublication' => true ]; private static $default_sort = [ 'ReadyForPublication' => 'DESC', 'Created' => 'DESC' ]; private static $required_fields = [ 'Title' ]; private static $searchable_fields = [ 'ClassName' => 'ExactMatchFilter', 'ReadyForPublication' => 'ExactMatchFilter', 'Code' => 'PartialMatchFilter', 'Title' => 'PartialMatchFilter' ]; public function scaffoldSearchFields($_params = null) { $list = ClassInfo::subclassesFor('PageRow'); $newList = []; foreach($list as $key => $entry) { $newList[$entry] = Injector::inst()->get($entry)->i18n_singular_name(); } $fields = parent::scaffoldSearchFields($_params); $fields->replaceField( 'ClassName', DropdownField::create( 'ClassName', 'Type', ['' => '--- ANY ---'] + $newList ) ); return $fields; } ####################### ### Field Names and Presentation Section ####################### private static $summary_fields = [ 'CodeNice' => 'Code', 'Type' => 'Type', 'TitleStrong' => 'Title', 'UsedOn' => 'Used On', 'ReadyForPublicationStrong' => 'Published' ]; private static $field_labels = [ 'ReadyForPublication' => 'Ready' ]; private static $field_labels_right = [ 'Code' => 'This is auto-generated (unique) code to keep track of content blocks', 'ReadyForPublication' => 'Is this Content Block ready for publication?' ]; ####################### ### Casting Section ####################### private static $casting = [ 'CodeNice' => 'HTMLText', 'Type' => 'Varchar', 'UsedOn' => 'Varchar', 'ChildPageRowHTML' => 'HTMLText', 'TitleStrong' => 'HTMLText', 'ReadyForPublicationStrong' => 'HTMLText' ]; public function getType() { return $this->singular_name(); } public function getCodeNice() { $v = '<span style="font-family: monospace;">'.substr($this->Code, 0, 3).'-'.substr($this->Code, -4).'</span>'; return DBField::create_field('HTMLText', $v); } public function getUsedOn() { $v = []; $pages = $this->Pages(); foreach($pages as $page) { $v[] = $page->MenuTitle; } return DBField::create_field('Varchar', implode(', ', $v)); } public function getTitleStrong() { $v = '<strong style="color: blue">'.$this->Title.'</strong>'; return DBField::create_field('HTMLText', $v); } public function getReadyForPublicationStrong() { if($this->ReadyForPublication) { $v = '<span style="color: green">Published</span>'; } else { $v = '<span style="color: red">NOT published</span>'; } return DBField::create_field('HTMLText', $v); } ####################### ### can Section ####################### /** * only children can be created */ public function canDelete($member = null) { return $this->Pages()->count() ? false : true; } ####################### ### write Section ####################### public function requireDefaultRecords() { parent::requireDefaultRecords(); //make template $theme = SSViewer::current_theme(); if($theme) { if ($this->ClassName !== 'PageRow') { $folder = Director::baseFolder(). '/themes/'. $theme.'_mysite/templates/Includes/page-row/types/'; if(! file_exists($folder)) { DB::alteration_message('✓ Creating '.$folder, 'created'); mkdir($folder, 0755, true); } if(file_exists($folder)){ $fileName = $folder . $this->templateForHTMLOutput($this->ClassName).'.ss'; if (! file_exists($fileName)) { DB::alteration_message('✓ Creating ...' . $fileName, 'created'); file_put_contents( $fileName, '<% include PageRowHeader %> <% include PageRowFooter %>' ); } else { DB::alteration_message('✓ Checked ...' . $fileName); } } } //scss files ... $folder = Director::baseFolder().'/themes/'. $theme.'_mysite/src/sass/page-rows/'; $fileName = $folder . $this->ClassName.'.scss'; if(! file_exists($folder)) { mkdir($folder, 0755, true); } if (! file_exists($fileName)) { DB::alteration_message('✓ Creating ...' . $fileName, 'created'); file_put_contents( $fileName, '.'.strtolower($this->ClassName).'.row { }' ); } else { DB::alteration_message('✓ Checked ...' . $fileName); } } } public function validate() { $result = parent::validate(); if ($this->ReadyForPublication) { $fieldLabels = $this->FieldLabels(); $indexes = $this->Config()->get('indexes'); foreach ($this->Config()->get('required_fields') as $field) { $value = $this->$field; if (! $value) { $fieldWithoutID = $field; if (substr($fieldWithoutID, -2) === 'ID') { $fieldWithoutID = substr($fieldWithoutID, 0, -2); } $myName = isset($fieldLabels[$fieldWithoutID]) ? $fieldLabels[$fieldWithoutID] : $fieldWithoutID; $result->error( _t( 'PageRows.'.$field.'_REQUIRED', $myName.' is required' ), 'REQUIRED_PageRows_'.$field ); } if (isset($indexes[$field]) && isset($indexes[$field]['type']) && $indexes[$field]['type'] === 'unique') { $id = (empty($this->ID) ? 0 : $this->ID); $count = PageRows::get() ->filter(array($field => $value)) ->exclude(array('ID' => $id)) ->count(); if ($count > 0) { $myName = $fieldLabels['$field']; $result->error( _t( 'PageRows.'.$field.'_UNIQUE', $myName.' needs to be unique' ), 'UNIQUE_PageRows_'.$field ); } } } } return $result; } public function onBeforeWrite() { parent::onBeforeWrite(); if (!$this->Code) { $this->Code = hash('md5', rand()); } //... } public function onAfterWrite() { parent::onAfterWrite(); if (!$this->Code) { $this->Code = hash('md5', rand()); } if(class_exists('DynamicCache')) { DynamicCache::inst()->clear(); } } ####################### ### Import / Export Section ####################### ####################### ### CMS Edit Section ####################### protected $runCMSFieldFixups = true; public function getCMSFields() { $fields = parent::getCMSFields(); $fields->removeByName('BackgroundImage'); $fields->removeByName('BackgroundStyle'); $fields->removeByName('Pages'); if ($this->exists() && $this->Code) { //too late now! } else { $list = ClassInfo::subclassesFor('PageRow'); $arrayOfTypes = []; foreach ($list as $className) { if ($className === 'PageRow') { continue; } $arrayOfTypes[$className] = Injector::inst()->get($className)->singular_name(); } $fields->addFieldToTab( 'Root.Main', DropdownField::create( 'ClassName', 'Type', $arrayOfTypes ), 'Title' ); } $fieldLabels = $this->FieldLabels(); $fields->insertAfter( 'ReadyForPublication', ReadonlyField::create( 'ClassNameNice', 'Type', $this->singular_name() ) ); $fields->replaceField( 'Code', ReadonlyField::create( 'Code', 'Code' ) ); $fieldGroups = $this->myCMSFieldGroups(); foreach ($fieldGroups as $tabTitle => $fieldGroup) { if(is_array($fieldGroup) && count($fieldGroup)) { foreach ($fieldGroup as $fieldNameOrFormField) { if($fieldNameOrFormField instanceof FormField) { $fields->addFieldToTab( 'Root.'.$tabTitle, $fieldNameOrFormField ); } else { $fieldObject = $fields->dataFieldByName($fieldNameOrFormField); if ($fieldObject) { $fields->addFieldToTab( 'Root.'.$tabTitle, $fieldObject ); } } } } } //... if ($this->exists()) { $fields->addFieldsToTab( 'Root.Preview', [ LiteralField::create( 'PreviewClassName', '<h2><a href="'.$this->MyPreviewLink(strtolower($this->ClassName)).'">View All '.$this->singular_name().' Page Blocks</a></h2>' ), LiteralField::create( 'PreviewIframe', '<iframe src="'.$this->MyPreviewLink($this->ID).'" style="width: calc(100% - 2px); height: 600px; border: 1px solid #000;"></iframe>' ), LiteralField::create( 'PreviewAll', '<h2><a href="'.$this->MyPreviewLink('all').'">View All Page Blocks</a></h2>' ), LiteralField::create( 'PreviewOneOfEach', '<h2><a href="'.$this->MyPreviewLink('oneofeach').'">View One Of Each Page Block Type</a></h2>' ) ] ); if(Page::get()->count() > $this->Config()->get('max_number_of_pages_for_tree_selector')) { $fields->addFieldToTab( 'Root.Pages', GridField::create( 'Pages', 'Shown On ...', $this->Pages(), GridFieldConfig_RecordViewer::create() ) ); } else { $fields->addFieldToTab( 'Root.Pages', TreeMultiselectField::create( 'Pages', 'Shown On ...', 'SiteTree' ) ); } $usedInArray = []; $pageClasses = ClassInfo::subclassesFor('SiteTree'); foreach ($pageClasses as $pageClass) { $pageClassObject = Injector::inst()->get($pageClass); if ($pageClassObject instanceof Page) { $classesUsed = $pageClassObject->DefaultPageRows(); foreach ($classesUsed as $individualItems) { if ( ( is_array($individualItems) && ( $individualItems['Parent'] === $this->ClassName || $individualItems['Child']=== $this->ClassName ) ) || (is_string($individualItems) && $individualItems=== $this->ClassName) ) { $usedInArray[$pageClassObject->ClassName] = $pageClassObject->singular_name(); } } } } if (count($usedInArray)) { $fields->addFieldToTab( 'Root.Pages', LiteralField::create( 'UsedInInfo', '<h2>'.$this->plural_name().' ('.$this->ClassName.') are used in the following pages ...</h2><p> - '.implode('<br />- ', $usedInArray).' </p>' ) ); } } if ($this->runCMSFieldFixups) { $this->decorateCMSFields($fields); } return $fields; } protected function myCMSFieldGroups() { return [ 'Image' => $this->getImageCMSFields(), 'Layout' => $this->getLayoutCMSFields(), 'Background' => $this->getBackgroundFields(), 'Publish' => $this->getPublishCMSFields() ]; } ############################################# ### TEMPLATE STUFF ############################################# public function HTMLClassNamesAsString() { $str = $this->makeIntoHTMLClasses($this->baseClassesForHTMLAsArray()); $str .= ' '.$this->makeIntoHTMLClasses($this->AdditionalHTMLClassNamesAsArray()); return $str; } public function ChildInheritedClassNamesAsString() { return ""; } protected function baseClassesForHTMLAsArray() { /** * we avoid the use of Advertisement as this will be blocked by adblockers ... */ $array = [ ($this->HasChildPageRowHTML() ? 'has-child-row' : 'no-child-row'), $this->ClassName ]; foreach($this->hasOne() as $method => $item) { $field = $method.'ID'; if($this->$field) { $array [] = 'has-'.strtolower($method); } } return $array; } protected function makeIntoHTMLClasses($array) { $str = implode(' ', $array); $str = str_replace(' ', ' ', $str); $str = str_replace(' ', ' ', $str); $str = strtolower($str); return $str; } public function UserCanEditMe() { return $this->canEdit(); } private static $_current_owner_page_object_overridden = null; public static function set_current_page_object($page) { self::$_current_owner_page_object_overridden = $page; } public function CurrentOwnerPageObject() { if (self::$_current_owner_page_object_overridden) { return self::$_current_owner_page_object_overridden; } $controller = $this->CurrentOwnerController(); if ($controller) { return $controller->data(); } } public function CurrentOwnerController() { $controller = Controller::curr(); if ($controller instanceof Page_Controller) { return $controller; } } public function AdditionalHTMLClassNamesAsArray() { return []; } public function HTMLOutputAlwaysOutput($includeJS = true) { return $this->HTMLOutput($includeJS, true); } public function HTMLOutput($includeJS = true, $alwaysShow = false) { if ($this->ReadyForPublication || $alwaysShow) { $scripts = $this->customScripts(); if ($includeJS) { foreach ($scripts as $key => $script) { Requirements::customScript( $script, $key ); } } return $this->renderWith($this->templateForHTMLOutput()); } } /** * custom scripts required to run this show * @return array */ protected function customScripts() { return []; } protected function templateForHTMLOutput($className = null) { if (! $className) { $className = $this->ClassName; } return 'PageRow-'.$className; } public function MyPreviewLink($id = 0) { if (! $id) { $id = $this->ID; } $controller = Injector::inst()->get('PreviewPageRow'); return $controller->Link('preview/'.$id); } public function MyPublicViewLink() { if (! $id) { $id = $this->ID; } $controller = Injector::inst()->get('PreviewPageRow'); return $controller->Link('preview/'.$id); } public function MoreDetailsRowChildLinkingID() { return 'PageRow-'.$this->ID; } public function UserCanEditBlock($member = null) { return $this->canEdit($member); } public function ContextRelevantCMSEditLink() { $ownerPage = $this->CurrentOwnerPageObject(); if ($ownerPage && $ownerPage instanceof SiteTree) { return '/admin/pages/edit/EditForm/'.$ownerPage->ID.'/field/PageRows/item/'.$this->ID.'/edit/'; } else { return $this->CMSEditLink(); } } public function ChildClassMethodName() { return ''; } private $_childPageRowHTML = null; /** * @alias for HasChildPageRowHTML * @return bool */ public function HasChild() { return $this->CalculatedHasMoreDetailsRow(); } public function AsChildOpenByDefault() { return false; } public function MoreDetailsRowParentLinkingID() { if($this->CalculatedHasMoreDetailsRow()) { return 'PageRow'.$this->MoreDetailsRowID; } return null; } public function CalculatedHasMoreDetailsRow() { if(!empty($this->HasMoreDetailsSection)) { if(!empty($this->MoreDetailsRowID)) { if($object = $this->MoreDetailsRow()){ if($object->exists() && $object->ReadyForPublication) { return true; } } } } return false; } /** * * @return bool */ public function HasChildPageRowHTML() { return $this->CalculatedHasMoreDetailsRow(); } /** * @return null / string */ public function ChildPageRowHTML() { return $this->getChildPageRowHTML(); } /** * @return null / string */ public function getChildPageRowHTML() { if ($this->_childPageRowHTML === null) { $this->_childPageRowHTML = false; $method = $this->ChildClassMethodName(); if ($method) { $object = $this->$method(); if ($object && $object->exists()) { $this->_childPageRowHTML = $object->HTMLOutput(); } } } return $this->_childPageRowHTML; } ############################### # COPIED AND PATCHED FROM: # https://github.com/jonom/silverstripe-version-history/blob/master/code/VersionHistoryExtension.php ############################### protected function getImageCMSFields() { return []; } protected function getLayoutCMSFields() { return []; } protected function getBackgroundFields() { $a = []; if($this->IsPageRowWithBackgroundStyle()) { $a[] = DropdownField::create( 'BackgroundStyle', 'Background Style', $this->BackgroundStyleOptionsWithBasics() ); } if($this->IsPageRowWithBackgroundImage()) { $a[] = DropdownField::create( 'BackgroundImage', 'Background Image', $this->BackgroundImageOptionsWithBasics() ); } return $a; } protected function getPublishCMSFields() { return [ 'ReadyForPublication', 'Code' ]; } private $_bgImage = null; protected $_theSameBackgroundImageForAllOfThisTypeToDo = true; public function IsPageRowWithBackgroundImage() { $prefix = $this->Config()->get('bg_image_prefix'); $postfix = $this->Config()->get('bg_image_postfix'); if($prefix || $postfix) { $options = $this->BackgroundImageOptions(); if(count($options)) { return true; } } } public function HasBackgroundImage() { return $this->BackgroundImage ? true : false; } public function CalculatedBackgroundImage() { if($this->_bgImage === null) { $this->_bgImage = false; if($this->BackgroundImage) { $prefix = $this->Config()->get('bg_image_prefix'); $postfix = $this->Config()->get('bg_image_postfix'); if($this->BackgroundImage == 'random') { $a = $this->BackgroundImageOptions(); if(count($a)) { $this->_bgImage = $prefix.$a[array_rand($a)].$postfix; } } else { $this->_bgImage = $prefix.$this->BackgroundImage.$postfix; } if($this->HasSameBackgroundImageForAllOfThisType() && $this->_theSameBackgroundImageForAllOfThisTypeToDo) { $this->_theSameBackgroundImageForAllOfThisTypeToDo = false; Requirements::customCSS(' section.row.'.strtolower($this->ClassName).' { background-image: url('.$this->_bgImage.'); } '); } } } return $this->_bgImage; } protected function HasSameBackgroundImageForAllOfThisType() { return false; } protected function BackgroundImageOptions() { return $this->Config()->get('background_image_options'); } protected function BackgroundImageOptionsWithBasics() { $a = ['' => '--- no background image selected ---'] + $this->BackgroundImageOptions(); if(count($a) > 2) { $a['random'] = 'Random Background Image'; } return $a; } protected $_bgStyle = null; public function IsPageRowWithBackgroundStyle() { $options = $this->BackgroundStyleOptions(); if(count($options)) { return true; } } public function CalculatedBackgroundStyle() { if($this->_bgStyle === null) { $this->_bgStyle = false; if($this->BackgroundStyle) { if($this->BackgroundStyle == 'random') { $a = $this->BackgroundStyleOptions(); if(count($a)) { $this->_bgStyle = $a[array_rand($a)]; } } else { $this->_bgStyle = $this->BackgroundStyle; } } } return $this->_bgStyle; } protected function BackgroundStyleOptionsWithBasics() { $a = ['' => '--- default style ---'] + $this->BackgroundstyleOptions(); if(count($a) > 2) { $a['random'] = 'Random Background Style'; } return $a; } protected function BackgroundStyleOptions() { return $this->Config()->get('background_style_options'); } } |