/**
  * 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;
 }
 /**
  * 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;
 }
 /**
  * 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);
 }