/**
  * @param DataObject $entity
  * @param             $association_name
  * @param QueryObject $query
  * @return bool|PersistentCollection
  * @throws Exception
  */
 public function getOne2ManyAssociation(DataObject $entity, $association_name, QueryObject $query = null)
 {
     if (is_null($query)) {
         $query = new QueryObject();
     }
     $child_class = $entity->has_many($association_name);
     if (!$child_class) {
         throw new Exception(sprintf("entity %s has not an one-to-many association called %s", get_class($entity), $association_name));
     }
     if ($entity->getComponents($association_name) instanceof UnsavedRelationList) {
         $query = new QueryObject();
     }
     $old = UnitOfWork::getInstance()->getCollection($entity, $child_class, $query, '1-to-many');
     if ($old) {
         return $old;
     }
     $component = $entity->getComponents($association_name, (string) $query, $query->getOrder(true));
     foreach ($query->getAlias(QueryAlias::INNER) as $specification) {
         $component = $component->innerJoin($specification->getTable(), $specification->getCondition());
     }
     foreach ($query->getAlias(QueryAlias::LEFT) as $specification) {
         $component = $component->innerJoin($specification->getTable(), $specification->getCondition());
     }
     return new PersistentCollection($entity, $component, $query, '1-to-many', $association_name);
 }
 public function __construct(DataObject $controller, $name, $title = null, $className = null, $source = array(), $addTitle = null, $defaultsProperties = array(), $form = null)
 {
     $hasOne = false;
     if (!$title) {
         $this->title = self::name_to_label($name);
     }
     if (!$className) {
         if (substr($name, -2) == 'ID') {
             $name = substr($name, 0, -2);
         }
         if (!($hasOne = $className = $controller->has_one($name)) && !($className = $controller->belongs_to($name)) && (($settings = $controller->has_many($name)) || ($settings = $controller->many_many($name)))) {
             if (is_array($settings)) {
                 $className = $settings[1];
             } else {
                 $className = $settings;
             }
             $this->fieldType = 'CheckboxSetField';
         }
         if (!$className) {
             trigger_error('Couldn\'t determine class type from field name "' . $name . '". Please define the class name.');
         }
         if ($hasOne) {
             $name .= 'ID';
         }
     } else {
         if ($rels = $controller->has_many() + $controller->many_many()) {
             foreach ($rels as $rel => $class) {
                 if ($class == $className || ClassInfo::is_subclass_of($class, $className)) {
                     $this->fieldType = 'CheckboxSetField';
                     break;
                 }
             }
         }
     }
     if (!class_exists($className)) {
         trigger_error($className . ' class doesn\'t exist');
     }
     $this->setDefaults($defaultsProperties);
     $this->className = $className;
     $this->controller = $controller;
     parent::__construct($name, $title, $source, null, $form);
 }
 /**
  * Save value to dataobject
  *
  * @see forms/CheckboxSetField::saveInto()
  */
 public function saveInto(DataObject $record)
 {
     $fieldName = $this->name;
     // TODO - SiteTree admin seems to serialise value, whilst modeladmin doesn't
     // this explodes the serialised string, but there is probably a more elegant solution
     $valueArray = isset($this->value[0]) && strpos($this->value[0], ',') ? explode(',', $this->value[0]) : $this->value;
     if ($fieldName && ($record->has_many($fieldName) || $record->many_many($fieldName))) {
         // Set related records
         $record->{$fieldName}()->setByIDList($valueArray);
     } else {
         $record->{$fieldName} = implode(', ', $valueArray);
     }
 }
 /**
  * Constructor
  * 
  * @param DataObject $object The object that has_many somethings that we're calculating the aggregate for 
  * @param string $relationship The name of the relationship
  * @param string $filter (optional) An SQL filter to apply to the relationship rows before calculating the
  *                       aggregate
  */
 public function __construct($object, $relationship, $filter = '')
 {
     $this->object = $object;
     $this->relationship = $relationship;
     $this->has_many = $object->has_many($relationship);
     $this->many_many = $object->many_many($relationship);
     if (!$this->has_many && !$this->many_many) {
         user_error("Could not find relationship {$relationship} on object class {$object->class} in" . " Aggregate Relationship", E_USER_ERROR);
     }
     parent::__construct($this->has_many ? $this->has_many : $this->many_many[1], $filter);
 }
	/**
	 * Gets the foreign key from the child File class that relates to the $has_many or $many_many
	 * on the parent record
	 *
	 * @param DataObject $record The record to search
	 * @return string
	 */
	public function getForeignRelationName(DataObject $record) {
		
		if ($many_info = $record->many_many($this->name)) {
			// return parent field
			return $many_info[2];
		} elseif ($file_class = $record->has_many($this->name)) {
			$class = $record->class;
			$relation_name = false;
			while($class != "DataObject") {
				if($relation_name = singleton($file_class)->getReverseAssociation($class)) {
					break;
				}
				$class = get_parent_class($class);					
			}
			if(!$relation_name) {
				user_error("Could not find has_one or belongs many_many relation ship on $file_class", E_USER_ERROR);
			}

			return $relation_name .= "ID";
		}
		return false;
	}
	/**
	 * Gets the form fields as defined through the metadata
	 * on {@link $obj} and the custom parameters passed to FormScaffolder.
	 * Depending on those parameters, the fields can be used in ajax-context,
	 * contain {@link TabSet}s etc.
	 * 
	 * @return FieldSet
	 */
	public function getFieldSet() {
		$fields = new FieldSet();
		
		// tabbed or untabbed
		if($this->tabbed) {
			$fields->push(new TabSet("Root", $mainTab = new Tab("Main")));
			$mainTab->setTitle(_t('SiteTree.TABMAIN', "Main"));
		}
		
		// add database fields
		foreach($this->obj->db() as $fieldName => $fieldType) {
			if($this->restrictFields && !in_array($fieldName, $this->restrictFields)) continue;
			
			// @todo Pass localized title
			if($this->fieldClasses && isset($this->fieldClasses[$fieldName])) {
				$fieldClass = $this->fieldClasses[$fieldName];
				$fieldObject = new $fieldClass($fieldName);
			} else {
				$fieldObject = $this->obj->dbObject($fieldName)->scaffoldFormField(null, $this->getParamsArray());
			}
			$fieldObject->setTitle($this->obj->fieldLabel($fieldName));
			if($this->tabbed) {
				$fields->addFieldToTab("Root.Main", $fieldObject);
			} else {
				$fields->push($fieldObject);
			}
		}
		
		// add has_one relation fields
		if($this->obj->has_one()) {
			foreach($this->obj->has_one() as $relationship => $component) {
				if($this->restrictFields && !in_array($relationship, $this->restrictFields)) continue;
				$hasOneField = $this->obj->dbObject("{$relationship}ID")->scaffoldFormField(null, $this->getParamsArray());
				$hasOneField->setTitle($this->obj->fieldLabel($relationship));
				if($this->tabbed) {
					$fields->addFieldToTab("Root.Main", $hasOneField);
				} else {
					$fields->push($hasOneField);
				}
			}
		}
		
		// only add relational fields if an ID is present
		if($this->obj->ID) {
			// add has_many relation fields
			if($this->obj->has_many() && ($this->includeRelations === true || isset($this->includeRelations['has_many']))) {
				foreach($this->obj->has_many() as $relationship => $component) {
					if($this->tabbed) {
						$relationTab = $fields->findOrMakeTab(
							"Root.$relationship", 
							$this->obj->fieldLabel($relationship)
						);
					}
					$relationshipFields = singleton($component)->summaryFields();
					$foreignKey = $this->obj->getComponentJoinField($relationship);
					$ctf = new ComplexTableField(
						$this,
						$relationship,
						$component,
						$relationshipFields,
						"getCMSFields", 
						"$foreignKey = " . $this->obj->ID
					);
					$ctf->setPermissions(TableListField::permissions_for_object($component));
					if($this->tabbed) {
						$fields->addFieldToTab("Root.$relationship", $ctf);
					} else {
						$fields->push($ctf);
					}
				}
			}

			if($this->obj->many_many() && ($this->includeRelations === true || isset($this->includeRelations['many_many']))) {
				foreach($this->obj->many_many() as $relationship => $component) {
					if($this->tabbed) {
						$relationTab = $fields->findOrMakeTab(
							"Root.$relationship", 
							$this->obj->fieldLabel($relationship)
						);
					}

					$relationshipFields = singleton($component)->summaryFields();
					$filterWhere = $this->obj->getManyManyFilter($relationship, $component);
					$filterJoin = $this->obj->getManyManyJoin($relationship, $component);
					$ctf =  new ComplexTableField(
						$this,
						$relationship,
						$component,
						$relationshipFields,
						"getCMSFields", 
						$filterWhere,
						'', 
						$filterJoin
					);
					$ctf->setPermissions(TableListField::permissions_for_object($component));
					$ctf->popupClass = "ScaffoldingComplexTableField_Popup";
					if($this->tabbed) {
						$fields->addFieldToTab("Root.$relationship", $ctf);
					} else {
						$fields->push($ctf);
					}
				}
			}
		}
		
		return $fields;
	}
 /**
  * Save the current value of this CheckboxSetField into a DataObject.
  * If the field it is saving to is a has_many or many_many relationship,
  * it is saved by setByIDList(), otherwise it creates a comma separated
  * list for a standard DB text/varchar field.
  *
  * @param DataObject $record The record to save into
  */
 function saveInto(DataObject $record)
 {
     $fieldname = $this->name;
     if ($fieldname && $record && ($record->has_many($fieldname) || $record->many_many($fieldname))) {
         $idList = array();
         if ($this->value) {
             foreach ($this->value as $id => $bool) {
                 if ($bool) {
                     $idList[] = $id;
                 }
             }
         }
         $record->{$fieldname}()->setByIDList($idList);
     } elseif ($fieldname && $record) {
         if ($this->value) {
             $this->value = str_replace(',', '{comma}', $this->value);
             $record->{$fieldname} = implode(",", $this->value);
         } else {
             $record->{$fieldname} = '';
         }
     }
 }
 /**
  * @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);
 }
 /** 
  * Saves the Dataobjects contained in the field
  */
 function saveInto(DataObject $record)
 {
     // CMS sometimes tries to set the value to one.
     if (is_array($this->value)) {
         $newFields = array();
         // Sort into proper array
         $value = ArrayLib::invert($this->value);
         $dataObjects = $this->sortData($value, $record->ID);
         // New fields are nested in their own sub-array, and need to be sorted separately
         if (isset($dataObjects['new']) && $dataObjects['new']) {
             $newFields = $this->sortData($dataObjects['new'], $record->ID);
         }
         // Update existing fields
         // @todo Should this be in an else{} statement?
         $savedObjIds = $this->saveData($dataObjects, $this->editExisting);
         // Save newly added record
         if ($savedObjIds || $newFields) {
             $savedObjIds = $this->saveData($newFields, false);
         }
         // Optionally save the newly created records into a relationship
         // on $record. This assumes the name of this formfield instance
         // is set to a relationship name on $record.
         if ($this->relationAutoSetting) {
             $relationName = $this->Name();
             if ($record->has_many($relationName) || $record->many_many($relationName)) {
                 if ($savedObjIds) {
                     foreach ($savedObjIds as $id => $status) {
                         $record->{$relationName}()->add($id);
                     }
                 }
             }
         }
         // Update the internal source items cache
         $this->value = null;
         $items = $this->sourceItems();
         FormResponse::update_dom_id($this->id(), $this->FieldHolder());
     }
 }
Example #10
0
 /**
  * Update the permission set associated with $record DataObject
  *
  * @param DataObject $record
  */
 function saveInto(DataObject $record)
 {
     $fieldname = $this->name;
     $managedClass = $this->managedClass;
     // remove all permissions and re-add them afterwards
     $permissions = $record->{$fieldname}();
     foreach ($permissions as $permission) {
         $permission->delete();
     }
     if ($fieldname && $record && ($record->has_many($fieldname) || $record->many_many($fieldname))) {
         $idList = array();
         if ($this->value) {
             foreach ($this->value as $id => $bool) {
                 if ($bool) {
                     $perm = new $managedClass();
                     $perm->{$this->filterField} = $record->ID;
                     $perm->Code = $id;
                     $perm->write();
                 }
             }
         }
     }
 }
 /**
  * Gets the class of the file being managed. Used in case the relation
  * is cast as a subclass of File.
  *
  * @param DataObject $record
  * @return string|bool
  */
 public function getFileClass(DataObject $record)
 {
     if (!($file_class = $record->has_many($this->name))) {
         if (!($many_class = $record->many_many($this->name))) {
             return false;
         }
         // set child class.
         $file_class = $many_class[1];
     }
     return $file_class;
 }
 function saveInto(DataObject $record)
 {
     $fieldname = $this->name;
     $value = ArrayLib::invert($this->value);
     if ($fieldname && $record && ($record->has_many($fieldname) || $record->many_many($fieldname))) {
         $idList = array();
         if ($value) {
             foreach ($value['Value'] as $id => $bool) {
                 if ($bool) {
                     $idList[] = $id;
                 }
             }
         }
         $record->{$fieldname}()->setByIDList($idList);
     } elseif ($fieldname && $record) {
         if ($value) {
             if (is_array($value)) {
                 foreach ($value as $k => $items) {
                     if (is_array($items)) {
                         foreach ($items as $key => $val) {
                             if (!$val) {
                                 unset($value[$k][$key]);
                             } else {
                                 if ($k == 'Value') {
                                     $value[$k][$key] = str_replace(", ", "{comma}", $val);
                                 }
                             }
                         }
                     }
                 }
             }
             foreach ($value as $k => $v) {
                 if ($k == 'Value') {
                     $record->{$fieldname} = implode(",", $v);
                 } else {
                     $record->{$k} = Convert::array2json($v);
                 }
             }
         } else {
             $record->{$fieldname} = '';
         }
     }
 }
 /**
  * Gets the form fields as defined through the metadata
  * on {@link $obj} and the custom parameters passed to FormScaffolder.
  * Depending on those parameters, the fields can be used in ajax-context,
  * contain {@link TabSet}s etc.
  *
  * @return FieldList
  */
 public function getFieldList()
 {
     $fields = new FieldList();
     // tabbed or untabbed
     if ($this->tabbed) {
         $fields->push(new TabSet("Root", $mainTab = new Tab("Main")));
         $mainTab->setTitle(_t('SiteTree.TABMAIN', "Main"));
     }
     // add database fields
     foreach ($this->obj->db() as $fieldName => $fieldType) {
         if ($this->restrictFields && !in_array($fieldName, $this->restrictFields)) {
             continue;
         }
         // @todo Pass localized title
         if ($this->fieldClasses && isset($this->fieldClasses[$fieldName])) {
             $fieldClass = $this->fieldClasses[$fieldName];
             $fieldObject = new $fieldClass($fieldName);
         } else {
             $fieldObject = $this->obj->dbObject($fieldName)->scaffoldFormField(null, $this->getParamsArray());
         }
         $fieldObject->setTitle($this->obj->fieldLabel($fieldName));
         if ($this->tabbed) {
             $fields->addFieldToTab("Root.Main", $fieldObject);
         } else {
             $fields->push($fieldObject);
         }
     }
     // add has_one relation fields
     if ($this->obj->has_one()) {
         foreach ($this->obj->has_one() as $relationship => $component) {
             if ($this->restrictFields && !in_array($relationship, $this->restrictFields)) {
                 continue;
             }
             $fieldName = $component === 'DataObject' ? $relationship : "{$relationship}ID";
             if ($this->fieldClasses && isset($this->fieldClasses[$fieldName])) {
                 $fieldClass = $this->fieldClasses[$fieldName];
                 $hasOneField = new $fieldClass($fieldName);
             } else {
                 $hasOneField = $this->obj->dbObject($fieldName)->scaffoldFormField(null, $this->getParamsArray());
             }
             if (empty($hasOneField)) {
                 continue;
             }
             // Allow fields to opt out of scaffolding
             $hasOneField->setTitle($this->obj->fieldLabel($relationship));
             if ($this->tabbed) {
                 $fields->addFieldToTab("Root.Main", $hasOneField);
             } else {
                 $fields->push($hasOneField);
             }
         }
     }
     // only add relational fields if an ID is present
     if ($this->obj->ID) {
         // add has_many relation fields
         if ($this->obj->has_many() && ($this->includeRelations === true || isset($this->includeRelations['has_many']))) {
             foreach ($this->obj->has_many() as $relationship => $component) {
                 if ($this->tabbed) {
                     $relationTab = $fields->findOrMakeTab("Root.{$relationship}", $this->obj->fieldLabel($relationship));
                 }
                 $fieldClass = isset($this->fieldClasses[$relationship]) ? $this->fieldClasses[$relationship] : 'GridField';
                 $grid = Object::create($fieldClass, $relationship, $this->obj->fieldLabel($relationship), $this->obj->{$relationship}(), GridFieldConfig_RelationEditor::create());
                 if ($this->tabbed) {
                     $fields->addFieldToTab("Root.{$relationship}", $grid);
                 } else {
                     $fields->push($grid);
                 }
             }
         }
         if ($this->obj->many_many() && ($this->includeRelations === true || isset($this->includeRelations['many_many']))) {
             foreach ($this->obj->many_many() as $relationship => $component) {
                 if ($this->tabbed) {
                     $relationTab = $fields->findOrMakeTab("Root.{$relationship}", $this->obj->fieldLabel($relationship));
                 }
                 $fieldClass = isset($this->fieldClasses[$relationship]) ? $this->fieldClasses[$relationship] : 'GridField';
                 $grid = Object::create($fieldClass, $relationship, $this->obj->fieldLabel($relationship), $this->obj->{$relationship}(), GridFieldConfig_RelationEditor::create());
                 if ($this->tabbed) {
                     $fields->addFieldToTab("Root.{$relationship}", $grid);
                 } else {
                     $fields->push($grid);
                 }
             }
         }
     }
     return $fields;
 }
Example #14
0
 /**
  * @desc 
  */
 function saveInto(DataObject $record)
 {
     $fieldname = $this->name;
     if ($fieldname && $record && ($record->has_many($fieldname) || $record->many_many($fieldname))) {
         $record->{$fieldname}()->setByIDList($this->value);
     } else {
         if ($fieldname && $record && $record->hasField($fieldname)) {
             if ($this->value) {
                 $this->value = str_replace(",", "{comma}", $this->value);
                 $record->{$fieldname} = implode(",", $this->value);
             } else {
                 $record->{$fieldname} = '';
             }
         }
     }
 }
 /**
  * Update the permission set associated with $record DataObject
  *
  * @param DataObject $record
  */
 function saveInto(DataObject $record)
 {
     $fieldname = $this->name;
     $managedClass = $this->managedClass;
     // Remove all "privileged" permissions if the currently logged-in user is not an admin
     if (!Permission::check('ADMIN')) {
         foreach ($this->value as $id => $bool) {
             if (in_array($id, Permission::$privileged_permissions)) {
                 unset($this->value[$id]);
             }
         }
     }
     // remove all permissions and re-add them afterwards
     $permissions = $record->{$fieldname}();
     foreach ($permissions as $permission) {
         $permission->delete();
     }
     if ($fieldname && $record && ($record->has_many($fieldname) || $record->many_many($fieldname))) {
         $idList = array();
         if ($this->value) {
             foreach ($this->value as $id => $bool) {
                 if ($bool) {
                     $perm = new $managedClass();
                     $perm->{$this->filterField} = $record->ID;
                     $perm->Code = $id;
                     $perm->write();
                 }
             }
         }
     }
 }