/**
  * 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'));
 }
 /**
  * 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);
 }
 /**
  * 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);
 }
 /**
  * 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());
 }
 /**
  * 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);
 }
 /**
  * Returns a JSON array for history of a given file ID. Returns a list of all the history.
  *
  * @param HTTPRequest $request
  * @return HTTPResponse
  */
 public function apiHistory(HTTPRequest $request)
 {
     // CSRF check not required as the GET request has no side effects.
     $fileId = $request->getVar('fileId');
     if (!$fileId || !is_numeric($fileId)) {
         return new HTTPResponse(null, 400);
     }
     $class = File::class;
     $file = DataObject::get($class)->byID($fileId);
     if (!$file) {
         return new HTTPResponse(null, 404);
     }
     if (!$file->canView()) {
         return new HTTPResponse(null, 403);
     }
     $versions = Versioned::get_all_versions($class, $fileId)->limit($this->config()->max_history_entries)->sort('Version', 'DESC');
     $output = array();
     $next = array();
     $prev = null;
     // swap the order so we can get the version number to compare against.
     // i.e version 3 needs to know version 2 is the previous version
     $copy = $versions->map('Version', 'Version')->toArray();
     foreach (array_reverse($copy) as $k => $v) {
         if ($prev) {
             $next[$v] = $prev;
         }
         $prev = $v;
     }
     $_cachedMembers = array();
     /** @var File $version */
     foreach ($versions as $version) {
         $author = null;
         if ($version->AuthorID) {
             if (!isset($_cachedMembers[$version->AuthorID])) {
                 $_cachedMembers[$version->AuthorID] = DataObject::get(Member::class)->byID($version->AuthorID);
             }
             $author = $_cachedMembers[$version->AuthorID];
         }
         if ($version->canView()) {
             if (isset($next[$version->Version])) {
                 $summary = $version->humanizedChanges($version->Version, $next[$version->Version]);
                 // if no summary returned by humanizedChanges, i.e we cannot work out what changed, just show a
                 // generic message
                 if (!$summary) {
                     $summary = _t('SilverStripe\\AssetAdmin\\Controller\\AssetAdmin.SAVEDFILE', "Saved file");
                 }
             } else {
                 $summary = _t('SilverStripe\\AssetAdmin\\Controller\\AssetAdmin.UPLOADEDFILE', "Uploaded file");
             }
             $output[] = array('versionid' => $version->Version, 'date_ago' => $version->dbObject('LastEdited')->Ago(), 'date_formatted' => $version->dbObject('LastEdited')->Nice(), 'status' => $version->WasPublished ? _t('File.PUBLISHED', 'Published') : '', 'author' => $author ? $author->Name : _t('SilverStripe\\AssetAdmin\\Controller\\AssetAdmin.UNKNOWN', "Unknown"), 'summary' => $summary ? $summary : _t('SilverStripe\\AssetAdmin\\Controller\\AssetAdmin.NOSUMMARY', "No summary available"));
         }
     }
     return (new HTTPResponse(json_encode($output)))->addHeader('Content-Type', 'application/json');
 }