/** * * @param \GridField $gridField * @param \SS_List $dataList * @return \SS_List */ public function getManipulatedData(\GridField $gridField, \SS_List $dataList) { $state = $gridField->State->Milkyway_SS_GridFieldUtils_RangeSlider; if (!isset($state->min) && !isset($state->value)) { $settings = $this->scaffoldSliderSettingsForField(singleton($gridField->getModelClass())->obj($this->filterField), $dataList); $this->working = [$gridField, $dataList]; if (isset($settings['start'])) { if (is_array($settings['start'])) { $state->min = $settings['start'][0]; $state->max = $settings['start'][1]; } else { $state->value = $settings['start']; } } else { return $dataList; } } $dataListClone = clone $dataList; $dbField = singleton($gridField->getModelClass())->obj($this->filterField); if (isset($state->value)) { $comparisonFilter = $this->comparisonFilter ? '' : ':' . $this->comparisonFilter; $dataListClone = $dataListClone->filter($this->filterField . $comparisonFilter, $this->getValueForDB($dbField, $state->value)); } elseif (isset($state->min) && isset($state->max)) { $dataListClone = $dataListClone->filter([$this->filterField . ':GreaterThan' => $this->getValueForDB($dbField, $state->min), $this->filterField . ':LessThan' => $this->getValueForDB($dbField, $state->max)]); } return $dataListClone; }
/** * Gets the classes that can be created using this button, defaulting to the model class and * its subclasses. * * @param GridField $grid * @return array a map of class name to title */ public function getClasses(GridField $grid) { $result = array(); if (is_null($this->classes)) { $classes = array_values(ClassInfo::subclassesFor($grid->getModelClass())); sort($classes); } else { $classes = $this->classes; } $kill_ancestors = array(); foreach ($classes as $class => $title) { if (!is_string($class)) { $class = $title; $is_abstract = ($reflection = new ReflectionClass($class)) && $reflection->isAbstract(); if (!$is_abstract) { $title = singleton($class)->i18n_singular_name(); } } else { $is_abstract = ($reflection = new ReflectionClass($class)) && $reflection->isAbstract(); } if ($ancestor_to_hide = Config::inst()->get($class, 'hide_ancestor', Config::FIRST_SET)) { $kill_ancestors[$ancestor_to_hide] = true; } if ($is_abstract || !singleton($class)->canCreate()) { continue; } $result[$class] = $title; } if ($kill_ancestors) { foreach ($kill_ancestors as $class => $bool) { unset($result[$class]); } } return $result; }
protected function setupGridField(GridField $gridfield, Config_ForClass $classConfig) { if (!$gridfield) { return; } $config = $gridfield->getConfig(); $class = $gridfield->getModelClass(); // More item per page $paginator = $config->getComponentByType('GridFieldPaginator'); $paginator->setItemsPerPage(50); // Bulk manage if ($classConfig->bulk_manage && class_exists('GridFieldBulkManager')) { $already = $config->getComponentByType('GridFieldBulkManager'); if (!$already) { $config->addComponent($bulkManager = new GridFieldBulkManager()); $bulkManager->removeBulkAction('unLink'); } } // Better export if ($classConfig->export_csv) { /* @var $export GridFieldExportButton */ $export = $config->getComponentByType('GridFieldExportButton'); $export->setExportColumns(ExcelImportExport::exportFieldsForClass($class)); } else { $config->removeComponentsByType('GridFieldExportButton'); } if ($classConfig->export_excel) { if ($class == 'Group') { $config->addComponent(new GridFieldButtonRow('after')); } $config->addComponent(new ExcelGridFieldExportButton('buttons-after-left')); } }
public function handleAction(\GridField $gridField, $actionName, $arguments, $data) { if ($actionName != $this->urlSegment) { return; } $record = $gridField->Form && $gridField->Form->Record ? $gridField->Form->Record : null; if (!$record || !$record->SiteTreeID) { throw new \ValidationException(_t('Link.NO_CURRENT_PAGE', 'No current page to draw from'), 0); } $root = \SiteTree::get()->filter('ParentID', $record->SiteTreeID); if (!$root->exists()) { throw new \ValidationException(_t('Link.NO_PAGES', 'No pages available'), 0); } $item = singleton($gridField->getModelClass()); if (!$item->canCreate()) { throw new \ValidationException(_t('Link.CANNOT_CREATE', 'You cannot create a Link'), 0); } foreach ($root as $page) { $link = $item->create(); $link->Type = 'SiteTree'; $link->SiteTreeID = $page->ID; $link->write(); $gridField->getList()->add($link); } }
public function updateCMSFields(FieldList $fields) { if ($this->owner->ID) { // Relation handler for Blocks $SConfig = GridFieldConfig_RelationEditor::create(25); $SConfig->addComponent(new GridFieldOrderableRows('SortOrder')); $SConfig->addComponent(new GridFieldDeleteAction()); // If the copy button module is installed, add copy as option if (class_exists('GridFieldCopyButton')) { $SConfig->addComponent(new GridFieldCopyButton(), 'GridFieldDeleteAction'); } $gridField = new GridField("Blocks", "Content blocks", $this->owner->Blocks(), $SConfig); $classes = array_values(ClassInfo::subclassesFor($gridField->getModelClass())); if (count($classes) > 1 && class_exists('GridFieldAddNewMultiClass')) { $SConfig->removeComponentsByType('GridFieldAddNewButton'); $SConfig->addComponent(new GridFieldAddNewMultiClass()); } if (self::$create_block_tab) { $fields->addFieldToTab("Root.Blocks", $gridField); } else { // Downsize the content field $fields->removeByName('Content'); $fields->addFieldToTab('Root.Main', HTMLEditorField::create('Content')->setRows(self::$contentarea_rows), 'Metadata'); $fields->addFieldToTab("Root.Main", $gridField, 'Metadata'); } } return $fields; }
/** * Handles the add action for the given DataObject. * * @param $gridField GridField * @param $actionName string * @param $arguments mixed * @param $data array * * @return null|SS_HTTPResponse * * @throws UnexpectedValueException */ public function handleAction(GridField $gridField, $actionName, $arguments, $data) { if ($actionName == 'add') { $dbField = $this->getDataObjectField(); $objClass = $gridField->getModelClass(); /** * @var DataObject $obj */ $obj = new $objClass(); if ($obj->hasField($dbField)) { $obj->setCastedField($dbField, $data['gridfieldaddbydbfield'][$obj->ClassName][$dbField]); if ($obj->canCreate()) { $id = $gridField->getList()->add($obj); if (!$id) { $gridField->setError(_t('GridFieldAddByDBField.AddFail', 'Unable to save {class} to the database.', 'Unable to add the DataObject.', array('class' => get_class($obj))), 'error'); } } else { return Security::permissionFailure(Controller::curr(), _t('GridFieldAddByDBField.PermissionFail', 'You don\'t have permission to create a {class}.', 'Unable to add the DataObject.', array('class' => get_class($obj)))); } } else { throw new UnexpectedValueException(sprintf('Invalid field (%s) on %s.', $dbField, $obj->ClassName)); } } return null; }
/** * Gets the classes that can be created using this button, defaulting to the model class and * its subclasses. * * @param GridField $grid * @return array a map of class name to title */ public function getClasses(GridField $grid) { $result = array(); if (is_null($this->classes)) { $classes = array_values(ClassInfo::subclassesFor($grid->getModelClass())); sort($classes); } else { $classes = $this->classes; } foreach ($classes as $class => $title) { if (!is_string($class)) { $class = $title; if (($reflection = new ReflectionClass($class)) && $reflection->isAbstract()) { continue; } $title = singleton($class)->i18n_singular_name(); } else { if (($reflection = new ReflectionClass($class)) && $reflection->isAbstract()) { continue; } } if (!singleton($class)->canCreate()) { continue; } $result[$class] = $title; } return $result; }
/** * Gets the classes that can be created using this button, defaulting to the model class and * its subclasses. * * @param \GridField $grid * @return array a map of class name to title */ public function getAllowedClasses(\GridField $grid) { $result = array(); if ($this->useAllowedClasses) { $classes = $this->useAllowedClasses; $this->useAllowedClasses = null; return $classes; } else { if (is_null($this->allowedClasses)) { $classes = array_values(\ClassInfo::subclassesFor($grid->getModelClass())); sort($classes); } else { $classes = $this->allowedClasses; } } foreach ($classes as $class => $title) { if (!is_string($class)) { $class = $title; $title = singleton($class)->i18n_singular_name(); } if (!singleton($class)->canCreate()) { continue; } $result[$class] = $title; } return $result; }
/** * Generate export fields for EXCEL. * * @param GridField $gridField * @return array */ public function generateExportFileData($gridField) { $excelColumns = $this->exportColumns ? $this->exportColumns : singleton($gridField->getModelClass())->summaryFields(); $objPHPExcel = new \PHPExcel\Spreadsheet(); $worksheet = $objPHPExcel->getActiveSheet()->setTitle($gridField->getModelClass()); $col = 'A'; foreach ($excelColumns as $columnSource => $columnHeader) { $heading = !is_string($columnHeader) && is_callable($columnHeader) ? $columnSource : $columnHeader; $worksheet->setCellValue($col . '1', $heading); $col++; } $worksheet->freezePane('A2'); $items = $gridField->getManipulatedList(); // @todo should GridFieldComponents change behaviour based on whether others are available in the config? foreach ($gridField->getConfig()->getComponents() as $component) { if ($component instanceof GridFieldFilterHeader || $component instanceof GridFieldSortableHeader) { $items = $component->getManipulatedData($gridField, $items); } } $row = 2; foreach ($items->limit(null) as $item) { $columnData = array(); $col = 'A'; foreach ($excelColumns as $columnSource => $columnHeader) { if (!is_string($columnHeader) && is_callable($columnHeader)) { if ($item->hasMethod($columnSource)) { $relObj = $item->{$columnSource}(); } else { $relObj = $item->relObject($columnSource); } $value = $columnHeader($relObj); } else { $value = $gridField->getDataFieldValue($item, $columnSource); } $worksheet->getCell($col . $row)->setValueExplicit($value, PHPExcel\Cell\DataType::TYPE_STRING); $col++; } $row++; $item->destroy(); } $writer = PHPExcel\IOFactory::createWriter($objPHPExcel, 'Excel2007'); ob_start(); $writer->save('php://output'); $data = ob_get_clean(); return $data; }
/** * Check whether HTML output is allowed for the given field. * * @param string $fieldName Field name to check * @param GridField $gridField GridField to check * * @return void * * @author Sebastian Diel <*****@*****.**> * @since 26.03.2013 */ public function isHtmlAllowedFor($fieldName, $gridField) { $htmlIsAllowed = false; $object = singleton($gridField->getModelClass()); if ($object instanceof DataObject && $object->hasMethod('allowHtmlDataFor') && is_array($object->allowHtmlDataFor()) && in_array($fieldName, $object->allowHtmlDataFor())) { $htmlIsAllowed = true; } return $htmlIsAllowed; }
/** * Scaffold a bulk loader, if none is provided * * @param GridField $gridField * @return mixed */ public function scaffoldLoader(GridField $gridField) { $gridlist = $gridField->getList(); $class = $gridlist instanceof HasManyList ? "ListBulkLoader" : "BetterBulkLoader"; //set the correct constructor argument $arg = $class === "ListBulkLoader" || is_subclass_of($class, "ListBulkLoader") ? $gridlist : $gridField->getModelClass(); $loader = new $class($arg); $loader->setSource(new CsvBulkLoaderSource()); return $loader; }
/** * Generate export fields for CSV. * * @param GridField $gridField * @return array */ public function generateExportFileData($gridField) { $separator = $this->csvSeparator; $singl = singleton($gridField->getModelClass()); if ($singl->hasMethod('exportedFields')) { $fallbackColumns = $singl->exportedFields(); } else { $fallbackColumns = $singl->summaryFields(); } $csvColumns = $this->exportColumns ? $this->exportColumns : $fallbackColumns; $fileData = ''; $columnData = array(); $fieldItems = new ArrayList(); if ($this->csvHasHeader) { $headers = array(); // determine the CSV headers. If a field is callable (e.g. anonymous function) then use the // source name as the header instead foreach ($csvColumns as $columnSource => $columnHeader) { $headers[] = !is_string($columnHeader) && is_callable($columnHeader) ? utf8_decode($columnSource) : utf8_decode($columnHeader); } $fileData .= "\"" . implode("\"{$separator}\"", array_values($headers)) . "\""; $fileData .= "\n"; } $items = $gridField->getList(); foreach ($items as $item) { if (!$item->hasMethod('canView') || $item->canView()) { $columnData = array(); foreach ($csvColumns as $columnSource => $columnHeader) { if (!is_string($columnHeader) && is_callable($columnHeader)) { if ($item->hasMethod($columnSource)) { $relObj = $item->{$columnSource}(); } else { $relObj = $item->relObject($columnSource); } $value = $columnHeader($relObj); } else { $value = $gridField->getDataFieldValue($item, $columnSource); if (!$value) { $value = $gridField->getDataFieldValue($item, $columnHeader); } } $value = str_replace(array("\r", "\n"), "\n", $value); $columnData[] = '"' . str_replace('"', '""', utf8_decode($value)) . '"'; } $fileData .= implode($separator, $columnData); $fileData .= "\n"; } if ($item->hasMethod('destroy')) { $item->destroy(); } } return $fileData; }
/** * Handles adding a new instance of the grid's model class. * * @param GridField $grid * @param SS_HTTPRequest $request * @throws Exception * @return \GridFieldAddNewMultiClassHandler */ public function handleAdd($grid, $request) { $component = $grid->getConfig()->getComponentByType('GridFieldDetailForm'); if (!$component) { throw new Exception('The ReplicantAddNewButton component requires a detail form component in the grid.'); } $controller = $grid->getForm()->getController(); $className = $grid->getModelClass(); $obj = $className::create(); $handler = new ReplicantAddNewButtonHandler($grid, $component, $obj, $controller); $handler->setTemplate($component->getTemplate()); return $handler; }
/** * Adds the records to the database and returns a new {@link DataList} * * @param GridField * @param SS_List * @return SS_List */ public function getManipulatedData(GridField $gridField, SS_List $dataList) { $state = $gridField->State->MockDataGenerator; $count = (string) $state->Count; if (!$count) { return $dataList; } $generator = new MockDataBuilder($gridField->getModelClass()); $ids = $generator->setCount($count)->setIncludeRelations($state->IncludeRelations)->setDownloadImages($state->DownloadImages === true)->generate(); foreach ($ids as $id) { $dataList->add($id); } return $dataList; }
/** * Generate export fields for CSV. * * Replaces the definition in GridFieldExportButton, this is the same as original except * it sources the {@link List} from $gridField->getList() instead of $gridField->getManipulatedList() * * @param GridField $gridField * @return array */ public function generateExportFileData($gridField) { $separator = $this->csvSeparator; $csvColumns = $this->exportColumns ? $this->exportColumns : singleton($gridField->getModelClass())->summaryFields(); $fileData = ''; $columnData = array(); if ($this->csvHasHeader) { $headers = array(); // determine the CSV headers. If a field is callable (e.g. anonymous function) then use the // source name as the header instead foreach ($csvColumns as $columnSource => $columnHeader) { $headers[] = !is_string($columnHeader) && is_callable($columnHeader) ? $columnSource : $columnHeader; } $fileData .= "\"" . implode("\"{$separator}\"", array_values($headers)) . "\""; $fileData .= "\n"; } // The is the only variation from the parent, using getList() instead of getManipulatedList() $items = $gridField->getList(); // @todo should GridFieldComponents change behaviour based on whether others are available in the config? foreach ($gridField->getConfig()->getComponents() as $component) { if ($component instanceof GridFieldFilterHeader || $component instanceof GridFieldSortableHeader) { $items = $component->getManipulatedData($gridField, $items); } } foreach ($items->limit(null) as $item) { $columnData = array(); foreach ($csvColumns as $columnSource => $columnHeader) { if (!is_string($columnHeader) && is_callable($columnHeader)) { if ($item->hasMethod($columnSource)) { $relObj = $item->{$columnSource}(); } else { $relObj = $item->relObject($columnSource); } $value = $columnHeader($relObj); } else { $value = $gridField->getDataFieldValue($item, $columnSource); } $value = str_replace(array("\r", "\n"), "\n", $value); $columnData[] = '"' . str_replace('"', '\\"', $value) . '"'; } $fileData .= implode($separator, $columnData); $fileData .= "\n"; $item->destroy(); } return $fileData; }
public function getCMSFields() { $fields = parent::getCMSFields(); $fields->removeByName(array('PageID', 'SortOrder', 'Active', 'Title', 'Content', 'Blocks', 'YoutubeVideoID', 'Images', 'Media', 'Files', 'Videos')); if ($this->ID) { $BlockConfig = GridFieldConfig_RelationEditor::create(20); $BlockConfig->addComponent(new GridFieldOrderableRows('SortOrder')); $BlockGF = new GridField('Blocks', 'Blocks', $this->Blocks(), $BlockConfig); $classes = array_values(ClassInfo::subclassesFor($BlockGF->getModelClass())); if (count($classes) > 1 && class_exists('GridFieldAddNewMultiClass')) { $BlockConfig->removeComponentsByType('GridFieldAddNewButton'); $BlockConfig->addComponent(new GridFieldAddNewMultiClass()); } $fields->addFieldToTab("Root.Main", $BlockGF); } return $fields; }
/** * * @param GridField $gridField * @param SS_HTTPRequest $request * @return GridFieldDetailForm_ItemRequest */ public function handleItem($gridField, $request) { // Our getController could either give us a true Controller, if this is the top-level GridField. // It could also give us a RequestHandler in the form of GridFieldDetailForm_ItemRequest if this is a // nested GridField. $requestHandler = $gridField->getForm()->getController(); if (is_numeric($request->param('ID'))) { $record = $gridField->getList()->byId($request->param("ID")); } else { $record = Object::create($gridField->getModelClass()); } $handler = $this->getItemRequestHandler($gridField, $record, $requestHandler); // if no validator has been set on the GridField and the record has a // CMS validator, use that. if (!$this->getValidator() && (method_exists($record, 'getCMSValidator') || $record instanceof Object && $record->hasMethod('getCMSValidator'))) { $this->setValidator($record->getCMSValidator()); } return $handler->handleRequest($request, DataModel::inst()); }
/** * Handles the add action for the given DataObject * * @param $gridFIeld GridFIeld * @param $actionName string * @param $arguments mixed * @param $data array **/ public function handleAction(GridField $gridField, $actionName, $arguments, $data) { if ($actionName == "add") { $dbField = $this->getDataObjectField(); $objClass = $gridField->getModelClass(); $obj = new $objClass(); if ($obj->hasField($dbField)) { $obj->setCastedField($dbField, $data['gridfieldaddbydbfield'][$obj->ClassName][$dbField]); if ($obj->canCreate()) { $id = $gridField->getList()->add($obj); if (!$id) { $gridField->setError(_t("GridFieldAddByDBField.AddFail", "Unable to save {class} to the database.", "Unable to add the DataObject.", array("class" => get_class($obj))), "error"); } } else { return Security::permissionFailure(Controller::curr(), _t("GridFieldAddByDBField.PermissionFail", "You don't have permission to create a {class}.", "Unable to add the DataObject.", array("class" => get_class($obj)))); } } else { throw new UnexpectedValueException("Invalid field (" . $dbField . ") on " . $obj->ClassName . "."); } } }
/** * @covers GridField::getModelClass */ public function testGridFieldModelClassThrowsException() { $this->setExpectedException('LogicException'); $obj = new GridField('testfield', 'testfield', ArrayList::create()); $obj->getModelClass(); }
/** * HTML to be embedded into the GridField. * * @param GridField $gridField * * @return array */ public function getHTMLFragments($gridField) { // permission check if (!singleton($gridField->getModelClass())->canEdit()) { return array(); } // check BulkManager exists $bulkManager = $gridField->getConfig()->getComponentsByType('GridFieldBulkManager'); // upload management buttons $finishButton = FormAction::create('Finish', _t('GRIDFIELD_BULK_UPLOAD.FINISH_BTN_LABEL', 'Finish'))->addExtraClass('bulkUploadFinishButton')->setAttribute('data-icon', 'accept')->setUseButtonTag(true); $clearErrorButton = FormAction::create('ClearError', _t('GRIDFIELD_BULK_UPLOAD.CLEAR_ERROR_BTN_LABEL', 'Clear errors'))->addExtraClass('bulkUploadClearErrorButton')->setAttribute('data-icon', 'arrow-circle-double')->setUseButtonTag(true); if (count($bulkManager)) { $cancelButton = FormAction::create('Cancel', _t('GRIDFIELD_BULK_UPLOAD.CANCEL_BTN_LABEL', 'Cancel'))->addExtraClass('bulkUploadCancelButton ss-ui-action-destructive')->setAttribute('data-icon', 'decline')->setAttribute('data-url', $gridField->Link('bulkupload/cancel'))->setUseButtonTag(true); $bulkManager_config = $bulkManager->first()->getConfig(); $bulkManager_actions = $bulkManager_config['actions']; if (array_key_exists('bulkedit', $bulkManager_actions)) { $editAllButton = FormAction::create('EditAll', _t('GRIDFIELD_BULK_UPLOAD.EDIT_ALL_BTN_LABEL', 'Edit all'))->addExtraClass('bulkUploadEditButton')->setAttribute('data-icon', 'pencil')->setAttribute('data-url', $gridField->Link('bulkupload/edit'))->setUseButtonTag(true); } else { $editAllButton = ''; } } else { $cancelButton = ''; $editAllButton = ''; } // get uploadField + inject extra buttons $uploadField = $this->bulkUploadField($gridField); $uploadField->FinishButton = $finishButton; $uploadField->CancelButton = $cancelButton; $uploadField->EditAllButton = $editAllButton; $uploadField->ClearErrorButton = $clearErrorButton; $data = ArrayData::create(array('Colspan' => count($gridField->getColumns()), 'UploadField' => $uploadField->Field())); Requirements::css(BULKEDITTOOLS_UPLOAD_PATH . '/css/GridFieldBulkUpload.css'); Requirements::javascript(BULKEDITTOOLS_UPLOAD_PATH . '/javascript/GridFieldBulkUpload.js'); Requirements::javascript(BULKEDITTOOLS_UPLOAD_PATH . '/javascript/GridFieldBulkUpload_downloadtemplate.js'); Requirements::add_i18n_javascript(BULKEDITTOOLS_PATH . '/lang/js'); return array('header' => $data->renderWith('GridFieldBulkUpload')); }
/** * Handles the action. * * @param GridField $gridField GridField to handle action for * @param array $recordIDs Record IDs to handle action for * @param array $data Data to handle action for * * @return void * * @author Sebastian Diel <*****@*****.**> * @since 14.03.2013 */ public function handle(GridField $gridField, $recordIDs, $data) { foreach ($recordIDs as $recordID) { $record = DataObject::get_by_id($gridField->getModelClass(), $recordID); if ($record->exists()) { $record->isActive = false; $record->write(); } } }
/** * Handles sorting across pages * @param GridField $gridField Grid Field Reference * @param Array $data Data submitted in the request */ protected function sortToPage(GridField $gridField, $data) { if (!($paginator = $gridField->getConfig()->getComponentsByType('GridFieldPaginator')->First())) { user_error('Paginator not detected', E_USER_ERROR); } if (empty($data['ItemID'])) { user_error('No item to sort', E_USER_ERROR); } if (empty($data['Target'])) { user_error('No target page', E_USER_ERROR); } $className = $gridField->getModelClass(); $owner = $gridField->Form->getRecord(); $items = clone $gridField->getList(); $many_many = $items instanceof ManyManyList; $sortColumn = $this->sortColumn; $targetItem = $items->byID(intval($data['ItemID'])); if (!$targetItem) { user_error('Target item not found', E_USER_ERROR); } $currentPage = 1; $pageState = $gridField->State->GridFieldPaginator; if ($pageState->currentPage && $pageState->currentPage > 1) { $currentPage = $pageState->currentPage; } if ($many_many) { list($parentClass, $componentClass, $parentField, $componentField, $table) = $owner->many_many($gridField->getName()); } if ($data['Target'] == 'previouspage') { $items = $items->limit($paginator->getItemsPerPage() + 1, $paginator->getItemsPerPage() * ($currentPage - 1) - 1); } else { if ($data['Target'] == 'nextpage') { $items = $items->limit($paginator->getItemsPerPage() + 1, $paginator->getItemsPerPage() * ($currentPage - 1)); } else { user_error('Not implemented: ' . $data['Target'], E_USER_ERROR); } } $sortPositions = $items->column($sortColumn); //Event to notify the Controller or owner DataObject before list sort if ($owner && $owner instanceof DataObject && method_exists($owner, 'onBeforeGridFieldPageSort')) { $owner->onBeforeGridFieldPageSort(clone $items); } else { if (Controller::has_curr() && Controller::curr() instanceof ModelAdmin && method_exists(Controller::curr(), 'onBeforeGridFieldPageSort')) { Controller::curr()->onBeforeGridFieldPageSort(clone $items); } } //Start transaction if supported if (DB::getConn()->supportsTransactions()) { DB::getConn()->transactionStart(); } if ($data['Target'] == 'previouspage') { if ($many_many) { DB::query('UPDATE "' . $table . '" SET "' . $sortColumn . '" = ' . $sortPositions[0] . ' WHERE "' . $componentField . '" = ' . $targetItem->ID . ' AND "' . $parentField . '" = ' . $owner->ID); } else { $targetItem->{$sortColumn} = $sortPositions[0]; $targetItem->write(); } $i = 1; foreach ($items as $obj) { if ($obj->ID == $targetItem->ID) { continue; } if ($many_many) { DB::query('UPDATE "' . $table . '" SET "' . $sortColumn . '" = ' . $sortPositions[$i] . ' WHERE "' . $componentField . '" = ' . $obj->ID . ' AND "' . $parentField . '" = ' . $owner->ID); } else { $obj->{$sortColumn} = $sortPositions[$i]; $obj->write(); } $i++; } } else { if ($many_many) { DB::query('UPDATE "' . $table . '" SET "' . $sortColumn . '" = ' . $sortPositions[count($sortPositions) - 1] . ' WHERE "' . $componentField . '" = ' . $targetItem->ID . ' AND "' . $parentField . '" = ' . $owner->ID); } else { $targetItem->{$sortColumn} = $sortPositions[count($sortPositions) - 1]; $targetItem->write(); } $i = 0; foreach ($items as $obj) { if ($obj->ID == $targetItem->ID) { continue; } if ($many_many) { DB::query('UPDATE "' . $table . '" SET "' . $sortColumn . '" = ' . $sortPositions[$i] . ' WHERE "' . $componentField . '" = ' . $obj->ID . ' AND "' . $parentField . '" = ' . $owner->ID); } else { $obj->{$sortColumn} = $sortPositions[$i]; $obj->write(); } $i++; } } //End transaction if supported if (DB::getConn()->supportsTransactions()) { DB::getConn()->transactionEnd(); } //Event to notify the Controller or owner DataObject after list sort if ($owner && $owner instanceof DataObject && method_exists($owner, 'onAfterGridFieldPageSort')) { $owner->onAfterGridFieldPageSort(clone $items); } else { if (Controller::has_curr() && Controller::curr() instanceof ModelAdmin && method_exists(Controller::curr(), 'onAfterGridFieldPageSort')) { Controller::curr()->onAfterGridFieldPageSort(clone $items); } } }
/** * Handles requests to reorder a set of IDs in a specific order. * * @param GridField $grid * @param SS_HTTPRequest $request * @return SS_HTTPResponse */ public function handleReorder($grid, $request) { $list = $grid->getList(); $modelClass = $grid->getModelClass(); if ($list instanceof ManyManyList && !singleton($modelClass)->canView()) { $this->httpError(403); } else { if (!$list instanceof ManyManyList && !singleton($modelClass)->canEdit()) { $this->httpError(403); } } $ids = $request->postVar('order'); $field = $this->getSortField(); if (!is_array($ids)) { $this->httpError(400); } $sortterm = ''; if ($this->extraSortFields) { if (is_array($this->extraSortFields)) { foreach ($this->extraSortFields as $col => $dir) { $sortterm .= "{$col} {$dir}, "; } } else { $sortterm = $this->extraSortFields . ', '; } } $sortterm .= '"' . $this->getSortTable($list) . '"."' . $field . '"'; $items = $list->filter('ID', $ids)->sort($sortterm); // Ensure that each provided ID corresponded to an actual object. if (count($items) != count($ids)) { $this->httpError(404); } // Save any un-comitted changes to the gridfield if (($form = $grid->getForm()) && ($record = $form->getRecord())) { $form->loadDataFrom($request->requestVars(), true); $grid->saveInto($record); } // Populate each object we are sorting with a sort value. $this->populateSortValues($items); // Generate the current sort values. if ($items instanceof ManyManyList) { $current = array(); foreach ($items->toArray() as $record) { // NOTE: _SortColumn0 is the first ->sort() field // used by SS when functions are detected in a SELECT // or CASE WHEN. if (isset($record->_SortColumn0)) { $current[$record->ID] = $record->_SortColumn0; } else { $current[$record->ID] = $record->{$field}; } } } else { $current = $items->map('ID', $field)->toArray(); } // Perform the actual re-ordering. $this->reorderItems($list, $current, $ids); return $grid->FieldHolder(); }
/** * Handles the add action for the given DataObject * * @param $gridFIeld GridFIeld * @param $actionName string * @param $arguments mixed * @param $data array **/ public function handleAction(GridField $gridField, $actionName, $arguments, $data) { if ($actionName == "add") { // Get our submitted fields and object class $dbField = $this->getDataObjectField(); $objClass = $gridField->getModelClass(); $source_class = $this->getSourceClass(); $filter = array(); // Has the user used autocomplete if (isset($data['relationID']) && $data['relationID']) { $id = $data['relationID']; } else { $id = null; } $obj = new $objClass(); // Is this a valid field if (!$obj->hasField($dbField)) { throw new UnexpectedValueException("Invalid field (" . $dbField . ") on " . $obj->ClassName . "."); } // If we have an ID try and get an existing object then // check if we have a copy in items if ($id) { $source_item = $source_class::get()->byID($id); foreach ($this->getFilterFields() as $filter_field) { $filter[$filter_field] = $source_item->{$filter_field}; } } else { // Generate the filter we need to use $string = $data['gridfieldaddbydbfield']; foreach ($this->getFilterFields() as $filter_field) { $filter[$filter_field] = $string; } } // First check if we already have an object or if we need to // create one $existing_obj = $gridField->getList()->filterAny($filter)->first(); if ($existing_obj) { $obj = $existing_obj; } if ($obj->ID && $obj->canEdit()) { // An existing record and can edit, update quantity $curr_qty = $obj->Quantity ? $obj->Quantity : 0; $obj->setCastedField("Quantity", $curr_qty + 1); $id = $gridField->getList()->add($obj); } if (!$obj->ID && $obj->canCreate()) { // If source item not set, try and get one or get a // an existing record if (!$source_item) { $source_item = $source_class::get()->filterAny($filter)->first(); } if ($source_item) { foreach ($this->getSourceFields() as $obj_field => $source_field) { $obj->setCastedField($obj_field, $source_item->{$source_field}); } } else { $obj->setCastedField($this->getCreateField(), $string); } $obj->setCastedField("Quantity", 1); $id = $gridField->getList()->add($obj); } if (!$id) { $gridField->setError(_t("GridFieldAddOrderItem.AddFail", "Unable to save {class} to the database.", "Unable to add the DataObject.", array("class" => get_class($obj))), "error"); } // Finally, issue a redirect to update totals $controller = Controller::curr(); $response = $controller->response; $response->addHeader('X-Pjax', 'Content'); $response->addHeader('X-Reload', true); return $controller->redirect($gridField->getForm()->controller->Link(), 302); } }
/** * Generate export fields for Excel. * * @param GridField $gridField * @return PHPExcel */ public function generateExportFileData($gridField) { $class = $gridField->getModelClass(); $columns = $this->exportColumns ? $this->exportColumns : ExcelImportExport::exportFieldsForClass($class); $fileData = ''; $singl = singleton($class); $singular = $class ? $singl->i18n_singular_name() : ''; $plural = $class ? $singl->i18n_plural_name() : ''; $filter = new FileNameFilter(); if ($this->exportName) { $this->exportName = $filter->filter($this->exportName); } else { $this->exportName = $filter->filter('export-' . $plural); } $excel = new PHPExcel(); $excelProperties = $excel->getProperties(); $excelProperties->setTitle($this->exportName); $sheet = $excel->getActiveSheet(); if ($plural) { $sheet->setTitle($plural); } $row = 1; $col = 0; if ($this->hasHeader) { $headers = array(); // determine the headers. If a field is callable (e.g. anonymous function) then use the // source name as the header instead foreach ($columns as $columnSource => $columnHeader) { $headers[] = !is_string($columnHeader) && is_callable($columnHeader) ? $columnSource : $columnHeader; } foreach ($headers as $header) { $sheet->setCellValueByColumnAndRow($col, $row, $header); $col++; } $endcol = PHPExcel_Cell::stringFromColumnIndex($col - 1); $sheet->setAutoFilter("A1:{$endcol}1"); $sheet->getStyle("A1:{$endcol}1")->getFont()->setBold(true); $col = 0; $row++; } // Autosize $cellIterator = $sheet->getRowIterator()->current()->getCellIterator(); try { $cellIterator->setIterateOnlyExistingCells(true); } catch (Exception $ex) { continue; } foreach ($cellIterator as $cell) { $sheet->getColumnDimension($cell->getColumn())->setAutoSize(true); } //Remove GridFieldPaginator as we're going to export the entire list. $gridField->getConfig()->removeComponentsByType('GridFieldPaginator'); $items = $gridField->getManipulatedList(); // @todo should GridFieldComponents change behaviour based on whether others are available in the config? foreach ($gridField->getConfig()->getComponents() as $component) { if ($component instanceof GridFieldFilterHeader || $component instanceof GridFieldSortableHeader) { $items = $component->getManipulatedData($gridField, $items); } } foreach ($items->limit(null) as $item) { if (!$item->hasMethod('canView') || $item->canView()) { foreach ($columns as $columnSource => $columnHeader) { if (!is_string($columnHeader) && is_callable($columnHeader)) { if ($item->hasMethod($columnSource)) { $relObj = $item->{$columnSource}(); } else { $relObj = $item->relObject($columnSource); } $value = $columnHeader($relObj); } else { $value = $gridField->getDataFieldValue($item, $columnSource); if ($value === null) { $value = $gridField->getDataFieldValue($item, $columnHeader); } } $value = str_replace(array("\r", "\n"), "\n", $value); $sheet->setCellValueByColumnAndRow($col, $row, $value); $col++; } } if ($item->hasMethod('destroy')) { $item->destroy(); } $col = 0; $row++; } return $excel; }
/** * Generate export fields for CSV. * * @param GridField $gridField * @return array */ public function generateExportFileData($gridField) { $csvColumns = $this->exportColumns ? $this->exportColumns : singleton($gridField->getModelClass())->summaryFields(); $fileData = array(); if ($this->csvHasHeader) { $headers = array(); // determine the CSV headers. If a field is callable (e.g. anonymous function) then use the // source name as the header instead foreach ($csvColumns as $columnSource => $columnHeader) { $headers[] = !is_string($columnHeader) && is_callable($columnHeader) ? $columnSource : $columnHeader; } $fileData[] = $headers; } //Remove GridFieldPaginator as we're going to export the entire list. $gridField->getConfig()->removeComponentsByType('GridFieldPaginator'); $items = $gridField->getManipulatedList(); // @todo should GridFieldComponents change behaviour based on whether others are available in the config? foreach ($gridField->getConfig()->getComponents() as $component) { if ($component instanceof GridFieldFilterHeader || $component instanceof GridFieldSortableHeader) { $items = $component->getManipulatedData($gridField, $items); } } foreach ($items->limit(null) as $item) { if (!$item->hasMethod('canView') || $item->canView()) { $columnData = array(); foreach ($csvColumns as $columnSource => $columnHeader) { if (!is_string($columnHeader) && is_callable($columnHeader)) { if ($item->hasMethod($columnSource)) { $relObj = $item->{$columnSource}(); } else { $relObj = $item->relObject($columnSource); } $value = $columnHeader($relObj); } else { $value = $gridField->getDataFieldValue($item, $columnSource); if (!$value) { $value = $gridField->getDataFieldValue($item, $columnHeader); } } $columnData[] = $value; } $fileData[] = $columnData; } if ($item->hasMethod('destroy')) { $item->destroy(); } } // Convert the $fileData array into csv by capturing fputcsv's output $csv = fopen('php://temp', 'r+'); foreach ($fileData as $line) { fputcsv($csv, $line, $this->csvSeparator, $this->csvEnclosure); } rewind($csv); return stream_get_contents($csv); }
/** * @param GridField $gridField * @param array|SS_HTTPRequest $data * @return array */ public function handleIt($gridField, $data = array()) { if ($data instanceof SS_HTTPRequest) { $data = $data->requestVars(); } // Separate out the ID list from the checkboxes $fieldName = GridFieldCheckboxSelectComponent::CHECKBOX_COLUMN; $ids = isset($data[$fieldName]) && is_array($data[$fieldName]) ? $data[$fieldName] : array(); $class = $gridField->getModelClass(); if (!$class) { user_error('No model class is defined!'); } $response = array(); // Hook for subclasses $this->onBeforeList($gridField, $data, $ids); if (empty($ids)) { $this->onEmptyList($gridField, $response, $data, $ids); $records = new ArrayList(); } else { $records = DataObject::get($class)->filter('ID', $ids); foreach ($records as $index => $record) { call_user_func($this->rowHandler, $record, $index); } } $this->onAfterList($gridField, $response, $records, $data, $ids); return $response; }
/** * Handle the actions and apply any changes to the GridField * * @param GridField $gridField * @param string $actionName * @param mixed $arguments * @param array $data - form data * @return void */ public function handleAction(GridField $gridField, $actionName, $arguments, $data) { if ($actionName == 'unpublish' || $actionName == 'publish') { $item = Versioned::get_latest_version($gridField->getModelClass(), $arguments['RecordID']); if (!$item) { return; } if ($actionName == 'unpublish') { if (!$item->canPublish()) { throw new ValidationException(_t('GridFieldAction_Delete.DeletePermissionsFailure', "No delete permissions"), 0); } $item->doUnpublish(); } if ($actionName == 'publish') { if (!$item->canPublish()) { throw new ValidationException(_t('GridFieldAction_Delete.DeletePermissionsFailure', "No delete permissions"), 0); } $item->doPublish(); } } }
/** * Set the HTTP header to force a download and set the filename. * @param GridField $gridField * @param string $ext Extension to use in the filename. */ protected function setHeader($gridField, $ext) { $do = singleton($gridField->getModelClass()); Controller::curr()->getResponse()->addHeader("Content-Disposition", 'attachment; filename="' . $do->i18n_plural_name() . '.' . $ext . '"'); }
/** * Generate export fields for EXCEL. * * @param GridField $gridField * @return array */ public function generateExportFileData($gridField) { $excelColumns = $this->exportColumns ? $this->exportColumns : singleton($gridField->getModelClass())->summaryFields(); $objPHPExcel = new PHPExcel(); $worksheet = $objPHPExcel->getActiveSheet()->setTitle(singleton($gridField->getModelClass())->i18n_singular_name()); $col = 'A'; foreach ($excelColumns as $columnSource => $columnHeader) { $heading = !is_string($columnHeader) && is_callable($columnHeader) ? $columnSource : $columnHeader; $worksheet->setCellValue($col . '1', $heading); $col++; } $worksheet->freezePane('A2'); $items = $gridField->getManipulatedList(); // @todo should GridFieldComponents change behaviour based on whether others are available in the config? foreach ($gridField->getConfig()->getComponents() as $component) { if ($component instanceof GridFieldFilterHeader || $component instanceof GridFieldSortableHeader) { $items = $component->getManipulatedData($gridField, $items); } } $row = 2; foreach ($items->limit(null) as $item) { if (!$item->hasMethod('canView') || $item->canView()) { $columnData = array(); $col = 'A'; foreach ($excelColumns as $columnSource => $columnHeader) { if (!is_string($columnHeader) && is_callable($columnHeader)) { if ($item->hasMethod($columnSource)) { $relObj = $item->{$columnSource}(); } else { $relObj = $item->relObject($columnSource); } $value = $columnHeader($relObj); $worksheet->getCell($col . $row)->setValueExplicit($value, PHPExcel_Cell_DataType::TYPE_STRING); } else { $component = $item; $value = $gridField->getDataFieldValue($item, $columnSource); if (strpos($columnSource, '.') !== false) { $relations = explode('.', $columnSource); foreach ($relations as $relation) { if ($component->hasMethod($relation)) { $component = $component->{$relation}(); } elseif ($component instanceof SS_List) { $component = $component->relation($relation); } elseif ($component instanceof DataObject && ($dbObject = $component->obj($relation, null, false))) { $component = $dbObject; } } } elseif ($component instanceof DataObject && ($dbObject = $component->obj($columnSource, null, false))) { $component = $dbObject; } if (!$value) { $component = $item; $value = $gridField->getDataFieldValue($item, $columnHeader); if (strpos($columnHeader, '.') !== false) { $relations = explode('.', $columnHeader); foreach ($relations as $relation) { if ($component->hasMethod($relation)) { $component = $component->{$relation}(); } elseif ($component instanceof SS_List) { $component = $component->relation($relation); } elseif ($component instanceof DataObject && ($dbObject = $component->obj($relation, null, false))) { $component = $dbObject; } } } elseif ($component instanceof DataObject && ($dbObject = $component->obj($columnHeader, null, false))) { $component = $dbObject; } } if ($component && ($component instanceof Decimal || $component instanceof Float || $component instanceof Int || is_numeric($component))) { $worksheet->getCell($col . $row)->setValue($value); } else { $worksheet->getCell($col . $row)->setValueExplicit($value, PHPExcel_Cell_DataType::TYPE_STRING); } } $col++; } $row++; } if ($item->hasMethod('destroy')) { $item->destroy(); } } $writer = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5'); ob_start(); $writer->save('php://output'); $data = ob_get_clean(); return $data; }