/** * Out of the box, the handler "CurrentForm" value, which will return the rendered form. * Non-Ajax calls will redirect back. * * @param HTTPRequest $request * @param array $extraCallbacks List of anonymous functions or callables returning either a string * or HTTPResponse, keyed by their fragment identifier. The 'default' key can * be used as a fallback for non-ajax responses. * @return HTTPResponse * @throws HTTPResponse_Exception */ public function respond(HTTPRequest $request, $extraCallbacks = array()) { // Prepare the default options and combine with the others $callbacks = array_merge($this->callbacks, $extraCallbacks); $response = $this->getResponse(); $responseParts = array(); if (isset($this->fragmentOverride)) { $fragments = $this->fragmentOverride; } elseif ($fragmentStr = $request->getHeader('X-Pjax')) { $fragments = explode(',', $fragmentStr); } else { if ($request->isAjax()) { throw new HTTPResponse_Exception("Ajax requests to this URL require an X-Pjax header.", 400); } elseif (empty($callbacks['default'])) { throw new HTTPResponse_Exception("Missing default response handler for this URL", 400); } $response->setBody(call_user_func($callbacks['default'])); return $response; } // Execute the fragment callbacks and build the response. foreach ($fragments as $fragment) { if (isset($callbacks[$fragment])) { $res = call_user_func($callbacks[$fragment]); $responseParts[$fragment] = $res ? (string) $res : $res; } else { throw new HTTPResponse_Exception("X-Pjax = '{$fragment}' not supported for this URL.", 400); } } $response->setBody(Convert::raw2json($responseParts)); $response->addHeader('Content-Type', 'text/json'); return $response; }
/** * @inheritdoc * * @param HTTPRequest $request * @param Session $session * @param DataModel $model * * @return bool */ public function preRequest(HTTPRequest $request, Session $session, DataModel $model) { if (array_key_exists('flush', $request->getVars())) { foreach (ClassInfo::implementorsOf('SilverStripe\\Core\\Flushable') as $class) { $class::flush(); } } return true; }
public function testGetURL() { $req = new HTTPRequest('GET', '/'); $this->assertEquals('', $req->getURL()); $req = new HTTPRequest('GET', '/assets/somefile.gif'); $this->assertEquals('assets/somefile.gif', $req->getURL()); $req = new HTTPRequest('GET', '/home?test=1'); $this->assertEquals('home?test=1', $req->getURL(true)); $this->assertEquals('home', $req->getURL()); }
/** * Check if we should merge * * @param HTTPRequest $request * @return bool */ protected function getIsMerge($request) { $merge = $request->getVar('merge'); // Default to true if not given if (!isset($merge)) { return true; } // merge=0 or merge=false will disable merge return !in_array($merge, array('0', 'false')); }
/** * Get the file component from the request * * @param HTTPRequest $request * @return string */ protected function parseFilename(HTTPRequest $request) { $filename = ''; $next = $request->param('Filename'); while ($next) { $filename = $filename ? File::join_paths($filename, $next) : $next; $next = $request->shift(); } if ($extension = $request->getExtension()) { $filename = $filename . "." . $extension; } return $filename; }
public function testFragmentsOverride() { $negotiator = new PjaxResponseNegotiator(array('alpha' => function () { return 'alpha response'; }, 'beta' => function () { return 'beta response'; })); $request = new HTTPRequest('GET', '/'); $request->addHeader('X-Pjax', 'alpha'); $request->addHeader('Accept', 'text/json'); $response = $negotiator->setFragmentOverride(array('beta'))->respond($request); $json = json_decode($response->getBody()); $this->assertFalse(isset($json->alpha)); $this->assertObjectHasAttribute('beta', $json); }
/** * @param HTTPRequest $request */ public function runTask($request) { $name = $request->param('TaskName'); $tasks = $this->getTasks(); $title = function ($content) { printf(Director::is_cli() ? "%s\n\n" : '<h1>%s</h1>', $content); }; $message = function ($content) { printf(Director::is_cli() ? "%s\n" : '<p>%s</p>', $content); }; foreach ($tasks as $task) { if ($task['segment'] == $name) { $inst = Injector::inst()->create($task['class']); $title(sprintf('Running Task %s', $inst->getTitle())); if (!$inst->isEnabled()) { $message('The task is disabled'); return; } $inst->run($request); return; } } $message(sprintf('The build task "%s" could not be found', Convert::raw2xml($name))); }
/** * * @param GridField $gridField * @param 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(); /** @var DataObject $record */ 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()); }
/** * Show the "password sent" page, after a user has requested * to reset their password. * * @param HTTPRequest $request The HTTPRequest for this action. * @return string Returns the "password sent" page as HTML code. */ public function passwordsent($request) { $controller = $this->getResponseController(_t('Security.LOSTPASSWORDHEADER', 'Lost Password')); // if the controller calls Director::redirect(), this will break early if (($response = $controller->getResponse()) && $response->isFinished()) { return $response; } $email = Convert::raw2xml(rawurldecode($request->param('ID')) . '.' . $request->getExtension()); $customisedController = $controller->customise(array('Title' => _t('Security.PASSWORDSENTHEADER', "Password reset link sent to '{email}'", array('email' => $email)), 'Content' => "<p>" . _t('Security.PASSWORDSENTTEXT', "Thank you! A reset link has been sent to '{email}', provided an account exists for this email" . " address.", array('email' => $email)) . "</p>", 'Email' => $email)); //Controller::$currentController = $controller; return $customisedController->renderWith($this->getTemplatesFor('passwordsent')); }
/** * View of a single file, either on the filesystem or on the web. * * @throws HTTPResponse_Exception * @param HTTPRequest $request * @return string */ public function viewfile($request) { $file = null; $url = null; // Get file and url by request method if ($fileUrl = $request->getVar('FileURL')) { // Get remote url list($file, $url) = $this->viewfile_getRemoteFileByURL($fileUrl); } elseif ($id = $request->getVar('ID')) { // Or we could have been passed an ID directly list($file, $url) = $this->viewfile_getLocalFileByID($id); } else { // Or we could have been passed nothing, in which case panic throw $this->getErrorFor(_t("HTMLEditorField_Toolbar.ERROR_ID", 'Need either "ID" or "FileURL" parameter to identify the file')); } // Validate file exists if (!$url) { throw $this->getErrorFor(_t("HTMLEditorField_Toolbar.ERROR_NOTFOUND", 'Unable to find file to view')); } // Instantiate file wrapper and get fields based on its type // Check if appCategory is an image and exists on the local system, otherwise use Embed to reference a // remote image $fileCategory = $this->getFileCategory($url, $file); switch ($fileCategory) { case 'image': case 'image/supported': $fileWrapper = new HTMLEditorField_Image($url, $file); break; case 'flash': $fileWrapper = new HTMLEditorField_Flash($url, $file); break; default: // Only remote files can be linked via o-embed // {@see HTMLEditorField_Toolbar::getAllowedExtensions()) if ($file) { throw $this->getErrorFor(_t("HTMLEditorField_Toolbar.ERROR_OEMBED_REMOTE", "Embed is only compatible with remote files")); } // Other files should fallback to embed $fileWrapper = new HTMLEditorField_Embed($url, $file); break; } // Render fields and return $fields = $this->getFieldsForFile($url, $fileWrapper); return $fileWrapper->customise(array('Fields' => $fields))->renderWith($this->getTemplateViewFile()); }
/** * Handle an HTTP request, defined with a HTTPRequest object. * * @skipUpgrade * @param HTTPRequest $request * @param Session $session * @param DataModel $model * @return HTTPResponse|string */ protected static function handleRequest(HTTPRequest $request, Session $session, DataModel $model) { $rules = Director::config()->get('rules'); if (isset($_REQUEST['debug'])) { Debug::show($rules); } foreach ($rules as $pattern => $controllerOptions) { if (is_string($controllerOptions)) { if (substr($controllerOptions, 0, 2) == '->') { $controllerOptions = array('Redirect' => substr($controllerOptions, 2)); } else { $controllerOptions = array('Controller' => $controllerOptions); } } if (($arguments = $request->match($pattern, true)) !== false) { $request->setRouteParams($controllerOptions); // controllerOptions provide some default arguments $arguments = array_merge($controllerOptions, $arguments); // Pop additional tokens from the tokenizer if necessary if (isset($controllerOptions['_PopTokeniser'])) { $request->shift($controllerOptions['_PopTokeniser']); } // Handle redirection if (isset($arguments['Redirect'])) { return "redirect:" . Director::absoluteURL($arguments['Redirect'], true); } else { // Find the controller name $controller = $arguments['Controller']; Director::$urlParams = $arguments; $controllerObj = Injector::inst()->create($controller); $controllerObj->setSession($session); try { $result = $controllerObj->handleRequest($request, $model); } catch (HTTPResponse_Exception $responseException) { $result = $responseException->getResponse(); } if (!is_object($result) || $result instanceof HTTPResponse) { return $result; } user_error("Bad result from url " . $request->getURL() . " handled by " . get_class($controllerObj) . " controller: " . get_class($result), E_USER_WARNING); } } } // No URL rules matched, so return a 404 error. return new HTTPResponse('No URL rule was matched', 404); }
/** * Url handler for edit form * * @param HTTPRequest $request * @return Form */ public function DetailEditForm($request) { // Get ID either from posted back value, or url parameter $id = $request->param('ID') ?: $request->postVar('ID'); return $this->getDetailEditForm($id); }
/** * Url handler for add to campaign form * * @param HTTPRequest $request * @return Form */ public function addToCampaignForm($request) { // Get ID either from posted back value, or url parameter $id = $request->param('ID') ?: $request->postVar('ID'); return $this->getAddToCampaignForm($id); }
/** * Handle a field request. * Uses {@link Form->dataFieldByName()} to find a matching field, * and falls back to {@link FieldList->fieldByName()} to look * for tabs instead. This means that if you have a tab and a * formfield with the same name, this method gives priority * to the formfield. * * @param HTTPRequest $request * @return FormField */ public function handleField($request) { $field = $this->Fields()->dataFieldByName($request->param('FieldName')); if ($field) { return $field; } else { // falling back to fieldByName, e.g. for getting tabs return $this->Fields()->fieldByName($request->param('FieldName')); } }
/** * @param HTTPRequest $request * @return mixed */ public function edit($request) { $controller = $this->getToplevelController(); $form = $this->ItemEditForm(); $return = $this->customise(array('Backlink' => $controller->hasMethod('Backlink') ? $controller->Backlink() : $controller->Link(), 'ItemEditForm' => $form))->renderWith($this->getTemplates()); if ($request->isAjax()) { return $return; } else { // If not requested by ajax, we need to render it within the controller context+template return $controller->customise(array('Content' => $return)); } }
/** * Controller's default action handler. It will call the method named in "$Action", if that method * exists. If "$Action" isn't given, it will use "index" as a default. * * @param HTTPRequest $request * @param string $action * * @return DBHTMLText|HTTPResponse */ protected function handleAction($request, $action) { foreach ($request->latestParams() as $k => $v) { if ($v || !isset($this->urlParams[$k])) { $this->urlParams[$k] = $v; } } $this->action = $action; $this->requestParams = $request->requestVars(); if ($this->hasMethod($action)) { $result = parent::handleAction($request, $action); // If the action returns an array, customise with it before rendering the template. if (is_array($result)) { return $this->getViewer($action)->process($this->customise($result)); } else { return $result; } } // Fall back to index action with before/after handlers $beforeResult = $this->extend('beforeCallActionHandler', $request, $action); if ($beforeResult) { return reset($beforeResult); } $result = $this->getViewer($action)->process($this); $afterResult = $this->extend('afterCallActionHandler', $request, $action, $result); if ($afterResult) { return reset($afterResult); } return $result; }
/** * This is the action that gets executed when a GridField_AlterAction gets clicked. * * @param array $data * @param Form $form * @param HTTPRequest $request * * @return string */ public function gridFieldAlterAction($data, $form, HTTPRequest $request) { $data = $request->requestVars(); // Protection against CSRF attacks $token = $this->getForm()->getSecurityToken(); if (!$token->checkRequest($request)) { $this->httpError(400, _t("Form.CSRF_FAILED_MESSAGE", "There seems to have been a technical problem. Please click the back button, " . "refresh your browser, and try again.")); } $name = $this->getName(); $fieldData = null; if (isset($data[$name])) { $fieldData = $data[$name]; } $state = $this->getState(false); /** @skipUpgrade */ if (isset($fieldData['GridState'])) { $state->setValue($fieldData['GridState']); } foreach ($data as $dataKey => $dataValue) { if (preg_match('/^action_gridFieldAlterAction\\?StateID=(.*)/', $dataKey, $matches)) { $stateChange = Session::get($matches[1]); $actionName = $stateChange['actionName']; $arguments = array(); if (isset($stateChange['args'])) { $arguments = $stateChange['args']; } $html = $this->handleAlterAction($actionName, $arguments, $data); if ($html) { return $html; } } } if ($request->getHeader('X-Pjax') === 'CurrentField') { return $this->FieldHolder(); } return $form->forTemplate(); }
/** * Determine if the current user is able to set the given site stage / archive * * @param HTTPRequest $request * @return bool */ public static function can_choose_site_stage($request) { // Request is allowed if stage isn't being modified if ((!$request->getVar('stage') || $request->getVar('stage') === static::LIVE) && !$request->getVar('archiveDate')) { return true; } // Check permissions with member ID in session. $member = Member::currentUser(); $permissions = Config::inst()->get(get_called_class(), 'non_live_permissions'); return $member && Permission::checkMember($member, $permissions); }
/** * Determines if a specified file exists * * @param HTTPRequest $request * @return HTTPResponse */ public function fileexists(HTTPRequest $request) { // Assert that requested filename doesn't attempt to escape the directory $originalFile = $request->requestVar('filename'); if ($originalFile !== basename($originalFile)) { $return = array('error' => _t('File.NOVALIDUPLOAD', 'File is not a valid upload')); } else { $return = array('exists' => $this->checkFileExists($originalFile)); } // Encode and present response $response = new HTTPResponse(Convert::raw2json($return)); $response->addHeader('Content-Type', 'application/json'); if (!empty($return['error'])) { $response->setStatusCode(400); } return $response; }
public function handleRequest(HTTPRequest $request, DataModel $model) { // If this is the final portion of the request (i.e. the URL is just /admin), direct to the default panel if ($request->allParsed()) { $segment = Config::inst()->get($this->config()->default_panel, 'url_segment'); $this->redirect(Controller::join_links(self::admin_url(), $segment, '/')); return $this->getResponse(); } else { $rules = self::rules(); foreach ($rules as $pattern => $controller) { if (($arguments = $request->match($pattern, true)) !== false) { $controllerObj = Injector::inst()->create($controller); $controllerObj->setSession($this->session); return $controllerObj->handleRequest($request, $model); } } } return $this->httpError(404, 'Not found'); }
/** * Returns a json array of a search results that can be used by for example Jquery.ui.autosuggestion * * @param GridField $gridField * @param HTTPRequest $request * @return string */ public function doSearch($gridField, $request) { $dataClass = $gridField->getModelClass(); $allList = $this->searchList ? $this->searchList : DataList::create($dataClass); $searchFields = $this->getSearchFields() ? $this->getSearchFields() : $this->scaffoldSearchFields($dataClass); if (!$searchFields) { throw new LogicException(sprintf('GridFieldAddExistingAutocompleter: No searchable fields could be found for class "%s"', $dataClass)); } $params = array(); foreach ($searchFields as $searchField) { $name = strpos($searchField, ':') !== FALSE ? $searchField : "{$searchField}:StartsWith"; $params[$name] = $request->getVar('gridfield_relationsearch'); } $results = $allList->subtract($gridField->getList())->filterAny($params)->sort(strtok($searchFields[0], ':'), 'ASC')->limit($this->getResultsLimit()); $json = array(); Config::nest(); SSViewer::config()->update('source_file_comments', false); $viewer = SSViewer::fromString($this->resultsFormat); foreach ($results as $result) { $title = html_entity_decode($viewer->process($result)); $json[] = array('label' => $title, 'value' => $title, 'id' => $result->ID); } Config::unnest(); return Convert::array2json($json); }
public function testSubActions() { /* If a controller action returns another controller, ensure that the $action variable is correctly forwarded */ $response = $this->get("ControllerTest_ContainerController/subcontroller/subaction"); $this->assertEquals('subaction', $response->getBody()); $request = new HTTPRequest('GET', 'ControllerTest_ContainerController/subcontroller/substring/subvieweraction'); /* Shift to emulate the director selecting the controller */ $request->shift(); /* Handle the request to create conditions where improperly passing the action to the viewer might fail */ $controller = new ControllerTest_ContainerController(); try { $controller->handleRequest($request, DataModel::inst()); } catch (ControllerTest_SubController_Exception $e) { $this->fail($e->getMessage()); } }
/** * Allows requesting a view update on specific tree nodes. * Similar to {@link getsubtree()}, but doesn't enforce loading * all children with the node. Useful to refresh views after * state modifications, e.g. saving a form. * * @param HTTPRequest $request * @return string JSON */ public function updatetreenodes($request) { $data = array(); $ids = explode(',', $request->getVar('ids')); foreach ($ids as $id) { if ($id === "") { continue; } // $id may be a blank string, which is invalid and should be skipped over $record = $this->getRecord($id); if (!$record) { continue; } // In case a page is no longer available $recordController = $this->stat('tree_class') == 'SilverStripe\\CMS\\Model\\SiteTree' ? CMSPageEditController::singleton() : $this; // Find the next & previous nodes, for proper positioning (Sort isn't good enough - it's not a raw offset) // TODO: These methods should really be in hierarchy - for a start it assumes Sort exists $next = $prev = null; $className = $this->stat('tree_class'); $next = DataObject::get($className)->filter('ParentID', $record->ParentID)->filter('Sort:GreaterThan', $record->Sort)->first(); if (!$next) { $prev = DataObject::get($className)->filter('ParentID', $record->ParentID)->filter('Sort:LessThan', $record->Sort)->reverse()->first(); } $link = Controller::join_links($recordController->Link("show"), $record->ID); $html = LeftAndMain_TreeNode::create($record, $link, $this->isCurrentPage($record))->forTemplate() . '</li>'; $data[$id] = array('html' => $html, 'ParentID' => $record->ParentID, 'NextID' => $next ? $next->ID : null, 'PrevID' => $prev ? $prev->ID : null); } $this->getResponse()->addHeader('Content-Type', 'text/json'); return Convert::raw2json($data); }
/** * Get security token from request * * @param HTTPRequest $request * @return string */ protected function getRequestToken($request) { $name = $this->getName(); $header = 'X-' . ucwords(strtolower($name)); if ($token = $request->getHeader($header)) { return $token; } // Get from request var return $request->requestVar($name); }
public function runRegisteredController(HTTPRequest $request) { $controllerClass = null; $baseUrlPart = $request->param('Action'); $reg = Config::inst()->get(__CLASS__, 'registered_controllers'); if (isset($reg[$baseUrlPart])) { $controllerClass = $reg[$baseUrlPart]['controller']; } if ($controllerClass && class_exists($controllerClass)) { return $controllerClass::create(); } $msg = 'Error: no controller registered in ' . __CLASS__ . ' for: ' . $request->param('Action'); if (Director::is_cli()) { // in CLI we cant use httpError because of a bug with stuff being in the output already, see DevAdminControllerTest throw new Exception($msg); } else { $this->httpError(500, $msg); } }
public function testCheckRequest() { $t = new SecurityToken(); $n = $t->getName(); $t->setValue(null); $r = new HTTPRequest('GET', 'dummy', array($n => 'invalidtoken')); $this->assertFalse($t->checkRequest($r), 'Any token is invalid if no token is stored'); $t->setValue(null); $r = new HTTPRequest('GET', 'dummy', array($n => null)); $this->assertFalse($t->checkRequest($r), 'NULL token is invalid if no token is stored'); $t->setValue('mytoken'); $r = new HTTPRequest('GET', 'dummy', array($n => 'invalidtoken')); $this->assertFalse($t->checkRequest($r), 'Invalid token returns false'); $t->setValue('mytoken'); $r = new HTTPRequest('GET', 'dummy', array($n => 'mytoken')); $this->assertTrue($t->checkRequest($r), 'Valid token returns true'); $t->setValue('mytoken'); $r = new HTTPRequest('GET', 'dummy'); $r->addHeader('X-Securityid', 'mytoken'); $this->assertTrue($t->checkRequest($r), 'Valid token returns true'); $t->setValue('mytoken'); $r = new HTTPRequest('GET', 'dummy'); $r->addHeader('X-Securityid', 'wrongtoken'); $this->assertFalse($t->checkRequest($r), 'Valid token returns true'); }
/** * Get the whole tree of a part of the tree via an AJAX request. * * @param HTTPRequest $request * @return string * @throws Exception */ public function tree(HTTPRequest $request) { // Array sourceObject is an explicit list of values - construct a "flat tree" if (is_array($this->sourceObject)) { $output = "<ul class=\"tree\">\n"; foreach ($this->sourceObject as $k => $v) { $output .= '<li id="selector-' . $this->name . '-' . $k . '"><a>' . $v . '</a>'; } $output .= "</ul>"; return $output; } // Regular source specification $isSubTree = false; $this->search = $request->requestVar('search'); $id = is_numeric($request->latestParam('ID')) ? (int) $request->latestParam('ID') : (int) $request->requestVar('ID'); /** @var DataObject|Hierarchy $obj */ $obj = null; if ($id && !$request->requestVar('forceFullTree')) { $obj = DataObject::get_by_id($this->sourceObject, $id); $isSubTree = true; if (!$obj) { throw new Exception("TreeDropdownField->tree(): the object #{$id} of type {$this->sourceObject} could not be found"); } } else { if ($this->baseID) { $obj = DataObject::get_by_id($this->sourceObject, $this->baseID); } if (!$this->baseID || !$obj) { $obj = DataObject::singleton($this->sourceObject); } } // pre-process the tree - search needs to operate globally, not locally as marking filter does if ($this->search) { $this->populateIDs(); } if ($this->filterCallback || $this->search) { $obj->setMarkingFilterFunction(array($this, "filterMarking")); } $obj->markPartialTree($nodeCountThreshold = 30, $context = null, $this->childrenMethod, $this->numChildrenMethod); // allow to pass values to be selected within the ajax request if (isset($_REQUEST['forceValue']) || $this->value) { $forceValue = isset($_REQUEST['forceValue']) ? $_REQUEST['forceValue'] : $this->value; $values = preg_split('/,\\s*/', $forceValue); if ($values) { foreach ($values as $value) { if (!$value || $value == 'unchanged') { continue; } $obj->markToExpose($this->objectForKey($value)); } } } $self = $this; $titleFn = function (&$child) use(&$self) { /** @var DataObject|Hierarchy $child */ $keyField = $self->keyField; $labelField = $self->labelField; return sprintf('<li id="selector-%s-%s" data-id="%s" class="class-%s %s %s"><a rel="%d">%s</a>', Convert::raw2xml($self->getName()), Convert::raw2xml($child->{$keyField}), Convert::raw2xml($child->{$keyField}), Convert::raw2xml($child->class), Convert::raw2xml($child->markingClasses($self->numChildrenMethod)), $self->nodeIsDisabled($child) ? 'disabled' : '', (int) $child->ID, $child->obj($labelField)->forTemplate()); }; // Limit the amount of nodes shown for performance reasons. // Skip the check if we're filtering the tree, since its not clear how many children will // match the filter criteria until they're queried (and matched up with previously marked nodes). $nodeThresholdLeaf = Config::inst()->get('SilverStripe\\ORM\\Hierarchy\\Hierarchy', 'node_threshold_leaf'); if ($nodeThresholdLeaf && !$this->filterCallback && !$this->search) { $className = $this->sourceObject; $nodeCountCallback = function ($parent, $numChildren) use($className, $nodeThresholdLeaf) { if ($className === 'SilverStripe\\CMS\\Model\\SiteTree' && $parent->ID && $numChildren > $nodeThresholdLeaf) { return sprintf('<ul><li><span class="item">%s</span></li></ul>', _t('LeftAndMain.TooManyPages', 'Too many pages')); } return null; }; } else { $nodeCountCallback = null; } if ($isSubTree) { $html = $obj->getChildrenAsUL("", $titleFn, null, true, $this->childrenMethod, $this->numChildrenMethod, true, null, $nodeCountCallback); return substr(trim($html), 4, -5); } else { $html = $obj->getChildrenAsUL('class="tree"', $titleFn, null, true, $this->childrenMethod, $this->numChildrenMethod, true, null, $nodeCountCallback); return $html; } }
/** * Check if this action has a confirmation step * * @param HTTPRequest $request * @return HTTPResponse */ public function handleConfirmation($request) { // Find the action handler $action = $request->param('BatchAction'); $actionHandler = $this->actionByName($action); // Sanitise ID list and query the database for apges $csvIDs = $request->requestVar('csvIDs'); $ids = $this->cleanIDs($csvIDs); // Check dialog if ($actionHandler->hasMethod('confirmationDialog')) { $response = new HTTPResponse(json_encode($actionHandler->confirmationDialog($ids))); } else { $response = new HTTPResponse(json_encode(array('alert' => false))); } $response->addHeader("Content-type", "application/json"); return $response; }
/** * Handle the export, for both the action button and the URL * * @param GridField $gridField * @param HTTPRequest $request * @return HTTPResponse */ public function handleExport($gridField, $request = null) { $now = date("d-m-Y-H-i"); $fileName = "export-{$now}.csv"; if ($fileData = $this->generateExportFileData($gridField)) { return HTTPRequest::send_file($fileData, $fileName, 'text/csv'); } return null; }
/** * @param HTTPRequest $request * @return array */ protected function findAction($request) { $handlerClass = $this->class ? $this->class : get_class($this); // We stop after RequestHandler; in other words, at ViewableData while ($handlerClass && $handlerClass != 'SilverStripe\\View\\ViewableData') { $urlHandlers = Config::inst()->get($handlerClass, 'url_handlers', Config::UNINHERITED); if ($urlHandlers) { foreach ($urlHandlers as $rule => $action) { if (isset($_REQUEST['debug_request'])) { Debug::message("Testing '{$rule}' with '" . $request->remaining() . "' on {$this->class}"); } if ($request->match($rule, true)) { if (isset($_REQUEST['debug_request'])) { Debug::message("Rule '{$rule}' matched to action '{$action}' on {$this->class}. " . "Latest request params: " . var_export($request->latestParams(), true)); } return array('rule' => $rule, 'action' => $action); } } } $handlerClass = get_parent_class($handlerClass); } return null; }