/**
  * Implement this method in the task subclass to
  * execute via the TaskRunner
  */
 public function run($request)
 {
     if (!($adminEmail = $this->config()->get('administrator_email'))) {
         $contenders = $this->extend('feedMeAdminEmail') ?: [];
         $adminEmail = reset($contenders);
     }
     if ($adminEmail) {
         SS_Log::add_writer(new SS_LogEmailWriter($adminEmail, SS_Log::INFO));
     }
     // anything like a warning or above
     SS_Log::add_writer(new SS_LogEmailWriter(Security::findAnAdministrator()->Email), SS_Log::WARN);
     $excludedFeedClasses = $this->config()->get('excluded_feed_class_names');
     // for each implementor of the FeedMeFeedInterface check if it's not excluded then for each
     // instance of that model call feedMeImport on it.
     $implementors = ClassInfo::implementorsOf('FeedMeFeedModelInterface');
     foreach ($implementors as $className) {
         // chance to disable a feed by setting config.excluded_feed_class_names
         if (!in_array($className, $excludedFeedClasses)) {
             /** @var FeedMeFeedModelExtension $feedModel */
             foreach ($className::get() as $feedModel) {
                 $feedModel->feedMeImport();
             }
         }
     }
 }
 public function index()
 {
     $subclasses = ClassInfo::subclassesFor($this->class);
     unset($subclasses[$this->class]);
     if ($subclasses) {
         $subclass = array_pop($subclasses);
         $task = new $subclass();
         $task->index();
         return;
     }
     // Check if access key exists
     if (!isset($_REQUEST['Key'])) {
         echo 'Error: Access validation failed. No "Key" specified.';
         return;
     }
     // Check against access key defined in _config.php
     if ($_REQUEST['Key'] != EMAIL_BOUNCEHANDLER_KEY) {
         echo 'Error: Access validation failed. Invalid "Key" specified.';
         return;
     }
     if (!$_REQUEST['Email']) {
         echo "No email address";
         return;
     }
     $this->recordBounce($_REQUEST['Email'], $_REQUEST['Date'], $_REQUEST['Time'], $_REQUEST['Message']);
 }
 /**
  * Initializes context.
  * Every scenario gets it's own context object.
  *
  * @param array $parameters context parameters (set them up through behat.yml)
  */
 public function __construct(array $parameters)
 {
     parent::__construct($parameters);
     $this->useContext('BasicContext', new BasicContext($parameters));
     $this->useContext('LoginContext', new LoginContext($parameters));
     $this->useContext('CmsFormsContext', new CmsFormsContext($parameters));
     $this->useContext('CmsUiContext', new CmsUiContext($parameters));
     $fixtureContext = new FixtureContext($parameters);
     $fixtureContext->setFixtureFactory($this->getFixtureFactory());
     $this->useContext('FixtureContext', $fixtureContext);
     // Use blueprints to set user name from identifier
     $factory = $fixtureContext->getFixtureFactory();
     $blueprint = \Injector::inst()->create('FixtureBlueprint', 'Member');
     $blueprint->addCallback('beforeCreate', function ($identifier, &$data, &$fixtures) {
         if (!isset($data['FirstName'])) {
             $data['FirstName'] = $identifier;
         }
     });
     $factory->define('Member', $blueprint);
     // Auto-publish pages
     foreach (\ClassInfo::subclassesFor('SiteTree') as $id => $class) {
         $blueprint = \Injector::inst()->create('FixtureBlueprint', $class);
         $blueprint->addCallback('afterCreate', function ($obj, $identifier, &$data, &$fixtures) {
             $obj->publish('Stage', 'Live');
         });
         $factory->define($class, $blueprint);
     }
 }
 public function getCMSFields()
 {
     $fields = parent::getCMSFields();
     $fields->removeByName('ConfiguredScheduleID');
     $interval = $fields->dataFieldByName('Interval')->setDescription('Number of seconds between each run. e.g 3600 is 1 hour');
     $fields->replaceField('Interval', $interval);
     $dt = new DateTime();
     $fields->replaceField('StartDate', DateField::create('StartDate')->setConfig('dateformat', 'dd/MM/yyyy')->setConfig('showcalendar', true)->setDescription('DD/MM/YYYY e.g. ' . $dt->format('d/m/y')));
     $fields->replaceField('EndDate', DateField::create('EndDate')->setConfig('dateformat', 'dd/MM/yyyy')->setConfig('showcalendar', true)->setDescription('DD/MM/YYYY e.g. ' . $dt->format('d/m/y')));
     if ($this->ID == null) {
         foreach ($fields->dataFields() as $field) {
             //delete all included fields
             $fields->removeByName($field->Name);
         }
         $rangeTypes = ClassInfo::subclassesFor('ScheduleRange');
         $fields->addFieldToTab('Root.Main', TextField::create('Title', 'Title'));
         $fields->addFieldToTab('Root.Main', DropdownField::create('ClassName', 'Range Type', $rangeTypes));
     } else {
         $fields->addFieldToTab('Root.Main', ReadonlyField::create('ClassName', 'Type'));
     }
     if ($this->ClassName == __CLASS__) {
         $fields->removeByName('ApplicableDays');
     }
     return $fields;
 }
	function __construct($controller, $name, $sourceClass, $fieldList = null, $detailFormFields = null, $sourceFilter = "", $sourceSort = "", $sourceJoin = "") {

		Deprecation::notice('3.0', 'Use GridField with GridFieldConfig_RelationEditor');

		parent::__construct($controller, $name, $sourceClass, $fieldList, $detailFormFields, $sourceFilter, $sourceSort, $sourceJoin);
		
		$classes = array_reverse(ClassInfo::ancestry($this->controllerClass()));
		foreach($classes as $class) {
			$singleton = singleton($class);
			$manyManyRelations = $singleton->uninherited('many_many', true);
			if(isset($manyManyRelations) && array_key_exists($this->name, $manyManyRelations)) {
				$this->manyManyParentClass = $class;
				$manyManyTable = $class . '_' . $this->name;
				break;
			}
			$belongsManyManyRelations = $singleton->uninherited( 'belongs_many_many', true );
			 if( isset( $belongsManyManyRelations ) && array_key_exists( $this->name, $belongsManyManyRelations ) ) {
				$this->manyManyParentClass = $class;
				$manyManyTable = $belongsManyManyRelations[$this->name] . '_' . $this->name;
				break;
			}
		}
		$tableClasses = ClassInfo::dataClassesFor($this->sourceClass);
		$source = array_shift($tableClasses);
		$sourceField = $this->sourceClass;
		if($this->manyManyParentClass == $sourceField)
			$sourceField = 'Child';
		$parentID = $this->controller->ID;
		
		$this->sourceJoin .= " LEFT JOIN \"$manyManyTable\" ON (\"$source\".\"ID\" = \"$manyManyTable\".\"{$sourceField}ID\" AND \"{$this->manyManyParentClass}ID\" = '$parentID')";
		
		$this->joinField = 'Checked';
	}
 public function transform(FormField $field)
 {
     // Look for a performXXTransformation() method on the field itself.
     // performReadonlyTransformation() is a pretty commonly applied method.
     // Otherwise, look for a transformXXXField() method on this object.
     // This is more commonly done in custom transformations
     // We iterate through each array simultaneously, looking at [0] of both, then [1] of both.
     // This provides a more natural failover scheme.
     $transNames = array_reverse(array_values(ClassInfo::ancestry($this->class)));
     $fieldClasses = array_reverse(array_values(ClassInfo::ancestry($field->class)));
     $len = max(sizeof($transNames), sizeof($fieldClasses));
     for ($i = 0; $i < $len; $i++) {
         // This is lets fieldClasses be longer than transNames
         if ($transName = $transNames[$i]) {
             if ($field->hasMethod('perform' . $transName)) {
                 $funcName = 'perform' . $transName;
                 //echo "<li>$field->class used $funcName";
                 return $field->{$funcName}($this);
             }
         }
         // And this one does the reverse.
         if ($fieldClass = $fieldClasses[$i]) {
             if ($this->hasMethod('transform' . $fieldClass)) {
                 $funcName = 'transform' . $fieldClass;
                 //echo "<li>$field->class used $funcName";
                 return $this->{$funcName}($field);
             }
         }
     }
     user_error("FormTransformation:: Can't perform '{$this->class}' on '{$field->class}'", E_USER_ERROR);
 }
 /**
  * Add an option to include in the comment 
  */
 public function updateFieldConfiguration(FieldList $fields)
 {
     if (in_array($this->owner->Parent()->Classname, ClassInfo::subclassesFor('Consultation'))) {
         $comment = CheckboxField::create($this->owner->getSettingName('CommentField'), _t('CONSULTATION.INCLUDEINCOMMENT', 'Include this field in comment post'), $this->owner->getSetting('CommentField'));
         $fields->push($comment);
     }
 }
 public function updateCMSFields(FieldList $fields)
 {
     if ($this->owner->ID) {
         // Relation handler for Blocks
         $SConfig = GridFieldConfig_RelationEditor::create(25);
         $SConfig->addComponent(new GridFieldOrderableRows('SortOrder'));
         $SConfig->addComponent(new GridFieldDeleteAction());
         // If the copy button module is installed, add copy as option
         if (class_exists('GridFieldCopyButton')) {
             $SConfig->addComponent(new GridFieldCopyButton(), 'GridFieldDeleteAction');
         }
         $gridField = new GridField("Blocks", "Content blocks", $this->owner->Blocks(), $SConfig);
         $classes = array_values(ClassInfo::subclassesFor($gridField->getModelClass()));
         if (count($classes) > 1 && class_exists('GridFieldAddNewMultiClass')) {
             $SConfig->removeComponentsByType('GridFieldAddNewButton');
             $SConfig->addComponent(new GridFieldAddNewMultiClass());
         }
         if (self::$create_block_tab) {
             $fields->addFieldToTab("Root.Blocks", $gridField);
         } else {
             // Downsize the content field
             $fields->removeByName('Content');
             $fields->addFieldToTab('Root.Main', HTMLEditorField::create('Content')->setRows(self::$contentarea_rows), 'Metadata');
             $fields->addFieldToTab("Root.Main", $gridField, 'Metadata');
         }
     }
     return $fields;
 }
 /**
  *	Retrieve the existing searchable fields, appending our custom search index to enable it.
  *	@return array
  */
 public function updateSolrSearchableFields(&$fields)
 {
     // Make sure the extension requirements have been met before enabling the custom search index.
     if (ClassInfo::exists('QueuedJob')) {
         $fields[$this->index] = true;
     }
 }
 /**
  * Include CSS for page icons. We're not using the JSTree 'types' option
  * because it causes too much performance overhead just to add some icons.
  * 
  * @return String CSS 
  */
 public function generatePageIconsCss()
 {
     $css = '';
     $classes = ClassInfo::subclassesFor('SiteTree');
     foreach ($classes as $class) {
         $obj = singleton($class);
         $iconSpec = $obj->stat('icon');
         if (!$iconSpec) {
             continue;
         }
         // Legacy support: We no longer need separate icon definitions for folders etc.
         $iconFile = is_array($iconSpec) ? $iconSpec[0] : $iconSpec;
         // Legacy support: Add file extension if none exists
         if (!pathinfo($iconFile, PATHINFO_EXTENSION)) {
             $iconFile .= '-file.gif';
         }
         $iconPathInfo = pathinfo($iconFile);
         // Base filename
         $baseFilename = $iconPathInfo['dirname'] . '/' . $iconPathInfo['filename'];
         $fileExtension = $iconPathInfo['extension'];
         $selector = ".page-icon.class-{$class}, li.class-{$class} > a .jstree-pageicon";
         if (Director::fileExists($iconFile)) {
             $css .= "{$selector} { background: transparent url('{$iconFile}') 0 0 no-repeat; }\n";
         } else {
             // Support for more sophisticated rules, e.g. sprited icons
             $css .= "{$selector} { {$iconFile} }\n";
         }
     }
     return $css;
 }
 public function onAfterWrite()
 {
     parent::onAfterWrite();
     if ($this()->hasExtension(HasBlocks::class_name())) {
         /** @var \ManyManyList $existing */
         $existing = $this()->{HasBlocks::relationship_name()}();
         if ($this()->{self::SingleFieldName} || $this()->WasNew) {
             if ($defaultBlockClasses = $this->getDefaultBlockClasses()) {
                 // get class names along with count of each expected
                 $expected = array_count_values($defaultBlockClasses);
                 $sort = $existing->count() + 1;
                 foreach ($expected as $blockClass => $expectedCount) {
                     if (!\ClassInfo::exists($blockClass)) {
                         continue;
                     }
                     $existingCount = $existing->filter('ClassName', $blockClass)->count();
                     if ($existingCount < $expectedCount) {
                         for ($i = $existingCount; $i < $expectedCount; $i++) {
                             // generate a default title for the block from lang
                             // e.g. ContentBlock.DefaultTitle
                             $templateVars = ['pagetitle' => $this()->{Title::SingleFieldName}, 'singular' => singleton($blockClass)->i18n_singular_name(), 'index' => $i + 1];
                             // try the block class.DefaultTitle and then Block.DefaultTitle
                             $title = _t("{$blockClass}.DefaultTitle", _t('Block.DefaultTitle', '{pagetitle} {singular} - {index}', $templateVars), $templateVars);
                             /** @var Block $block */
                             $block = new $blockClass();
                             $block->update(['Title' => $title]);
                             $block->write();
                             $existing->add($block, ['Sort' => $sort++]);
                         }
                     }
                 }
             }
         }
     }
 }
 /**
  * Gets the classes that can be created using this button, defaulting to the model class and
  * its subclasses.
  *
  * @param \GridField $grid
  * @return array a map of class name to title
  */
 public function getAllowedClasses(\GridField $grid)
 {
     $result = array();
     if ($this->useAllowedClasses) {
         $classes = $this->useAllowedClasses;
         $this->useAllowedClasses = null;
         return $classes;
     } else {
         if (is_null($this->allowedClasses)) {
             $classes = array_values(\ClassInfo::subclassesFor($grid->getModelClass()));
             sort($classes);
         } else {
             $classes = $this->allowedClasses;
         }
     }
     foreach ($classes as $class => $title) {
         if (!is_string($class)) {
             $class = $title;
             $title = singleton($class)->i18n_singular_name();
         }
         if (!singleton($class)->canCreate()) {
             continue;
         }
         $result[$class] = $title;
     }
     return $result;
 }
 function getModularCMSFields($relationName = 'Modules', $title = 'Content Modules')
 {
     $fields = array();
     $GLOBALS['_CONTENT_MODULE_PARENT_PAGEID'] = $this->owner->ID;
     $area = $this->owner->obj($relationName);
     if ($area && $area->exists()) {
         $fields[] = HeaderField::create($relationName . 'Header', $title, 2);
         $fields[] = GridField::create($relationName, $title, $area->Modules(), GridFieldConfig_RecordEditor::create()->addComponent(new GridFieldOrderableRows('SortOrder'))->removeComponentsByType('GridFieldAddNewButton')->addComponent($add = new GridFieldAddNewMultiClass()));
         if (($allowed_modules = $this->owner->Config()->get('allowed_modules')) && is_array($allowed_modules) && count($allowed_modules)) {
             if (isset($allowed_modules[$relationName])) {
                 $add->setClasses($allowed_modules[$relationName]);
             } else {
                 $add->setClasses($allowed_modules);
             }
         } else {
             // Remove the base "ContentModule" from allowed modules.
             $classes = array_values(ClassInfo::subclassesFor('ContentModule'));
             sort($classes);
             if (($key = array_search('ContentModule', $classes)) !== false) {
                 unset($classes[$key]);
             }
             $add->setClasses($classes);
         }
     } else {
         $fields[] = LiteralField::create('SaveFirstToAddModules', '<div class="message">You must save first before you can add modules.</div>');
     }
     return $fields;
 }
 /**
  * Gets the classes that can be created using this button, defaulting to the model class and
  * its subclasses.
  *
  * @param GridField $grid
  * @return array a map of class name to title
  */
 public function getClasses(GridField $grid)
 {
     $result = array();
     if (is_null($this->classes)) {
         $classes = array_values(ClassInfo::subclassesFor($grid->getModelClass()));
         sort($classes);
     } else {
         $classes = $this->classes;
     }
     $kill_ancestors = array();
     foreach ($classes as $class => $title) {
         if (!is_string($class)) {
             $class = $title;
             $is_abstract = ($reflection = new ReflectionClass($class)) && $reflection->isAbstract();
             if (!$is_abstract) {
                 $title = singleton($class)->i18n_singular_name();
             }
         } else {
             $is_abstract = ($reflection = new ReflectionClass($class)) && $reflection->isAbstract();
         }
         if ($ancestor_to_hide = Config::inst()->get($class, 'hide_ancestor', Config::FIRST_SET)) {
             $kill_ancestors[$ancestor_to_hide] = true;
         }
         if ($is_abstract || !singleton($class)->canCreate()) {
             continue;
         }
         $result[$class] = $title;
     }
     if ($kill_ancestors) {
         foreach ($kill_ancestors as $class => $bool) {
             unset($result[$class]);
         }
     }
     return $result;
 }
 function __construct($controller, $name, $sourceClass, $fieldList = null, $detailFormFields = null, $sourceFilter = "", $sourceSort = "", $sourceJoin = "")
 {
     parent::__construct($controller, $name, $sourceClass, $fieldList, $detailFormFields, $sourceFilter, $sourceSort, $sourceJoin);
     //Sort by heirarchy, depending on number of parents indent
     $classes = array_reverse(ClassInfo::ancestry($this->controllerClass()));
     foreach ($classes as $class) {
         $singleton = singleton($class);
         $manyManyRelations = $singleton->uninherited('many_many', true);
         if (isset($manyManyRelations) && array_key_exists($this->name, $manyManyRelations)) {
             $this->manyManyParentClass = $class;
             $this->manyManyTable = $class . '_' . $this->name;
             break;
         }
         $belongsManyManyRelations = $singleton->uninherited('belongs_many_many', true);
         if (isset($belongsManyManyRelations) && array_key_exists($this->name, $belongsManyManyRelations)) {
             $singleton = singleton($belongsManyManyRelations[$this->name]);
             $manyManyRelations = $singleton->uninherited('many_many', true);
             $this->manyManyParentClass = $class;
             $relation = array_flip($manyManyRelations);
             $this->manyManyTable = $belongsManyManyRelations[$this->name] . '_' . $relation[$class];
             break;
         }
     }
     $tableClasses = ClassInfo::dataClassesFor($this->sourceClass);
     $source = array_shift($tableClasses);
     $sourceField = $this->sourceClass;
     if ($this->manyManyParentClass == $sourceField) {
         $sourceField = 'Child';
     }
     $parentID = $this->controller->ID;
     $this->sourceJoin .= " LEFT JOIN \"{$this->manyManyTable}\" ON (\"{$source}\".\"ID\" = \"{$this->manyManyTable}\".\"{$sourceField}ID\" AND \"{$this->manyManyTable}\".\"{$this->manyManyParentClass}ID\" = '{$parentID}')";
     $this->joinField = 'Checked';
 }
 function updateCMSFields(FieldList $fields)
 {
     if ($attributes = $fields->fieldByName("ProductAttributeType")) {
         $attributes->getConfig()->removeComponentsByType("GridFieldAddNewButton")->addComponent($multiclass = new GridFieldAddNewMultiClass());
         $multiclass->setClasses(array_values(ClassInfo::subclassesFor("ProductAttributeType")));
     }
 }
 /**
  * Retrieve a modifier of a given class for the order.
  * Modifier will be retrieved from database if it already exists,
  * or created if it is always required.
  *
  * @param string $className
  * @param boolean $forcecreate - force the modifier to be created.
  */
 public function getModifier($className, $forcecreate = false)
 {
     if (!ClassInfo::exists($className)) {
         user_error("Modifier class \"{$className}\" does not exist.");
     }
     //search for existing
     $modifier = $className::get()->filter("OrderID", $this->order->ID)->first();
     if ($modifier) {
         //remove if no longer valid
         if (!$modifier->valid()) {
             //TODO: need to provide feedback message - why modifier was removed
             $modifier->delete();
             $modifier->destroy();
             return null;
         }
         return $modifier;
     }
     $modifier = new $className();
     if ($modifier->required() || $forcecreate) {
         //create any modifiers that are required for every order
         $modifier->OrderID = $this->order->ID;
         $modifier->write();
         $this->order->Modifiers()->add($modifier);
         return $modifier;
     }
     return null;
 }
 /**
  *
  * @return ArrayList
  */
 public function AvailableWidgets()
 {
     $widgets = new ArrayList();
     foreach ($this->widgetClasses as $widgetClass) {
         $classes = ClassInfo::subclassesFor($widgetClass);
         if (isset($classes['Widget'])) {
             unset($classes['Widget']);
         } else {
             if (isset($classes[0]) && $classes[0] == 'Widget') {
                 unset($classes[0]);
             }
         }
         foreach ($classes as $class) {
             $available = Config::inst()->get($class, 'only_available_in');
             if (!empty($available) && is_array($available)) {
                 if (in_array($this->Name, $available)) {
                     $widgets->push(singleton($class));
                 }
             } else {
                 $widgets->push(singleton($class));
             }
         }
     }
     return $widgets;
 }
 /**
  * Provides a GUI for the insert/edit shortcode popup
  * @return Form
  **/
 public function ShortcodeForm()
 {
     if (!Permission::check('CMS_ACCESS_CMSMain')) {
         return;
     }
     Config::inst()->update('SSViewer', 'theme_enabled', false);
     // create a list of shortcodable classes for the ShortcodeType dropdown
     $classList = ClassInfo::implementorsOf('Shortcodable');
     $classes = array();
     foreach ($classList as $class) {
         $classes[$class] = singleton($class)->singular_name();
     }
     // load from the currently selected ShortcodeType or Shortcode data
     $classname = false;
     $shortcodeData = false;
     if ($shortcode = $this->request->requestVar('Shortcode')) {
         $shortcode = str_replace("", '', $shortcode);
         //remove BOM inside string on cursor position...
         $shortcodeData = singleton('ShortcodableParser')->the_shortcodes(array(), $shortcode);
         if (isset($shortcodeData[0])) {
             $shortcodeData = $shortcodeData[0];
             $classname = $shortcodeData['name'];
         }
     } else {
         $classname = $this->request->requestVar('ShortcodeType');
     }
     if ($shortcodeData) {
         $headingText = _t('Shortcodable.EDITSHORTCODE', 'Edit Shortcode');
     } else {
         $headingText = _t('Shortcodable.INSERTSHORTCODE', 'Insert Shortcode');
     }
     // essential fields
     $fields = FieldList::create(array(CompositeField::create(LiteralField::create('Heading', sprintf('<h3 class="htmleditorfield-shortcodeform-heading insert">%s</h3>', $headingText)))->addExtraClass('CompositeField composite cms-content-header nolabel'), LiteralField::create('shortcodablefields', '<div class="ss-shortcodable content">'), DropdownField::create('ShortcodeType', 'ShortcodeType', $classes, $classname)->setHasEmptyDefault(true)->addExtraClass('shortcode-type')));
     // attribute and object id fields
     if ($classname) {
         if (class_exists($classname)) {
             $class = singleton($classname);
             if (is_subclass_of($class, 'DataObject')) {
                 if (singleton($classname)->hasMethod('get_shortcodable_records')) {
                     $dataObjectSource = $classname::get_shortcodable_records();
                 } else {
                     $dataObjectSource = $classname::get()->map()->toArray();
                 }
                 $fields->push(DropdownField::create('id', $class->singular_name(), $dataObjectSource)->setHasEmptyDefault(true));
             }
             if ($attrFields = $classname::shortcode_attribute_fields()) {
                 $fields->push(CompositeField::create($attrFields)->addExtraClass('attributes-composite'));
             }
         }
     }
     // actions
     $actions = FieldList::create(array(FormAction::create('insert', _t('Shortcodable.BUTTONINSERTSHORTCODE', 'Insert shortcode'))->addExtraClass('ss-ui-action-constructive')->setAttribute('data-icon', 'accept')->setUseButtonTag(true)));
     // form
     $form = Form::create($this, "ShortcodeForm", $fields, $actions)->loadDataFrom($this)->addExtraClass('htmleditorfield-form htmleditorfield-shortcodable cms-dialog-content');
     if ($shortcodeData) {
         $form->loadDataFrom($shortcodeData['atts']);
     }
     $this->extend('updateShortcodeForm', $form);
     return $form;
 }
 /**
  * Returns an array of all implementors of the `IIndicator` interface.
  *
  * @return IIndicator[] list of all implementors
  */
 public static function get_all()
 {
     $indicators = \ClassInfo::implementorsOf(self::$interface_name);
     return array_map(function ($indicatorName) {
         return \Object::create($indicatorName);
     }, $indicators);
 }
 /**
  * Most of the code below was copied from ManyManyComplexTableField.
  * Painful, but necessary, until PHP supports multiple inheritance.
  */
 function __construct($controller, $name, $sourceClass, $fieldList, $detailFormFields = null, $sourceFilter = "", $sourceSort = "Created DESC", $sourceJoin = "")
 {
     parent::__construct($controller, $name, $sourceClass, $fieldList, $detailFormFields, $sourceFilter, $sourceSort, $sourceJoin);
     $manyManyTable = false;
     $classes = array_reverse(ClassInfo::ancestry($this->controllerClass()));
     foreach ($classes as $class) {
         if ($class != "Object") {
             $singleton = singleton($class);
             $manyManyRelations = $singleton->uninherited('many_many', true);
             if (isset($manyManyRelations) && array_key_exists($this->name, $manyManyRelations)) {
                 $this->manyManyParentClass = $class;
                 $manyManyTable = $class . '_' . $this->name;
                 break;
             }
             $belongsManyManyRelations = $singleton->uninherited('belongs_many_many', true);
             if (isset($belongsManyManyRelations) && array_key_exists($this->name, $belongsManyManyRelations)) {
                 $this->manyManyParentClass = $class;
                 $manyManyTable = $belongsManyManyRelations[$this->name] . '_' . $this->name;
                 break;
             }
         }
     }
     if (!$manyManyTable) {
         user_error("I could not find the relation {$this}-name in " . $this->controllerClass() . " or any of its ancestors.", E_USER_WARNING);
     }
     $tableClasses = ClassInfo::dataClassesFor($this->sourceClass);
     $source = array_shift($tableClasses);
     $sourceField = $this->sourceClass;
     if ($this->manyManyParentClass == $sourceField) {
         $sourceField = 'Child';
     }
     $parentID = $this->controller->ID;
     $this->sourceJoin .= " LEFT JOIN `{$manyManyTable}` ON (`{$source}`.`ID` = `{$sourceField}ID` AND `{$this->manyManyParentClass}ID` = '{$parentID}')";
     $this->joinField = 'Checked';
 }
 public function locateConfigFor($name)
 {
     if (isset($this->configs[$name])) {
         return $this->configs[$name];
     }
     $config = Config::inst()->get('Injector', $name);
     if ($config) {
         $this->configs[$name] = $config;
         return $config;
     }
     // do parent lookup if it's a class
     if (class_exists($name)) {
         $parents = array_reverse(array_keys(ClassInfo::ancestry($name)));
         array_shift($parents);
         foreach ($parents as $parent) {
             // have we already got for this?
             if (isset($this->configs[$parent])) {
                 return $this->configs[$parent];
             }
             $config = Config::inst()->get('Injector', $parent);
             if ($config) {
                 $this->configs[$name] = $config;
                 return $config;
             } else {
                 $this->configs[$parent] = false;
             }
         }
         // there is no parent config, so we'll record that as false so we don't do the expensive
         // lookup through parents again
         $this->configs[$name] = false;
     }
 }
 /**
  * Returns true if the folder contains files
  * @return boolean
  */
 public function containsFiles()
 {
     if (!$this->owner instanceof Folder) {
         return false;
     }
     return (bool) DB::query("SELECT COUNT(*) FROM File WHERE ParentID = " . (int) $this->owner->ID . " AND ClassName NOT IN ('" . implode("','", array_values(ClassInfo::subclassesFor('Folder'))) . "')")->value();
 }
 public function getPopularInteractions($interactionType, $itemClass, $days, $number = 10)
 {
     $since = date('Y-m-d H:i:s', strtotime("-{$days} days"));
     // Execute an SQL query so we can group by and count.
     $interactions = UserInteraction::get()->filter(array('Type' => $interactionType, 'ItemClass' => $itemClass, 'Created:GreaterThan' => $since));
     $interactionType = Convert::raw2sql($interactionType);
     $itemClass = Convert::raw2sql($itemClass);
     $subs = ClassInfo::subclassesFor($itemClass);
     $subs[] = $itemClass;
     if ($i = array_search('ErrorPage', $subs)) {
         unset($subs[$i]);
     }
     $in = "'" . implode("','", $subs) . "'";
     $query = new SQLQuery('*', 'UserInteraction', "Type = '{$interactionType}' AND ItemClass IN ({$in}) AND DATEDIFF(NOW(), Created) <= {$days}", 'Views DESC, Title ASC', 'Title', '', $number);
     $query->selectField('COUNT(Title)', 'Views');
     $results = $query->execute();
     $container = ArrayList::create();
     // The array list will need to be populated with objects so the template accepts it.
     for ($i = 0; $i < $results->numRecords(); $i++) {
         $object = UserInteraction::create($results->record());
         if ($object->canView()) {
             $container->add($object);
         }
     }
     return $container;
 }
 public function updateCMSFields(FieldList $fields)
 {
     $sortable = singleton('CleanTeaser')->hasExtension('SortableDataExtension');
     $config = GridFieldConfig_RelationEditor::create();
     $config->addComponent($gridFieldForm = new GridFieldDetailForm());
     $dataFields = array();
     if (singleton('CleanTeaser')->hasExtension('CMSPublishableDataExtension')) {
         $dataFields['PublishIndicator'] = 'Published';
     }
     $dataFields = array_merge($dataFields, array('Thumbnail' => 'Thumbnail', 'Title' => 'Title', 'CleanDescription' => 'Description'));
     $config->getComponentByType('GridFieldDataColumns')->setDisplayFields($dataFields);
     $gridFieldForm->setTemplate('CMSGridFieldPopupForms');
     if ($sortable) {
         $config->addComponent(new GridFieldSortableRows('SortOrder'));
     }
     if (ClassInfo::exists('GridFieldBulkUpload')) {
         $iu = new GridFieldBulkUpload('ImageID');
         if (singleton('CleanTeaser')->hasExtension('ControlledFolderDataExtension')) {
             $iu->setUfConfig('folderName', singleton('CleanTeaser')->getUploadFolder());
         } else {
             $iu->setUfConfig('folderName', CleanTeaser::$upload_folder);
         }
         $config->addComponent($iu);
     }
     if ($sortable) {
         $data = $this->owner->CleanTeasers("ClassName = 'CleanTeaser'")->sort('SortOrder');
     } else {
         $data = $this->owner->CleanTeasers("ClassName = 'CleanTeaser'");
     }
     // $config->removeComponentsByType('GridFieldAddNewButton');
     // if (ClassInfo::exists('GridFieldBulkUpload')) {
     // 	$config->addComponent(new GridFieldAddNewMultiClass());
     // }
     $fields->addFieldToTab("Root.Teasers", GridField::create('CleanTeasers', 'CleanTeaser', $data, $config));
 }
 protected function onBeforeWrite()
 {
     if ($this->isChanged('ParentClass')) {
         $this->ParentClass = ClassInfo::baseDataClass($this->ParentClass);
     }
     parent::onBeforeWrite();
 }
 protected function getRemoteObject($node)
 {
     $clazz = $node->nodeName;
     $object = null;
     // do we have this data object type?
     if (ClassInfo::exists($clazz)) {
         // we'll create one
         $object = new $clazz();
     } else {
         $object = new Page();
     }
     // track the name property and set it LAST again to handle special cases like file
     // that overwrite other properties when $name is set
     $name = null;
     foreach ($node->childNodes as $property) {
         if ($property instanceof DOMText) {
             continue;
         }
         $pname = $property->nodeName;
         if (isset($this->remap[$pname])) {
             $pname = $this->remap[$pname];
         }
         if ($pname == 'Filename') {
             $name = $property->nodeValue;
         }
         $object->{$pname} = $property->nodeValue;
     }
     $object->SourceClassName = $clazz;
     if (!is_null($name)) {
         $object->Filename = $name;
     }
     return $object;
 }
 /**
  * A simple Gridfield factory
  * @param  string $model
  * @param  string $relationname
  * @param  DataObject $reference
  * @return GridField
  */
 public static function create_gridfield_for($model, $relationname, $reference)
 {
     if ($relationname != null && ClassInfo::exists($model)) {
         $config = GridFieldConfig_RelationEditor::create();
         $config->addComponent($gridFieldForm = new GridFieldDetailForm());
         if ($items = $reference->{$relationname}()) {
             if (is_a($items, 'ManyManyList') && ClassInfo::exists('GridFieldManyRelationHandler')) {
                 $config->addComponent(new GridFieldManyRelationHandler(), 'GridFieldPaginator');
             } else {
                 $sortable = singleton($model)->hasExtension('SortableDataExtension');
                 if ($sortable) {
                     $config->addComponent(new GridFieldSortableRows('SortOrder'));
                 }
             }
             $gridfield = GridField::create($relationname, $model, $items, $config);
             $datacolumns = $gridfield->getConfig()->getComponentByType('GridFieldDataColumns');
             $cfields = singleton($model)->summaryFields();
             if (singleton($model)->hasExtension('CMSPublishableDataExtension') && !isset($cfields['PublishStatus'])) {
                 $cfields = array('PublishStatus' => 'PublishStatus') + $cfields;
             }
             $datacolumns->setDisplayFields($cfields);
             return $gridfield;
         } else {
             throw new InvalidArgumentException("Couldn't find relation.");
         }
     } else {
         throw new InvalidArgumentException("Couldn't create GridField because wrong parameters passed to the factory.");
     }
 }
 /**
  * @uses ModelAsController::getNestedController()
  * @param SS_HTTPRequest $request
  * @param DataModel $model
  * @return SS_HTTPResponse
  */
 public function handleRequest(SS_HTTPRequest $request, DataModel $model)
 {
     $this->setRequest($request);
     $this->setDataModel($model);
     $this->pushCurrent();
     // Create a response just in case init() decides to redirect
     $this->response = new SS_HTTPResponse();
     $this->init();
     // If we had a redirection or something, halt processing.
     if ($this->response->isFinished()) {
         $this->popCurrent();
         return $this->response;
     }
     // If the database has not yet been created, redirect to the build page.
     if (!DB::is_active() || !ClassInfo::hasTable('SiteTree')) {
         $this->response->redirect(Director::absoluteBaseURL() . 'dev/build?returnURL=' . (isset($_GET['url']) ? urlencode($_GET['url']) : null));
         $this->popCurrent();
         return $this->response;
     }
     try {
         $result = $this->getNestedController();
         if ($result instanceof RequestHandler) {
             $result = $result->handleRequest($this->getRequest(), $model);
         } else {
             if (!$result instanceof SS_HTTPResponse) {
                 user_error("ModelAsController::getNestedController() returned bad object type '" . get_class($result) . "'", E_USER_WARNING);
             }
         }
     } catch (SS_HTTPResponse_Exception $responseException) {
         $result = $responseException->getResponse();
     }
     $this->popCurrent();
     return $result;
 }
 /**
  * Version viewer must only be added at if this is the final getCMSFields for a class.
  * in order to avoid having to rename all fields from eg Root.Main to Root.Current.Main
  * To do this we test if getCMSFields is from the current class
  */
 public function isEndofLine($className)
 {
     $methodFromClass = ClassInfo::has_method_from($this->ClassName, 'getCMSFields', $className);
     if ($methodFromClass) {
         return true;
     }
 }