Example #1
0
 /**
  * Builds an item edit form.  The arguments to getCMSFields() are the popupController and
  * popupFormName, however this is an experimental API and may change.
  * 
  * @todo In the future, we will probably need to come up with a tigher object representing a partially
  * complete controller with gaps for extra functionality.  This, for example, would be a better way
  * of letting Security/login put its log-in form inside a UI specified elsewhere.
  * 
  * @return Form 
  */
 public function ItemEditForm()
 {
     $list = $this->gridField->getList();
     if (empty($this->record)) {
         $controller = $this->getToplevelController();
         $noActionURL = $controller->removeAction($_REQUEST['url']);
         $controller->getResponse()->removeHeader('Location');
         //clear the existing redirect
         return $controller->redirect($noActionURL, 302);
     }
     $canView = $this->record->canView();
     $canEdit = $this->record->canEdit();
     $canDelete = $this->record->canDelete();
     $canCreate = $this->record->canCreate();
     if (!$canView) {
         $controller = $this->getToplevelController();
         // TODO More friendly error
         return $controller->httpError(403);
     }
     $actions = new FieldList();
     if ($this->record->ID !== 0) {
         if ($canEdit) {
             $actions->push(FormAction::create('doSave', _t('GridFieldDetailForm.Save', 'Save'))->setUseButtonTag(true)->addExtraClass('ss-ui-action-constructive')->setAttribute('data-icon', 'accept'));
         }
         if ($canDelete) {
             $actions->push(FormAction::create('doDelete', _t('GridFieldDetailForm.Delete', 'Delete'))->setUseButtonTag(true)->addExtraClass('ss-ui-action-destructive action-delete'));
         }
     } else {
         // adding new record
         //Change the Save label to 'Create'
         $actions->push(FormAction::create('doSave', _t('GridFieldDetailForm.Create', 'Create'))->setUseButtonTag(true)->addExtraClass('ss-ui-action-constructive')->setAttribute('data-icon', 'add'));
         // Add a Cancel link which is a button-like link and link back to one level up.
         $curmbs = $this->Breadcrumbs();
         if ($curmbs && $curmbs->count() >= 2) {
             $one_level_up = $curmbs->offsetGet($curmbs->count() - 2);
             $text = sprintf("<a class=\"%s\" href=\"%s\">%s</a>", "crumb ss-ui-button ss-ui-action-destructive cms-panel-link ui-corner-all", $one_level_up->Link, _t('GridFieldDetailForm.CancelBtn', 'Cancel'));
             $actions->push(new LiteralField('cancelbutton', $text));
         }
     }
     $fields = $this->component->getFields();
     if (!$fields) {
         $fields = $this->record->getCMSFields();
     }
     // If we are creating a new record in a has-many list, then
     // pre-populate the record's foreign key. Also disable the form field as
     // it has no effect.
     if ($list instanceof HasManyList) {
         $key = $list->getForeignKey();
         $id = $list->getForeignID();
         if (!$this->record->isInDB()) {
             $this->record->{$key} = $id;
         }
         if ($field = $fields->dataFieldByName($key)) {
             $fields->makeFieldReadonly($field);
         }
     }
     // Caution: API violation. Form expects a Controller, but we are giving it a RequestHandler instead.
     // Thanks to this however, we are able to nest GridFields, and also access the initial Controller by
     // dereferencing GridFieldDetailForm_ItemRequest->getController() multiple times. See getToplevelController
     // below.
     $form = new Form($this, 'ItemEditForm', $fields, $actions, $this->component->getValidator());
     $form->loadDataFrom($this->record, $this->record->ID == 0 ? Form::MERGE_IGNORE_FALSEISH : Form::MERGE_DEFAULT);
     if ($this->record->ID && !$canEdit) {
         // Restrict editing of existing records
         $form->makeReadonly();
         // Hack to re-enable delete button if user can delete
         if ($canDelete) {
             $form->Actions()->fieldByName('action_doDelete')->setReadonly(false);
         }
     } elseif (!$this->record->ID && !$canCreate) {
         // Restrict creation of new records
         $form->makeReadonly();
     }
     // Load many_many extraData for record.
     // Fields with the correct 'ManyMany' namespace need to be added manually through getCMSFields().
     if ($list instanceof ManyManyList) {
         $extraData = $list->getExtraData('', $this->record->ID);
         $form->loadDataFrom(array('ManyMany' => $extraData));
     }
     // TODO Coupling with CMS
     $toplevelController = $this->getToplevelController();
     if ($toplevelController && $toplevelController instanceof LeftAndMain) {
         // Always show with base template (full width, no other panels),
         // regardless of overloaded CMS controller templates.
         // TODO Allow customization, e.g. to display an edit form alongside a search form from the CMS controller
         $form->setTemplate('LeftAndMain_EditForm');
         $form->addExtraClass('cms-content cms-edit-form center');
         $form->setAttribute('data-pjax-fragment', 'CurrentForm Content');
         if ($form->Fields()->hasTabset()) {
             $form->Fields()->findOrMakeTab('Root')->setTemplate('CMSTabSet');
             $form->addExtraClass('cms-tabset');
         }
         $form->Backlink = $this->getBackLink();
     }
     $cb = $this->component->getItemEditFormCallback();
     if ($cb) {
         $cb($form, $this);
     }
     $this->extend("updateItemEditForm", $form);
     return $form;
 }
	/**
	 * Saves the data in this form field into a database record.
	 *
	 * @param DataObject $record The record being updated by the form
	 */
	public function saveInto(DataObject $record) {
		// Can't do has_many without a parent id
		if(!$record->isInDB()) {
			$record->write();
		}
		if(!$file_class = $this->getFileClass($record)) {
			return false;
		}
		if(isset($_REQUEST[$this->name]) && is_array($_REQUEST[$this->name])) {
			if($relation_name = $this->getForeignRelationName($record)) {
				// Null out all the existing relations and reset.
				$currentComponentSet = $record->{$this->name}();
				$currentComponentSet->removeAll();
				// Assign all the new relations (may have already existed)
				foreach($_REQUEST[$this->name] as $id) {
					if($file = DataObject::get_by_id($this->baseFileClass, $id)) {
						$new = ($file_class != $this->baseFileClass) ? $file->newClassInstance($file_class) : $file;
						$new->write();
						$currentComponentSet->add($new);
					}
				}
			}
		}		
	}
 /**
  * Saves the form data into a record. Nulls out all of the existing file relationships
  * and rebuilds them, in order to accommodate any deletions.
  *
  * @param DataObject $record The record associated with the parent form
  * 
  * @See Modified for pull request by Micah Sheets to add manymanysortable
  */
 public function saveInto(DataObject $record)
 {
     // Can't do has_many without a parent id
     if (!$record->isInDB()) {
         $record->write();
     }
     if (!($file_class = $this->getFileClass($record))) {
         return false;
     }
     // Null out all the existing relations and reset.
     $currentComponentSet = $record->{$this->name}();
     $currentComponentSet->removeAll();
     if (isset($_REQUEST[$this->name]) && is_array($_REQUEST[$this->name])) {
         if ($relation_name = $this->getForeignRelationName($record)) {
             // Assign all the new relations (may have already existed)
             $data = $_REQUEST;
             for ($count = 0; $count < count($data[$this->name]); ++$count) {
                 $id = $data[$this->name][$count];
                 $sort = $data['sort'][$count];
                 if ($file = DataObject::get_by_id("File", $id)) {
                     $new = $file_class != "File" ? $file->newClassInstance($file_class) : $file;
                     $new->write();
                     $currentComponentSet->add($new, array('ManyManySort' => $sort));
                 }
             }
         }
     }
 }
Example #4
0
 /**
  * Scaffolds the relation WidgetArea into the context CMSFields and configurates
  * the GridField.
  * 
  * @param DataObject $context Context to get Widget admin for
  * 
  * @return void
  *
  * @author Sebastian Diel <*****@*****.**>
  * @since 05.03.2014
  */
 public static function scaffold_widget_area_fields_for($context)
 {
     $fields = $context->WidgetArea()->scaffoldFormFields(array('includeRelations' => $context->isInDB(), 'tabbed' => false, 'ajaxSafe' => true));
     if ($context->isInDB()) {
         $widgetsField = $fields->dataFieldByName('Widgets');
         $widgetsFieldConfig = $widgetsField->getConfig();
         $widgetsFieldConfig->removeComponentsByType('GridFieldAddExistingAutocompleter');
         if (class_exists('GridFieldSortableRows')) {
             $widgetsFieldConfig->addComponent(new GridFieldSortableRows('Sort'));
         }
         $widgetsFieldConfig->getComponentByType('GridFieldDataColumns')->setDisplayFields(array('Title' => $context->fieldLabel('Title'), 'ClassName' => _t('WidgetSetWidget.TYPE')));
         // this is configured with a remove relation button by default which results in unaccessible widgets
         $widgetsFieldConfig->removeComponentsByType('GridFieldDeleteAction');
         // so we add a new one without a relation button
         $widgetsFieldConfig->addComponent(new GridFieldDeleteAction());
     }
     return $fields;
 }
 /**
  * Clone of DataObject::getCMSFields() with some additional SilverCart
  * related features.
  * <ul>
  *  <li>Restricted fields can be updated by DataExtension (updateRestrictCMSFields).</li>
  *  <li>Translation fields of DataObjects with SilverCart based translation model will be scaffolded.</li>
  * </ul>
  * 
  * @param DataObject $dataObject                     DataObject to get CMS fields for
  * @param string     $neighbourFieldOfLanguageFields Name of the field to insert language fields after or before
  * @param bool       $insertLangugeFieldsAfter       Determines whether to add language fields before or after the given neighbour field
  * @param bool       $tabbed                         Determines whether get tabbed fields or not
  * 
  * @return FieldList
  */
 public static function getCMSFields(DataObject $dataObject, $neighbourFieldOfLanguageFields = null, $insertLangugeFieldsAfter = true, $tabbed = true)
 {
     $params = array('includeRelations' => $dataObject->isInDB(), 'tabbed' => $tabbed, 'ajaxSafe' => true);
     $restrictFields = array();
     $dataObject->extend('updateRestrictCMSFields', $restrictFields);
     if (!empty($restrictFields)) {
         $params['restrictFields'] = $restrictFields;
     }
     $tabbedFields = self::scaffoldFormFields($dataObject, $params);
     if ($dataObject->has_extension($dataObject->class, 'SilvercartDataObjectMultilingualDecorator')) {
         $languageFields = SilvercartLanguageHelper::prepareCMSFields($dataObject->getLanguageClassName());
         foreach ($languageFields as $languageField) {
             if (!is_null($neighbourFieldOfLanguageFields)) {
                 if ($insertLangugeFieldsAfter) {
                     $tabbedFields->insertAfter($languageField, $neighbourFieldOfLanguageFields);
                     /*
                      * Change the name of the field the insert the next field
                      * Otherwise the sort order would be inverted
                      */
                     $neighbourFieldOfLanguageFields = $languageField->getName();
                 } else {
                     $tabbedFields->insertBefore($languageField, $neighbourFieldOfLanguageFields);
                 }
             } else {
                 $tabbedFields->addFieldToTab('Root.Main', $languageField);
             }
         }
     }
     $dataObject->extend('updateCMSFields', $tabbedFields);
     return $tabbedFields;
 }
 /**
  * Builds an item edit form.  The arguments to getCMSFields() are the popupController and
  * popupFormName, however this is an experimental API and may change.
  *
  * @todo In the future, we will probably need to come up with a tigher object representing a partially
  * complete controller with gaps for extra functionality.  This, for example, would be a better way
  * of letting Security/login put its log-in form inside a UI specified elsewhere.
  *
  * @return Form
  */
 public function ItemEditForm()
 {
     $list = $this->gridField->getList();
     if (empty($this->record)) {
         $controller = $this->getToplevelController();
         $url = $controller->getRequest()->getURL();
         $noActionURL = $controller->removeAction($url);
         $controller->getResponse()->removeHeader('Location');
         //clear the existing redirect
         return $controller->redirect($noActionURL, 302);
     }
     $canView = $this->record->canView();
     $canEdit = $this->record->canEdit();
     $canDelete = $this->record->canDelete();
     $canCreate = $this->record->canCreate();
     if (!$canView) {
         $controller = $this->getToplevelController();
         // TODO More friendly error
         return $controller->httpError(403);
     }
     // Build actions
     $actions = $this->getFormActions();
     // If we are creating a new record in a has-many list, then
     // pre-populate the record's foreign key.
     if ($list instanceof HasManyList && !$this->record->isInDB()) {
         $key = $list->getForeignKey();
         $id = $list->getForeignID();
         $this->record->{$key} = $id;
     }
     $fields = $this->component->getFields();
     if (!$fields) {
         $fields = $this->record->getCMSFields();
     }
     // If we are creating a new record in a has-many list, then
     // Disable the form field as it has no effect.
     if ($list instanceof HasManyList) {
         $key = $list->getForeignKey();
         if ($field = $fields->dataFieldByName($key)) {
             $fields->makeFieldReadonly($field);
         }
     }
     // Caution: API violation. Form expects a Controller, but we are giving it a RequestHandler instead.
     // Thanks to this however, we are able to nest GridFields, and also access the initial Controller by
     // dereferencing GridFieldDetailForm_ItemRequest->getController() multiple times. See getToplevelController
     // below.
     $form = new Form($this, 'ItemEditForm', $fields, $actions, $this->component->getValidator());
     $form->loadDataFrom($this->record, $this->record->ID == 0 ? Form::MERGE_IGNORE_FALSEISH : Form::MERGE_DEFAULT);
     if ($this->record->ID && !$canEdit) {
         // Restrict editing of existing records
         $form->makeReadonly();
         // Hack to re-enable delete button if user can delete
         if ($canDelete) {
             $form->Actions()->fieldByName('action_doDelete')->setReadonly(false);
         }
     } elseif (!$this->record->ID && !$canCreate) {
         // Restrict creation of new records
         $form->makeReadonly();
     }
     // Load many_many extraData for record.
     // Fields with the correct 'ManyMany' namespace need to be added manually through getCMSFields().
     if ($list instanceof ManyManyList) {
         $extraData = $list->getExtraData('', $this->record->ID);
         $form->loadDataFrom(array('ManyMany' => $extraData));
     }
     // TODO Coupling with CMS
     $toplevelController = $this->getToplevelController();
     if ($toplevelController && $toplevelController instanceof LeftAndMain) {
         // Always show with base template (full width, no other panels),
         // regardless of overloaded CMS controller templates.
         // TODO Allow customization, e.g. to display an edit form alongside a search form from the CMS controller
         $form->setTemplate('LeftAndMain_EditForm');
         $form->addExtraClass('cms-content cms-edit-form center');
         $form->setAttribute('data-pjax-fragment', 'CurrentForm Content');
         if ($form->Fields()->hasTabset()) {
             $form->Fields()->findOrMakeTab('Root')->setTemplate('CMSTabSet');
             $form->addExtraClass('cms-tabset');
         }
         $form->Backlink = $this->getBackLink();
     }
     $cb = $this->component->getItemEditFormCallback();
     if ($cb) {
         $cb($form, $this);
     }
     $this->extend("updateItemEditForm", $form);
     return $form;
 }