/** * @var bool * * @throws Exception */ public static function requireRecords($force = false) { if (self::$ran && !$force) { return true; } self::$ran = true; if (!(Director::isDev() || Director::isTest())) { throw new Exception('requireRecords can only be run in development or test environments'); } $factory = Injector::inst()->create('PopulateFactory'); foreach (self::config()->get('truncate_objects') as $objName) { $versions = array(); if (class_exists($objName)) { foreach (DataList::create($objName) as $obj) { // if the object has the versioned extension, make sure we delete // that as well if ($obj->hasExtension('Versioned')) { foreach ($obj->getVersionedStages() as $stage) { $versions[$stage] = true; $obj->deleteFromStage($stage); } } try { @$obj->delete(); } catch (Exception $e) { // notice } } } if ($versions) { self::truncate_versions($objName, $versions); } foreach ((array) ClassInfo::getValidSubClasses($objName) as $table) { self::truncate_table($table); self::truncate_versions($table, $versions); } self::truncate_table($objName); } foreach (self::config()->get('include_yaml_fixtures') as $fixtureFile) { $fixture = new YamlFixture($fixtureFile); $fixture->writeInto($factory); $fixture = null; } // hook allowing extensions to clean up records, modify the result or // export the data to a SQL file (for importing performance). $static = !(isset($this) && get_class($this) == __CLASS__); if ($static) { $populate = Injector::inst()->create('Populate'); } else { $populate = $this; } $populate->extend('onAfterPopulateRecords'); return true; }
private function getModuleTypes() { $moduleTypes = array(); $classes = ClassInfo::getValidSubClasses('ContentModule'); foreach ($classes as $type) { $instance = singleton($type); $html = sprintf('<span class="page-icon class-%s"></span><strong class="title">%s</strong><span class="description">%s</span>', $instance->ClassName, $instance->stat('singular_name'), $instance->stat('description')); $moduleTypes[$instance->ClassName] = $html; } return $moduleTypes; }
public function updateCMSFields(FieldList $fields) { if (Permission::check('ADMIN')) { // get a list of all page types. $SubClasses = ClassInfo::getValidSubClasses('SiteTree'); $ClassOptions = array(); foreach ($SubClasses as $SubClass) { if ($SubClass != 'SiteTree') { $ClassOptions[$SubClass] = $SubClass; } } $fields->addFieldToTab("Root.Permissions", new CheckboxSetField("BlockPageTypes", "Block these page type so users cannot create", $ClassOptions)); } else { $fields->removeByName('Access'); $fields->removeFieldFromTab('Root.Main', 'Theme'); } }
/** * @var bool * * @throws Exception */ public static function requireRecords($force = false) { if (self::$ran && !$force) { return true; } self::$ran = true; if (!(Director::isDev() || Director::isTest())) { throw new Exception('requireRecords can only be run in development or test environments'); } $factory = Injector::inst()->create('PopulateFactory'); foreach (self::config()->get('truncate_objects') as $objName) { $versions = array(); if (class_exists($objName)) { foreach (DataList::create($objName) as $obj) { // if the object has the versioned extension, make sure we delete // that as well if ($obj->hasExtension('Versioned')) { foreach ($obj->getVersionedStages() as $stage) { $versions[$stage] = true; $obj->deleteFromStage($stage); } } try { @$obj->delete(); } catch (Exception $e) { // notice } } } if ($versions) { self::truncate_versions($objName, $versions); } foreach (ClassInfo::getValidSubClasses($objName) as $table) { self::truncate_table($table); self::truncate_versions($table, $versions); } self::truncate_table($objName); } foreach (self::config()->get('include_yaml_fixtures') as $fixtureFile) { $fixture = new YamlFixture($fixtureFile); $fixture->writeInto($factory); $fixture = null; } return true; }
public function getCMSFields() { $fields = parent::getCMSFields(); $boxes = array(); if ($this->hasExtension('Translatable')) { $fields->removeByName('Locale'); $fields->insertBefore(new LanguageDropdownField('Locale', _t('CMSMain.LANGUAGEDROPDOWNLABEL', 'Language'), array(), 'SiteTree', 'Locale-English', singleton('SiteTree')), 'Title'); $fields->removeByName('Translations'); Translatable::set_current_locale($this->Locale); } foreach (ClassInfo::getValidSubClasses('PromoBox') as $boxClass) { if ($boxClass != 'PromoBox') { $instance = singleton($boxClass); $boxes[$boxClass] = $instance->i18n_singular_name(); } } $fields->addFieldToTab('Root.Main', new DropdownField('ClassName', 'Type (save after changing this to see fields)', $boxes, 'ImagePromoBox')); $fields->removeByName('Pages'); return $fields; }
/** * * If there's no ExternalContentSource ID available from Session or Request data then instead of * LeftAndMain::currentPageID() returning just `null`, "extend" its range to use the first sub-class * of {@link ExternalContentSource} the system can find, either via config or introspection. * * @return number | null */ public function getCurrentPageID() { if (!($id = $this->currentPageID())) { // Try an id from an ExternalContentSource Subclass $defaultSources = ClassInfo::getValidSubClasses('ExternalContentSource'); array_shift($defaultSources); // Use one if defined in config, otherwise use first one found through reflection $defaultSourceConfig = Config::inst()->get('ExternalContentSource', 'default_source'); if ($defaultSourceConfig) { $class = $defaultSourceConfig; } else { if (isset($defaultSources[0])) { $class = $defaultSources[0]; } else { $class = null; } } if ($class && ($source = DataObject::get($class)->first())) { return $source->ID; } return null; } return $id; }
/** * Return a subclass map of SiteTree * that shouldn't be hidden through * {@link SiteTree::$hide_ancestor} * * @return array */ public static function page_type_classes() { $classes = ClassInfo::getValidSubClasses(); $baseClassIndex = array_search('SiteTree', $classes); if ($baseClassIndex !== FALSE) { unset($classes[$baseClassIndex]); } $kill_ancestors = array(); // figure out if there are any classes we don't want to appear foreach ($classes as $class) { $instance = singleton($class); // do any of the progeny want to hide an ancestor? if ($ancestor_to_hide = $instance->stat('hide_ancestor')) { // note for killing later $kill_ancestors[] = $ancestor_to_hide; } } // If any of the descendents don't want any of the elders to show up, cruelly render the elders surplus to requirements. if ($kill_ancestors) { $kill_ancestors = array_unique($kill_ancestors); foreach ($kill_ancestors as $mark) { // unset from $classes $idx = array_search($mark, $classes); unset($classes[$idx]); } } return $classes; }
public function getCMSFields() { // Get a list of available product classes $classnames = ClassInfo::getValidSubClasses("CatalogueCategory"); $categories_array = array(); foreach ($classnames as $classname) { $description = Config::inst()->get($classname, 'description'); if ($classname == 'CatalogueCategory' && !$description) { $description = self::config()->description; } $description = $description ? $classname . ' - ' . $description : $classname; $categories_array[$classname] = $description; } if (!$this->ID) { $controller = Controller::curr(); $parent_id = $controller->request->getVar("ParentID"); $fields = new FieldList($rootTab = new TabSet("Root", $tabMain = new Tab('Main', HiddenField::create("Title")->setValue(_t("Catalogue.NewCategory", "New Category")), HiddenField::create("ParentID")->setValue($parent_id), ProductTypeField::create("ClassName", _t("Catalogue.SelectCategoryType", "Select a type of Category"), $categories_array)))); } else { // If CMS Installed, use URLSegmentField, otherwise use text // field for URL if (class_exists('SiteTreeURLSegmentField')) { $baseLink = Controller::join_links(Director::absoluteBaseURL()); $url_field = SiteTreeURLSegmentField::create("URLSegment"); $url_field->setURLPrefix($baseLink); } else { $url_field = TextField::create("URLSegment"); } $fields = new FieldList($rootTab = new TabSet("Root", $tabMain = new Tab('Main', TextField::create("Title", $this->fieldLabel('Title')), $url_field, TreeDropdownField::create('ParentID', _t('CatalogueAdmin.ParentCategory', 'Parent Category'), 'CatalogueCategory')->setLabelField("Title"), ToggleCompositeField::create('Metadata', _t('CatalogueAdmin.MetadataToggle', 'Metadata'), array($metaFieldDesc = TextareaField::create("MetaDescription", $this->fieldLabel('MetaDescription')), $metaFieldExtra = TextareaField::create("ExtraMeta", $this->fieldLabel('ExtraMeta'))))->setHeadingLevel(4)), $tabSettings = new Tab('Settings', DropdownField::create("ClassName", _t("CatalogueAdmin.CategoryType", "Type of Category"), $categories_array)))); // Help text for MetaData on page content editor $metaFieldDesc->setRightTitle(_t('CatalogueAdmin.MetaDescHelp', "Search engines use this content for displaying search results (although it will not influence their ranking)."))->addExtraClass('help'); $metaFieldExtra->setRightTitle(_t('CatalogueAdmin.MetaExtraHelp', "HTML tags for additional meta information. For example <meta name=\"customName\" content=\"your custom content here\" />"))->addExtraClass('help'); $fields->addFieldToTab('Root.Products', GridField::create("Products", "", $this->Products(), GridFieldConfig_RelationEditor::create()->addComponent(new GridFieldOrderableRows('SortOrder')))); } $this->extend('updateCMSFields', $fields); return $fields; }
public function getCMSFields() { // Get a list of available product classes $classnames = ClassInfo::getValidSubClasses("CatalogueProduct"); $product_array = array(); foreach ($classnames as $classname) { if ($classname != "CatalogueProduct") { $description = Config::inst()->get($classname, 'description'); if ($classname == 'Product' && !$description) { $description = self::config()->description; } $description = $description ? $classname . ' - ' . $description : $classname; $product_array[$classname] = $description; } } // If we are creating a product, let us choose the product type if (!$this->ID) { $fields = new FieldList($rootTab = new TabSet("Root", $tabMain = new Tab('Main', HiddenField::create("Title")->setValue(_t("Catalogue.NewProduct", "New Product")), ProductTypeField::create("ClassName", _t("Catalogue.SelectProductType", "Select a type of Product"), $product_array)))); } else { // If CMS Installed, use URLSegmentField, otherwise use text // field for URL if (class_exists('SiteTreeURLSegmentField')) { $baseLink = Controller::join_links(Director::absoluteBaseURL()); $url_field = SiteTreeURLSegmentField::create("URLSegment"); $url_field->setURLPrefix($baseLink); } else { $url_field = TextField::create("URLSegment"); } $fields = new FieldList($rootTab = new TabSet("Root", $tabMain = new Tab('Main', TextField::create("Title", $this->fieldLabel('Title')), $url_field, HTMLEditorField::create('Content', $this->fieldLabel('Content'))->setRows(20)->addExtraClass('stacked'), ToggleCompositeField::create('Metadata', _t('CatalogueAdmin.MetadataToggle', 'Metadata'), array($metaFieldDesc = TextareaField::create("MetaDescription", $this->fieldLabel('MetaDescription')), $metaFieldExtra = TextareaField::create("ExtraMeta", $this->fieldLabel('ExtraMeta'))))->setHeadingLevel(4)), $tabSettings = new Tab('Settings', NumericField::create("BasePrice", _t("Catalogue.Price", "Price")), TextField::create("StockID", $this->fieldLabel('StockID'))->setRightTitle(_t("Catalogue.StockIDHelp", "For example, a product SKU")), DropdownField::create("TaxRateID", $this->fieldLabel('TaxRate'), TaxRate::get()->map())->setEmptyString(_t("Catalogue.None", "None")), TreeMultiSelectField::create("Categories", null, "CatalogueCategory"), CheckboxField::create("Disabled", _t("Catalogue.DisableProduct", "Disable this product (will not appear on shopfront)")), DropdownField::create("ClassName", _t("CatalogueAdmin.ProductType", "Type of product"), $product_array)), $tabImages = new Tab('Images', SortableUploadField::create('Images', $this->fieldLabel('Images'), $this->Images())))); // Help text for MetaData on page content editor $metaFieldDesc->setRightTitle(_t('CatalogueAdmin.MetaDescHelp', "Search engines use this content for displaying search results (although it will not influence their ranking)."))->addExtraClass('help'); $metaFieldExtra->setRightTitle(_t('CatalogueAdmin.MetaExtraHelp', "HTML tags for additional meta information. For example <meta name=\"customName\" content=\"your custom content here\" />"))->addExtraClass('help'); $fields->addFieldToTab('Root.Related', GridField::create('RelatedProducts', "", $this->RelatedProducts(), GridFieldConfig_RelationEditor::create())); } $this->extend('updateCMSFields', $fields); return $fields; }
/** * Get the class dropdown used in the CMS to change the class of a page. * This returns the list of options in the drop as a Map from class name * to text in dropdown. * * @return array */ function getClassDropdown() { $classes = ClassInfo::getValidSubClasses('SiteTree'); array_shift($classes); foreach ($classes as $class) { $instance = singleton($class); if (($instance instanceof HiddenClass || !$instance->canCreate()) && $class != $this->class) { continue; } /* $addAction = $instance->uninherited('add_action', true); if(!$addAction) { $addAction = $instance->singular_name(); } */ $addAction = $instance->i18n_singular_name(); if ($class == $this->class) { $currentClass = $class; $currentAddAction = $addAction; } else { $result[$class] = $class == $this->class ? _t('SiteTree.CURRENTLY', 'Currently') . ' ' . $addAction : _t('SiteTree.CHANGETO', 'Change to') . ' ' . $addAction; } } // sort alphabetically, and put current on top asort($result); $result = array_reverse($result); $result[$currentClass] = $currentAddAction . ' (' . _t('SiteTree.CURRENT', 'current') . ')'; $result = array_reverse($result); return $result; }
/** * Populates an array of classes in the CMS which allows the * user to change the page type. */ public function PageTypes() { $classes = ClassInfo::getValidSubClasses(); array_shift($classes); $result = new DataObjectSet(); $kill_ancestors = array(); // figure out if there are any classes we don't want to appear foreach ($classes as $class) { $instance = singleton($class); // do any of the progeny want to hide an ancestor? if ($ancestor_to_hide = $instance->stat('hide_ancestor')) { // note for killing later $kill_ancestors[] = $ancestor_to_hide; } } // If any of the descendents don't want any of the elders to show up, cruelly render the elders surplus to requirements. if ($kill_ancestors) { foreach ($kill_ancestors as $mark) { // unset from $classes $idx = array_search($mark, $classes); unset($classes[$idx]); } } foreach ($classes as $class) { $instance = singleton($class); if ($instance instanceof HiddenClass) { continue; } if (!$instance->canCreate()) { continue; } // skip this type if it is restricted if ($instance->stat('need_permission') && !$this->can(singleton($class)->stat('need_permission'))) { continue; } /* * Since i18n_singular_name() this is not necessary $addAction = $instance->uninherited('add_action', true); if($addAction) { // backwards compatibility for actions like "a page" (instead of "page") $addAction = preg_replace('/^a /','',$addAction); $addAction = ucfirst($addAction); } else { $addAction = $instance->i18n_singular_name(); } */ $addAction = $instance->i18n_singular_name(); $result->push(new ArrayData(array("ClassName" => $class, "AddAction" => $addAction))); } $result->sort('AddAction'); return $result; }
/** * Get the list of classes that can be selected and used as data-values * * @param $includeLiterals Set to false to exclude non-data fields * @return array */ public function getEditableFieldClasses($includeLiterals = true) { $classes = ClassInfo::getValidSubClasses('EditableFormField'); // Remove classes we don't want to display in the dropdown. $editableFieldClasses = array(); foreach ($classes as $class) { // Skip abstract / hidden classes if (Config::inst()->get($class, 'abstract', Config::UNINHERITED) || Config::inst()->get($class, 'hidden')) { continue; } if (!$includeLiterals && Config::inst()->get($class, 'literal')) { continue; } $singleton = singleton($class); if (!$singleton->canCreate()) { continue; } $editableFieldClasses[$class] = $singleton->i18n_singular_name(); } asort($editableFieldClasses); return $editableFieldClasses; }
public static function pageCreationPermissions() { $pageCreation = array("Page Creation" => array()); //Get all the page types //(Not done with SiteTree::page_type_classes as this will remove already hidden pages) $classes = ClassInfo::getValidSubClasses("SiteTree"); foreach ($classes as $class) { //Exclude SiteTree from the list if ($class != "SiteTree") { $code = "SIMPLIFY_NO_CREATE_" . $class; $label = "Hide create " . $class; $pageCreation["Page Creation"][$code] = $label; } } return $pageCreation; }