/**
  * Handles saving the updated order of objects.
  */
 public function order($request)
 {
     $objects = $this->sourceItems();
     $sort = Object::get_static($this->sourceClass, 'default_sort');
     $newIDs = $request->postVar('ids');
     $sortVals = array_values($objects->map('ID', $sort));
     // populate new ID values
     foreach ($objects as $object) {
         if (!$object->{$sort}) {
             $table = $object->class;
             $query = DB::query("SELECT MAX(\"{$sort}\") + 1 FROM \"{$table}\"");
             $object->{$sort} = $oldIDs[$object->ID] = $query->value();
             $object->write();
         }
     }
     // save the new ID values - but only use existing sort values to prevent
     // conflicts with items not in the table
     foreach ($newIDs as $key => $id) {
         $object = $objects->find('ID', $id);
         $object->{$sort} = $sortVals[$key];
         $object->write();
     }
     $objects->sort($sort);
     return $this->FieldHolder();
 }
コード例 #2
0
 /**
  * @param SiteTree $record
  * @return Array template data
  */
 static function get_for_record($record)
 {
     $items = '';
     $message = '';
     $navItemClasses = ClassInfo::subclassesFor('SilverStripeNavigatorItem');
     array_shift($navItemClasses);
     // Sort menu items according to priority
     $menuPriority = array();
     $i = 0;
     foreach ($navItemClasses as $navItemClass) {
         if ($navItemClass == 'SilverStripeNavigatorItem') {
             continue;
         }
         $i++;
         $obj = new $navItemClass();
         // This funny litle formula ensures that the first item added with the same priority will be left-most.
         $priority = Object::get_static($navItemClass, 'priority');
         $menuPriority[$priority * 100 - 1] = $obj;
     }
     ksort($menuPriority);
     foreach ($menuPriority as $obj) {
         $text = $obj->getHTML($record);
         if ($text) {
             $items .= $text;
         }
         $newMessage = $obj->getMessage($record);
         if ($newMessage) {
             $message = $newMessage;
         }
     }
     return array('items' => $items, 'message' => $message);
 }
 /**
  * Alter file path to generated a static (static) error page file to handle error page template on different sub-sites 
  *
  * @see Error::get_filepath_for_errorcode()
  *
  * FIXME since {@link Subsite::currentSubsite()} partly relies on Session, viewing other sub-site (including main site) between 
  * opening ErrorPage in the CMS and publish ErrorPage causes static error page to get generated incorrectly. 
  */
 function alternateFilepathForErrorcode($statusCode, $locale = null)
 {
     $static_filepath = Object::get_static($this->owner->ClassName, 'static_filepath');
     $subdomainPart = "";
     // Try to get current subsite from session
     $subsite = Subsite::currentSubsite(false);
     // since this function is called from Page class before the controller is created, we have to get subsite from domain instead
     if (!$subsite) {
         $subsiteID = Subsite::getSubsiteIDForDomain();
         if ($subsiteID != 0) {
             $subsite = DataObject::get_by_id("Subsite", $subsiteID);
         } else {
             $subsite = null;
         }
     }
     if ($subsite) {
         $subdomain = $subsite->domain();
         $subdomainPart = "-{$subdomain}";
     }
     if (singleton('SiteTree')->hasExtension('Translatable') && $locale && $locale != Translatable::default_locale()) {
         $filepath = $static_filepath . "/error-{$statusCode}-{$locale}{$subdomainPart}.html";
     } else {
         $filepath = $static_filepath . "/error-{$statusCode}{$subdomainPart}.html";
     }
     return $filepath;
 }
	public function onAfterInit() {
		$cssTemplate = Object::get_static('GalleristPageDecorator', 'css_template');
		if ((bool)$cssTemplate && $this->owner->hasMethod('data')) {
			Requirements::customCSS($this->owner->data()->renderWith($cssTemplate));
		}
		Requirements::themedCSS('gallerist');
	}
 function testErrorPageLocations()
 {
     $subsite1 = $this->objFromFixture('Subsite', 'domaintest1');
     Subsite::changeSubsite($subsite1->ID);
     $path = ErrorPage::get_filepath_for_errorcode(500);
     $static_path = Object::get_static('ErrorPage', 'static_filepath');
     $expected_path = $static_path . '/error-500-' . $subsite1->domain() . '.html';
     $this->assertEquals($expected_path, $path);
 }
コード例 #6
0
	public function setUp() {
		parent::setUp();
		$this->oldMarkupTemplate = Object::get_static('GalleristPageDecorator', 'markup_template');
		Object::add_static_var('GalleristPageDecorator', 'markup_template', 'Gallerist', true);
		$this->oldGalleristActive = Object::get_static('Page', 'gallerist_active');
		Object::add_static_var('Page', 'gallerist_active', true, true);
		foreach($this->allFixtureIDs('Image') as $fileID) {
			$file = DataObject::get_by_id('Image', $fileID);
			copy(BASE_PATH . "/gallerist/images/{$file->Name}", BASE_PATH . "/{$file->Filename}");
		}
	}
コード例 #7
0
 /**
  * Test {@link Object::addStaticVar()} correctly replaces static vars
  */
 public function testAddStaticReplace()
 {
     Object::addStaticVars('ObjectStaticTest_Fourth', array('second' => array('test_4')), true);
     Object::addStaticVars('ObjectStaticTest_Third', array('second' => array('test_3_2')));
     $this->assertEquals(Object::get_static('ObjectStaticTest_Fourth', 'second', true), array('test_4'));
     $this->assertEquals(Object::get_static('ObjectStaticTest_Third', 'second', true), array('test_3_2', 'test_3'));
     Object::addStaticVars('ObjectStaticTest_Third', array('second' => array('test_3_2')), true);
     $this->assertEquals(Object::get_static('ObjectStaticTest_Third', 'second', true), array('test_3_2'));
     Object::add_static_var('ObjectStaticTest_Third', 'fourth', array('test_3_2'));
     $this->assertEquals(Object::get_static('ObjectStaticTest_Fourth', 'fourth', true), array('test_3_2', 'test_4'));
     Object::add_static_var('ObjectStaticTest_Third', 'fourth', array('test_3_2'), true);
     $this->assertEquals(Object::get_static('ObjectStaticTest_Fourth', 'fourth', true), array('test_4', 'test_3_2'));
 }
コード例 #8
0
 public function __construct($controller, $name = null, $sourceClass = null, $fileFieldName = null, $fieldList = null, $detailFormFields = null, $sourceFilter = "", $sourceSort = "Created DESC", $sourceJoin = "")
 {
     if (!class_exists("SWFUploadField")) {
         die("<strong>" . _t('DataObjectManager.ERROR', 'Error') . "</strong>: " . _t('FileDataObjectManager.SWFUPLOAD', 'DataObjectManager requires the SWFUpload module.'));
     }
     parent::__construct($controller, $name, $sourceClass, $fieldList, $detailFormFields, $sourceFilter, $sourceSort, $sourceJoin);
     // Intelligent constructor for fileFieldName
     $SNG = singleton($this->sourceClass());
     if ($fileFieldName === null) {
         if ($has_ones = $SNG->stat('has_one')) {
             foreach ($has_ones as $relation => $value) {
                 if (is_subclass_of($value, "File")) {
                     $fileFieldName = $relation;
                     $fileClassName = $value;
                     break;
                 }
             }
         }
     }
     if (isset($_REQUEST['ctf'][$this->Name()])) {
         $this->view = $_REQUEST['ctf'][$this->Name()]['view'];
     }
     if ($this->sourceClass() == "File" || is_subclass_of($this->sourceClass(), "File")) {
         $this->hasDataObject = false;
         $this->fileFieldName = $name;
         $this->fileClassName = $this->sourceClass();
         $this->dataObjectFieldName = null;
     } else {
         $this->dataObjectFieldName = $name;
         $this->fileFieldName = $fileFieldName;
         $this->fileClassName = $SNG->has_one($this->fileFieldName);
         if (!$this->fileClassName) {
             die("<strong>FileDataObjectManager::__construct():</strong>" . _t('FileDataObjectManager.FILERELATION', 'Could not determine file relationship'));
         }
     }
     $this->controllerClassName = $controller->class;
     if ($key = array_search($this->controllerClassName, $SNG->stat('has_one'))) {
         $this->controllerFieldName = $key;
     } else {
         $this->controllerFieldName = $this->controllerClassName;
     }
     $this->controllerID = $controller->ID;
     // Check for allowed file types
     if ($types = Object::get_static($this->fileClassName, 'allowed_file_types')) {
         $this->setAllowedFileTypes($types);
     }
 }
コード例 #9
0
 /**
  * Factory that returns a RESTFormatter subclass that formats in a particular format based on mimetype or extension
  *
  * @static
  * @param SS_HTTPRequest | string - $request
  * @return RESTFormatter - an instance of a RESTFormatter that can do the job, or null if none can.
  */
 public static function get_formatter($request = null)
 {
     // Request can be an SS_HTTPRequest object
     if ($request instanceof SS_HTTPRequest) {
         // Try and get the mimetype from the request's Accept header
         $mimetypes = $request->getAcceptMimetypes();
         // Alternatively the type might be specified by the client as an extension on the URL
         $extension = $request->getExtension();
     } else {
         $mimetypes = array($request);
         $extension = $request;
     }
     // Filter out empty items and */*
     $mimetypes = array_filter($mimetypes, array(__CLASS__, 'useful_mimetype'));
     // If we didn't get a mimetype _or_ an extension, use the default
     if (!$mimetypes && !$extension) {
         $mimetypes = array(self::$default);
     }
     // Now step through looking for matches on any specified mimetype or exception
     $byMimeType = null;
     $byExtension = null;
     foreach (ClassInfo::subclassesFor(__CLASS__) as $class) {
         if ($class == __CLASS__) {
             continue;
         }
         if ($mimetypes && count(array_intersect($mimetypes, Object::get_static($class, 'mimetypes')))) {
             $byMimeType = $class;
             break;
             // Mimetypes take priority over extensions. If we get a match we're done.
         }
         if ($extension && in_array($extension, Object::get_static($class, 'url_extensions'))) {
             $byExtension = $class;
             if (!$mimetypes) {
                 break;
             }
             // We're only done on a match if we don't have a mimetype to look for.
         }
     }
     // Mime type match gets priority over extension
     if ($byMimeType) {
         return new $byMimeType();
     }
     if ($byExtension) {
         return new $byExtension();
     }
 }
コード例 #10
0
ファイル: CMSMenu.php プロジェクト: rixrix/sapphire
 /**
  * Add the appropriate Director rules for the given controller.
  */
 protected static function add_director_rule_for_controller($controllerClass)
 {
     $urlBase = Object::get_static($controllerClass, 'url_base');
     $urlSegment = Object::get_static($controllerClass, 'url_segment');
     $urlRule = Object::get_static($controllerClass, 'url_rule');
     $urlPriority = Object::get_static($controllerClass, 'url_priority');
     if ($urlSegment || $controllerClass == "CMSMain") {
         $link = Controller::join_links($urlBase, $urlSegment) . '/';
         // Make director rule
         if ($urlRule[0] == '/') {
             $urlRule = substr($urlRule, 1);
         }
         $rule = $link . '/' . $urlRule;
         // the / will combine with the / on the end of $link to make a //
         Director::addRules($urlPriority, array($rule => $controllerClass));
     }
 }
コード例 #11
0
 /**
  * Factory that returns a RESTParser subclass that parses data in a particular format based on mimetype or content
  *
  * TODO: This is pretty copy-pasta from RESTFormatter. Maybe consolidate this code with that?
  *
  * @static
  * @param SS_HTTPRequest | string - $request
  * @return RESTParser - an instance of a RESTParser that can do the job, or null if none can.
  */
 public static function get_parser($request = null)
 {
     // Request can be an SS_HTTPRequest object
     if ($request instanceof SS_HTTPRequest) {
         // Try and get the mimetype from the request's Accept header
         $mimetypes = self::get_content_type_mimetypes($request);
         // Alternatively the type might be auto-detected from the request
         $body = $request->getBody();
     } else {
         $mimetypes = array($request);
         $body = '';
     }
     // Filter out empty items and */*
     $mimetypes = array_filter($mimetypes, array(__CLASS__, 'useful_mimetype'));
     // Now step through looking for matches on any specified mimetype or exception
     $byMimeType = null;
     $bySignature = null;
     foreach (ClassInfo::subclassesFor(__CLASS__) as $class) {
         if ($class == __CLASS__) {
             continue;
         }
         if ($mimetypes && count(array_intersect($mimetypes, Object::get_static($class, 'mimetypes')))) {
             $byMimeType = $class;
             break;
             // Mimetypes take priority over extensions. If we get a match we're done.
         }
         if ($body && call_user_func(array($class, 'matches_signature'), $body)) {
             $bySignature = $class;
             if (!$mimetypes) {
                 break;
             }
             // We're only done on a match if we don't have a mimetype to look for.
         }
     }
     // Mime type match gets priority over extension
     if ($byMimeType) {
         return new $byMimeType();
     }
     if ($bySignature) {
         return new $bySignature();
     }
 }
コード例 #12
0
 /**
  * Debug helper method.
  * Can be called from /shoppingcart/debug/
  * @return String
  */
 public function debug()
 {
     $this->calculateOrderAttributes(true);
     $html = "\r\n\t\t\t<h2>" . $this->ClassName . "</h2><ul>";
     $fields = Object::get_static($this->ClassName, "db");
     foreach ($fields as $key => $type) {
         $html .= "<li><b>{$key} ({$type}):</b> " . $this->{$key} . "</li>";
     }
     $fields = Object::get_static($this->ClassName, "casting");
     foreach ($fields as $key => $type) {
         $method = "get" . $key;
         $html .= "<li><b>{$key} ({$type}):</b> " . $this->{$method}() . " </li>";
     }
     $html .= "</ul>";
     return $html;
 }
コード例 #13
0
ファイル: MultiForm.php プロジェクト: racontemoi/shibuichi
 /**
  * Start the MultiForm instance.
  *
  * @param Controller instance $controller Controller this form is created on
  * @param string $name The form name, typically the same as the method name
  */
 public function __construct($controller, $name)
 {
     if (isset($_GET['MultiFormSessionID'])) {
         $this->setCurrentSessionHash($_GET['MultiFormSessionID']);
     }
     // Set up the session for this MultiForm instance
     $this->setSession();
     // Get the current step available (Note: either returns an existing
     // step or creates a new one if none available)
     $currentStep = $this->getCurrentStep();
     // Set the step returned above as the current step
     $this->setCurrentStep($currentStep);
     // Set the form of the step to this form instance
     $currentStep->setForm($this);
     // Set up the fields for the current step
     $fields = $currentStep->getFields();
     // Set up the actions for the current step
     $actions = $this->actionsFor($currentStep);
     // Set up validation (if necessary)
     $validator = null;
     $applyValidation = true;
     // Check if the $_REQUEST action that user clicked is an exempt one
     $actionNames = Object::get_static(get_class($this), 'actions_exempt_from_validation');
     if ($actionNames) {
         foreach ($actionNames as $exemptAction) {
             if (!empty($_REQUEST[$exemptAction])) {
                 $applyValidation = false;
                 break;
             }
         }
     }
     // Apply validation if the current step requires validation (is not exempt)
     if ($applyValidation) {
         if ($currentStep->getValidator()) {
             $validator = $currentStep->getValidator();
         }
     }
     // Give the fields, actions, and validation for the current step back to the parent Form class
     parent::__construct($controller, $name, $fields, $actions, $validator);
     // Set a hidden field in our form with an encrypted hash to identify this session.
     $this->fields->push(new HiddenField('MultiFormSessionID', false, $this->session->Hash));
     // If there is saved data for the current step, we load it into the form it here
     //(CAUTION: loadData() MUST unserialize first!)
     if ($currentStep->loadData()) {
         $this->loadDataFrom($currentStep->loadData());
     }
     // Disable security token - we tie a form to a session ID instead
     $this->disableSecurityToken();
 }
コード例 #14
0
 function augmentDatabase()
 {
     $classTable = $this->owner->class;
     $isRootClass = $this->owner->class == ClassInfo::baseDataClass($this->owner->class);
     // Build a list of suffixes whose tables need versioning
     $allSuffixes = array();
     foreach (Versioned::$versionableExtensions as $versionableExtension => $suffixes) {
         if ($this->owner->hasExtension($versionableExtension)) {
             $allSuffixes = array_merge($allSuffixes, (array) $suffixes);
             foreach ((array) $suffixes as $suffix) {
                 $allSuffixes[$suffix] = $versionableExtension;
             }
         }
     }
     // Add the default table with an empty suffix to the list (table name = class name)
     array_push($allSuffixes, '');
     foreach ($allSuffixes as $key => $suffix) {
         // check that this is a valid suffix
         if (!is_int($key)) {
             continue;
         }
         if ($suffix) {
             $table = "{$classTable}_{$suffix}";
         } else {
             $table = $classTable;
         }
         if ($fields = DataObject::database_fields($this->owner->class)) {
             $options = Object::get_static($this->owner->class, 'create_table_options');
             $indexes = $this->owner->databaseIndexes();
             if ($suffix && ($ext = $this->owner->getExtensionInstance($allSuffixes[$suffix]))) {
                 if (!$ext->isVersionedTable($table)) {
                     continue;
                 }
                 $ext->setOwner($this->owner);
                 $fields = $ext->fieldsInExtraTables($suffix);
                 $ext->clearOwner();
                 $indexes = $fields['indexes'];
                 $fields = $fields['db'];
             }
             // Create tables for other stages
             foreach ($this->stages as $stage) {
                 // Extra tables for _Live, etc.
                 //Change unique indexes to 'index'.  Versioned tables may run into unique indexing difficulties otherwise.
                 foreach ($indexes as $key => $index) {
                     if (is_array($index) && $index['type'] == 'unique') {
                         $indexes[$key]['type'] = 'index';
                     }
                 }
                 if ($stage != $this->defaultStage) {
                     DB::requireTable("{$table}_{$stage}", $fields, $indexes, false, $options);
                 }
                 // Version fields on each root table (including Stage)
                 /*
                 if($isRootClass) {
                 	$stageTable = ($stage == $this->defaultStage) ? $table : "{$table}_$stage";
                 	$parts=Array('datatype'=>'int', 'precision'=>11, 'null'=>'not null', 'default'=>(int)0);
                 	$values=Array('type'=>'int', 'parts'=>$parts);
                 	DB::requireField($stageTable, 'Version', $values);
                 }
                 */
             }
             if ($isRootClass) {
                 // Create table for all versions
                 $versionFields = array_merge(self::$db_for_versions_table, (array) $fields);
                 $versionIndexes = array_merge(self::$indexes_for_versions_table, (array) $indexes);
             } else {
                 // Create fields for any tables of subclasses
                 $versionFields = array_merge(array("RecordID" => "Int", "Version" => "Int"), (array) $fields);
                 //Unique indexes will not work on versioned tables, so we'll convert them to standard indexes:
                 foreach ($indexes as $key => $index) {
                     if (is_array($index) && strtolower($index['type']) == 'unique') {
                         $indexes[$key]['type'] = 'index';
                     }
                 }
                 $versionIndexes = array_merge(array('RecordID_Version' => array('type' => 'unique', 'value' => 'RecordID,Version'), 'RecordID' => true, 'Version' => true), (array) $indexes);
             }
             if (DB::getConn()->hasTable("{$table}_versions")) {
                 // Fix data that lacks the uniqueness constraint (since this was added later and
                 // bugs meant that the constraint was validated)
                 $duplications = DB::query("SELECT MIN(\"ID\") AS \"ID\", \"RecordID\", \"Version\" \n\t\t\t\t\t\tFROM \"{$table}_versions\" GROUP BY \"RecordID\", \"Version\" \n\t\t\t\t\t\tHAVING COUNT(*) > 1");
                 foreach ($duplications as $dup) {
                     DB::alteration_message("Removing {$table}_versions duplicate data for " . "{$dup['RecordID']}/{$dup['Version']}", "deleted");
                     DB::query("DELETE FROM \"{$table}_versions\" WHERE \"RecordID\" = {$dup['RecordID']}\n\t\t\t\t\t\t\tAND \"Version\" = {$dup['Version']} AND \"ID\" != {$dup['ID']}");
                 }
                 // Remove junk which has no data in parent classes. Only needs to run the following
                 // when versioned data is spread over multiple tables
                 if (!$isRootClass && ($versionedTables = ClassInfo::dataClassesFor($table))) {
                     foreach ($versionedTables as $child) {
                         if ($table == $child) {
                             break;
                         }
                         // only need subclasses
                         $count = DB::query("\n\t\t\t\t\t\t\t\tSELECT COUNT(*) FROM \"{$table}_versions\"\n\t\t\t\t\t\t\t\tLEFT JOIN \"{$child}_versions\" \n\t\t\t\t\t\t\t\t\tON \"{$child}_versions\".\"RecordID\" = \"{$table}_versions\".\"RecordID\"\n\t\t\t\t\t\t\t\t\tAND \"{$child}_versions\".\"Version\" = \"{$table}_versions\".\"Version\"\n\t\t\t\t\t\t\t\tWHERE \"{$child}_versions\".\"ID\" IS NULL\n\t\t\t\t\t\t\t")->value();
                         if ($count > 0) {
                             DB::alteration_message("Removing orphaned versioned records", "deleted");
                             $effectedIDs = DB::query("\n\t\t\t\t\t\t\t\t\tSELECT \"{$table}_versions\".\"ID\" FROM \"{$table}_versions\"\n\t\t\t\t\t\t\t\t\tLEFT JOIN \"{$child}_versions\" \n\t\t\t\t\t\t\t\t\t\tON \"{$child}_versions\".\"RecordID\" = \"{$table}_versions\".\"RecordID\"\n\t\t\t\t\t\t\t\t\t\tAND \"{$child}_versions\".\"Version\" = \"{$table}_versions\".\"Version\"\n\t\t\t\t\t\t\t\t\tWHERE \"{$child}_versions\".\"ID\" IS NULL\n\t\t\t\t\t\t\t\t")->column();
                             if (is_array($effectedIDs)) {
                                 foreach ($effectedIDs as $key => $value) {
                                     DB::query("DELETE FROM \"{$table}_versions\" WHERE \"{$table}_versions\".\"ID\" = '{$value}'");
                                 }
                             }
                         }
                     }
                 }
             }
             DB::requireTable("{$table}_versions", $versionFields, $versionIndexes, true, $options);
         } else {
             DB::dontRequireTable("{$table}_versions");
             foreach ($this->stages as $stage) {
                 if ($stage != $this->defaultStage) {
                     DB::dontrequireTable("{$table}_{$stage}");
                 }
             }
         }
     }
 }
コード例 #15
0
 /**
  * Builds the XML data.
  *
  * SilvercartPaymentMethod relations get treated specially here.
  *
  * @param DataObject $obj       Object to build XML data for
  * @param array      $fields    Fields to build XML data for
  * @param array      $relations Relations to support
  *
  * @return string
  *
  * @author Sebastian Diel <*****@*****.**>
  * @since 23.06.2014
  */
 public function convertDataObjectWithoutHeader(DataObject $obj, $fields = null, $relations = null)
 {
     $className = $obj->class;
     $id = $obj->ID;
     $objHref = Director::absoluteURL(static::$api_base . $obj->class . "/" . $obj->ID);
     if (substr($obj->ClassName, 0, 17) == 'SilvercartPayment') {
         $relClassName = 'SilvercartPaymentMethod';
     } else {
         $relClassName = $obj->ClassName;
     }
     $xml = "<{$relClassName} href=\"{$objHref}.xml\">\n";
     $this->getDataObjectFieldPermissions($obj);
     $fields = array_intersect((array) $this->getCustomAddFields(), (array) $this->getCustomFields());
     foreach ($this->getFieldsForObj($obj) as $fieldName => $fieldType) {
         // Field filtering
         if (SilvercartRestfulServer::isBlackListField($obj->class, $fieldName)) {
             continue;
         }
         if ($fields && !in_array($fieldName, $fields)) {
             continue;
         }
         $fieldValue = $obj->{$fieldName};
         if (!mb_check_encoding($fieldValue, 'utf-8')) {
             $fieldValue = "(data is badly encoded)";
         }
         if (is_object($fieldValue) && is_subclass_of($fieldValue, 'Object') && $fieldValue->hasMethod('toXML')) {
             $xml .= $fieldValue->toXML();
         } else {
             $xml .= "<{$fieldName}>" . Convert::raw2xml($fieldValue) . "</{$fieldName}>\n";
         }
     }
     if ($this->getRelationDepth() > 0) {
         foreach ($obj->has_one() as $relName => $relClass) {
             if ($this->skipRelation($relName, $relClass, $fields)) {
                 continue;
             }
             $fieldName = $relName . 'ID';
             $href = '';
             if ($obj->{$fieldName}) {
                 $relObj = null;
                 if ($this->getRelationDetailDepth() > 0) {
                     $relObj = DataObject::get_by_id($relClass, $obj->{$fieldName});
                 }
                 if ($relObj) {
                     $relationDepth = $this->getRelationDepth();
                     $this->setRelationDepth($relationDepth - 1);
                     $originalCustomAddFields = $this->getCustomAddFields();
                     $customAddFields = Object::get_static($relObj->ClassName, 'custom_add_export_fields');
                     $this->setCustomAddFields((array) $customAddFields);
                     $xml .= $this->convertDataObjectWithoutHeader($relObj, $fields);
                     $this->setCustomAddFields($originalCustomAddFields);
                     $this->setRelationDepth($relationDepth);
                 } else {
                     $href = Director::absoluteURL(static::$api_base . "{$relClass}/" . $obj->{$fieldName});
                 }
             } else {
                 $href = Director::absoluteURL(static::$api_base . "{$className}/{$id}/{$relName}");
             }
             if (!empty($href)) {
                 $xml .= "<{$relName} linktype=\"has_one\" href=\"{$href}.xml\" id=\"" . $obj->{$fieldName} . "\"></{$relName}>\n";
             }
         }
         foreach ($obj->has_many() as $relName => $relClass) {
             if ($this->skipRelation($relName, $relClass, $fields)) {
                 continue;
             }
             $xml .= $this->addMany($relName, $relClass, $objHref, $obj, 'has_many', $fields);
         }
         foreach ($obj->many_many() as $relName => $relClass) {
             if ($this->skipRelation($relName, $relClass, $fields)) {
                 continue;
             }
             $xml .= $this->addMany($relName, $relClass, $objHref, $obj, 'many_many', $fields);
         }
     }
     $xml .= "</{$relClassName}>\n";
     return $xml;
 }
コード例 #16
0
	/**
	 * Perform retroactive DataObject cleaning.
	 * 
	 * @param SS_HTTPRequest $request
	 */
	public function run($request) {
		if (!Object::get_static('SapphireTest', 'is_running_test')) {
			JanitorDebug::set_verbose(true);
		}
		if (JanitorDBP::available()) {
			$this->backupPath = JanitorDBP::backup_database();
		}
		$dataObjectSubClasses = (array)ClassInfo::subclassesFor('DataObject');
		// Remove DataObject
		array_shift($dataObjectSubClasses);
		foreach ($dataObjectSubClasses as $class) {
			$retroactiveCleaner = new DataObjectRetroactiveCleaner($class);
			$retroactiveCleaner->clean();
		}
	}
コード例 #17
0
 /**
  * Get a unified array of allowed actions on this controller (if such data is available) from both the controller
  * ancestry and any extensions.
  *
  * @return array|null
  */
 public function allowedActions()
 {
     $actions = Object::combined_static(get_class($this), 'allowed_actions', 'RequestHandler');
     foreach ($this->extension_instances as $extension) {
         if ($extensionActions = Object::get_static(get_class($extension), 'allowed_actions')) {
             $actions = array_merge($actions, $extensionActions);
         }
     }
     if ($actions) {
         // convert all keys and values to lowercase to
         // allow for easier comparison, unless it is a permission code
         $actions = array_change_key_case($actions, CASE_LOWER);
         foreach ($actions as $key => $value) {
             if (is_numeric($key)) {
                 $actions[$key] = strtolower($value);
             }
         }
         return $actions;
     }
 }
コード例 #18
0
 /**
  * Return a DataObjectSet of ArrayData objects containing the following pieces of info
  * about each batch action:
  *  - Link
  *  - Title
  *  - DoingText
  */
 function batchActionList()
 {
     $actions = Object::get_static($this->class, 'batch_actions');
     $actionList = new DataObjectSet();
     foreach ($actions as $urlSegment => $actionClass) {
         $actionObj = new $actionClass();
         if ($actionObj->canView()) {
             $actionDef = new ArrayData(array("Link" => Controller::join_links($this->Link(), $urlSegment), "Title" => $actionObj->getActionTitle(), "DoingText" => $actionObj->getDoingText()));
             $actionList->push($actionDef);
         }
     }
     return $actionList;
 }
コード例 #19
0
 /**
  * Get the value of a field on this object, automatically inserting the value into any available casting objects
  * that have been specified.
  *
  * @param string $fieldName
  * @param array $arguments
  * @param bool $forceReturnedObject if TRUE, the value will ALWAYS be casted to an object before being returned,
  *        even if there is no explicit casting information
  * @param string $cacheName a custom cache name
  */
 public function obj($fieldName, $arguments = null, $forceReturnedObject = true, $cache = false, $cacheName = null)
 {
     if (isset($_REQUEST['debug_profile'])) {
         Profiler::mark("obj.{$fieldName}", "on a {$this->class} object");
     }
     if (!$cacheName) {
         $cacheName = $arguments ? $fieldName . implode(',', $arguments) : $fieldName;
     }
     if (!isset($this->objCache[$cacheName])) {
         if ($this->hasMethod($fieldName)) {
             $value = $arguments ? call_user_func_array(array($this, $fieldName), $arguments) : $this->{$fieldName}();
         } else {
             $value = $this->{$fieldName};
         }
         if (!is_object($value) && ($this->castingClass($fieldName) || $forceReturnedObject)) {
             if (!($castConstructor = $this->castingHelper($fieldName))) {
                 $castConstructor = $this->stat('default_cast');
             }
             $valueObject = Object::create_from_string($castConstructor, $fieldName);
             $valueObject->setValue($value, $this->hasMethod('getAllFields') ? $this->getAllFields() : null);
             $value = $valueObject;
         }
         if ($cache) {
             $this->objCache[$cacheName] = $value;
         }
     } else {
         $value = $this->objCache[$cacheName];
     }
     if (isset($_REQUEST['debug_profile'])) {
         Profiler::unmark("obj.{$fieldName}", "on a {$this->class} object");
     }
     if (!is_object($value) && $forceReturnedObject) {
         $default = Object::get_static('ViewableData', 'default_cast');
         $value = new $default($fieldName);
     }
     return $value;
 }
コード例 #20
0
 /**
  * Test that DataObject::$api_access can be set to true via a extension
  */
 function testApiAccessCanBeExtended()
 {
     $this->assertTrue(Object::get_static('DataExtensionTest_Member', 'api_access'));
 }
コード例 #21
0
	public function getSetting($setting)
	{
	   if($this->$setting) {
	     return $this->$setting;
	   }
	   return Object::get_static($this->class,DOMUtil::to_underscore($setting));
	}
コード例 #22
0
 /**
  * Handles URL requests.
  *
  *  - ViewableData::handleRequest() iterates through each rule in {@link self::$url_handlers}.
  *  - If the rule matches, the named method will be called.
  *  - If there is still more URL to be processed, then handleRequest() is called on the object that that method returns.
  *
  * Once all of the URL has been processed, the final result is returned.  However, if the final result is an array, this
  * array is interpreted as being additional template data to customise the 2nd to last result with, rather than an object
  * in its own right.  This is most frequently used when a Controller's action will return an array of data with which to
  * customise the controller.
  * 
  * @param $params The parameters taken from the parsed URL of the parent url handler
  * @param $request The {@link HTTPRequest} object that is reponsible for distributing URL parsing
  * @uses HTTPRequest
  * @uses HTTPRequest->match()
  * @return HTTPResponse|RequestHandler|string|array
  */
 function handleRequest($request)
 {
     // $handlerClass is used to step up the class hierarchy to implement url_handlers inheritance
     $handlerClass = $this->class ? $this->class : get_class($this);
     if ($this->brokenOnConstruct) {
         user_error("parent::__construct() needs to be called on {$handlerClass}::__construct()", E_USER_WARNING);
     }
     $this->request = $request;
     // We stop after RequestHandler; in other words, at ViewableData
     while ($handlerClass && $handlerClass != 'ViewableData') {
         $urlHandlers = Object::get_static($handlerClass, 'url_handlers');
         if ($urlHandlers) {
             foreach ($urlHandlers as $rule => $action) {
                 if (isset($_REQUEST['debug_request'])) {
                     Debug::message("Testing '{$rule}' with '" . $request->remaining() . "' on {$this->class}");
                 }
                 if ($params = $request->match($rule, true)) {
                     // FIXME: This unnecessary coupling was added to fix a bug in Image_Uploader.
                     if ($this instanceof Controller) {
                         $this->urlParams = $request->allParams();
                     }
                     if (isset($_REQUEST['debug_request'])) {
                         Debug::message("Rule '{$rule}' matched to action '{$action}' on {$this->class}.  Latest request params: " . var_export($request->latestParams(), true));
                     }
                     // Actions can reference URL parameters, eg, '$Action/$ID/$OtherID' => '$Action',
                     if ($action[0] == '$') {
                         $action = $params[substr($action, 1)];
                     }
                     if ($this->checkAccessAction($action)) {
                         if (!$action) {
                             if (isset($_REQUEST['debug_request'])) {
                                 Debug::message("Action not set; using default action method name 'index'");
                             }
                             $action = "index";
                         } else {
                             if (!is_string($action)) {
                                 user_error("Non-string method name: " . var_export($action, true), E_USER_ERROR);
                             }
                         }
                         $result = $this->{$action}($request);
                     } else {
                         return $this->httpError(403, "Action '{$action}' isn't allowed on class {$this->class}");
                     }
                     if ($result instanceof HTTPResponse && $result->isError()) {
                         if (isset($_REQUEST['debug_request'])) {
                             Debug::message("Rule resulted in HTTP error; breaking");
                         }
                         return $result;
                     }
                     // If we return a RequestHandler, call handleRequest() on that, even if there is no more URL to parse.
                     // It might have its own handler.  However, we only do this if we haven't just parsed an empty rule ourselves,
                     // to prevent infinite loops
                     if (!$request->isEmptyPattern($rule) && is_object($result) && $result instanceof RequestHandler) {
                         $returnValue = $result->handleRequest($request);
                         // Array results can be used to handle
                         if (is_array($returnValue)) {
                             $returnValue = $this->customise($returnValue);
                         }
                         return $returnValue;
                         // If we return some other data, and all the URL is parsed, then return that
                     } else {
                         if ($request->allParsed()) {
                             return $result;
                             // But if we have more content on the URL and we don't know what to do with it, return an error.
                         } else {
                             return $this->httpError(404, "I can't handle sub-URLs of a {$this->class} object.");
                         }
                     }
                     return $this;
                 }
             }
         }
         $handlerClass = get_parent_class($handlerClass);
     }
     // If nothing matches, return this object
     return $this;
 }
コード例 #23
0
 /**
  * Get all registered actions through the static defaults set by {@link register()}.
  * Filters for the currently set {@link recordClass}.
  * 
  * @return array See {@link register()} for the returned format.
  */
 function batchActions()
 {
     $actions = Object::get_static($this->class, 'batch_actions');
     if ($actions) {
         foreach ($actions as $action) {
             if ($action['recordClass'] != $this->recordClass) {
                 unset($action);
             }
         }
     }
     return $actions;
 }
 function stat($name, $uncached = false)
 {
     return Object::get_static($this->class ? $this->class : get_class($this), $name, $uncached);
 }
コード例 #25
0
 function Description()
 {
     return Object::get_static($this->class, 'description');
 }
コード例 #26
0
 /**
  * Returns a merging of the model's default syncing configuration
  * and the context configuration for this model
  *
  * @param string $model
  * @return array
  */
 public function getConfig($model)
 {
     $default = null;
     if (class_exists($model)) {
         if (class_exists('Config')) {
             $default = Config::inst()->get($model, 'sync');
         } else {
             $default = Object::get_static($model, 'sync');
         }
     }
     if (!is_array($default)) {
         $default = array();
     }
     $override = isset($this->modelConfig[$model]) ? $this->modelConfig[$model] : array();
     return array_merge($default, $override);
 }
コード例 #27
0
 /**
  * Test that DataObject::$api_access can be set to true via a decorator
  */
 function testApiAccessCanBeDecorated()
 {
     $this->assertTrue(Object::get_static('DataObjectDecoratorTest_Member', 'api_access'));
 }
コード例 #28
0
 function getName()
 {
     $stat = Object::get_static($this->noun, 'name');
     return $stat ? $stat : $this->noun;
 }
コード例 #29
0
 /**
  * Get an object from the fixture.
  * @param $className The data class, as specified in your fixture file.  Parent classes won't work
  * @param $identifier The identifier string, as provided in your fixture file
  */
 protected function objFromFixture($className, $identifier)
 {
     if (!$this->fixtures) {
         user_error("You've called objFromFixture() but you haven't specified static \$fixture_file.\n", E_USER_WARNING);
         return;
     }
     foreach ($this->fixtures as $fixture) {
         $match = $fixture->objFromFixture($className, $identifier);
         if ($match) {
             return $match;
         }
     }
     $fixtureFiles = Object::get_static(get_class($this), 'fixture_file');
     user_error(sprintf("Couldn't find object '%s' (class: %s) in files %s", $identifier, $className, is_array($fixtureFiles) ? implode(',', $fixtureFiles) : $fixtureFiles), E_USER_ERROR);
     return false;
 }
コード例 #30
0
	public function Gallerist() {
		if (Object::get_static($this->owner->class, 'gallerist_active')) {
			return $this->owner->renderWith(Object::get_static('GalleristPageDecorator',
				'markup_template'));
		}
		return '';
	}