Created $new_php_file successfully."; } /** * For a related object, figure out which fields to show by default on the template. * Most of this comes from _defaults.yml * * @param string $relationClass The class of this relation * @return array */ private static function get_template_fields($relationClass) { if($relationClass == 'SiteTree' || is_subclass_of($relationClass, 'SiteTree')) $fields = array_flip(Bedrock::get_default('SiteTreeFields')); elseif($relationClass == "Image" || is_subclass_of($relationClass,'Image')) $fields = array_flip(Bedrock::get_default('ImageFields')); elseif($relationClass == "File" || is_subclass_of($relationClass,'File')) $fields = array_flip(Bedrock::get_default('FileFields')); elseif(singleton($relationClass)->uninherited('db') !== null) $fields = singleton($relationClass)->uninherited('db'); else { $fields = array(); } return $fields; } /** * Based on all the DB fields and related objects, build out a basic template of example * code that will render all the labels and values of the fields on this page. * Uses helper methods in {@link BedrockTemplate} to build out the syntax as a string. * * @param string $class The class represented by this template * @return string */ private static function build_template_contents($class) { $SNG = singleton($class); BedrockTemplate::start_template(); $db = ($SNG->uninherited('db') !== null) ? $SNG->uninherited('db') : array_flip(Bedrock::get_default('SiteTreeFields')); foreach($db as $fieldName => $type) { if($type == "Boolean") BedrockTemplate::if_block($fieldName); else BedrockTemplate::label_and_value($fieldName); } $has_many = $SNG->uninherited('has_many'); $many_many = $SNG->uninherited('many_many'); if($has_many || $many_many) { $relations = array_merge($has_many, $many_many); foreach($relations as $relationName => $relationClass) { BedrockTemplate::start_relation($relationName); BedrockTemplate::open_control($relationName); if(class_exists($relationClass)) { $fields = self::get_template_fields($relationClass); BedrockTemplate::inner_control($fields); } BedrockTemplate::close_control(); } } if($has_one = $SNG->uninherited('has_one')) { foreach($has_one as $relationName => $relationClass) { BedrockTemplate::start_relation($relationName); if(class_exists($relationClass)) { $fields = self::get_template_fields($relationClass); if(!empty($fields)) { foreach($fields as $fieldName => $type) { BedrockTemplate::label_and_value($fieldName, $relationName); } } } } } return BedrockTemplate::end_template(); } /** * Creates a .ss file for the given class * * @param string $class The class represented by this template * @param BedrockSetting $config The configuration of the class */ private static function create_template_file($class, $config) { if(!class_exists($class)) user_error("Could not build template for $class. It does not exist yet!", E_USER_ERROR); $project_dir = SSViewer::current_theme() ? 'themes/'.SSViewer::current_theme() : project(); $layout_dir = "/$project_dir/templates/Layout"; $abs_layout_dir = Director::baseFolder().$layout_dir; $startingTemplate = $config->getTemplateBase(); $starting_template_path = Director::baseFolder() . "{$layout_dir}/_project.ss"; $new_template_path = Director::baseFolder() . "{$layout_dir}/{$class}.ss"; if(file_exists($new_template_path) && !isset($_REQUEST['overwrite'])) return; if(!Director::fileExists($starting_template_path)) user_error("You must create a stock template named '_project.ss' in $layout_dir", E_USER_ERROR); if(!is_writable($abs_layout_dir)) { user_error("The directory $abs_layout_dir is not writable!", E_USER_ERROR); } $tags = self::build_template_contents($class); $contents = file_get_contents($starting_template_path); $new_content = str_replace("\$Content","\$Content".$tags, $contents); $new_template = fopen($new_template_path,"w"); fwrite($new_template, $new_content); @chmod($new_template_path, Bedrock::$file_permissions); self::$template_count++; echo "
Created $new_template_path successfully.
"; } /** * Make sure the user has admin credentials and we're not on a production site. */ public function init() { parent::init(); if(!Director::isDev()) return Director::redirectBack(); elseif(!Permission::check("ADMIN")) { Security::permissionFailure($this, _t('Bedrock.NOTADMIN','You must be an administrator to run the project generator') ); } } /** * By default, redirect to the {@link buildphp} action. The user can pass "overwrite" * as a request parameter to overwrite the templates. Otherwise, existing templates * are left in tact and will not receive any new fields that may have been added * in the _project.yml file. */ public function index() { $overwrite = isset($_REQUEST['overwrite']) ? "?overwrite=1" : ""; return Director::redirect("/project/generate/buildphp{$overwrite}"); } /** * This action executes the template build for all the page types in the yml file. */ public function buildtemplates() { if($types = Bedrock::get_setting('PageTypes')) { foreach($types as $class => $config) { if($class != "SiteConfig") self::create_template_file($class, $config); } } echo sprintf("
Created %d PHP files and %s templates. You may now build the database
",$this->getRequest()->getVar('php'),self::$template_count); die(); } /** * This action executes the PHP file build for all page types in the YML file. * Redirects to {@link buildtemplates} once PHP files are in place. */ public function buildphp() { if($types = Bedrock::get_setting('PageTypes')) { foreach($types as $class => $config) { $parentClass = $config->getParent() ? $config->getParent() : 'Page'; if(!class_exists($class)) { self::create_php_file("SiteTree",$class,$parentClass); } if($components = $config->getComponents()) { foreach($components as $component) { if(!class_exists($component->getComponentClass())) { $parentClass = $component->getParent() ? $component->getParent() : 'DataObject'; self::create_php_file("DataObject",$component->getComponentClass(), $parentClass); } if($sub_components = $component->getComponents()) { foreach($sub_components as $sub) { if(!class_exists($sub->getComponentClass())) { $parentClass = $sub->getParent() ? $sub->getParent() : 'DataObject'; self::create_php_file("DataObject", $sub->getComponentClass(), $parentClass); } } } } } } } if($components = Bedrock::get_setting('Components')) { foreach($components as $component) { if(class_exists($component->getComponentClass())) continue; $parentClass = $component->getParent() ? $component->getParent() : 'DataObject'; self::create_php_file("DataObject",$component->getComponentClass(), $parentClass); } } $overwrite = isset($_REQUEST['overwrite']) ? "&overwrite=1" : ""; return Director::redirect("/project/generate/buildtemplates?flush=1&template=1&php=".self::$php_count.$overwrite); } /** * Builds out the fixtures specified in the yml file. * Caution: This action can only be run after the database has been built with */ public function fixtures() { if($fixtures = Bedrock::get_setting('Fixtures')) $ret = Bedrock::build_fixtures($fixtures->toArray()); $duplicate = self::$duplicate; ksort($duplicate); array_reverse($duplicate); foreach($duplicate as $key) { list($level, $id, $c) = explode("_",$key); $tab = ""; for($i=0;$i<=$level;$i++) $tab .= " "; if($page = DataObject::get_by_id("SiteTree", $id)) { for($i = 0; $i < $c; $i++) { $p = $page->duplicateWithChildren(); $p->Status = "Published"; $p->write(); $p->publish("Stage", "Live"); $ret .= "
$tab Duplicated {$p->Title}
"; } } else $ret .= "
$tab Page ID $id not found
"; } die($ret); } }