diff --git a/code/GridFieldEditableCells.php b/code/GridFieldEditableCells.php
index dd6ea72..e759d01 100644
--- a/code/GridFieldEditableCells.php
+++ b/code/GridFieldEditableCells.php
@@ -1,150 +1,160 @@
fields = $fields;
-
- $columns = array();
- foreach($this->fields as $field) $columns[] = $field->getName();
- $this->columns = $columns;
- }
-
- /**
- * Add extra fields to the column list
- *
- * @param GridField $gridField
- * @param array - List reference of all column names.
- */
- public function augmentColumns($gridField, &$columns) {
-
- // remove columns handled by GridFieldEditableCells from GridFieldDataColumns
- // @FIXME: if _all_ columns get removed from GridFieldDataColumns infact none gets removed
- $datacolumnscomponent = $gridField->getConfig()->getComponentByType('GridFieldDataColumns');
- $datacolumns = $datacolumnscomponent->getDisplayFields($gridField);
- $datacolumns = array_diff($datacolumns, $this->columns);
- $datacolumnscomponent->setDisplayFields($datacolumns);
-
- foreach($this->columns as $name) {
- if(!in_array($name, $columns)) {
- if(($pos = array_search('Actions', $columns)) === false) {
- $columns[] = $name;
- } else {
- array_splice($columns, $pos, $pos * -1, $name);
- }
- }
- }
- }
-
- /**
- * List of handled columns
- *
- * @param GridField $gridField
- * @return array
- */
- public function getColumnsHandled($gridField) {
-
- return $this->columns;
- }
-
- /**
- * Set titles for the column header
- *
- * @param GridField $gridField
- * @param string $columnName
- * @return array - Map of arbitrary metadata identifiers to their values.
- */
- public function getColumnMetadata($gridField, $columnName) {
-
- return array('title' => $columnName);
- }
-
- /**
- * Return a formfield for the extra field column or an edit button for the actions column
- *
- * @param GridField $gridField
- * @param DataObject $record - Record displayed in this row
- * @param string $columnName
- * @return string - HTML for the column. Return NULL to skip.
- */
- public function getColumnContent($gridField, $record, $columnName) {
-
- Requirements::javascript('GridFieldAddOns/javascript/GridFieldEditableCells.js');
- Requirements::css('GridFieldAddOns/css/GridFieldEditableCells.css');
-
- $name = "{$gridField->Name}_EditableCell[{$record->ID}][{$columnName}]";
- $value = $record->has_one($columnName) ? $record->{$columnName . 'ID'} : $record->$columnName;
- $field = clone($this->fields->fieldByName($columnName));
- $field->setName($name);
- $field->setValue($value);
-
- return $field->Field();
- }
-
- /**
- * Generate HTML attributes for each individual cells as selectors for CSS and JS
- *
- * @param GridField $gridField
- * @param DataObject $record displayed in this row
- * @param string $columnName
- * @return array
- */
- public function getColumnAttributes($gridField, $record, $columnName) {
-
- return array(
- "data-gridfield-editable-cell-column" => $columnName,
- "data-gridfield-editable-cell-dirty" => 0,
- );
- }
-
- /**
- * Return URLs to be handled by this grid field, in an array the same form as $url_handlers.
- * Handler methods will be called on the component, rather than the grid field.
- */
- public function getURLHandlers($gridField) {
- return array(
- 'savecomponent/$ID' => 'savecomponent',
- );
- }
-
- public function savecomponent($gridField, $request) {
-
- $data = $request->postVar($gridField->getName() . '_EditableCell');
- foreach($data as $id => $params) {
- $record = $gridField->getList()->byId((int)$id);
- if(!$record) return json_encode(array('type' => 'error', 'message' => 'Bad request'));
- if(!$record->canEdit()) return json_encode(array('type' => 'error', 'message' => 'Permission denied'));
- $add = array();
- foreach($params as $key => $val) {
- $val = Convert::raw2sql($val);
- if($record->hasDatabaseField($key)) {
- $record->$key = $val;
- } else if($record->has_one($key)) {
- $col = $key . 'ID';
- $record->$col = $val;
- } else if($gridField->getList() instanceof ManyManyList) {
- $extradata = $gridField->getList()->getExtraData($gridField->getName(), $record->ID);
- if(array_key_exists($key, $extradata)) $add[$key] = $val;
- }
- }
- if($record->isChanged()) {
- try {
- $record->write(true);
- return json_encode(array('type' => 'good', 'message' => 'Record saved'));
- } catch(ValidationException $e) {
- return json_encode(array('type' => 'bad', 'message' => $e->getMessage()));
- }
- } else if(count($add)) {
- $gridField->getList()->add($record, $add);
- return json_encode(array('type' => 'good', 'message' => 'Relation updated'));
- } else {
- return json_encode(array('type' => 'good', 'message' => 'Nothing chnaged'));
- }
-
- }
- }
-
-}
\ No newline at end of file
+class GridFieldEditableCells implements GridField_ColumnProvider, GridField_URLHandler
+{
+
+ protected $fields;
+ protected $columns;
+
+ public function __construct(FieldList $fields)
+ {
+ $this->fields = $fields;
+
+ $columns = array();
+ foreach ($this->fields as $field) {
+ $columns[] = $field->getName();
+ }
+ $this->columns = $columns;
+ }
+
+ /**
+ * Add extra fields to the column list
+ *
+ * @param GridField $gridField
+ * @param array - List reference of all column names.
+ */
+ public function augmentColumns($gridField, &$columns)
+ {
+
+ // remove columns handled by GridFieldEditableCells from GridFieldDataColumns
+ // @FIXME: if _all_ columns get removed from GridFieldDataColumns infact none gets removed
+ $datacolumnscomponent = $gridField->getConfig()->getComponentByType('GridFieldDataColumns');
+ $datacolumns = $datacolumnscomponent->getDisplayFields($gridField);
+ $datacolumns = array_diff($datacolumns, $this->columns);
+ $datacolumnscomponent->setDisplayFields($datacolumns);
+
+ foreach ($this->columns as $name) {
+ if (!in_array($name, $columns)) {
+ if (($pos = array_search('Actions', $columns)) === false) {
+ $columns[] = $name;
+ } else {
+ array_splice($columns, $pos, $pos * -1, $name);
+ }
+ }
+ }
+ }
+
+ /**
+ * List of handled columns
+ *
+ * @param GridField $gridField
+ * @return array
+ */
+ public function getColumnsHandled($gridField)
+ {
+ return $this->columns;
+ }
+
+ /**
+ * Set titles for the column header
+ *
+ * @param GridField $gridField
+ * @param string $columnName
+ * @return array - Map of arbitrary metadata identifiers to their values.
+ */
+ public function getColumnMetadata($gridField, $columnName)
+ {
+ return array('title' => $columnName);
+ }
+
+ /**
+ * Return a formfield for the extra field column or an edit button for the actions column
+ *
+ * @param GridField $gridField
+ * @param DataObject $record - Record displayed in this row
+ * @param string $columnName
+ * @return string - HTML for the column. Return NULL to skip.
+ */
+ public function getColumnContent($gridField, $record, $columnName)
+ {
+ Requirements::javascript('GridFieldAddOns/javascript/GridFieldEditableCells.js');
+ Requirements::css('GridFieldAddOns/css/GridFieldEditableCells.css');
+
+ $name = "{$gridField->Name}_EditableCell[{$record->ID}][{$columnName}]";
+ $value = $record->has_one($columnName) ? $record->{$columnName . 'ID'} : $record->$columnName;
+ $field = clone($this->fields->fieldByName($columnName));
+ $field->setName($name);
+ $field->setValue($value);
+
+ return $field->Field();
+ }
+
+ /**
+ * Generate HTML attributes for each individual cells as selectors for CSS and JS
+ *
+ * @param GridField $gridField
+ * @param DataObject $record displayed in this row
+ * @param string $columnName
+ * @return array
+ */
+ public function getColumnAttributes($gridField, $record, $columnName)
+ {
+ return array(
+ "data-gridfield-editable-cell-column" => $columnName,
+ "data-gridfield-editable-cell-dirty" => 0,
+ );
+ }
+
+ /**
+ * Return URLs to be handled by this grid field, in an array the same form as $url_handlers.
+ * Handler methods will be called on the component, rather than the grid field.
+ */
+ public function getURLHandlers($gridField)
+ {
+ return array(
+ 'savecomponent/$ID' => 'savecomponent',
+ );
+ }
+
+ public function savecomponent($gridField, $request)
+ {
+ $data = $request->postVar($gridField->getName() . '_EditableCell');
+ foreach ($data as $id => $params) {
+ $record = $gridField->getList()->byId((int)$id);
+ if (!$record) {
+ return json_encode(array('type' => 'error', 'message' => 'Bad request'));
+ }
+ if (!$record->canEdit()) {
+ return json_encode(array('type' => 'error', 'message' => 'Permission denied'));
+ }
+ $add = array();
+ foreach ($params as $key => $val) {
+ $val = Convert::raw2sql($val);
+ if ($record->hasDatabaseField($key)) {
+ $record->$key = $val;
+ } elseif ($record->has_one($key)) {
+ $col = $key . 'ID';
+ $record->$col = $val;
+ } elseif ($gridField->getList() instanceof ManyManyList) {
+ $extradata = $gridField->getList()->getExtraData($gridField->getName(), $record->ID);
+ if (array_key_exists($key, $extradata)) {
+ $add[$key] = $val;
+ }
+ }
+ }
+ if ($record->isChanged()) {
+ try {
+ $record->write(true);
+ return json_encode(array('type' => 'good', 'message' => 'Record saved'));
+ } catch (ValidationException $e) {
+ return json_encode(array('type' => 'bad', 'message' => $e->getMessage()));
+ }
+ } elseif (count($add)) {
+ $gridField->getList()->add($record, $add);
+ return json_encode(array('type' => 'good', 'message' => 'Relation updated'));
+ } else {
+ return json_encode(array('type' => 'good', 'message' => 'Nothing chnaged'));
+ }
+ }
+ }
+}
diff --git a/code/GridFieldExpandableForm.php b/code/GridFieldExpandableForm.php
index 3b778a7..b55932a 100644
--- a/code/GridFieldExpandableForm.php
+++ b/code/GridFieldExpandableForm.php
@@ -1,175 +1,183 @@
formorfields = $formorfields;
+ }
- $this->formorfields = $formorfields;
- }
+ public function getURLHandlers($gridField)
+ {
+ return array(
+ 'expand/$ID' => 'handleItem',
+ );
+ }
- public function getURLHandlers($gridField) {
- return array(
- 'expand/$ID' => 'handleItem',
- );
- }
+ public function handleItem($gridField, $request)
+ {
+ $controller = $gridField->getForm()->Controller();
- public function handleItem($gridField, $request) {
+ $record = $gridField->getList()->byId($request->param("ID"));
- $controller = $gridField->getForm()->Controller();
+ $handler = Object::create('GridFieldExpandableForm_ItemRequest', $gridField, $this, $record, $controller, 'DetailForm', $this->formorfields);
- $record = $gridField->getList()->byId($request->param("ID"));
+ return $handler->handleRequest($request, DataModel::inst());
+ }
- $handler = Object::create('GridFieldExpandableForm_ItemRequest', $gridField, $this, $record, $controller, 'DetailForm', $this->formorfields);
+ public function getHTMLFragments($gridField)
+ {
+ Requirements::javascript(FRAMEWORK_DIR . '/thirdparty/jquery-ui/jquery-ui.js');
+ Requirements::javascript('GridFieldAddOns/javascript/GridFieldExpandableForm.js');
+ Requirements::css('GridFieldAddOns/css/GridFieldExpandableForm.css');
- return $handler->handleRequest($request, DataModel::inst());
- }
-
- public function getHTMLFragments($gridField) {
-
- Requirements::javascript(FRAMEWORK_DIR . '/thirdparty/jquery-ui/jquery-ui.js');
- Requirements::javascript('GridFieldAddOns/javascript/GridFieldExpandableForm.js');
- Requirements::css('GridFieldAddOns/css/GridFieldExpandableForm.css');
-
- $gridField->addExtraClass('expandable-forms');
- $gridField->setAttribute('data-pseudo-form-url', $gridField->Link('expand'));
-
- return array();
- }
+ $gridField->addExtraClass('expandable-forms');
+ $gridField->setAttribute('data-pseudo-form-url', $gridField->Link('expand'));
+ return array();
+ }
}
-class GridFieldExpandableForm_ItemRequest extends RequestHandler {
-
- static $url_handlers = array(
- '$Action!' => '$Action',
- '' => 'edit',
- );
-
- protected $gridfield;
- protected $component;
- protected $record;
- protected $controller;
- protected $name;
- protected $formorfields;
- protected $template = 'GridFieldExpandableForm';
-
- public function __construct($gridfield, $component, $record, $controller, $name, $formorfields) {
- $this->gridfield = $gridfield;
- $this->component = $component;
- $this->record = $record;
- $this->controller = $controller;
- $this->name = $name;
- $this->formorfields = $formorfields;
- parent::__construct();
- }
-
- public function edit($request) {
- $controller = $this->getToplevelController();
- $form = $this->ExpandableForm($this->gridField, $request);
-
- return $this->customise(array(
- 'ExpandableForm' => $form,
- ))->renderWith($this->template);
- }
-
- public function ExpandableForm() {
-
- if($this->formorfields instanceof FieldList) {
- $fields = $this->formorfields;
- } else if($this->formorfields instanceof ViewableData) {
- $form = $this->formorfields;
- } else if($this->record->hasMethod('getExandableForm')) {
- $form = $this->record->getExandableForm($this, __FUNCTION__);
- $this->record->extend('updateExandableForm', $form);
- } else if($this->record->hasMethod('getExandableFormFields')) {
- $fields = $this->record->getExandableFormFields();
- $this->record->extend('updateExandableFormFields', $fields);
- } else {
- $fields = $this->record->scaffoldFormFields();
- $this->record->extend('updateExandableFormFields', $fields);
- }
-
- if(empty($form)) {
- $actions = new FieldList();
- $actions->push(FormAction::create('doSave', _t('GridFieldDetailForm.Save', 'Save'))
- ->setUseButtonTag(true)
- ->addExtraClass('ss-ui-action-constructive')
- ->setAttribute('data-icon', 'accept')
- ->setAttribute('data-action-type', 'default'));
-
- $form = new Form(
- $this,
- 'ExpandableForm',
- $fields,
- $actions,
- $this->validator
- );
- }
-
- $form->loadDataFrom($this->record, Form::MERGE_DEFAULT);
-
- $form->IncludeFormTag = false;
-
- return $form;
- }
-
- public function doSave($data, $form) {
- try {
- $form->saveInto($this->record);
- $this->record->write();
- $list = $this->gridfield->getList();
- if($list instanceof ManyManyList) {
- $extradata = array_intersect_key($data, $list->getField('extraFields'));
- $list->add($this->record, $extradata);
- } else {
- $list->add($this->record);
- }
- } catch(ValidationException $e) {
- $form->sessionMessage($e->getResult()->message(), 'bad');
- $responseNegotiator = new PjaxResponseNegotiator(array(
- 'CurrentForm' => function() use(&$form) {
- return $form->forTemplate();
- },
- 'default' => function() use(&$controller) {
- return $controller->redirectBack();
- }
- ));
- if($controller->getRequest()->isAjax()){
- $controller->getRequest()->addHeader('X-Pjax', 'CurrentForm');
- }
- return $responseNegotiator->respond($controller->getRequest());
- }
- return $this->customise(array('ExpandableForm' => $form))->renderWith($this->template);
- }
-
- public function doDelete($data, $form) {
- try {
- if (!$this->record->canDelete()) {
- throw new ValidationException(
- _t('GridFieldDetailForm.DeletePermissionsFailure',"No delete permissions"),0);
- }
-
- $this->record->delete();
- } catch(ValidationException $e) {
- $form->sessionMessage($e->getResult()->message(), 'bad');
- return Controller::curr()->redirectBack();
- }
- return 'deleted';
- }
-
- protected function getToplevelController() {
- $c = $this->popupController;
- while($c && $c instanceof GridFieldExpandableForm_ItemRequest) {
- $c = $c->getController();
- }
- return $c;
- }
-
- public function Link($action = null) {
- return Controller::join_links($this->gridfield->Link('expand'),
- $this->record->ID ? $this->record->ID : 'new', $action);
- }
-}
\ No newline at end of file
+class GridFieldExpandableForm_ItemRequest extends RequestHandler
+{
+
+ public static $url_handlers = array(
+ '$Action!' => '$Action',
+ '' => 'edit',
+ );
+
+ protected $gridfield;
+ protected $component;
+ protected $record;
+ protected $controller;
+ protected $name;
+ protected $formorfields;
+ protected $template = 'GridFieldExpandableForm';
+
+ public function __construct($gridfield, $component, $record, $controller, $name, $formorfields)
+ {
+ $this->gridfield = $gridfield;
+ $this->component = $component;
+ $this->record = $record;
+ $this->controller = $controller;
+ $this->name = $name;
+ $this->formorfields = $formorfields;
+ parent::__construct();
+ }
+
+ public function edit($request)
+ {
+ $controller = $this->getToplevelController();
+ $form = $this->ExpandableForm($this->gridField, $request);
+
+ return $this->customise(array(
+ 'ExpandableForm' => $form,
+ ))->renderWith($this->template);
+ }
+
+ public function ExpandableForm()
+ {
+ if ($this->formorfields instanceof FieldList) {
+ $fields = $this->formorfields;
+ } elseif ($this->formorfields instanceof ViewableData) {
+ $form = $this->formorfields;
+ } elseif ($this->record->hasMethod('getExandableForm')) {
+ $form = $this->record->getExandableForm($this, __FUNCTION__);
+ $this->record->extend('updateExandableForm', $form);
+ } elseif ($this->record->hasMethod('getExandableFormFields')) {
+ $fields = $this->record->getExandableFormFields();
+ $this->record->extend('updateExandableFormFields', $fields);
+ } else {
+ $fields = $this->record->scaffoldFormFields();
+ $this->record->extend('updateExandableFormFields', $fields);
+ }
+
+ if (empty($form)) {
+ $actions = new FieldList();
+ $actions->push(FormAction::create('doSave', _t('GridFieldDetailForm.Save', 'Save'))
+ ->setUseButtonTag(true)
+ ->addExtraClass('ss-ui-action-constructive')
+ ->setAttribute('data-icon', 'accept')
+ ->setAttribute('data-action-type', 'default'));
+
+ $form = new Form(
+ $this,
+ 'ExpandableForm',
+ $fields,
+ $actions,
+ $this->validator
+ );
+ }
+
+ $form->loadDataFrom($this->record, Form::MERGE_DEFAULT);
+
+ $form->IncludeFormTag = false;
+
+ return $form;
+ }
+
+ public function doSave($data, $form)
+ {
+ try {
+ $form->saveInto($this->record);
+ $this->record->write();
+ $list = $this->gridfield->getList();
+ if ($list instanceof ManyManyList) {
+ $extradata = array_intersect_key($data, $list->getField('extraFields'));
+ $list->add($this->record, $extradata);
+ } else {
+ $list->add($this->record);
+ }
+ } catch (ValidationException $e) {
+ $form->sessionMessage($e->getResult()->message(), 'bad');
+ $responseNegotiator = new PjaxResponseNegotiator(array(
+ 'CurrentForm' => function () use (&$form) {
+ return $form->forTemplate();
+ },
+ 'default' => function () use (&$controller) {
+ return $controller->redirectBack();
+ }
+ ));
+ if ($controller->getRequest()->isAjax()) {
+ $controller->getRequest()->addHeader('X-Pjax', 'CurrentForm');
+ }
+ return $responseNegotiator->respond($controller->getRequest());
+ }
+ return $this->customise(array('ExpandableForm' => $form))->renderWith($this->template);
+ }
+
+ public function doDelete($data, $form)
+ {
+ try {
+ if (!$this->record->canDelete()) {
+ throw new ValidationException(
+ _t('GridFieldDetailForm.DeletePermissionsFailure', "No delete permissions"), 0);
+ }
+
+ $this->record->delete();
+ } catch (ValidationException $e) {
+ $form->sessionMessage($e->getResult()->message(), 'bad');
+ return Controller::curr()->redirectBack();
+ }
+ return 'deleted';
+ }
+
+ protected function getToplevelController()
+ {
+ $c = $this->popupController;
+ while ($c && $c instanceof GridFieldExpandableForm_ItemRequest) {
+ $c = $c->getController();
+ }
+ return $c;
+ }
+
+ public function Link($action = null)
+ {
+ return Controller::join_links($this->gridfield->Link('expand'),
+ $this->record->ID ? $this->record->ID : 'new', $action);
+ }
+}
diff --git a/code/GridFieldRecordHighlighter.php b/code/GridFieldRecordHighlighter.php
index 58f2ba2..8a7c6a6 100644
--- a/code/GridFieldRecordHighlighter.php
+++ b/code/GridFieldRecordHighlighter.php
@@ -1,121 +1,125 @@
alerts = $alerts;
- }
-
- /**
- * Add extra fields to the column list
- *
- * @param GridField $gridField
- * @param array - List reference of all column names.
- */
- public function augmentColumns($gridField, &$columns) {
-
- array_unshift($columns, 'Alerts');
- }
-
- /**
- * List of handled columns
- *
- * @param GridField $gridField
- * @return array
- */
- public function getColumnsHandled($gridField) {
-
- return array('Alerts');
- }
-
- /**
- * Set titles for the column header
- *
- * @param GridField $gridField
- * @param string $columnName
- * @return array - Map of arbitrary metadata identifiers to their values.
- */
- public function getColumnMetadata($gridField, $columnName) {
-
- return array('title' => '');
- }
-
- /**
- * Return a formfield for the extra field column or an edit button for the actions column
- *
- * @param GridField $gridField
- * @param DataObject $record - Record displayed in this row
- * @param string $columnName
- * @return string - HTML for the column. Return NULL to skip.
- */
- public function getColumnContent($gridField, $record, $columnName) {
-
- Requirements::javascript('GridFieldAddOns/javascript/GridFieldRecordHighlighter.js');
- Requirements::css('GridFieldAddOns/css/GridFieldRecordHighlighter.css');
-
- $alerts = $this->getAlerts($record);
-
- $content = array();
- foreach($alerts as $alert) $content[] = "";
-
- return implode($content);
- }
-
- /**
- * Generate HTML attributes for each individual cells as selectors for CSS and JS
- *
- * @param GridField $gridField
- * @param DataObject $record displayed in this row
- * @param string $columnName
- * @return array
- */
- public function getColumnAttributes($gridField, $record, $columnName) {
-
- $attr = array();
-
- foreach($this->getAlerts($record) as $alert) {
- if($alert['status'] == 'alert') {
- $attr = array('class' => 'ss-gridfield-highlight', 'data-highlight-status' => 'error');
- } else if(empty($attr)) {
- $attr = array('class' => 'ss-gridfield-highlight', 'data-highlight-status' => 'highlight');
- }
- }
-
- return $attr;
- }
-
- function getAlerts($record) {
-
- $alerts = array();
-
- foreach($this->alerts as $getter => $rule) {
- $actualvalue = $record->hasField($getter) ? $record->$getter : $record->$getter();
- foreach($rule['patterns'] as $nominalvalue => $return) {
- if(
- ($rule['comparator'] == 'equal' && $actualvalue == $nominalvalue) ||
- ($rule['comparator'] == 'equalstrict' && $actualvalue === $nominalvalue) ||
- ($rule['comparator'] == 'unequal' && $actualvalue != $nominalvalue) ||
- ($rule['comparator'] == 'unequalstrict' && $actualvalue !== $nominalvalue) ||
- ($rule['comparator'] == 'greater' && $actualvalue > $nominalvalue) ||
- ($rule['comparator'] == 'greaterorequal' && $actualvalue >= $nominalvalue) ||
- ($rule['comparator'] == 'less' && $actualvalue < $nominalvalue) ||
- ($rule['comparator'] == 'lessorequal' && $actualvalue <= $nominalvalue) ||
- ($rule['comparator'] == 'beginwith' && strtolower(substr($actualvalue, 0, strlen($nominalvalue))) == strtolower($nominalvalue)) ||
- ($rule['comparator'] == 'endwith' && strtolower(substr($actualvalue, -1 * strlen($nominalvalue))) == strtolower($nominalvalue)) ||
- ($rule['comparator'] == 'contain' && stripos($actualvalue, $nominalvalue) !== false) ||
- ($rule['comparator'] == 'regex' && preg_match($nominalvalue, $actualvalue))
- ) {
- $alerts[$getter] = array(
- 'status' => $return['status'],
- 'message' => sprintf($return['message'], Convert::raw2xml($nominalvalue), Convert::raw2xml($actualvalue)),
- );
- break;
- }
- }
- }
-
- return $alerts;
- }
-}
\ No newline at end of file
+class GridFieldRecordHighlighter implements GridField_ColumnProvider
+{
+
+ protected $alerts;
+
+ public function __construct($alerts)
+ {
+ $this->alerts = $alerts;
+ }
+
+ /**
+ * Add extra fields to the column list
+ *
+ * @param GridField $gridField
+ * @param array - List reference of all column names.
+ */
+ public function augmentColumns($gridField, &$columns)
+ {
+ array_unshift($columns, 'Alerts');
+ }
+
+ /**
+ * List of handled columns
+ *
+ * @param GridField $gridField
+ * @return array
+ */
+ public function getColumnsHandled($gridField)
+ {
+ return array('Alerts');
+ }
+
+ /**
+ * Set titles for the column header
+ *
+ * @param GridField $gridField
+ * @param string $columnName
+ * @return array - Map of arbitrary metadata identifiers to their values.
+ */
+ public function getColumnMetadata($gridField, $columnName)
+ {
+ return array('title' => '');
+ }
+
+ /**
+ * Return a formfield for the extra field column or an edit button for the actions column
+ *
+ * @param GridField $gridField
+ * @param DataObject $record - Record displayed in this row
+ * @param string $columnName
+ * @return string - HTML for the column. Return NULL to skip.
+ */
+ public function getColumnContent($gridField, $record, $columnName)
+ {
+ Requirements::javascript('GridFieldAddOns/javascript/GridFieldRecordHighlighter.js');
+ Requirements::css('GridFieldAddOns/css/GridFieldRecordHighlighter.css');
+
+ $alerts = $this->getAlerts($record);
+
+ $content = array();
+ foreach ($alerts as $alert) {
+ $content[] = "";
+ }
+
+ return implode($content);
+ }
+
+ /**
+ * Generate HTML attributes for each individual cells as selectors for CSS and JS
+ *
+ * @param GridField $gridField
+ * @param DataObject $record displayed in this row
+ * @param string $columnName
+ * @return array
+ */
+ public function getColumnAttributes($gridField, $record, $columnName)
+ {
+ $attr = array();
+
+ foreach ($this->getAlerts($record) as $alert) {
+ if ($alert['status'] == 'alert') {
+ $attr = array('class' => 'ss-gridfield-highlight', 'data-highlight-status' => 'error');
+ } elseif (empty($attr)) {
+ $attr = array('class' => 'ss-gridfield-highlight', 'data-highlight-status' => 'highlight');
+ }
+ }
+
+ return $attr;
+ }
+
+ public function getAlerts($record)
+ {
+ $alerts = array();
+
+ foreach ($this->alerts as $getter => $rule) {
+ $actualvalue = $record->hasField($getter) ? $record->$getter : $record->$getter();
+ foreach ($rule['patterns'] as $nominalvalue => $return) {
+ if (
+ ($rule['comparator'] == 'equal' && $actualvalue == $nominalvalue) ||
+ ($rule['comparator'] == 'equalstrict' && $actualvalue === $nominalvalue) ||
+ ($rule['comparator'] == 'unequal' && $actualvalue != $nominalvalue) ||
+ ($rule['comparator'] == 'unequalstrict' && $actualvalue !== $nominalvalue) ||
+ ($rule['comparator'] == 'greater' && $actualvalue > $nominalvalue) ||
+ ($rule['comparator'] == 'greaterorequal' && $actualvalue >= $nominalvalue) ||
+ ($rule['comparator'] == 'less' && $actualvalue < $nominalvalue) ||
+ ($rule['comparator'] == 'lessorequal' && $actualvalue <= $nominalvalue) ||
+ ($rule['comparator'] == 'beginwith' && strtolower(substr($actualvalue, 0, strlen($nominalvalue))) == strtolower($nominalvalue)) ||
+ ($rule['comparator'] == 'endwith' && strtolower(substr($actualvalue, -1 * strlen($nominalvalue))) == strtolower($nominalvalue)) ||
+ ($rule['comparator'] == 'contain' && stripos($actualvalue, $nominalvalue) !== false) ||
+ ($rule['comparator'] == 'regex' && preg_match($nominalvalue, $actualvalue))
+ ) {
+ $alerts[$getter] = array(
+ 'status' => $return['status'],
+ 'message' => sprintf($return['message'], Convert::raw2xml($nominalvalue), Convert::raw2xml($actualvalue)),
+ );
+ break;
+ }
+ }
+ }
+
+ return $alerts;
+ }
+}
diff --git a/code/GridFieldUserColumns.php b/code/GridFieldUserColumns.php
index 3c116f0..96d8ea7 100644
--- a/code/GridFieldUserColumns.php
+++ b/code/GridFieldUserColumns.php
@@ -1,163 +1,196 @@
gridField = $gridField;
- }
-
- /**
- * This component is not providing columns but manipulating the columns provided by GridFieldDataColumns.
- *
- * @param GridField $gridField
- * @param array - List reference of all column names.
- */
- public function augmentColumns($gridField, &$columns) {
-
- $this->init($gridField);
-
- Requirements::javascript('GridFieldAddOns/javascript/GridFieldUserColumns.js');
-
- $usercolumns = $this->currentColumns();
- $extracolumns = array_diff($columns, $this->availableColumns());
- $displaycolumns = array_values(array_unique(array_merge(array_keys($usercolumns), $extracolumns)));
-
- $datacolumnscomponent = $gridField->getConfig()->getComponentByType('GridFieldDataColumns');
- $datacolumnscomponent->setDisplayFields($usercolumns);
-
- $columns = $displaycolumns;
- }
-
- function defaultColumns() {
-
- if(!$this->default_columns) {
- if(!$this->gridField) throw new Exception('GridField not yet set. Do not call GridFieldUserColumns::defaultColumns() before GridFieldUserColumns::augmentColumns().');
- $datacolumnscomponent = $this->gridField->getConfig()->getComponentByType('GridFieldDataColumns');
- $this->default_columns = $datacolumnscomponent->getDisplayFields($this->gridField);
- }
-
- return $this->default_columns;
- }
-
- function userColumns() {
-
- if(!$this->gridField) throw new Exception('GridField not yet set. Do not call GridFieldUserColumns::userColumns() before GridFieldUserColumns::augmentColumns().');
-
- if(
- Member::currentUser()->hasField('GridFieldUserColumns') &&
- Member::currentUser()->GridFieldUserColumns &&
- ($usercolumns = Member::currentUser()->getGridFieldUserColumnsFor($this->gridField->getList()->dataClass()))
- ) {
- return $usercolumns;
- }
- return false;
- }
-
- function currentColumns() {
- $user = $this->userColumns();
- return is_array($user) ? $user : $this->defaultColumns();
- }
-
- function availableColumns() {
-
- if(!$this->gridField) throw new Exception('GridField not yet set. Do not call GridFieldUserColumns::userColumns() before GridFieldUserColumns::augmentColumns().');
-
- $class = $this->gridField->getList()->dataClass();
- $default = $this->defaultColumns();
- $user = $this->userColumns();
- $extra = Config::inst()->get($class, self::$static_field_for_extra_columns);
- $default = is_array($extra) ? array_merge($default, $extra) : $default;
-
- return is_array($user) ? array_merge($user, $default) : $default;
- }
-
- // since we're not really provide columns we're not returning anything
- public function getColumnsHandled($gridField) { return array(); }
- public function getColumnMetadata($gridField, $columnName) { return array(); }
- public function getColumnContent($gridField, $record, $columnName) { return false; }
- public function getColumnAttributes($gridField, $record, $columnName) { return array(); }
-
- /**
- * Returns a map where the keys are fragment names and the values are pieces of HTML to add to these fragments.
- *
- * Here are 4 built-in fragments: 'header', 'footer', 'before', and 'after', but components may also specify
- * fragments of their own.
- *
- * To specify a new fragment, specify a new fragment by including the text "$DefineFragment(fragmentname)" in the
- * HTML that you return. Fragment names should only contain alphanumerics, -, and _.
- *
- * If you attempt to return HTML for a fragment that doesn't exist, an exception will be thrown when the GridField
- * is rendered.
- *
- * @return Array
- */
- public function getHTMLFragments($gridField) {
-
- $gridField->getList()->dataClass();
- $buttonlabel = _t('GridFieldAddOns.ChangeColumns',"Change Columns");
-
- return array(
- 'buttons-before-right' => "$buttonlabel",
- );
- }
-
- public function getURLHandlers($gridField) {
- return array(
- 'usercolumnsform' => 'UserColumnsForm',
- 'saveusercolumns' => 'saveUserColumns',
- );
- }
-
- function UserColumnsForm($gridField, $request) {
- $this->init($gridField);
- return $this->renderWith('GridFieldUserColumns_Form');
- }
-
- function Columns() {
- $available = $this->availableColumns();
- $current = $this->currentColumns();
-
- $columns = new ArrayList();
- foreach($available as $key => $val) {
- $selected = array_search($val, $current) !== false;
- $columns->push(new ArrayData(array('Name' => $key, 'Title' => $val, 'Selected' => $selected)));
- }
- return $columns;
- }
-
- function saveUserColumns($gridField, $request) {
- $this->init($gridField);
- $available = $this->availableColumns();
- $postcolumns = $request->postVar('columns');
- $newcolumns = array();
- if(!is_array($postcolumns)) return json_encode('bad');
- foreach($postcolumns as $col) {
- list($name, $title) = explode(':', $col);
- if(!isset($available[$name]) || $available[$name] != $title) return json_encode(array('bad', $this->gridField->getList()->dataClass()));
- $newcolumns[$name] = $title;
- }
- Member::currentUser()->setGridFieldUserColumnsFor($gridField->getList()->dataClass(), $newcolumns);
- return json_encode('good');
- }
+class GridFieldUserColumns extends ViewableData implements GridField_ColumnProvider, GridField_HTMLProvider, GridField_URLHandler
+{
+
+ public static $static_field_for_extra_columns = 'extra_summary_fields';
+
+ protected $gridField;
+ protected $default_columns;
+
+ public function init($gridField)
+ {
+ $this->gridField = $gridField;
+ }
+
+ /**
+ * This component is not providing columns but manipulating the columns provided by GridFieldDataColumns.
+ *
+ * @param GridField $gridField
+ * @param array - List reference of all column names.
+ */
+ public function augmentColumns($gridField, &$columns)
+ {
+ $this->init($gridField);
+
+ Requirements::javascript('GridFieldAddOns/javascript/GridFieldUserColumns.js');
+
+ $usercolumns = $this->currentColumns();
+ $extracolumns = array_diff($columns, $this->availableColumns());
+ $displaycolumns = array_values(array_unique(array_merge(array_keys($usercolumns), $extracolumns)));
+
+ $datacolumnscomponent = $gridField->getConfig()->getComponentByType('GridFieldDataColumns');
+ $datacolumnscomponent->setDisplayFields($usercolumns);
+
+ $columns = $displaycolumns;
+ }
+
+ public function defaultColumns()
+ {
+ if (!$this->default_columns) {
+ if (!$this->gridField) {
+ throw new Exception('GridField not yet set. Do not call GridFieldUserColumns::defaultColumns() before GridFieldUserColumns::augmentColumns().');
+ }
+ $datacolumnscomponent = $this->gridField->getConfig()->getComponentByType('GridFieldDataColumns');
+ $this->default_columns = $datacolumnscomponent->getDisplayFields($this->gridField);
+ }
+
+ return $this->default_columns;
+ }
+
+ public function userColumns()
+ {
+ if (!$this->gridField) {
+ throw new Exception('GridField not yet set. Do not call GridFieldUserColumns::userColumns() before GridFieldUserColumns::augmentColumns().');
+ }
+
+ if (
+ Member::currentUser()->hasField('GridFieldUserColumns') &&
+ Member::currentUser()->GridFieldUserColumns &&
+ ($usercolumns = Member::currentUser()->getGridFieldUserColumnsFor($this->gridField->getList()->dataClass()))
+ ) {
+ return $usercolumns;
+ }
+ return false;
+ }
+
+ public function currentColumns()
+ {
+ $user = $this->userColumns();
+ return is_array($user) ? $user : $this->defaultColumns();
+ }
+
+ public function availableColumns()
+ {
+ if (!$this->gridField) {
+ throw new Exception('GridField not yet set. Do not call GridFieldUserColumns::userColumns() before GridFieldUserColumns::augmentColumns().');
+ }
+
+ $class = $this->gridField->getList()->dataClass();
+ $default = $this->defaultColumns();
+ $user = $this->userColumns();
+ $extra = Config::inst()->get($class, self::$static_field_for_extra_columns);
+ $default = is_array($extra) ? array_merge($default, $extra) : $default;
+
+ return is_array($user) ? array_merge($user, $default) : $default;
+ }
+
+ // since we're not really provide columns we're not returning anything
+ public function getColumnsHandled($gridField)
+ {
+ return array();
+ }
+ public function getColumnMetadata($gridField, $columnName)
+ {
+ return array();
+ }
+ public function getColumnContent($gridField, $record, $columnName)
+ {
+ return false;
+ }
+ public function getColumnAttributes($gridField, $record, $columnName)
+ {
+ return array();
+ }
+
+ /**
+ * Returns a map where the keys are fragment names and the values are pieces of HTML to add to these fragments.
+ *
+ * Here are 4 built-in fragments: 'header', 'footer', 'before', and 'after', but components may also specify
+ * fragments of their own.
+ *
+ * To specify a new fragment, specify a new fragment by including the text "$DefineFragment(fragmentname)" in the
+ * HTML that you return. Fragment names should only contain alphanumerics, -, and _.
+ *
+ * If you attempt to return HTML for a fragment that doesn't exist, an exception will be thrown when the GridField
+ * is rendered.
+ *
+ * @return Array
+ */
+ public function getHTMLFragments($gridField)
+ {
+ $gridField->getList()->dataClass();
+ $buttonlabel = _t('GridFieldAddOns.ChangeColumns', "Change Columns");
+
+ return array(
+ 'buttons-before-right' => "$buttonlabel",
+ );
+ }
+
+ public function getURLHandlers($gridField)
+ {
+ return array(
+ 'usercolumnsform' => 'UserColumnsForm',
+ 'saveusercolumns' => 'saveUserColumns',
+ );
+ }
+
+ public function UserColumnsForm($gridField, $request)
+ {
+ $this->init($gridField);
+ return $this->renderWith('GridFieldUserColumns_Form');
+ }
+
+ public function Columns()
+ {
+ $available = $this->availableColumns();
+ $current = $this->currentColumns();
+
+ $columns = new ArrayList();
+ foreach ($available as $key => $val) {
+ $selected = array_search($val, $current) !== false;
+ $columns->push(new ArrayData(array('Name' => $key, 'Title' => $val, 'Selected' => $selected)));
+ }
+ return $columns;
+ }
+
+ public function saveUserColumns($gridField, $request)
+ {
+ $this->init($gridField);
+ $available = $this->availableColumns();
+ $postcolumns = $request->postVar('columns');
+ $newcolumns = array();
+ if (!is_array($postcolumns)) {
+ return json_encode('bad');
+ }
+ foreach ($postcolumns as $col) {
+ list($name, $title) = explode(':', $col);
+ if (!isset($available[$name]) || $available[$name] != $title) {
+ return json_encode(array('bad', $this->gridField->getList()->dataClass()));
+ }
+ $newcolumns[$name] = $title;
+ }
+ Member::currentUser()->setGridFieldUserColumnsFor($gridField->getList()->dataClass(), $newcolumns);
+ return json_encode('good');
+ }
}
-class GridFieldConfig_ExtendedRecordEditor extends GridFieldConfig_RecordEditor {
+class GridFieldConfig_ExtendedRecordEditor extends GridFieldConfig_RecordEditor
+{
- function __construct($itemsPerPage = null) {
- parent::__construct($itemsPerPage);
- $this->addComponent(new GridFieldUserColumns());
- }
+ public function __construct($itemsPerPage = null)
+ {
+ parent::__construct($itemsPerPage);
+ $this->addComponent(new GridFieldUserColumns());
+ }
}
-class GridFieldConfig_ExtendedRelationEditor extends GridFieldConfig_RelationEditor {
+class GridFieldConfig_ExtendedRelationEditor extends GridFieldConfig_RelationEditor
+{
- function __construct($itemsPerPage = null) {
- parent::__construct($itemsPerPage);
- $this->addComponent(new GridFieldUserColumns());
- }
-}
\ No newline at end of file
+ public function __construct($itemsPerPage = null)
+ {
+ parent::__construct($itemsPerPage);
+ $this->addComponent(new GridFieldUserColumns());
+ }
+}
diff --git a/code/GridFieldUserColumnsExtension.php b/code/GridFieldUserColumnsExtension.php
index b277908..44bce7b 100644
--- a/code/GridFieldUserColumnsExtension.php
+++ b/code/GridFieldUserColumnsExtension.php
@@ -1,21 +1,26 @@
'Text',
- );
+ public static $db = array(
+ 'GridFieldUserColumns' => 'Text',
+ );
- function getGridFieldUserColumnsFor($gridfielddataclass) {
- if(!$this->owner->GridFieldUserColumns) return false;
- $columns = unserialize($this->owner->GridFieldUserColumns);
- return isset($columns[$gridfielddataclass]) ? $columns[$gridfielddataclass] : false;
- }
+ public function getGridFieldUserColumnsFor($gridfielddataclass)
+ {
+ if (!$this->owner->GridFieldUserColumns) {
+ return false;
+ }
+ $columns = unserialize($this->owner->GridFieldUserColumns);
+ return isset($columns[$gridfielddataclass]) ? $columns[$gridfielddataclass] : false;
+ }
- function setGridFieldUserColumnsFor($gridfielddataclass, $newcolumns) {
- $columns = $this->owner->GridFieldUserColumns ? unserialize($this->owner->GridFieldUserColumns) : array();
- $columns[$gridfielddataclass] = $newcolumns;
- $this->owner->GridFieldUserColumns = serialize($columns);
- $this->owner->write();
- }
-}
\ No newline at end of file
+ public function setGridFieldUserColumnsFor($gridfielddataclass, $newcolumns)
+ {
+ $columns = $this->owner->GridFieldUserColumns ? unserialize($this->owner->GridFieldUserColumns) : array();
+ $columns[$gridfielddataclass] = $newcolumns;
+ $this->owner->GridFieldUserColumns = serialize($columns);
+ $this->owner->write();
+ }
+}