public function preRequest(HTTPRequest $request, Session $session, DataModel $model)
 {
     // Bootstrap session so that Session::get() accesses the right instance
     $dummyController = new Controller();
     $dummyController->setSession($session);
     $dummyController->setRequest($request);
     $dummyController->pushCurrent();
     // Block non-authenticated users from setting the stage mode
     if (!Versioned::can_choose_site_stage($request)) {
         $permissionMessage = sprintf(_t("ContentController.DRAFT_SITE_ACCESS_RESTRICTION", 'You must log in with your CMS password in order to view the draft or archived content. ' . '<a href="%s">Click here to go back to the published site.</a>'), Convert::raw2xml(Controller::join_links(Director::baseURL(), $request->getURL(), "?stage=Live")));
         // Force output since RequestFilter::preRequest doesn't support response overriding
         $response = Security::permissionFailure($dummyController, $permissionMessage);
         $session->inst_save();
         $dummyController->popCurrent();
         // Prevent output in testing
         if (class_exists('SilverStripe\\Dev\\SapphireTest', false) && SapphireTest::is_running_test()) {
             throw new HTTPResponse_Exception($response);
         }
         $response->output();
         die;
     }
     Versioned::choose_site_stage();
     $dummyController->popCurrent();
     return true;
 }
 public function getColumnContent($field, $record, $col)
 {
     if (!$record->canView()) {
         return null;
     }
     $data = new ArrayData(array('Link' => Controller::join_links($field->Link('item'), $record->ID, 'view')));
     $template = SSViewer::get_templates_by_class($this, '', __CLASS__);
     return $data->renderWith($template);
 }
 /**
  * Provide downloadable url
  *
  * @param string $path
  * @return string|null
  */
 public function getPublicUrl($path)
 {
     $rootPath = realpath(BASE_PATH);
     $filesPath = realpath($this->pathPrefix);
     if (stripos($filesPath, $rootPath) === 0) {
         $dir = substr($filesPath, strlen($rootPath));
         return Controller::join_links(Director::baseURL(), $dir, $path);
     }
     // File outside of webroot can't be used
     return null;
 }
 public function getHTMLFragments($gridField)
 {
     $singleton = singleton($gridField->getModelClass());
     if (!$singleton->canCreate()) {
         return array();
     }
     if (!$this->buttonName) {
         // provide a default button name, can be changed by calling {@link setButtonName()} on this component
         $objectName = $singleton->i18n_singular_name();
         $this->buttonName = _t('GridField.Add', 'Add {name}', array('name' => $objectName));
     }
     $data = new ArrayData(array('NewLink' => Controller::join_links($gridField->Link('item'), 'new'), 'ButtonName' => $this->buttonName));
     $templates = SSViewer::get_templates_by_class($this, '', __CLASS__);
     return array($this->targetFragment => $data->renderWith($templates));
 }
 public function forTemplate()
 {
     return sprintf('<div id="cms-editor-dialogs" data-url-linkform="%s" data-url-mediaform="%s"></div>', Controller::join_links($this->controller->Link(), $this->name, 'LinkForm', 'forTemplate'), Controller::join_links($this->controller->Link(), $this->name, 'MediaForm', 'forTemplate'));
 }
 public function testChangePasswordForLoggedInUsers()
 {
     $goodResponse = $this->doTestLoginForm('*****@*****.**', '1nitialPassword');
     // Change the password
     $this->get('Security/changepassword?BackURL=test/back');
     $changedResponse = $this->doTestChangepasswordForm('1nitialPassword', 'changedPassword');
     $this->assertEquals(302, $changedResponse->getStatusCode());
     $this->assertEquals(Controller::join_links(Director::absoluteBaseURL(), 'test/back'), $changedResponse->getHeader('Location'));
     $this->assertEquals($this->idFromFixture('SilverStripe\\Security\\Member', 'test'), $this->session()->inst_get('loggedInAs'));
     // Check if we can login with the new password
     $goodResponse = $this->doTestLoginForm('*****@*****.**', 'changedPassword');
     $this->assertEquals(302, $goodResponse->getStatusCode());
     $this->assertEquals(Controller::join_links(Director::absoluteBaseURL(), 'test/link'), $goodResponse->getHeader('Location'));
     $this->assertEquals($this->idFromFixture('SilverStripe\\Security\\Member', 'test'), $this->session()->inst_get('loggedInAs'));
 }
 /**
  * @param string $action
  * @return string
  */
 public function Link($action = null)
 {
     return Controller::join_links($this->parent->Link(), '/select/', $action);
 }
 /**
  * Return a link to this field.
  *
  * @param string $action
  *
  * @return string
  */
 public function Link($action = null)
 {
     return Controller::join_links($this->form->FormAction(), 'field/' . $this->name, $action);
 }
 public function Link($action = null)
 {
     return Controller::join_links('test', $action, '/');
 }
 /**
  * Returns a link to this controller. Overload with your own Link rules if they exist.
  *
  * @param string $action Optional action
  * @return string
  */
 public function Link($action = null)
 {
     return Controller::join_links(ClassInfo::shortName($this), $action, '/');
 }
 /**
  * Login in the user and figure out where to redirect the browser.
  *
  * The $data has this format
  * array(
  *   'AuthenticationMethod' => 'MemberAuthenticator',
  *   'Email' => '*****@*****.**',
  *   'Password' => '1nitialPassword',
  *   'BackURL' => 'test/link',
  *   [Optional: 'Remember' => 1 ]
  * )
  *
  * @param array $data
  * @return HTTPResponse
  */
 protected function logInUserAndRedirect($data)
 {
     Session::clear('SessionForms.MemberLoginForm.Email');
     Session::clear('SessionForms.MemberLoginForm.Remember');
     if (Member::currentUser()->isPasswordExpired()) {
         if (isset($_REQUEST['BackURL']) && ($backURL = $_REQUEST['BackURL'])) {
             Session::set('BackURL', $backURL);
         }
         /** @skipUpgrade */
         $cp = ChangePasswordForm::create($this->controller, 'ChangePasswordForm');
         $cp->sessionMessage(_t('Member.PASSWORDEXPIRED', 'Your password has expired. Please choose a new one.'), 'good');
         return $this->controller->redirect('Security/changepassword');
     }
     // Absolute redirection URLs may cause spoofing
     if (!empty($_REQUEST['BackURL'])) {
         $url = $_REQUEST['BackURL'];
         if (Director::is_site_url($url)) {
             $url = Director::absoluteURL($url);
         } else {
             // Spoofing attack, redirect to homepage instead of spoofing url
             $url = Director::absoluteBaseURL();
         }
         return $this->controller->redirect($url);
     }
     // If a default login dest has been set, redirect to that.
     if ($url = Security::config()->default_login_dest) {
         $url = Controller::join_links(Director::absoluteBaseURL(), $url);
         return $this->controller->redirect($url);
     }
     // Redirect the user to the page where they came from
     $member = Member::currentUser();
     if ($member) {
         $firstname = Convert::raw2xml($member->FirstName);
         if (!empty($data['Remember'])) {
             Session::set('SessionForms.MemberLoginForm.Remember', '1');
             $member->logIn(true);
         } else {
             $member->logIn();
         }
         Session::set('Security.Message.message', _t('Member.WELCOMEBACK', "Welcome Back, {firstname}", array('firstname' => $firstname)));
         Session::set("Security.Message.type", "good");
     }
     return Controller::curr()->redirectBack();
 }
 /**
  * Get the URL of the logout page.
  *
  * To update the logout url use the "Security.logout_url" config setting.
  *
  * @return string
  */
 public static function lost_password_url()
 {
     return Controller::join_links(Director::baseURL(), self::config()->lost_password_url);
 }
 /**
  * @param string $action
  * @return string
  */
 public function Link($action = null)
 {
     return Controller::join_links($this->parent->Link(), '/item/', $this->itemID, $action);
 }
 /**
  * Generate the JavaScript that will set TinyMCE's configuration:
  * - Parse all configurations into JSON objects to be used in JavaScript
  * - Includes TinyMCE and configurations using the {@link Requirements} system
  *
  * @return array
  */
 protected function getConfig()
 {
     $settings = $this->getSettings();
     // https://www.tinymce.com/docs/configure/url-handling/#document_base_url
     $settings['document_base_url'] = Director::absoluteBaseURL();
     // https://www.tinymce.com/docs/api/class/tinymce.editormanager/#baseURL
     $tinyMCEBaseURL = Controller::join_links(Director::absoluteBaseURL(), $this->config()->get('base_dir') ?: ADMIN_THIRDPARTY_DIR . '/tinymce');
     $settings['baseURL'] = $tinyMCEBaseURL;
     // map all plugins to absolute urls for loading
     $plugins = array();
     foreach ($this->getPlugins() as $plugin => $path) {
         if (!$path) {
             // Empty paths: Convert to urls in standard base url
             $path = Controller::join_links($tinyMCEBaseURL, "plugins/{$plugin}/plugin.min.js");
         } elseif (!Director::is_absolute_url($path)) {
             // Non-absolute urls are made absolute
             $path = Director::absoluteURL($path);
         }
         $plugins[$plugin] = $path;
     }
     // https://www.tinymce.com/docs/configure/integration-and-setup/#external_plugins
     if ($plugins) {
         $settings['external_plugins'] = $plugins;
     }
     // https://www.tinymce.com/docs/configure/editor-appearance/#groupingtoolbarcontrols
     $buttons = $this->getButtons();
     $settings['toolbar'] = [];
     foreach ($buttons as $rowButtons) {
         $row = implode(' ', $rowButtons);
         if (count($buttons) > 1) {
             $settings['toolbar'][] = $row;
         } else {
             $settings['toolbar'] = $row;
         }
     }
     // https://www.tinymce.com/docs/configure/content-appearance/#content_css
     $settings['content_css'] = $this->getEditorCSS();
     // https://www.tinymce.com/docs/configure/editor-appearance/#theme_url
     $theme = $this->getTheme();
     if (!Director::is_absolute_url($theme)) {
         $theme = Controller::join_links($tinyMCEBaseURL, "themes/{$theme}/theme.min.js");
     }
     $settings['theme_url'] = $theme;
     // Send back
     return $settings;
 }
    /**
     * Redirect the user to the change password form.
     *
     * @return HTTPResponse
     */
    protected function redirectToChangePassword()
    {
        // Since this form is loaded via an iframe, this redirect must be performed via javascript
        $changePasswordForm = new ChangePasswordForm($this->controller, 'SilverStripe\\Security\\ChangePasswordForm');
        $changePasswordForm->sessionMessage(_t('Member.PASSWORDEXPIRED', 'Your password has expired. Please choose a new one.'), 'good');
        // Get redirect url
        $changePasswordURL = $this->getExternalLink('changepassword');
        if ($backURL = $this->controller->getRequest()->requestVar('BackURL')) {
            Session::set('BackURL', $backURL);
            $changePasswordURL = Controller::join_links($changePasswordURL, '?BackURL=' . urlencode($backURL));
        }
        $changePasswordURLATT = Convert::raw2att($changePasswordURL);
        $changePasswordURLJS = Convert::raw2js($changePasswordURL);
        $message = _t('CMSMemberLoginForm.PASSWORDEXPIRED', '<p>Your password has expired. <a target="_top" href="{link}">Please choose a new one.</a></p>', 'Message displayed to user if their session cannot be restored', array('link' => $changePasswordURLATT));
        // Redirect to change password page
        $this->controller->getResponse()->setStatusCode(200);
        $this->controller->getResponse()->setBody(<<<PHP
<!DOCTYPE html>
<html><body>
{$message}
<script type="application/javascript">
setTimeout(function(){top.location.href = "{$changePasswordURLJS}";}, 0);
</script>
</body></html>
PHP
);
        return $this->controller->getResponse();
    }
 /**
  * @param String $url
  * @return String
  */
 public function addToUrl($url)
 {
     return Controller::join_links($url, sprintf('?%s=%s', $this->getName(), $this->getValue()));
 }
 public function Link($action = null)
 {
     return Controller::join_links('FormTest_ControllerWithStrictPostCheck', $this->request->latestParam('Action'), $this->request->latestParam('ID'), $action);
 }
 /**
  *
  * @param GridField $gridField
  * @return string[] - HTML
  */
 public function getHTMLFragments($gridField)
 {
     $dataClass = $gridField->getModelClass();
     $forTemplate = new ArrayData(array());
     $forTemplate->Fields = new FieldList();
     $searchField = new TextField('gridfield_relationsearch', _t('GridField.RelationSearch', "Relation search"));
     $searchField->setAttribute('data-search-url', Controller::join_links($gridField->Link('search')));
     $searchField->setAttribute('placeholder', $this->getPlaceholderText($dataClass));
     $searchField->addExtraClass('relation-search no-change-track action_gridfield_relationsearch');
     $findAction = new GridField_FormAction($gridField, 'gridfield_relationfind', _t('GridField.Find', "Find"), 'find', 'find');
     $findAction->setAttribute('data-icon', 'relationfind');
     $findAction->addExtraClass('action_gridfield_relationfind');
     $addAction = new GridField_FormAction($gridField, 'gridfield_relationadd', _t('GridField.LinkExisting', "Link Existing"), 'addto', 'addto');
     $addAction->setAttribute('data-icon', 'chain--plus');
     $addAction->addExtraClass('action_gridfield_relationadd');
     // If an object is not found, disable the action
     if (!is_int($gridField->State->GridFieldAddRelation(null))) {
         $addAction->setReadonly(true);
     }
     $forTemplate->Fields->push($searchField);
     $forTemplate->Fields->push($findAction);
     $forTemplate->Fields->push($addAction);
     if ($form = $gridField->getForm()) {
         $forTemplate->Fields->setForm($form);
     }
     $template = SSViewer::get_templates_by_class($this, '', __CLASS__);
     return array($this->targetFragment => $forTemplate->renderWith($template));
 }
 /**
  * @param bool $unlinked
  * @return ArrayList
  */
 public function Breadcrumbs($unlinked = false)
 {
     $items = parent::Breadcrumbs($unlinked);
     // Show the class name rather than ModelAdmin title as root node
     $models = $this->getManagedModels();
     $params = $this->getRequest()->getVars();
     if (isset($params['url'])) {
         unset($params['url']);
     }
     $items[0]->Title = $models[$this->modelClass]['title'];
     $items[0]->Link = Controller::join_links($this->Link($this->sanitiseClassName($this->modelClass)), '?' . http_build_query($params));
     return $items;
 }
 public function Link($action = null)
 {
     /** @skipUpgrade */
     return Controller::join_links(Director::baseURL(), "CMSSecurity", $action);
 }
 /**
  * We overwrite the field attribute to add our hidden fields, as this
  * formfield can contain multiple values.
  *
  * @param array $properties
  * @return DBHTMLText
  */
 public function Field($properties = array())
 {
     $value = '';
     $titleArray = array();
     $idArray = array();
     $items = $this->getItems();
     $emptyTitle = _t('DropdownField.CHOOSE', '(Choose)', 'start value of a dropdown');
     if ($items && count($items)) {
         foreach ($items as $item) {
             $idArray[] = $item->ID;
             $titleArray[] = $item instanceof ViewableData ? $item->obj($this->labelField)->forTemplate() : Convert::raw2xml($item->{$this->labelField});
         }
         $title = implode(", ", $titleArray);
         $value = implode(",", $idArray);
     } else {
         $title = $emptyTitle;
     }
     $dataUrlTree = '';
     if ($this->form) {
         $dataUrlTree = $this->Link('tree');
         if (!empty($idArray)) {
             $dataUrlTree = Controller::join_links($dataUrlTree, '?forceValue=' . implode(',', $idArray));
         }
     }
     $properties = array_merge($properties, array('Title' => $title, 'EmptyTitle' => $emptyTitle, 'Link' => $dataUrlTree, 'Value' => $value));
     return FormField::Field($properties);
 }
 /**
  * Return a SS_List of ArrayData objects containing the following pieces of info
  * about each batch action:
  *  - Link
  *  - Title
  *
  * @return ArrayList
  */
 public function batchActionList()
 {
     $actions = $this->batchActions();
     $actionList = new ArrayList();
     foreach ($actions as $urlSegment => $action) {
         $actionObj = $this->buildAction($action['class']);
         if ($actionObj->canView()) {
             $actionDef = new ArrayData(array("Link" => Controller::join_links($this->Link(), $urlSegment), "Title" => $actionObj->getActionTitle()));
             $actionList->push($actionDef);
         }
     }
     return $actionList;
 }
 public function Link($action = null)
 {
     return Controller::join_links("item-a/", $action);
 }
 /**
  * Gets user-visible url to edit a specific {@see ChangeSetItem}
  *
  * @param int $itemID
  * @return string
  */
 public function ItemLink($itemID)
 {
     return Controller::join_links($this->Link('item'), $itemID);
 }
 /**
  * Save  handler
  *
  * @param array $data
  * @param Form $form
  * @return HTTPResponse
  */
 public function save($data, $form)
 {
     $request = $this->getRequest();
     $className = $this->stat('tree_class');
     // Existing or new record?
     $id = $data['ID'];
     if (is_numeric($id) && $id > 0) {
         $record = DataObject::get_by_id($className, $id);
         if ($record && !$record->canEdit()) {
             return Security::permissionFailure($this);
         }
         if (!$record || !$record->ID) {
             $this->httpError(404, "Bad record ID #" . (int) $id);
         }
     } else {
         if (!singleton($this->stat('tree_class'))->canCreate()) {
             return Security::permissionFailure($this);
         }
         $record = $this->getNewItem($id, false);
     }
     // save form data into record
     $form->saveInto($record, true);
     $record->write();
     $this->extend('onAfterSave', $record);
     $this->setCurrentPageID($record->ID);
     $message = _t('LeftAndMain.SAVEDUP', 'Saved.');
     if ($request->getHeader('X-Formschema-Request')) {
         $schemaId = Controller::join_links($this->Link('schema/DetailEditForm'), $id);
         // Ensure that newly created records have all their data loaded back into the form.
         $form->loadDataFrom($record);
         $form->setMessage($message, 'good');
         $data = $this->getSchemaForForm($form, $schemaId);
         $response = new HTTPResponse(Convert::raw2json($data));
         $response->addHeader('Content-Type', 'application/json');
     } else {
         $response = $this->getResponseNegotiator()->respond($request);
     }
     $response->addHeader('X-Status', rawurlencode($message));
     return $response;
 }
 /**
  * Gets the list of modes this record can be previewed in.
  *
  * {@link https://tools.ietf.org/html/draft-kelly-json-hal-07#section-5}
  *
  * @return array Map of links in acceptable HAL format
  */
 public function getPreviewLinks()
 {
     $links = [];
     // Preview draft
     $stage = $this->getObjectInStage(Versioned::DRAFT);
     if ($stage instanceof CMSPreviewable && $stage->canView() && ($link = $stage->PreviewLink())) {
         $links[Versioned::DRAFT] = ['href' => Controller::join_links($link, '?stage=' . Versioned::DRAFT), 'type' => $stage->getMimeType()];
     }
     // Preview live
     $live = $this->getObjectInStage(Versioned::LIVE);
     if ($live instanceof CMSPreviewable && $live->canView() && ($link = $live->PreviewLink())) {
         $links[Versioned::LIVE] = ['href' => Controller::join_links($link, '?stage=' . Versioned::LIVE), 'type' => $live->getMimeType()];
     }
     return $links;
 }
 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');
 }
 /**
  * Turns the given URL into an absolute URL. By default non-site root relative urls will be
  * evaluated relative to the current base_url.
  *
  * @param string $url URL To transform to absolute.
  * @param string $relativeParent Method to use for evaluating relative urls.
  * Either one of BASE (baseurl), ROOT (site root), or REQUEST (requested page).
  * Defaults to BASE, which is the same behaviour as template url resolution.
  * Ignored if the url is absolute or site root.
  *
  * @return string
  */
 public static function absoluteURL($url, $relativeParent = self::BASE)
 {
     if (is_bool($relativeParent)) {
         // Deprecate old boolean second parameter
         Deprecation::notice('5.0', 'Director::absoluteURL takes an explicit parent for relative url');
         $relativeParent = $relativeParent ? self::BASE : self::REQUEST;
     }
     // Check if there is already a protocol given
     if (preg_match('/^http(s?):\\/\\//', $url)) {
         return $url;
     }
     // Absolute urls without protocol are added
     // E.g. //google.com -> http://google.com
     if (strpos($url, '//') === 0) {
         return self::protocol() . substr($url, 2);
     }
     // Determine method for mapping the parent to this relative url
     if ($relativeParent === self::ROOT || self::is_root_relative_url($url)) {
         // Root relative urls always should be evaluated relative to the root
         $parent = self::protocolAndHost();
     } elseif ($relativeParent === self::REQUEST) {
         // Request relative urls rely on the REQUEST_URI param (old default behaviour)
         if (!isset($_SERVER['REQUEST_URI'])) {
             return false;
         }
         $parent = dirname($_SERVER['REQUEST_URI'] . 'x');
     } else {
         // Default to respecting site base_url
         $parent = self::absoluteBaseURL();
     }
     // Map empty urls to relative slash and join to base
     if (empty($url) || $url === '.' || $url === './') {
         $url = '/';
     }
     return Controller::join_links($parent, $url);
 }
 /**
  * Return the form's action attribute.
  * This is build by adding an executeForm get variable to the parent controller's Link() value
  *
  * @return string
  */
 public function FormAction()
 {
     if ($this->formActionPath) {
         return $this->formActionPath;
     } elseif ($this->controller->hasMethod("FormObjectLink")) {
         return $this->controller->FormObjectLink($this->name);
     } else {
         return Controller::join_links($this->controller->Link(), $this->name);
     }
 }
 function Link($action = null)
 {
     return Controller::join_links('EmailFieldTest_Controller', $this->getRequest()->latestParam('Action'), $this->getRequest()->latestParam('ID'), $action);
 }