public function convert(DataObject $object)
 {
     if ($object->hasMethod('toFilteredMap')) {
         return Convert::raw2json($object->toFilteredMap());
     }
     return Convert::raw2json($object->toMap());
 }
Example #2
0
 protected function walkRelationshipChain(DataObject $from, ArrayList $list, array $parts, $lastPart, $lastItem)
 {
     $part = array_shift($parts);
     if (!$from->hasMethod($part)) {
         // error, no such part of relationship chain
         return false;
     }
     if (count($parts)) {
         foreach ($from->{$part}() as $item) {
             $this->walkRelationshipChain($item, $list, $parts, $part, $item);
         }
     } else {
         $images = $from->{$part}()->toNestedArray();
         // mark the images with a source from relationship and ID
         /** @var Image $image */
         foreach ($images as &$image) {
             if ($lastItem instanceof Variation) {
                 $options = $lastItem->Options();
                 foreach ($options as $option) {
                     $image['ProductID'] = $lastItem->Product()->ID;
                     $image['VariationID'] = $lastItem->ID;
                     $image['OptionID'] = $option->ID;
                     $image['AttributeID'] = $option->AttributeID;
                 }
             }
         }
         $list->merge(new ArrayList($images));
     }
     return true;
 }
 /**
  * @param DataObject $obj
  * @param array      $config
  * @return array|bool
  */
 public function convertDataObjectToArray(DataObject $obj, $config = array())
 {
     $content = array();
     $allowedFields = $obj instanceof FlexibleDataFormatterInterface ? $obj->getAllowedFields($config) : array_keys($obj->db());
     foreach ($allowedFields as $fieldName) {
         if ($obj->hasMethod($fieldName)) {
             $fieldValue = $obj->{$fieldName}();
         } else {
             $fieldValue = $obj->dbObject($fieldName);
             if (is_null($fieldValue)) {
                 $fieldValue = $obj->{$fieldName};
             }
         }
         if ($fieldValue instanceof Object) {
             switch (get_class($fieldValue)) {
                 case 'Boolean':
                     $content[$fieldName] = (bool) $fieldValue->getValue();
                     break;
                 case 'PrimaryKey':
                     $content[$fieldName] = $obj->{$fieldName};
                     break;
                 case 'HTMLText':
                     $content[$fieldName] = $fieldValue->forTemplate();
                     break;
                 default:
                     $content[$fieldName] = $fieldValue->getValue();
                     break;
             }
         } else {
             $content[$fieldName] = $fieldValue;
         }
     }
     if ($obj instanceof FlexibleDataFormatterInterface) {
         foreach ($obj->getAllowedHasOneRelations($config) as $relName) {
             if ($obj->{$relName . 'ID'}) {
                 $content[$relName] = $this->convertDataObjectToArray($obj->{$relName}(), $config);
             }
         }
         foreach ($obj->getAllowedHasManyRelations($config) as $relName) {
             $items = $obj->{$relName}();
             if ($items instanceof SS_List && count($items) > 0) {
                 $content[$relName] = array();
                 foreach ($items as $item) {
                     $content[$relName][] = $this->convertDataObjectToArray($item, $config);
                 }
             }
         }
         foreach ($obj->getAllowedManyManyRelations($config) as $relName) {
             $items = $obj->{$relName}();
             if ($items instanceof SS_List && count($items) > 0) {
                 $content[$relName] = array();
                 foreach ($items as $item) {
                     $content[$relName][] = $this->convertDataObjectToArray($item, $config);
                 }
             }
         }
     }
     return $content;
 }
 public function convert(DataObject $object)
 {
     if ($object->hasMethod('toFilteredMap')) {
         $data = $object->toFilteredMap();
     } else {
         $data = $object->toMap();
     }
     $converter = new ArrayToXml('item');
     return $converter->convertArray($data);
 }
 /**
  * @param GridField $gridField
  * @param DataObject $record
  * @param string $columnName
  *
  * @return string - the HTML for the column
  */
 public function getColumnContent($gridField, $record, $columnName)
 {
     // No permission checks, handled through GridFieldDetailForm,
     // which can make the form readonly if no edit permissions are available.
     if ($record->hasMethod("CMSEditLink")) {
         $data = new ArrayData(array('Link' => Controller::join_links($record->CMSEditLink())));
         return $data->renderWith('GridFieldEditButtonInSiteTree');
     } else {
         return parent::getColumnContent($gridField, $record, $columnName);
     }
 }
 /**
  * Recursivly search for a PlaceholderImage.
  *
  * @param DataObject $object
  * @return Image | null
  */
 protected function getPlaceholderImageRecursive(DataObject $object)
 {
     if ($object->has_one('PlaceholderImage')) {
         $image = $object->getComponent('PlaceholderImage');
         if ($image->exists()) {
             return $image;
         }
     }
     $parentObject = $object->hasMethod('Parent') ? $object->Parent() : null;
     return isset($parentObject) && $parentObject->exists() ? $this->getPlaceholderImageRecursive($parentObject) : null;
 }
 public function trackInteraction($interactionType, DataObject $item = null, Member $user = null)
 {
     if ($user == null) {
         $user = Member::currentUserID();
     }
     // Create a new user interaction object to track the page count.
     $link = '#';
     if ($item->hasMethod('RelativeLink')) {
         $link = $item->RelativeLink();
     }
     $interaction = UserInteraction::create(array('Title' => $item->Title, 'Type' => $interactionType, 'ItemClass' => get_class($item), 'ItemID' => $item->ID, 'URL' => $link, 'MemberID' => $user));
     $interaction->write();
 }
 /**
  * Sets the value of the form field. 
  *
  * @param mixed $value If numeric, get the file by ID, otherwise, introspect the $data object
  * @param DataObject $data The record associated with the parent form
  */
 public function setValue($value = null, $data = null)
 {
     if (!is_numeric($value)) {
         if ($id = Controller::curr()->getRequest()->requestVar($this->Name() . "ID")) {
             $value = $id;
         } elseif (!$value && $data && $data instanceof DataObject && $data->hasMethod($this->name)) {
             $funcName = $this->name;
             if ($obj = $data->{$funcName}()) {
                 if ($obj instanceof File || $obj instanceof S3File) {
                     $value = $obj->ID;
                 }
             }
         }
     }
     parent::setValue($value, $data);
 }
 /**
  * Gets the workflow definition for a given dataobject, if there is one
  *
  * Will recursively query parent elements until it finds one, if available
  *
  * @param DataObject $dataObject
  */
 public function getDefinitionFor(DataObject $dataObject)
 {
     if ($dataObject->hasExtension('WorkflowApplicable') || $dataObject->hasExtension('FileWorkflowApplicable')) {
         if ($dataObject->WorkflowDefinitionID) {
             return DataObject::get_by_id('WorkflowDefinition', $dataObject->WorkflowDefinitionID);
         }
         if ($dataObject->ParentID) {
             return $this->getDefinitionFor($dataObject->Parent());
         }
         if ($dataObject->hasMethod('workflowParent')) {
             $obj = $dataObject->workflowParent();
             if ($obj) {
                 return $this->getDefinitionFor($obj);
             }
         }
     }
     return null;
 }
 /**
  * 
  * Dynamically augments any $cacheableClass object with 
  * methods and properties of $model.
  * 
  * Warning: Uses PHP magic methods __get() and __set().
  * 
  * @param DataObject $model
  * @param string $cacheableClass
  * @return ViewableData $cacheable
  */
 public static function model2cacheable(DataObject $model, $cacheableClass = null)
 {
     if (!$cacheableClass) {
         $cacheableClass = "Cacheable" . $model->ClassName;
     }
     $cacheable = $cacheableClass::create();
     $cacheable_fields = $cacheable->get_cacheable_fields();
     foreach ($cacheable_fields as $field) {
         $cacheable->__set($field, $model->__get($field));
     }
     $cacheable_functions = $cacheable->get_cacheable_functions();
     foreach ($cacheable_functions as $function) {
         /*
          * Running tests inside a project with its own YML config for 
          * cacheable_fields and cacheable_functions will fail if we don't check first
          */
         if ($model->hasMethod($function)) {
             $cacheable->__set($function, $model->{$function}());
         }
     }
     return $cacheable;
 }
 /**
  * Save the results into the form
  * Calls function $record->onChange($items) before saving to the assummed 
  * Component set.
  */
 function saveInto(DataObject $record)
 {
     // Detect whether this field has actually been updated
     if ($this->value !== 'unchanged') {
         $fieldName = $this->name;
         $saveDest = $record->{$fieldName}();
         if (!$saveDest) {
             user_error("TreeMultiselectField::saveInto() Field '{$fieldName}' not found on {$record->class}.{$record->ID}", E_USER_ERROR);
         }
         if ($this->value) {
             $items = split(" *, *", trim($this->value));
         }
         // Allows you to modify the items on your object before save
         $funcName = "onChange{$fieldName}";
         if ($record->hasMethod($funcName)) {
             $result = $record->{$funcName}($items);
             if (!$result) {
                 return;
             }
         }
         $saveDest->setByIDList($items);
     }
 }
 /**
  * Gets a writer for a DataObject
  * 
  * If the field already has a value, a writer is created matching that 
  * identifier. Otherwise, a new writer is created based on either 
  * 
  * - The $type passed in 
  * - whether the $object class specifies a prefered storage type via 
  *   getEffectiveContentStore
  * - what the `defaultStore` is set to for the content service
  * 
  *
  * @param DataObject $object
  *				The object to get a writer for
  * @param String $field
  *				The field being written to 
  * @param String $type
  *				Explicitly state what the content store type will be
  * @return ContentWriter
  */
 public function getWriterFor(DataObject $object = null, $field = 'FilePointer', $type = null)
 {
     if ($object && $field && $object->hasField($field)) {
         $val = $object->{$field};
         if (strlen($val)) {
             $reader = $this->getReader($val);
             if ($reader && $reader->isReadable()) {
                 return $reader->getWriter();
             }
         }
     }
     if (!$type) {
         // specifically expecting to be handling File objects, but allows other
         // objects to play too
         if ($object && $object->hasMethod('getEffectiveContentStore')) {
             $type = $object->getEffectiveContentStore();
         } else {
             $type = $this->defaultStore;
         }
     }
     // looks like we're getting a writer with no underlying file (as yet)
     return $this->getWriter($type);
 }
 /**
  * Determines the validator to use for the edit form
  * @example 'getCMSValidator'
  *
  * @param DataObject $file File context to generate validator from
  * @return Validator Validator object
  */
 public function getFileEditValidator(DataObject $file)
 {
     // Empty validator
     if (empty($this->fileEditValidator)) {
         return null;
     }
     // Validator instance
     if ($this->fileEditValidator instanceof Validator) {
         return $this->fileEditValidator;
     }
     // Method to call on the given file
     if ($file->hasMethod($this->fileEditValidator)) {
         return $file->{$this->fileEditValidator}();
     }
     user_error("Invalid value for UploadField::fileEditValidator", E_USER_ERROR);
 }
Example #14
0
 /**
  * Mark all children of the given node that match the marking filter.
  *
  * @param DataObject $node              Parent node
  * @param mixed      $context
  * @param string     $childrenMethod    The name of the instance method to call to get the object's list of children
  * @param string     $numChildrenMethod The name of the instance method to call to count the object's children
  * @return DataList
  */
 public function markChildren($node, $context = null, $childrenMethod = "AllChildrenIncludingDeleted", $numChildrenMethod = "numChildren")
 {
     if ($node->hasMethod($childrenMethod)) {
         $children = $node->{$childrenMethod}($context);
     } else {
         user_error(sprintf("Can't find the method '%s' on class '%s' for getting tree children", $childrenMethod, get_class($node)), E_USER_ERROR);
     }
     $node->markExpanded();
     if ($children) {
         foreach ($children as $child) {
             $markingMatches = $this->markingFilterMatches($child);
             if ($markingMatches) {
                 // Mark a child node as unexpanded if it has children and has not already been expanded
                 if ($child->{$numChildrenMethod}() && !$child->isExpanded()) {
                     $child->markUnexpanded();
                 } else {
                     $child->markExpanded();
                 }
                 $this->markedNodes[$child->ID] = $child;
             }
         }
     }
     return $children;
 }
 /**
  * @param DataObject $obj
  * @param array $params
  * @param int|array $sort
  * @param int|array $limit
  * @param string $relationName
  * @return SQLQuery|boolean
  */
 protected function getObjectRelationQuery($obj, $params, $sort, $limit, $relationName)
 {
     if ($obj->hasMethod("{$relationName}Query")) {
         // @todo HACK Switch to ComponentSet->getQuery() once we implement it (and lazy loading)
         $query = $obj->{"{$relationName}Query"}(null, $sort, null, $limit);
         $relationClass = $obj->{"{$relationName}Class"}();
     } elseif ($relationClass = $obj->many_many($relationName)) {
         // many_many() returns different notation
         $relationClass = $relationClass[1];
         $query = $obj->getManyManyComponentsQuery($relationName);
     } elseif ($relationClass = $obj->has_many($relationName)) {
         $query = $obj->getComponentsQuery($relationName);
     } elseif ($relationClass = $obj->has_one($relationName)) {
         $query = null;
     } else {
         return false;
     }
     // get all results
     return $this->getSearchQuery($relationClass, $params, $sort, $limit, $query);
 }
 /**
  * Track a change to a DataObject
  * @return DataChangeRecord
  **/
 public function track(DataObject $changedObject, $type = 'Change')
 {
     $changes = $changedObject->getChangedFields(true, 2);
     if (count($changes)) {
         // remove any changes to ignored fields
         $ignored = $changedObject->hasMethod('getIgnoredFields') ? $changedObject->getIgnoredFields() : null;
         if ($ignored) {
             $changes = array_diff_key($changes, $ignored);
             foreach ($ignored as $ignore) {
                 if (isset($changes[$ignore])) {
                     unset($changes[$ignore]);
                 }
             }
         }
     }
     foreach (self::config()->field_blacklist as $key) {
         if (isset($changes[$key])) {
             unset($changes[$key]);
         }
     }
     if (empty($changes) && $type == 'Change') {
         return;
     }
     if ($type === 'Delete' && Versioned::get_reading_mode() === 'Stage.Live') {
         $type = 'Delete from Live';
     }
     $this->ChangeType = $type;
     $this->ClassType = $changedObject->ClassName;
     $this->ClassID = $changedObject->ID;
     // @TODO this will cause issue for objects without titles
     $this->ObjectTitle = $changedObject->Title;
     $this->Stage = Versioned::get_reading_mode();
     $before = array();
     $after = array();
     if ($type != 'Change' && $type != 'New') {
         // If we are (un)publishing we want to store the entire object
         $before = $type === 'Unpublish' ? $changedObject->toMap() : null;
         $after = $type === 'Publish' ? $changedObject->toMap() : null;
     } else {
         // Else we're tracking the changes to the object
         foreach ($changes as $field => $change) {
             if ($field == 'SecurityID') {
                 continue;
             }
             $before[$field] = $change['before'];
             $after[$field] = $change['after'];
         }
     }
     if ($this->Before && $this->Before !== 'null' && is_array($before)) {
         //merge the old array last to keep it's value as we want keep the earliest version of each field
         $this->Before = json_encode(array_replace(json_decode($this->Before, true), $before));
     } else {
         $this->Before = json_encode($before);
     }
     if ($this->After && $this->After !== 'null' && is_array($after)) {
         //merge the new array last to keep it's value as we want the newest version of each field
         $this->After = json_encode(array_replace($after, json_decode($this->After, true)));
     } else {
         $this->After = json_encode($after);
     }
     if (self::config()->save_request_vars) {
         foreach (self::config()->request_vars_blacklist as $key) {
             unset($_GET[$key]);
             unset($_POST[$key]);
         }
         $this->GetVars = isset($_GET) ? json_encode($_GET) : null;
         $this->PostVars = isset($_POST) ? json_encode($_POST) : null;
     }
     $this->ChangedByID = Member::currentUserID();
     if (Member::currentUserID() && Member::currentUser()) {
         $this->CurrentEmail = Member::currentUser()->Email;
     }
     if (isset($_SERVER['SERVER_NAME'])) {
         $protocol = 'http';
         $protocol = isset($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] == "on" ? 'https://' : 'http://';
         $this->CurrentURL = $protocol . $_SERVER["SERVER_NAME"] . ":" . $_SERVER["SERVER_PORT"] . $_SERVER["REQUEST_URI"];
     } else {
         if (Director::is_cli()) {
             $this->CurrentURL = 'CLI';
         } else {
             $this->CurrentURL = 'Could not determine current URL';
         }
     }
     $this->RemoteIP = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : (Director::is_cli() ? 'CLI' : 'Unknown remote addr');
     $this->Referer = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '';
     $this->Agent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '';
     $this->write();
     return $this;
 }
Example #17
0
	/**
	 * Handles saving the page. Needs to keep an eye on fields
	 * and options which have been removed / added 
	 *
	 * @param DataObject Record to Save it In
	 */
	function saveInto(DataObject $record) {
		$name = $this->name;
		$fieldSet = $record->$name();		        
		
		// @todo shouldn't we deal with customFormActions on that object?
		$record->EmailOnSubmit = isset($_REQUEST[$name]['EmailOnSubmit']) ? "1" : "0";
		$record->SubmitButtonText = isset($_REQUEST[$name]['SubmitButtonText']) ? $_REQUEST[$name]['SubmitButtonText'] : "";
		$record->ShowClearButton = isset($_REQUEST[$name]['ShowClearButton']) ? "1" : "0";
		
		// store the field IDs and delete the missing fields
		// alternatively, we could delete all the fields and re add them
		$missingFields = array();

		foreach($fieldSet as $existingField) {
			$missingFields[$existingField->ID] = $existingField;
		}

		if(isset($_REQUEST[$name]) && is_array($_REQUEST[$name])) {
			foreach($_REQUEST[$name] as $newEditableID => $newEditableData) {
				if(!is_numeric($newEditableID)) continue;
				
				// get it from the db
			  	$editable = DataObject::get_by_id('EditableFormField', $newEditableID); 
	
		  		// if it exists in the db update it
		  		if($editable) {
			
					// remove it from the removed fields list
					if(isset($missingFields[$editable->ID]) && isset($newEditableData) && is_array($newEditableData)) {
						unset($missingFields[$editable->ID]);
					}

					// set form id
					if($editable->ParentID == 0) {
						$editable->ParentID = $record->ID;
					}
					
					// save data
					$editable->populateFromPostData($newEditableData);
				}
		    }
		}

    	// remove the fields not saved
		if($this->canEdit()) {
    		foreach($missingFields as $removedField) {
    			if(is_numeric($removedField->ID)) {
					// check we can edit this
					$removedField->delete();
				}
			}
    	}

    	if($record->hasMethod('customFormSave')) {
			$record->customFormSave($_REQUEST[$name], $record);
		}	
		
		if($record->hasMethod('processNewFormFields')) {
			$record->processNewFormFields();
		}
	}
Example #18
0
 function testExtensionCanBeAppliedToDataObject()
 {
     $do = new DataObject();
     $mo = new DataExtensionTest_MyObject();
     $this->assertTrue($do->hasMethod('testMethodApplied'));
     $this->assertTrue($mo->hasMethod('testMethodApplied'));
     $this->assertEquals("hello world", $mo->testMethodApplied());
     $this->assertEquals("hello world", $do->testMethodApplied());
 }
 /**
  * @param  DataObject $target
  * @return array
  */
 public function getContextFields(DataObject $target)
 {
     $result = array();
     if (!$target) {
         return $result;
     }
     $fields = $target->inheritedDatabaseFields();
     foreach ($fields as $field => $fieldDesc) {
         $result[$field] = $target->{$field};
     }
     if ($target instanceof CMSPreviewable) {
         $result['CMSLink'] = $target->CMSEditLink();
     } else {
         if ($target->hasMethod('WorkflowLink')) {
             $result['CMSLink'] = $target->WorkflowLink();
         }
     }
     return $result;
 }
Example #20
0
 /**
  * @param DataObject $obj
  * @param array $params
  * @param int|array $sort
  * @param int|array $limit
  * @param string $relationName
  * @return SQLQuery|boolean
  */
 protected function getObjectRelationQuery($obj, $params, $sort, $limit, $relationName)
 {
     // The relation method will return a DataList, that getSearchQuery subsequently manipulates
     if ($obj->hasMethod($relationName)) {
         $query = $obj->{$relationName}();
         return $this->getSearchQuery($query->dataClass(), $params, $sort, $limit, $query);
     }
 }
 /**
  * Returns a DataObject relation's data
  * formatted and ready to embed.
  * 
  * @param  DataObject $record       The DataObject to get the data from
  * @param  string     $relationName The name of the relation
  * @return array|null               Formatted DataObject or RelationList ready to embed or null if nothing to embed
  */
 protected function getEmbedData(DataObject $record, $relationName)
 {
     if ($record->hasMethod($relationName)) {
         $relationData = $record->{$relationName}();
         if ($relationData instanceof RelationList) {
             return $this->formatDataList($relationData);
         } else {
             return $this->formatDataObject($relationData);
         }
     }
     return null;
 }
 /**
  * Pull out all the fields that should be indexed for a particular object
  *
  * This mapping is done to make it easier to
  *
  * @param DataObject $dataObject
  * @return array
  */
 protected function objectToFields($dataObject)
 {
     $ret = array();
     $fields = Config::inst()->get($dataObject->ClassName, 'db');
     $fields['Created'] = 'SS_Datetime';
     $fields['LastEdited'] = 'SS_Datetime';
     $ret['ClassName'] = array('Type' => 'Varchar', 'Value' => $dataObject->class);
     $ret['SS_ID'] = array('Type' => 'Int', 'Value' => $dataObject->ID);
     foreach ($fields as $name => $type) {
         if (preg_match('/^(\\w+)\\(/', $type, $match)) {
             $type = $match[1];
         }
         // Just index everything; the query can figure out what to exclude... !
         $value = $dataObject->{$name};
         if ($type == 'MultiValueField') {
             $value = $value->getValues();
         }
         $ret[$name] = array('Type' => $type, 'Value' => $value);
     }
     $rels = Config::inst()->get($dataObject->ClassName, 'has_one');
     if ($rels) {
         foreach (array_keys($rels) as $rel) {
             $ret["{$rel}ID"] = array('Type' => 'ForeignKey', 'Value' => $dataObject->{$rel . "ID"});
         }
     }
     if ($dataObject->hasMethod('additionalSolrValues')) {
         $extras = $dataObject->extend('additionalSolrValues');
         if ($extras && is_array($extras)) {
             foreach ($extras as $add) {
                 foreach ($add as $k => $v) {
                     $ret[$k] = array('Type' => $this->mapper->mapValueToType($k, $v), 'Value' => $v);
                 }
             }
         }
     }
     return $ret;
 }
 /**
  * Mark all children of the given node that match the marking filter.
  * @param DataObject $node Parent node.
  */
 public function markChildren($node, $context = null, $childrenMethod = "AllChildrenIncludingDeleted", $numChildrenMethod = "numChildren")
 {
     if ($node->hasMethod($childrenMethod)) {
         $children = $node->{$childrenMethod}($context);
     } else {
         user_error(sprintf("Can't find the method '%s' on class '%s' for getting tree children", $childrenMethod, get_class($this->owner)), E_USER_ERROR);
     }
     $node->markExpanded();
     if ($children) {
         foreach ($children as $child) {
             if (!$this->markingFilter || $this->markingFilterMatches($child)) {
                 if ($child->{$numChildrenMethod}()) {
                     $child->markUnexpanded();
                 } else {
                     $child->markExpanded();
                 }
                 $this->markedNodes[$child->ID] = $child;
             }
         }
     }
 }
Example #24
0
 /**
  * Loads the related record values into this field. UploadField can be uploaded
  * in one of three ways:
  * 
  *  - By passing in a list of file IDs in the $value parameter (an array with a single
  *    key 'Files', with the value being the actual array of IDs).
  *  - By passing in an explicit list of File objects in the $record parameter, and
  *    leaving $value blank.
  *  - By passing in a dataobject in the $record parameter, from which file objects
  *    will be extracting using the field name as the relation field.
  * 
  * Each of these methods will update both the items (list of File objects) and the 
  * field value (list of file ID values).
  * 
  * @param array $value Array of submitted form data, if submitting from a form
  * @param array|DataObject|SS_List $record Full source record, either as a DataObject,
  * SS_List of items, or an array of submitted form data
  * @return UploadField Self reference
  */
 public function setValue($value, $record = null)
 {
     // If we're not passed a value directly, we can attempt to infer the field
     // value from the second parameter by inspecting its relations
     $items = new ArrayList();
     // Determine format of presented data
     if (empty($value) && $record) {
         // If a record is given as a second parameter, but no submitted values,
         // then we should inspect this instead for the form values
         if ($record instanceof DataObject && $record->hasMethod($this->getName())) {
             // If given a dataobject use reflection to extract details
             $data = $record->{$this->getName()}();
             if ($data instanceof DataObject) {
                 // If has_one, add sole item to default list
                 $items->push($data);
             } elseif ($data instanceof SS_List) {
                 // For many_many and has_many relations we can use the relation list directly
                 $items = $data;
             }
         } elseif ($record instanceof SS_List) {
             // If directly passing a list then save the items directly
             $items = $record;
         }
     } elseif (!empty($value['Files'])) {
         // If value is given as an array (such as a posted form), extract File IDs from this
         $class = $this->getRelationAutosetClass();
         $items = DataObject::get($class)->byIDs($value['Files']);
     }
     // If javascript is disabled, direct file upload (non-html5 style) can
     // trigger a single or multiple file submission. Note that this may be
     // included in addition to re-submitted File IDs as above, so these
     // should be added to the list instead of operated on independently.
     if ($uploadedFiles = $this->extractUploadedFileData($value)) {
         foreach ($uploadedFiles as $tempFile) {
             $file = $this->saveTemporaryFile($tempFile, $error);
             if ($file) {
                 $items->add($file);
             } else {
                 throw new ValidationException($error);
             }
         }
     }
     // Filter items by what's allowed to be viewed
     $filteredItems = new ArrayList();
     $fileIDs = array();
     foreach ($items as $file) {
         if ($file->exists() && $file->canView()) {
             $filteredItems->push($file);
             $fileIDs[] = $file->ID;
         }
     }
     // Filter and cache updated item list
     $this->items = $filteredItems;
     // Same format as posted form values for this field. Also ensures that
     // $this->setValue($this->getValue()); is non-destructive
     $value = $fileIDs ? array('Files' => $fileIDs) : null;
     // Set value using parent
     return parent::setValue($value, $record);
 }
 /**
  * @param  DataObject $target
  * @return array
  */
 public function getContextFields(DataObject $target)
 {
     $fields = $target->summaryFields();
     $result = array();
     foreach ($fields as $field => $fieldDesc) {
         $result[$field] = $target->{$field};
     }
     if ($target instanceof SiteTree) {
         $result['CMSLink'] = singleton('CMSMain')->Link("show/{$target->ID}");
     } else {
         if ($target->hasMethod('WorkflowLink')) {
             $result['CMSLink'] = $target->WorkflowLink();
         }
     }
     return $result;
 }
 /**
  * @param GridField $gridField
  * @param DataObject $record
  * @param string $columnName
  *
  * @return string - the HTML for the column
  */
 public function getColumnContent($gridField, $record, $columnName)
 {
     $data = new ArrayData(array('Link' => $record->hasMethod('getExternalLink') ? $record->getExternalLink() : $record->ExternalLink, 'Text' => $record->hasMethod('getExternalLinkText') ? $record->getExternalLinkText() : 'External Link'));
     return $data->renderWith('GridFieldExternalLink');
 }
Example #27
0
 function saveInto(DataObject $record)
 {
     $name = $this->name;
     $fieldSet = $record->{$name}();
     $record->EmailTo = $_REQUEST[$name]['EmailTo'];
     $record->EmailOnSubmit = isset($_REQUEST[$name]['EmailOnSubmit']) ? "1" : "0";
     $record->SubmitButtonText = $_REQUEST[$name]['SubmitButtonText'];
     // store the field IDs and delete the missing fields
     // alternatively, we could delete all the fields and re add them
     $missingFields = array();
     foreach ($fieldSet as $existingField) {
         $missingFields[$existingField->ID] = $existingField;
     }
     // write the new fields to the database
     if ($_REQUEST[$name]) {
         foreach (array_keys($_REQUEST[$name]) as $newEditableID) {
             $newEditableData = $_REQUEST[$name][$newEditableID];
             // `ParentID`=0 is for the new page
             $editable = DataObject::get_one('EditableFormField', "(`ParentID`='{$record->ID}' OR `ParentID`=0) AND `EditableFormField`.`ID`='{$newEditableID}'");
             // check if we are updating an existing field
             if ($editable && isset($missingFields[$editable->ID])) {
                 unset($missingFields[$editable->ID]);
             }
             // create a new object
             // this should now be obsolete
             if (!$editable && !empty($newEditableData['Type']) && class_exists($newEditableData['Type'])) {
                 $editable = new $newEditableData['Type']();
                 $editable->ID = 0;
                 $editable->ParentID = $record->ID;
                 if (!is_subclass_of($editable, 'EditableFormField')) {
                     $editable = null;
                 }
             }
             if ($editable) {
                 if ($editable->ParentID == 0) {
                     $editable->ParentID = $record->ID;
                 }
                 $editable->populateFromPostData($newEditableData);
                 //$editable->write();
             }
         }
     }
     // remove the fields not saved
     foreach ($missingFields as $removedField) {
         if (is_numeric($removedField->ID)) {
             $removedField->delete();
         }
     }
     if ($record->hasMethod('customFormSave')) {
         $record->customFormSave($_REQUEST[$name], $record);
     }
     //$record->writeWithoutVersion();
     if ($record->hasMethod('processNewFormFields')) {
         $record->processNewFormFields();
     }
 }
Example #28
0
 /**
  * Mark all children of the given node that match the marking filter.
  * @param DataObject $node Parent node.
  * @return DataList
  */
 public function markChildren($node, $context = null, $childrenMethod = "AllChildrenIncludingDeleted", $numChildrenMethod = "numChildren")
 {
     if ($node->hasMethod($childrenMethod)) {
         $children = $node->{$childrenMethod}($context);
     } else {
         user_error(sprintf("Can't find the method '%s' on class '%s' for getting tree children", $childrenMethod, get_class($node)), E_USER_ERROR);
     }
     $node->markExpanded();
     if ($children) {
         foreach ($children as $child) {
             $markingMatches = $this->markingFilterMatches($child);
             // Filtered results should always show opened, since actual matches
             // might be hidden by non-matching parent nodes.
             if ($this->markingFilter && $markingMatches) {
                 $child->markOpened();
             }
             if (!$this->markingFilter || $markingMatches) {
                 if ($child->{$numChildrenMethod}()) {
                     $child->markUnexpanded();
                 } else {
                     $child->markExpanded();
                 }
                 $this->markedNodes[$child->ID] = $child;
             }
         }
     }
     return $children;
 }
	/**
	 * Returns all fields on the object which should be shown
	 * in the output. Can be customised through {@link self::setCustomFields()}.
	 *
	 * @todo Allow for custom getters on the processed object (currently filtered through inheritedDatabaseFields)
	 * @todo Field level permission checks
	 * 
	 * @param DataObject $obj
	 * @return array
	 */
	protected function getFieldsForObj($obj) {
		$dbFields = array();
		
		// if custom fields are specified, only select these
		if(is_array($this->customFields)) {
			foreach($this->customFields as $fieldName) {
				// @todo Possible security risk by making methods accessible - implement field-level security
				if($obj->hasField($fieldName) || $obj->hasMethod("get{$fieldName}")) $dbFields[$fieldName] = $fieldName; 
			}
		} else {
			// by default, all database fields are selected
			$dbFields = $obj->inheritedDatabaseFields();
		}

		if(is_array($this->customAddFields)) {
			foreach($this->customAddFields as $fieldName) {
				// @todo Possible security risk by making methods accessible - implement field-level security
				if($obj->hasField($fieldName) || $obj->hasMethod("get{$fieldName}")) $dbFields[$fieldName] = $fieldName; 
			}
		}
		
		// add default required fields
		$dbFields = array_merge($dbFields, array('ID'=>'Int'));
		
		// @todo Requires PHP 5.1+
		if(is_array($this->removeFields)) {
			$dbFields = array_diff_key($dbFields, array_combine($this->removeFields,$this->removeFields));
		}

		return $dbFields;
	}
 /**
  * @param DataObject $obj
  * @param array $params
  * @param int|array $sort
  * @param int|array $limit
  * @param string $relationName
  * @return SQLQuery|boolean
  */
 protected function getObjectRelationQuery($obj, $params, $sort, $limit, $relationName)
 {
     // The relation method will return a DataList, that getSearchQuery subsequently manipulates
     if ($obj->hasMethod($relationName)) {
         if ($relationClass = $obj->has_one($relationName)) {
             $joinField = $relationName . 'ID';
             $list = DataList::create($relationClass)->byIDs(array($obj->{$joinField}));
         } else {
             $list = $obj->{$relationName}();
         }
         $apiAccess = singleton($list->dataClass())->stat('api_access');
         if (!$apiAccess) {
             return false;
         }
         return $this->getSearchQuery($list->dataClass(), $params, $sort, $limit, $list);
     }
 }