/**
  * Handle a form submission.  GET and POST requests behave identically.
  * Populates the form with {@link loadDataFrom()}, calls {@link validate()},
  * and only triggers the requested form action/method
  * if the form is valid.
  *
  * @param HTTPRequest $request
  * @throws HTTPResponse_Exception
  */
 public function httpSubmission($request)
 {
     // Strict method check
     if ($this->strictFormMethodCheck) {
         // Throws an error if the method is bad...
         if ($this->formMethod != $request->httpMethod()) {
             $response = Controller::curr()->getResponse();
             $response->addHeader('Allow', $this->formMethod);
             $this->httpError(405, _t("Form.BAD_METHOD", "This form requires a " . $this->formMethod . " submission"));
         }
         // ...and only uses the variables corresponding to that method type
         $vars = $this->formMethod == 'GET' ? $request->getVars() : $request->postVars();
     } else {
         $vars = $request->requestVars();
     }
     // Populate the form
     $this->loadDataFrom($vars, true);
     // Protection against CSRF attacks
     $token = $this->getSecurityToken();
     if (!$token->checkRequest($request)) {
         $securityID = $token->getName();
         if (empty($vars[$securityID])) {
             $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."));
         } else {
             // Clear invalid token on refresh
             $data = $this->getData();
             unset($data[$securityID]);
             Session::set("FormInfo.{$this->FormName()}.data", $data);
             Session::set("FormInfo.{$this->FormName()}.errors", array());
             $this->sessionMessage(_t("Form.CSRF_EXPIRED_MESSAGE", "Your session has expired. Please re-submit the form."), "warning");
             return $this->controller->redirectBack();
         }
     }
     // Determine the action button clicked
     $funcName = null;
     foreach ($vars as $paramName => $paramVal) {
         if (substr($paramName, 0, 7) == 'action_') {
             // Break off querystring arguments included in the action
             if (strpos($paramName, '?') !== false) {
                 list($paramName, $paramVars) = explode('?', $paramName, 2);
                 $newRequestParams = array();
                 parse_str($paramVars, $newRequestParams);
                 $vars = array_merge((array) $vars, (array) $newRequestParams);
             }
             // Cleanup action_, _x and _y from image fields
             $funcName = preg_replace(array('/^action_/', '/_x$|_y$/'), '', $paramName);
             break;
         }
     }
     // If the action wasn't set, choose the default on the form.
     if (!isset($funcName) && ($defaultAction = $this->defaultAction())) {
         $funcName = $defaultAction->actionName();
     }
     if (isset($funcName)) {
         $this->setButtonClicked($funcName);
     }
     // Permission checks (first on controller, then falling back to form)
     if ($this->controller->hasMethod($funcName) && !$this->controller->checkAccessAction($funcName) && !$this->buttonClicked()) {
         return $this->httpError(403, sprintf('Action "%s" not allowed on controller (Class: %s)', $funcName, get_class($this->controller)));
     } elseif ($this->hasMethod($funcName) && !$this->checkAccessAction($funcName)) {
         return $this->httpError(403, sprintf('Action "%s" not allowed on form (Name: "%s")', $funcName, $this->name));
     }
     // TODO : Once we switch to a stricter policy regarding allowed_actions (meaning actions must be set
     // explicitly in allowed_actions in order to run)
     // Uncomment the following for checking security against running actions on form fields
     /* else {
     			// Try to find a field that has the action, and allows it
     			$fieldsHaveMethod = false;
     			foreach ($this->Fields() as $field){
     				if ($field->hasMethod($funcName) && $field->checkAccessAction($funcName)) {
     					$fieldsHaveMethod = true;
     				}
     			}
     			if (!$fieldsHaveMethod) {
     				return $this->httpError(
     					403,
     					sprintf('Action "%s" not allowed on any fields of form (Name: "%s")', $funcName, $this->Name())
     				);
     			}
     		}*/
     // Validate the form
     if (!$this->validate()) {
         return $this->getValidationErrorResponse();
     }
     // First, try a handler method on the controller (has been checked for allowed_actions above already)
     if ($this->controller->hasMethod($funcName)) {
         return $this->controller->{$funcName}($vars, $this, $request);
         // Otherwise, try a handler method on the form object.
     } elseif ($this->hasMethod($funcName)) {
         return $this->{$funcName}($vars, $this, $request);
     } elseif ($field = $this->checkFieldsForAction($this->Fields(), $funcName)) {
         return $field->{$funcName}($vars, $this, $request);
     }
     return $this->httpError(404);
 }
 /**
  * Creates a single folder, within an optional parent folder.
  *
  * @param HTTPRequest $request
  * @return HTTPRequest|HTTPResponse
  */
 public function apiCreateFolder(HTTPRequest $request)
 {
     $data = $request->postVars();
     $class = 'SilverStripe\\Assets\\Folder';
     // CSRF check
     $token = SecurityToken::inst();
     if (empty($data[$token->getName()]) || !$token->check($data[$token->getName()])) {
         return new HTTPResponse(null, 400);
     }
     // check addchildren permissions
     /** @var Folder $parentRecord */
     $parentRecord = null;
     if (!empty($data['ParentID']) && is_numeric($data['ParentID'])) {
         $parentRecord = DataObject::get_by_id($class, $data['ParentID']);
     }
     $data['Parent'] = $parentRecord;
     $data['ParentID'] = $parentRecord ? (int) $parentRecord->ID : 0;
     // Build filename
     $baseFilename = isset($data['Name']) ? basename($data['Name']) : _t('SilverStripe\\AssetAdmin\\Controller\\AssetAdmin.NEWFOLDER', "NewFolder");
     if ($parentRecord && $parentRecord->ID) {
         $baseFilename = $parentRecord->getFilename() . '/' . $baseFilename;
     }
     // Ensure name is unique
     $nameGenerator = $this->getNameGenerator($baseFilename);
     $filename = null;
     foreach ($nameGenerator as $filename) {
         if (!File::find($filename)) {
             break;
         }
     }
     $data['Name'] = basename($filename);
     // Create record
     /** @var Folder $record */
     $record = Injector::inst()->create($class);
     // check create permissions
     if (!$record->canCreate(null, $data)) {
         return (new HTTPResponse(null, 403))->addHeader('Content-Type', 'application/json');
     }
     $record->ParentID = $data['ParentID'];
     $record->Name = $record->Title = basename($data['Name']);
     $record->write();
     $result = $this->getObjectFromData($record);
     return (new HTTPResponse(json_encode($result)))->addHeader('Content-Type', 'application/json');
 }