public function __construct($controller, $name, $fields = null, $actions = null, $validator = null)
 {
     if (!$fields) {
         $helpHtml = _t('MemberImportForm.Help1', '<p>Import users in <em>CSV format</em> (comma-separated values).' . ' <small><a href="#" class="toggle-advanced">Show advanced usage</a></small></p>');
         $helpHtml .= _t('MemberImportForm.Help2', '<div class="advanced">' . '<h4>Advanced usage</h4>' . '<ul>' . '<li>Allowed columns: <em>%s</em></li>' . '<li>Existing users are matched by their unique <em>Code</em> property, and updated with any new values from ' . 'the imported file.</li>' . '<li>Groups can be assigned by the <em>Groups</em> column. Groups are identified by their <em>Code</em> property, ' . 'multiple groups can be separated by comma. Existing group memberships are not cleared.</li>' . '</ul>' . '</div>');
         $importer = new MemberCsvBulkLoader();
         $importSpec = $importer->getImportSpec();
         $helpHtml = sprintf($helpHtml, implode(', ', array_keys($importSpec['fields'])));
         $fields = new FieldList(new LiteralField('Help', $helpHtml), $fileField = new FileField('CsvFile', DBField::create_field('HTMLFragment', _t('SecurityAdmin_MemberImportForm.FileFieldLabel', 'CSV File <small>(Allowed extensions: *.csv)</small>'))));
         $fileField->getValidator()->setAllowedExtensions(array('csv'));
     }
     if (!$actions) {
         $action = new FormAction('doImport', _t('SecurityAdmin_MemberImportForm.BtnImport', 'Import from CSV'));
         $action->addExtraClass('btn btn-secondary-outline ss-ui-button');
         $actions = new FieldList($action);
     }
     if (!$validator) {
         $validator = new RequiredFields('CsvFile');
     }
     parent::__construct($controller, $name, $fields, $actions, $validator);
     Requirements::javascript(FRAMEWORK_ADMIN_DIR . '/client/dist/js/vendor.js');
     Requirements::javascript(FRAMEWORK_ADMIN_DIR . '/client/dist/js/MemberImportForm.js');
     Requirements::css(FRAMEWORK_ADMIN_DIR . '/client/dist/styles/bundle.css');
     $this->addExtraClass('cms');
     $this->addExtraClass('import-form');
 }
 /**
  * @inheritdoc
  */
 public function onAfterInit()
 {
     $config = SiteConfig::current_site_config();
     // include the JS snippet into the frontend page markup
     if ($trackingID = $config->GoogleAnalyticsTrackingID) {
         $analyticsData = new ArrayData(['GoogleAnalyticsTrackingID' => $trackingID, 'GoogleAnalyticsParameters' => $config->GoogleAnalyticsParameters, 'GoogleAnalyticsConstructorParameters' => $config->GoogleAnalyticsConstructorParameters]);
         Requirements::insertHeadTags($analyticsData->renderWith('GoogleAnalyticsJSSnippet'), 'GoogleAnalytics');
     }
 }
 /**
  * @param String $html
  * @return string
  */
 public function onAfterRender($html)
 {
     if ($this->getField()->getConfig('showcalendar')) {
         // Include language files (if required)
         if ($this->jqueryLocaleFile) {
             Requirements::javascript($this->jqueryLocaleFile);
         }
     }
     return $html;
 }
 /**
  * Test a URL request, returning a response object. This method is the counterpart of
  * Director::direct() that is used in functional testing. It will execute the URL given, and
  * return the result as an HTTPResponse object.
  *
  * @uses Controller::handleRequest() Handles the page logic for a Director::direct() call.
  *
  * @param string $url The URL to visit.
  * @param array $postVars The $_POST & $_FILES variables.
  * @param array|Session $session The {@link Session} object representing the current session.
  * By passing the same object to multiple  calls of Director::test(), you can simulate a persisted
  * session.
  * @param string $httpMethod The HTTP method, such as GET or POST.  It will default to POST if
  * postVars is set, GET otherwise. Overwritten by $postVars['_method'] if present.
  * @param string $body The HTTP body.
  * @param array $headers HTTP headers with key-value pairs.
  * @param array|Cookie_Backend $cookies to populate $_COOKIE.
  * @param HTTPRequest $request The {@see SS_HTTP_Request} object generated as a part of this request.
  *
  * @return HTTPResponse
  *
  * @throws HTTPResponse_Exception
  */
 public static function test($url, $postVars = null, $session = array(), $httpMethod = null, $body = null, $headers = array(), $cookies = array(), &$request = null)
 {
     Config::nest();
     Injector::nest();
     // These are needed so that calling Director::test() does not muck with whoever is calling it.
     // Really, it's some inappropriate coupling and should be resolved by making less use of statics.
     $oldReadingMode = Versioned::get_reading_mode();
     $getVars = array();
     if (!$httpMethod) {
         $httpMethod = $postVars || is_array($postVars) ? "POST" : "GET";
     }
     if (!$session) {
         $session = Injector::inst()->create('SilverStripe\\Control\\Session', array());
     }
     $cookieJar = $cookies instanceof Cookie_Backend ? $cookies : Injector::inst()->createWithArgs('SilverStripe\\Control\\Cookie_Backend', array($cookies ?: array()));
     // Back up the current values of the superglobals
     $existingRequestVars = isset($_REQUEST) ? $_REQUEST : array();
     $existingGetVars = isset($_GET) ? $_GET : array();
     $existingPostVars = isset($_POST) ? $_POST : array();
     $existingSessionVars = isset($_SESSION) ? $_SESSION : array();
     $existingCookies = isset($_COOKIE) ? $_COOKIE : array();
     $existingServer = isset($_SERVER) ? $_SERVER : array();
     $existingRequirementsBackend = Requirements::backend();
     Cookie::config()->update('report_errors', false);
     Requirements::set_backend(Requirements_Backend::create());
     // Set callback to invoke prior to return
     $onCleanup = function () use($existingRequestVars, $existingGetVars, $existingPostVars, $existingSessionVars, $existingCookies, $existingServer, $existingRequirementsBackend, $oldReadingMode) {
         // Restore the super globals
         $_REQUEST = $existingRequestVars;
         $_GET = $existingGetVars;
         $_POST = $existingPostVars;
         $_SESSION = $existingSessionVars;
         $_COOKIE = $existingCookies;
         $_SERVER = $existingServer;
         Requirements::set_backend($existingRequirementsBackend);
         // These are needed so that calling Director::test() does not muck with whoever is calling it.
         // Really, it's some inappropriate coupling and should be resolved by making less use of statics
         Versioned::set_reading_mode($oldReadingMode);
         Injector::unnest();
         // Restore old CookieJar, etc
         Config::unnest();
     };
     if (strpos($url, '#') !== false) {
         $url = substr($url, 0, strpos($url, '#'));
     }
     // Handle absolute URLs
     if (parse_url($url, PHP_URL_HOST)) {
         $bits = parse_url($url);
         // If a port is mentioned in the absolute URL, be sure to add that into the HTTP host
         if (isset($bits['port'])) {
             $_SERVER['HTTP_HOST'] = $bits['host'] . ':' . $bits['port'];
         } else {
             $_SERVER['HTTP_HOST'] = $bits['host'];
         }
     }
     // Ensure URL is properly made relative.
     // Example: url passed is "/ss31/my-page" (prefixed with BASE_URL), this should be changed to "my-page"
     $url = self::makeRelative($url);
     $urlWithQuerystring = $url;
     if (strpos($url, '?') !== false) {
         list($url, $getVarsEncoded) = explode('?', $url, 2);
         parse_str($getVarsEncoded, $getVars);
     }
     // Replace the super globals with appropriate test values
     $_REQUEST = ArrayLib::array_merge_recursive((array) $getVars, (array) $postVars);
     $_GET = (array) $getVars;
     $_POST = (array) $postVars;
     $_SESSION = $session ? $session->inst_getAll() : array();
     $_COOKIE = $cookieJar->getAll(false);
     Injector::inst()->registerService($cookieJar, 'SilverStripe\\Control\\Cookie_Backend');
     $_SERVER['REQUEST_URI'] = Director::baseURL() . $urlWithQuerystring;
     $request = new HTTPRequest($httpMethod, $url, $getVars, $postVars, $body);
     if ($headers) {
         foreach ($headers as $k => $v) {
             $request->addHeader($k, $v);
         }
     }
     // Pre-request filtering
     // @see issue #2517
     $model = DataModel::inst();
     $output = Injector::inst()->get('SilverStripe\\Control\\RequestProcessor')->preRequest($request, $session, $model);
     if ($output === false) {
         $onCleanup();
         throw new HTTPResponse_Exception(_t('Director.INVALID_REQUEST', 'Invalid request'), 400);
     }
     // TODO: Pass in the DataModel
     $result = Director::handleRequest($request, $session, $model);
     // Ensure that the result is an HTTPResponse object
     if (is_string($result)) {
         if (substr($result, 0, 9) == 'redirect:') {
             $response = new HTTPResponse();
             $response->redirect(substr($result, 9));
             $result = $response;
         } else {
             $result = new HTTPResponse($result);
         }
     }
     $output = Injector::inst()->get('SilverStripe\\Control\\RequestProcessor')->postRequest($request, $result, $model);
     if ($output === false) {
         $onCleanup();
         throw new HTTPResponse_Exception("Invalid response");
     }
     // Return valid response
     $onCleanup();
     return $result;
 }
 public function testRequireCallInTemplateInclude()
 {
     //TODO undo skip test on the event that templates ever obtain the ability to reference MODULE_DIR (or something to that effect)
     if (FRAMEWORK_DIR === 'framework') {
         $template = new SSViewer(array('SSViewerTestProcess'));
         Requirements::set_suffix_requirements(false);
         $this->assertEquals(1, substr_count($template->process(array()), "tests/javascript/forms/RequirementsTest_a.js"));
     } else {
         $this->markTestSkipped('Requirement will always fail if the framework dir is not ' . 'named \'framework\', since templates require hard coded paths');
     }
 }
 public function groupimport()
 {
     Requirements::clear();
     Requirements::javascript(FRAMEWORK_ADMIN_DIR . '/client/dist/js/vendor.js');
     Requirements::javascript(ltrim(FRAMEWORK_ADMIN_DIR . '/client/dist/js/MemberImportForm.js', '/'));
     Requirements::css(ltrim(FRAMEWORK_ADMIN_DIR . '/client/dist/styles/bundle.css', '/'));
     return $this->renderWith('BlankPage', array('Content' => ' ', 'Form' => $this->GroupImportForm()->forTemplate()));
 }
 /**
  * Action to handle editing of a single file
  *
  * @param HTTPRequest $request
  * @return DBHTMLText
  */
 public function edit(HTTPRequest $request)
 {
     // Check form field state
     if ($this->parent->isDisabled() || $this->parent->isReadonly()) {
         return $this->httpError(403);
     }
     // Check item permissions
     $item = $this->getItem();
     if (!$item) {
         return $this->httpError(404);
     }
     if ($item instanceof Folder) {
         return $this->httpError(403);
     }
     if (!$item->canEdit()) {
         return $this->httpError(403);
     }
     Requirements::css(ltrim(FRAMEWORK_ADMIN_DIR . '/client/dist/styles/UploadField.css', '/'));
     return $this->customise(array('Form' => $this->EditForm()))->renderWith($this->parent->getTemplateFileEdit());
 }
 /**
  * Include an link to the feed
  *
  * @param string $url URL of the feed
  * @param string $title Title to show
  */
 public static function linkToFeed($url, $title = null)
 {
     $title = Convert::raw2xml($title);
     Requirements::insertHeadTags('<link rel="alternate" type="application/rss+xml" title="' . $title . '" href="' . $url . '" />');
 }
 public function tearDown()
 {
     // Preserve memory settings
     ini_set('memory_limit', $this->originalMemoryLimit ? $this->originalMemoryLimit : -1);
     // Restore email configuration
     $this->mailer = null;
     // Restore password validation
     if ($this->originalMemberPasswordValidator) {
         Member::set_password_validator($this->originalMemberPasswordValidator);
     }
     // Restore requirements
     if ($this->originalRequirements) {
         Requirements::set_backend($this->originalRequirements);
     }
     // Mark test as no longer being run - we use originalIsRunningTest to allow for nested SapphireTest calls
     self::$is_running_test = $this->originalIsRunningTest;
     $this->originalIsRunningTest = null;
     // Reset mocked datetime
     DBDatetime::clear_mock_now();
     // Stop the redirection that might have been requested in the test.
     // Note: Ideally a clean Controller should be created for each test.
     // Now all tests executed in a batch share the same controller.
     $controller = Controller::has_curr() ? Controller::curr() : null;
     if ($controller && ($response = $controller->getResponse()) && $response->getHeader('Location')) {
         $response->setStatusCode(200);
         $response->removeHeader('Location');
     }
     Versioned::set_reading_mode($this->originalReadingMode);
     //unnest injector / config now that tests are over
     Injector::unnest();
     Config::unnest();
 }
 public function init()
 {
     // include TinyMCE Javascript
     Requirements::javascript($this->getScriptURL());
 }
 protected function init()
 {
     parent::init();
     Requirements::javascript(FRAMEWORK_ADMIN_DIR . '/client/dist/js/vendor.js');
     Requirements::javascript(FRAMEWORK_ADMIN_DIR . '/client/dist/js/CMSSecurity.js');
 }
 /**
  * Handle the print, for both the action button and the URL
  *
  * @param GridField $gridField
  * @param HTTPRequest $request
  * @return DBHTMLText
  */
 public function handlePrint($gridField, $request = null)
 {
     set_time_limit(60);
     Requirements::clear();
     Requirements::css(ltrim(FRAMEWORK_DIR . '/admin/client/dist/styles/GridField_print.css', '/'));
     if ($data = $this->generatePrintData($gridField)) {
         return $data->renderWith(get_class($gridField) . "_print");
     }
     return null;
 }
 public function index()
 {
     // Requires a separate JS file, because we can't reach into the iframe with entwine.
     Requirements::javascript(ltrim(FRAMEWORK_ADMIN_DIR . '/client/dist/js/UploadField_select.js', '/'));
     return $this->renderWith('SilverStripe\\Admin\\CMSDialog');
 }
 /**
  * Set this store as the new asset backend
  *
  * @param string $basedir Basedir to store assets, which will be placed beneath 'assets' folder
  */
 public static function activate($basedir)
 {
     // Assign this as the new store
     $publicAdapter = new PublicAssetAdapter(ASSETS_PATH . '/' . $basedir);
     $publicFilesystem = new Filesystem($publicAdapter, ['visibility' => AdapterInterface::VISIBILITY_PUBLIC]);
     $protectedAdapter = new ProtectedAssetAdapter(ASSETS_PATH . '/' . $basedir . '/.protected');
     $protectedFilesystem = new Filesystem($protectedAdapter, ['visibility' => AdapterInterface::VISIBILITY_PRIVATE]);
     $backend = new AssetStoreTest_SpyStore();
     $backend->setPublicFilesystem($publicFilesystem);
     $backend->setProtectedFilesystem($protectedFilesystem);
     Injector::inst()->registerService($backend, 'AssetStore');
     // Assign flysystem backend to generated asset handler at the same time
     $generated = new GeneratedAssetHandler();
     $generated->setFilesystem($publicFilesystem);
     Injector::inst()->registerService($generated, 'GeneratedAssetHandler');
     Requirements::backend()->setAssetHandler($generated);
     // Disable legacy and set defaults
     Config::inst()->remove(get_class(new FlysystemAssetStore()), 'legacy_filenames');
     Config::inst()->update('SilverStripe\\Control\\Director', 'alternate_base_url', '/');
     DBFile::config()->force_resample = false;
     File::config()->force_resample = false;
     self::reset();
     self::$basedir = $basedir;
     // Ensure basedir exists
     SSFilesystem::makeFolder(self::base_path());
 }
 public function init()
 {
     Requirements::add_i18n_javascript(ASSET_ADMIN_DIR . '/client/lang', false, true);
     Requirements::javascript(ASSET_ADMIN_DIR . "/client/dist/js/bundle.js");
     Requirements::css(ASSET_ADMIN_DIR . "/client/dist/styles/bundle.css");
 }
 public function testConditionalTemplateRequire()
 {
     $testPath = ltrim(preg_replace('#^' . BASE_PATH . '#', '', dirname(__DIR__)), '/');
     /** @var Requirements_Backend $backend */
     $backend = Injector::inst()->create('SilverStripe\\View\\Requirements_Backend');
     $this->setupRequirements($backend);
     $holder = Requirements::backend();
     Requirements::set_backend($backend);
     $data = new ArrayData(array('FailTest' => true));
     $data->renderWith('RequirementsTest_Conditionals');
     $this->assertFileIncluded($backend, 'css', $testPath . '/css/forms/RequirementsTest_a.css');
     $this->assertFileIncluded($backend, 'js', array($testPath . '/javascript/forms/RequirementsTest_b.js', $testPath . '/javascript/forms/RequirementsTest_c.js'));
     $this->assertFileNotIncluded($backend, 'js', $testPath . '/javascript/forms/RequirementsTest_a.js');
     $this->assertFileNotIncluded($backend, 'css', array($testPath . '/css/forms/RequirementsTest_b.css', $testPath . '/css/forms/RequirementsTest_c.css'));
     $backend->clear();
     $data = new ArrayData(array('FailTest' => false));
     $data->renderWith('RequirementsTest_Conditionals');
     $this->assertFileNotIncluded($backend, 'css', $testPath . '/css/forms/RequirementsTest_a.css');
     $this->assertFileNotIncluded($backend, 'js', array($testPath . '/javascript/forms/RequirementsTest_b.js', $testPath . '/javascript/forms/RequirementsTest_c.js'));
     $this->assertFileIncluded($backend, 'js', $testPath . '/javascript/forms/RequirementsTest_a.js');
     $this->assertFileIncluded($backend, 'css', array($testPath . '/css/forms/RequirementsTest_b.css', $testPath . '/css/forms/RequirementsTest_c.css'));
     Requirements::set_backend($holder);
 }
 /**
  * Set up the controller
  */
 public function init()
 {
     parent::init();
     Requirements::add_i18n_javascript(ASSET_ADMIN_DIR . '/client/lang', false, true);
     Requirements::javascript(ASSET_ADMIN_DIR . "/client/dist/js/bundle.js");
     Requirements::css(ASSET_ADMIN_DIR . "/client/dist/styles/bundle.css");
     CMSBatchActionHandler::register('delete', DeleteAssets::class, Folder::class);
 }
 /**
  * Return a {@link Form} instance allowing a user to
  * add images and flash objects to the TinyMCE content editor.
  *
  * @return Form
  */
 public function MediaForm()
 {
     // TODO Handle through GridState within field - currently this state set too late to be useful here (during
     // request handling)
     $parentID = $this->getAttachParentID();
     $fileFieldConfig = GridFieldConfig::create()->addComponents(new GridFieldSortableHeader(), new GridFieldFilterHeader(), new GridFieldDataColumns(), new GridFieldPaginator(7), new GridFieldDeleteAction(), new GridFieldDetailForm());
     $fileField = GridField::create('Files', false, null, $fileFieldConfig);
     $fileField->setList($this->getFiles($parentID));
     $fileField->setAttribute('data-selectable', true);
     $fileField->setAttribute('data-multiselect', true);
     /** @var GridFieldDataColumns $columns */
     $columns = $fileField->getConfig()->getComponentByType('SilverStripe\\Forms\\GridField\\GridFieldDataColumns');
     $columns->setDisplayFields(array('StripThumbnail' => false, 'Title' => _t('File.Title'), 'Created' => File::singleton()->fieldLabel('Created')));
     $columns->setFieldCasting(array('Created' => 'DBDatetime->Nice'));
     $fromCMS = new CompositeField($select = TreeDropdownField::create('ParentID', "", 'SilverStripe\\Assets\\Folder')->addExtraClass('noborder')->setValue($parentID), $fileField);
     $fromCMS->addExtraClass('content ss-uploadfield htmleditorfield-from-cms');
     $select->addExtraClass('content-select');
     $URLDescription = _t('HTMLEditorField.URLDESCRIPTION', 'Insert videos and images from the web into your page simply by entering the URL of the file. Make sure you have the rights or permissions before sharing media directly from the web.<br /><br />Please note that files are not added to the file store of the CMS but embeds the file from its original location, if for some reason the file is no longer available in its original location it will no longer be viewable on this page.');
     $fromWeb = new CompositeField($description = new LiteralField('URLDescription', '<div class="url-description">' . $URLDescription . '</div>'), $remoteURL = new TextField('RemoteURL', 'http://'), new LiteralField('addURLImage', '<button type="button" class="action ui-action-constructive ui-button field font-icon-plus add-url">' . _t('HTMLEditorField.BUTTONADDURL', 'Add url') . '</button>'));
     $remoteURL->addExtraClass('remoteurl');
     $fromWeb->addExtraClass('content ss-uploadfield htmleditorfield-from-web');
     Requirements::css(ltrim(FRAMEWORK_ADMIN_DIR . '/client/dist/styles/AssetUploadField.css', '/'));
     $computerUploadField = UploadField::create('AssetUploadField', '');
     $computerUploadField->setConfig('previewMaxWidth', 40);
     $computerUploadField->setConfig('previewMaxHeight', 30);
     $computerUploadField->addExtraClass('toolbar toolbar--content ss-assetuploadfield htmleditorfield-from-computer');
     $computerUploadField->removeExtraClass('ss-uploadfield');
     $computerUploadField->setTemplate('SilverStripe\\Forms\\HTMLEditorField_UploadField');
     $computerUploadField->setFolderName(Upload::config()->get('uploads_folder'));
     $defaultPanel = new CompositeField($computerUploadField, $fromCMS);
     $fromWebPanel = new CompositeField($fromWeb);
     $defaultPanel->addExtraClass('htmleditorfield-default-panel');
     $fromWebPanel->addExtraClass('htmleditorfield-web-panel');
     $allFields = new CompositeField($defaultPanel, $fromWebPanel, $editComposite = new CompositeField(new LiteralField('contentEdit', '<div class="content-edit ss-uploadfield-files files"></div>')));
     $allFields->addExtraClass('ss-insert-media');
     $headings = new CompositeField(new LiteralField('Heading', sprintf('<h3 class="htmleditorfield-mediaform-heading insert">%s</h3>', _t('HTMLEditorField.INSERTMEDIA', 'Insert media from')) . sprintf('<h3 class="htmleditorfield-mediaform-heading update">%s</h3>', _t('HTMLEditorField.UpdateMEDIA', 'Update media'))));
     $headings->addExtraClass('cms-content-header');
     $editComposite->addExtraClass('ss-assetuploadfield');
     $fields = new FieldList($headings, $allFields);
     $form = new Form($this->controller, "{$this->name}/MediaForm", $fields, new FieldList());
     $form->unsetValidator();
     $form->disableSecurityToken();
     $form->loadDataFrom($this);
     $form->addExtraClass('htmleditorfield-form htmleditorfield-mediaform cms-dialog-content');
     // Allow other people to extend the fields being added to the imageform
     $this->extend('updateMediaForm', $form);
     return $form;
 }
    /**
     * Send this HTTPReponse to the browser
     */
    public function output()
    {
        // Attach appropriate X-Include-JavaScript and X-Include-CSS headers
        if (Director::is_ajax()) {
            Requirements::include_in_response($this);
        }
        if (in_array($this->statusCode, self::$redirect_codes) && headers_sent($file, $line)) {
            $url = Director::absoluteURL($this->headers['Location'], true);
            $urlATT = Convert::raw2htmlatt($url);
            $urlJS = Convert::raw2js($url);
            $title = Director::isDev() ? "{$urlATT}... (output started on {$file}, line {$line})" : "{$urlATT}...";
            echo <<<EOT
<p>Redirecting to <a href="{$urlATT}" title="Click this link if your browser does not redirect you">{$title}</a></p>
<meta http-equiv="refresh" content="1; url={$urlATT}" />
<script type="application/javascript">setTimeout(function(){
\twindow.location.href = "{$urlJS}";
}, 50);</script>
EOT;
        } else {
            $line = $file = null;
            if (!headers_sent($file, $line)) {
                header($_SERVER['SERVER_PROTOCOL'] . " {$this->statusCode} " . $this->getStatusDescription());
                foreach ($this->headers as $header => $value) {
                    //etags need to be quoted
                    if (strcasecmp('etag', $header) === 0 && 0 !== strpos($value, '"')) {
                        $value = sprintf('"%s"', $value);
                    }
                    header("{$header}: {$value}", true, $this->statusCode);
                }
            } else {
                // It's critical that these status codes are sent; we need to report a failure if not.
                if ($this->statusCode >= 300) {
                    user_error("Couldn't set response type to {$this->statusCode} because " . "of output on line {$line} of {$file}", E_USER_WARNING);
                }
            }
            // Only show error pages or generic "friendly" errors if the status code signifies
            // an error, and the response doesn't have any body yet that might contain
            // a more specific error description.
            if (Director::isLive() && $this->isError() && !$this->body) {
                $formatter = Injector::inst()->get('FriendlyErrorFormatter');
                echo $formatter->format(array('code' => $this->statusCode));
            } else {
                echo $this->body;
            }
        }
    }
 /**
  * The process() method handles the "meat" of the template processing.
  *
  * It takes care of caching the output (via {@link Cache}), as well as
  * replacing the special "$Content" and "$Layout" placeholders with their
  * respective subtemplates.
  *
  * The method injects extra HTML in the header via {@link Requirements::includeInHTML()}.
  *
  * Note: You can call this method indirectly by {@link ViewableData->renderWith()}.
  *
  * @param ViewableData $item
  * @param array|null $arguments Arguments to an included template
  * @param ViewableData $inheritedScope The current scope of a parent template including a sub-template
  * @return DBHTMLText Parsed template output.
  */
 public function process($item, $arguments = null, $inheritedScope = null)
 {
     SSViewer::$topLevel[] = $item;
     $template = $this->chosen;
     $cacheFile = TEMP_FOLDER . "/.cache" . str_replace(array('\\', '/', ':'), '.', Director::makeRelative(realpath($template)));
     $lastEdited = filemtime($template);
     if (!file_exists($cacheFile) || filemtime($cacheFile) < $lastEdited) {
         $content = file_get_contents($template);
         $content = $this->parseTemplateContent($content, $template);
         $fh = fopen($cacheFile, 'w');
         fwrite($fh, $content);
         fclose($fh);
     }
     $underlay = array('I18NNamespace' => basename($template));
     // Makes the rendered sub-templates available on the parent item,
     // through $Content and $Layout placeholders.
     foreach (array('Content', 'Layout') as $subtemplate) {
         $sub = null;
         if (isset($this->subTemplates[$subtemplate])) {
             $sub = $this->subTemplates[$subtemplate];
         } elseif (!is_array($this->templates)) {
             $sub = ['type' => $subtemplate, $this->templates];
         } elseif (!array_key_exists('type', $this->templates) || !$this->templates['type']) {
             $sub = array_merge($this->templates, ['type' => $subtemplate]);
         }
         if ($sub) {
             $subtemplateViewer = clone $this;
             // Disable requirements - this will be handled by the parent template
             $subtemplateViewer->includeRequirements(false);
             // Select the right template
             $subtemplateViewer->setTemplate($sub);
             if ($subtemplateViewer->exists()) {
                 $underlay[$subtemplate] = $subtemplateViewer->process($item, $arguments);
             }
         }
     }
     $output = $this->includeGeneratedTemplate($cacheFile, $item, $arguments, $underlay, $inheritedScope);
     if ($this->includeRequirements) {
         $output = Requirements::includeInHTML($output);
     }
     array_pop(SSViewer::$topLevel);
     // If we have our crazy base tag, then fix # links referencing the current page.
     $rewrite = SSViewer::config()->get('rewrite_hash_links');
     if ($this->rewriteHashlinks && $rewrite) {
         if (strpos($output, '<base') !== false) {
             if ($rewrite === 'php') {
                 $thisURLRelativeToBase = "<?php echo \\SilverStripe\\Core\\Convert::raw2att(preg_replace(\"/^(\\\\/)+/\", \"/\", \$_SERVER['REQUEST_URI'])); ?>";
             } else {
                 $thisURLRelativeToBase = Convert::raw2att(preg_replace("/^(\\/)+/", "/", $_SERVER['REQUEST_URI']));
             }
             $output = preg_replace('/(<a[^>]+href *= *)"#/i', '\\1"' . $thisURLRelativeToBase . '#', $output);
         }
     }
     return DBField::create_field('HTMLFragment', $output);
 }
Esempio n. 21
0
 /**
  * Encode an email-address to help protect it from spam bots. At the moment only simple string substitutions, which
  * are not 100% safe from email harvesting.
  *
  * @todo Integrate javascript-based solution
  *
  * @param string $email Email-address
  * @param string $method Method for obfuscating/encoding the address
  *	- 'direction': Reverse the text and then use CSS to put the text direction back to normal
  *	- 'visible': Simple string substitution ('@' to '[at]', '.' to '[dot], '-' to [dash])
  *	- 'hex': Hexadecimal URL-Encoding - useful for mailto: links
  * @return string
  */
 public static function obfuscate($email, $method = 'visible')
 {
     switch ($method) {
         case 'direction':
             Requirements::customCSS('span.codedirection { unicode-bidi: bidi-override; direction: rtl; }', 'codedirectionCSS');
             return '<span class="codedirection">' . strrev($email) . '</span>';
         case 'visible':
             $obfuscated = array('@' => ' [at] ', '.' => ' [dot] ', '-' => ' [dash] ');
             return strtr($email, $obfuscated);
         case 'hex':
             $encoded = '';
             for ($x = 0; $x < strlen($email); $x++) {
                 $encoded .= '&#x' . bin2hex($email[$x]) . ';';
             }
             return $encoded;
         default:
             user_error('Email::obfuscate(): Unknown obfuscation method', E_USER_NOTICE);
             return $email;
     }
 }
 public function printable()
 {
     $form = $this->getEditForm($this->currentPageID());
     if (!$form) {
         return false;
     }
     $form->transform(new PrintableTransformation());
     $form->setActions(null);
     Requirements::clear();
     Requirements::css(FRAMEWORK_ADMIN_DIR . '/dist/css/LeftAndMain_printable.css');
     return array("PrintForm" => $form);
 }
 public function tearDown()
 {
     parent::tearDown();
     Requirements::set_combined_files_enabled($this->backupCombined);
 }
    /**
     * Constructor
     *
     * @skipUpgrade
     * @param Controller $controller The parent controller, necessary to
     *                               create the appropriate form action tag.
     * @param string $name The method on the controller that will return this
     *                     form object.
     * @param FieldList $fields All of the fields in the form - a
     *                                   {@link FieldList} of {@link FormField}
     *                                   objects.
     * @param FieldList|FormAction $actions All of the action buttons in the
     *                                     form - a {@link FieldList} of
     *                                     {@link FormAction} objects
     * @param bool $checkCurrentUser If set to TRUE, it will be checked if a
     *                               the user is currently logged in, and if
     *                               so, only a logout button will be rendered
     */
    public function __construct($controller, $name, $fields = null, $actions = null, $checkCurrentUser = true)
    {
        // This is now set on the class directly to make it easier to create subclasses
        // $this->authenticator_class = $authenticatorClassName;
        $customCSS = project() . '/css/member_login.css';
        if (Director::fileExists($customCSS)) {
            Requirements::css($customCSS);
        }
        if (isset($_REQUEST['BackURL'])) {
            $backURL = $_REQUEST['BackURL'];
        } else {
            $backURL = Session::get('BackURL');
        }
        if ($checkCurrentUser && Member::currentUser() && Member::logged_in_session_exists()) {
            $fields = FieldList::create(HiddenField::create("AuthenticationMethod", null, $this->authenticator_class, $this));
            $actions = FieldList::create(FormAction::create("logout", _t('Member.BUTTONLOGINOTHER', "Log in as someone else")));
        } else {
            if (!$fields) {
                $label = Member::singleton()->fieldLabel(Member::config()->unique_identifier_field);
                $fields = FieldList::create(HiddenField::create("AuthenticationMethod", null, $this->authenticator_class, $this), $emailField = TextField::create("Email", $label, null, null, $this), PasswordField::create("Password", _t('Member.PASSWORD', 'Password')));
                if (Security::config()->remember_username) {
                    $emailField->setValue(Session::get('SessionForms.MemberLoginForm.Email'));
                } else {
                    // Some browsers won't respect this attribute unless it's added to the form
                    $this->setAttribute('autocomplete', 'off');
                    $emailField->setAttribute('autocomplete', 'off');
                }
                if (Security::config()->autologin_enabled) {
                    $fields->push(CheckboxField::create("Remember", _t('Member.KEEPMESIGNEDIN', "Keep me signed in"))->setAttribute('title', sprintf(_t('Member.REMEMBERME', "Remember me next time? (for %d days on this device)"), RememberLoginHash::config()->get('token_expiry_days'))));
                }
            }
            if (!$actions) {
                $actions = FieldList::create(FormAction::create('dologin', _t('Member.BUTTONLOGIN', "Log in")), LiteralField::create('forgotPassword', '<p id="ForgotPassword"><a href="' . Security::lost_password_url() . '">' . _t('Member.BUTTONLOSTPASSWORD', "I've lost my password") . '</a></p>'));
            }
        }
        if (isset($backURL)) {
            $fields->push(HiddenField::create('BackURL', 'BackURL', $backURL));
        }
        // Reduce attack surface by enforcing POST requests
        $this->setFormMethod('POST', true);
        parent::__construct($controller, $name, $fields, $actions);
        $this->setValidator(RequiredFields::create('Email', 'Password'));
        // Focus on the email input when the page is loaded
        $js = <<<JS
\t\t\t(function() {
\t\t\t\tvar el = document.getElementById("MemberLoginForm_LoginForm_Email");
\t\t\t\tif(el && el.focus && (typeof jQuery == 'undefined' || jQuery(el).is(':visible'))) el.focus();
\t\t\t})();
JS;
        Requirements::customScript($js, 'MemberLoginFormFieldFocus');
    }