/** * Output file to the browser. * For performance reasons, we avoid SS_HTTPResponse and just output the contents instead. */ public function sendFile($file) { $path = $file->getFullPath(); if (SapphireTest::is_running_test()) { return file_get_contents($path); } header('Content-Description: File Transfer'); // Quotes needed to retain spaces (http://kb.mozillazine.org/Filenames_with_spaces_are_truncated_upon_download) header('Content-Disposition: inline; filename="' . basename($path) . '"'); header('Content-Length: ' . $file->getAbsoluteSize()); header('Content-Type: ' . HTTP::get_mime_type($file->getRelativePath())); header('Content-Transfer-Encoding: binary'); // Fixes IE6,7,8 file downloads over HTTPS bug (http://support.microsoft.com/kb/812935) header('Pragma: '); if ($this->config()->min_download_bandwidth) { // Allow the download to last long enough to allow full download with min_download_bandwidth connection. increase_time_limit_to((int) (filesize($path) / ($this->config()->min_download_bandwidth * 1024))); } else { // Remove the timelimit. increase_time_limit_to(0); } // Clear PHP buffer, otherwise the script will try to allocate memory for entire file. while (ob_get_level() > 0) { ob_end_flush(); } // Prevent blocking of the session file by PHP. Without this the user can't visit another page of the same // website during download (see http://konrness.com/php5/how-to-prevent-blocking-php-requests/) session_write_close(); readfile($path); die; }
/** * Output file to the browser. * For performance reasons, we avoid SS_HTTPResponse and just output the contents instead. */ public function sendFile($file) { $reader = $file->reader(); if (!$reader || !$reader->isReadable()) { return; } if (class_exists('SapphireTest', false) && SapphireTest::is_running_test()) { return $reader->read(); } $type = HTTP::get_mime_type($file->Filename); $disposition = strpos($type, 'image') !== false ? 'inline' : 'attachment'; header('Content-Description: File Transfer'); // Quotes needed to retain spaces (http://kb.mozillazine.org/Filenames_with_spaces_are_truncated_upon_download) header(sprintf('Content-Disposition: %s; filename="%s"', $disposition, basename($file->Filename))); header('Content-Length: ' . $file->FileSize); header('Content-Type: ' . $type); header('Content-Transfer-Encoding: binary'); // Ensure we enforce no-cache headers consistently, so that files accesses aren't cached by CDN/edge networks header('Pragma: no-cache'); header('Cache-Control: private, no-cache, no-store'); increase_time_limit_to(0); // Clear PHP buffer, otherwise the script will try to allocate memory for entire file. while (ob_get_level() > 0) { ob_end_flush(); } // Prevent blocking of the session file by PHP. Without this the user can't visit another page of the same // website during download (see http://konrness.com/php5/how-to-prevent-blocking-php-requests/) session_write_close(); echo $reader->read(); die; }
/** * Run through the rules for this validator checking against * the temporary file set by {@link setTmpFile()} to see if * the file is deemed valid or not. * * @return boolean */ public function validate() { // we don't validate for empty upload fields yet if (!isset($this->tmpFile['name']) || empty($this->tmpFile['name'])) { return true; } $isRunningTests = class_exists('SapphireTest', false) && SapphireTest::is_running_test(); //needed to allow XHR uploads /*if(isset($this->tmpFile['tmp_name']) && !is_uploaded_file($this->tmpFile['tmp_name']) && !$isRunningTests) { $this->errors[] = _t('File.NOVALIDUPLOAD', 'File is not a valid upload'); return false; }*/ $pathInfo = pathinfo($this->tmpFile['name']); // filesize validation if (!$this->isValidSize()) { $ext = isset($pathInfo['extension']) ? $pathInfo['extension'] : ''; $arg = File::format_size($this->getAllowedMaxFileSize($ext)); $this->errors[] = sprintf(_t('File.TOOLARGE', 'Filesize is too large, maximum %s allowed.', PR_MEDIUM, 'Argument 1: Filesize (e.g. 1MB)'), $arg); return false; } // extension validation if (!$this->isValidExtension()) { $this->errors[] = sprintf(_t('File.INVALIDEXTENSION', 'Extension is not allowed (valid: %s)', PR_MEDIUM, 'Argument 1: Comma-separated list of valid extensions'), wordwrap(implode(', ', $this->allowedExtensions))); return false; } return true; }
public function preRequest(SS_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>'), 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('SapphireTest', false) && SapphireTest::is_running_test()) { throw new SS_HTTPResponse_Exception($response); } $response->output(); die; } Versioned::choose_site_stage(); $dummyController->popCurrent(); return true; }
/** * Start a new instance of this class. * @param string $url The URL to parse for links */ function __construct($url) { $this->url = $url; if (class_exists('SapphireTest', false) && SapphireTest::is_running_test()) { $this->showMessages = false; } }
function init() { parent::init(); $canAccess = Director::isDev() || Director::is_cli() && !SapphireTest::is_running_test() || Permission::check("ADMIN"); if (!$canAccess) { return Security::permissionFailure($this); } }
public function init() { parent::init(); $isRunningTests = class_exists('SapphireTest', false) && SapphireTest::is_running_test(); $canAccess = Director::isDev() || Director::is_cli() && !$isRunningTests || Permission::check("ADMIN"); if (!$canAccess) { return Security::permissionFailure($this); } }
/** * Require basic authentication. Will request a username and password if none is given. * * Used by {@link Controller::init()}. * * @throws SS_HTTPResponse_Exception * * @param string $realm * @param string|array $permissionCode Optional * @param boolean $tryUsingSessionLogin If true, then the method with authenticate against the * session log-in if those credentials are disabled. * @return Member $member */ public static function requireLogin($realm, $permissionCode = null, $tryUsingSessionLogin = true) { $isRunningTests = class_exists('SapphireTest', false) && SapphireTest::is_running_test(); if (!Security::database_is_ready() || Director::is_cli() && !$isRunningTests) { return true; } /* * Enable HTTP Basic authentication workaround for PHP running in CGI mode with Apache * Depending on server configuration the auth header may be in HTTP_AUTHORIZATION or * REDIRECT_HTTP_AUTHORIZATION * * The follow rewrite rule must be in the sites .htaccess file to enable this workaround * RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] */ $authHeader = isset($_SERVER['HTTP_AUTHORIZATION']) ? $_SERVER['HTTP_AUTHORIZATION'] : (isset($_SERVER['REDIRECT_HTTP_AUTHORIZATION']) ? $_SERVER['REDIRECT_HTTP_AUTHORIZATION'] : null); $matches = array(); if ($authHeader && preg_match('/Basic\\s+(.*)$/i', $authHeader, $matches)) { list($name, $password) = explode(':', base64_decode($matches[1])); $_SERVER['PHP_AUTH_USER'] = strip_tags($name); $_SERVER['PHP_AUTH_PW'] = strip_tags($password); } $member = null; if (isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW'])) { $member = MemberAuthenticator::authenticate(array('Email' => $_SERVER['PHP_AUTH_USER'], 'Password' => $_SERVER['PHP_AUTH_PW']), null); } if (!$member && $tryUsingSessionLogin) { $member = Member::currentUser(); } // If we've failed the authentication mechanism, then show the login form if (!$member) { $response = new SS_HTTPResponse(null, 401); $response->addHeader('WWW-Authenticate', "Basic realm=\"{$realm}\""); if (isset($_SERVER['PHP_AUTH_USER'])) { $response->setBody(_t('BasicAuth.ERRORNOTREC', "That username / password isn't recognised")); } else { $response->setBody(_t('BasicAuth.ENTERINFO', "Please enter a username and password.")); } // Exception is caught by RequestHandler->handleRequest() and will halt further execution $e = new SS_HTTPResponse_Exception(null, 401); $e->setResponse($response); throw $e; } if ($permissionCode && !Permission::checkMember($member->ID, $permissionCode)) { $response = new SS_HTTPResponse(null, 401); $response->addHeader('WWW-Authenticate', "Basic realm=\"{$realm}\""); if (isset($_SERVER['PHP_AUTH_USER'])) { $response->setBody(_t('BasicAuth.ERRORNOTADMIN', "That user is not an administrator.")); } // Exception is caught by RequestHandler->handleRequest() and will halt further execution $e = new SS_HTTPResponse_Exception(null, 401); $e->setResponse($response); throw $e; } return $member; }
/** * Register our shutdown handler */ public function __construct() { // bind a shutdown function to process all 'immediate' queued jobs if needed, but only in CLI mode if (self::$use_shutdown_function && Director::is_cli()) { if (class_exists('PHPUnit_Framework_TestCase') && SapphireTest::is_running_test()) { // do NOTHING } else { register_shutdown_function(array($this, 'onShutdown')); } } }
function init() { parent::init(); // We allow access to this controller regardless of live-status or ADMIN permission only // if on CLI or with the database not ready. The latter makes it less errorprone to do an // initial schema build without requiring a default-admin login. // Access to this controller is always allowed in "dev-mode", or of the user is ADMIN. $canAccess = Director::isDev() || !Security::database_is_ready() || Director::is_cli() && !SapphireTest::is_running_test() || Permission::check("ADMIN"); if (!$canAccess) { return Security::permissionFailure($this, "This page is secured and you need administrator rights to access it. " . "Enter your credentials below and we will send you right along."); } }
/** * standard Silverstripe method - required * */ function init() { parent::init(); // We allow access to this controller regardless of live-status or ADMIN permission only // or if on CLI. // Access to this controller is always allowed in "dev-mode", or if the user is ADMIN. $isRunningTests = class_exists('SapphireTest', false) && SapphireTest::is_running_test(); $canAccess = Director::isDev() || Director::is_cli() && !$isRunningTests || Permission::check("ADMIN") || Permission::check(EcommerceConfig::get("EcommerceRole", "admin_group_code")); if (!$canAccess) { return Security::permissionFailure($this, "The e-commerce development control panel is secured and you need administrator rights to access it. " . "Enter your credentials below and we will send you right along."); } }
function init() { parent::init(); $isRunningTests = (class_exists('SapphireTest', false) && SapphireTest::is_running_test()); $canAccess = ( Director::isDev() // We need to ensure that DevelopmentAdminTest can simulate permission failures when running // "dev/tasks" from CLI. || (Director::is_cli() && !$isRunningTests) || Permission::check("ADMIN") ); if(!$canAccess) return Security::permissionFailure($this); }
/** * @return \Member */ protected static function getBasicAuthMember() { $realm = \Config::inst()->get('HttpAuth', 'Realm'); $permissionCode = \Config::inst()->get('HttpAuth', 'PermissionCode'); $isRunningTests = class_exists('SapphireTest', false) && \SapphireTest::is_running_test(); $tryUsingSessionLogin = $isRunningTests || \Config::inst()->get('HttpAuth', 'TryUsingSessionLogin'); try { $member = \BasicAuth::requireLogin($realm, $permissionCode, $tryUsingSessionLogin); return $member; } catch (\Exception $ex) { return null; } }
/** * Use table information and locales to dynamically build required table fields * @see DataExtension::get_extra_config() * @inheritdoc */ public static function get_extra_config($class, $extension, $args) { if (!self::is_translatable_installed()) { // remain silent during a test if (SapphireTest::is_running_test()) { return null; } // raise an error otherwise user_error('Translatable module is not installed but required.', E_USER_WARNING); return null; } if ($args) { self::$arguments[$class] = $args; } return array('db' => self::collectDBFields($class)); }
public function init() { parent::init(); // We allow access to this controller regardless of live-status or ADMIN permission only // if on CLI or with the database not ready. The latter makes it less errorprone to do an // initial schema build without requiring a default-admin login. // Access to this controller is always allowed in "dev-mode", or of the user is ADMIN. $isRunningTests = class_exists('SapphireTest', false) && SapphireTest::is_running_test(); $canAccess = Director::isDev() || !Security::database_is_ready() || Director::is_cli() && !$isRunningTests || Permission::check("ADMIN"); if (!$canAccess) { return Security::permissionFailure($this, "This page is secured and you need administrator rights to access it. " . "Enter your credentials below and we will send you right along."); } //render the debug view $renderer = Object::create('DebugView'); $renderer->writeHeader(); $renderer->writeInfo(_t("Shop.DEVTOOLSTITLE", "Shop Development Tools"), Director::absoluteBaseURL()); }
/** * Require basic authentication. Will request a username and password if none is given. * * Used by {@link Controller::init()}. * * @throws SS_HTTPResponse_Exception * * @param string $realm * @param string|array $permissionCode Optional * @param boolean $tryUsingSessionLogin If true, then the method with authenticate against the * session log-in if those credentials are disabled. * @return Member $member */ public static function requireLogin($realm, $permissionCode = null, $tryUsingSessionLogin = true) { $isRunningTests = class_exists('SapphireTest', false) && SapphireTest::is_running_test(); if (!Security::database_is_ready() || Director::is_cli() && !$isRunningTests) { return true; } $matches = array(); if (isset($_SERVER['HTTP_AUTHORIZATION']) && preg_match('/Basic\\s+(.*)$/i', $_SERVER['HTTP_AUTHORIZATION'], $matches)) { list($name, $password) = explode(':', base64_decode($matches[1])); $_SERVER['PHP_AUTH_USER'] = strip_tags($name); $_SERVER['PHP_AUTH_PW'] = strip_tags($password); } $member = null; if (isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW'])) { $member = MemberAuthenticator::authenticate(array('Email' => $_SERVER['PHP_AUTH_USER'], 'Password' => $_SERVER['PHP_AUTH_PW']), null); } if (!$member && $tryUsingSessionLogin) { $member = Member::currentUser(); } // If we've failed the authentication mechanism, then show the login form if (!$member) { $response = new SS_HTTPResponse(null, 401); $response->addHeader('WWW-Authenticate', "Basic realm=\"{$realm}\""); if (isset($_SERVER['PHP_AUTH_USER'])) { $response->setBody(_t('BasicAuth.ERRORNOTREC', "That username / password isn't recognised")); } else { $response->setBody(_t('BasicAuth.ENTERINFO', "Please enter a username and password.")); } // Exception is caught by RequestHandler->handleRequest() and will halt further execution $e = new SS_HTTPResponse_Exception(null, 401); $e->setResponse($response); throw $e; } if ($permissionCode && !Permission::checkMember($member->ID, $permissionCode)) { $response = new SS_HTTPResponse(null, 401); $response->addHeader('WWW-Authenticate', "Basic realm=\"{$realm}\""); if (isset($_SERVER['PHP_AUTH_USER'])) { $response->setBody(_t('BasicAuth.ERRORNOTADMIN', "That user is not an administrator.")); } // Exception is caught by RequestHandler->handleRequest() and will halt further execution $e = new SS_HTTPResponse_Exception(null, 401); $e->setResponse($response); throw $e; } return $member; }
public function geocodeAddress() { //we don't want geocoding to occur during testing //TODO: we could possibly switch to a mock setup if (class_exists('SapphireTest', false) && SapphireTest::is_running_test()) { return; } //TODO: check if address is valid $geocoder = self::get_geocoder(); try { $geocoded = $geocoder->geocode($this->owner->toString()); $this->owner->Latitude = $geocoded->getLatitude(); $this->owner->Longitude = $geocoded->getLongitude(); } catch (Exception $e) { SS_Log::log($e, SS_Log::ERR); } }
/** * * @param StaticPagesQueue $eventClass * @return bool - if the event was fired or not * @throws Exception */ public static function fire_event(StaticPagesQueueEvent $eventClass) { if (class_exists('SapphireTest') && SapphireTest::is_running_test() && !self::$fire_test_events) { return false; } $eventClassName = get_class($eventClass); if (!array_key_exists($eventClassName, self::$events)) { throw new StaticPagesQueueEvent_Exception('The event "' . $eventClassName . '" has not yet been registered and therefore can\'t be triggered.'); } $interfaceName = self::$events[$eventClassName]; $implementors = ClassInfo::implementorsOf($interfaceName); $methodName = lcfirst(str_replace('Listener', '', $interfaceName)); foreach ($implementors as $implementor) { $controller = new $implementor(); $controller->{$methodName}($eventClass); } return true; }
function init() { parent::init(); // We allow access to this controller regardless of live-status or ADMIN permission only // if on CLI or with the database not ready. The latter makes it less errorprone to do an // initial schema build without requiring a default-admin login. // Access to this controller is always allowed in "dev-mode", or of the user is ADMIN. $isRunningTests = (class_exists('SapphireTest', false) && SapphireTest::is_running_test()); $canAccess = ( Director::isDev() || !Security::database_is_ready() // We need to ensure that DevelopmentAdminTest can simulate permission failures when running // "dev/tests" from CLI. || (Director::is_cli() && !$isRunningTests) || Permission::check("ADMIN") ); if(!$canAccess) { return Security::permissionFailure($this, "This page is secured and you need administrator rights to access it. " . "Enter your credentials below and we will send you right along."); } }
/** * Check if combined files are enabled * * @return bool */ public function getCombinedFilesEnabled() { if (!$this->combinedFilesEnabled) { return false; } // Tests should be combined if (class_exists('SapphireTest', false) && SapphireTest::is_running_test()) { return true; } // Check if specified via querystring if (isset($_REQUEST['combine'])) { return true; } // Non-dev sites are always combined if (!Director::isDev()) { return true; } // Fallback to default return Config::inst()->get(__CLASS__, 'combine_in_dev'); }
/** * Register our shutdown handler */ public function __construct() { // bind a shutdown function to process all 'immediate' queued jobs if needed, but only in CLI mode if (Config::inst()->get(__CLASS__, 'use_shutdown_function') && Director::is_cli()) { if (class_exists('PHPUnit_Framework_TestCase') && SapphireTest::is_running_test()) { // do NOTHING } else { register_shutdown_function(array($this, 'onShutdown')); } } if (Config::inst()->get('Email', 'queued_job_admin_email') == '') { Config::inst()->update('Email', 'queued_job_admin_email', Config::inst()->get('Email', 'admin_email')); } }
function tearDown() { // Preserve memory settings ini_set('memory_limit', $this->originalMemoryLimit ? $this->originalMemoryLimit : -1); // Restore email configuration Email::set_mailer($this->originalMailer); $this->originalMailer = null; $this->mailer = null; // Restore password validation Member::set_password_validator($this->originalMemberPasswordValidator); // Restore requirements 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 theme setting SSViewer::set_theme($this->originalTheme); // Reset mocked datetime SS_Datetime::clear_mock_now(); // Restore nested_urls state if ($this->originalNestedURLsState) { SiteTree::enable_nested_urls(); } else { SiteTree::disable_nested_urls(); } // 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 && $controller->response && $controller->response->getHeader('Location')) { $controller->response->setStatusCode(200); $controller->response->removeHeader('Location'); } }
/** * @todo This should really be taken care of by the testing framework */ protected function debugMessage($msg) { if (class_exists('SapphireTest', false) && !SapphireTest::is_running_test()) { Debug::message($msg); } }
/** * Force the site to run on SSL. * * To use, call from _config.php. For example: * <code> * if(Director::isLive()) Director::forceSSL(); * </code> * * If you don't want your entire site to be on SSL, you can pass an array of PCRE regular expression * patterns for matching relative URLs. For example: * <code> * if(Director::isLive()) Director::forceSSL(array('/^admin/', '/^Security/')); * </code> * * Note that the session data will be lost when moving from HTTP to HTTPS. * It is your responsibility to ensure that this won't cause usability problems. * * CAUTION: This does not respect the site environment mode. You should check this * as per the above examples using Director::isLive() or Director::isTest() for example. * * @return boolean|string String of URL when unit tests running, boolean FALSE if patterns don't match request URI */ static function forceSSL($patterns = null) { $matched = false; if ($patterns) { // protect portions of the site based on the pattern $relativeURL = self::makeRelative(Director::absoluteURL($_SERVER['REQUEST_URI'])); foreach ($patterns as $pattern) { if (preg_match($pattern, $relativeURL)) { $matched = true; break; } } } else { // protect the entire site $matched = true; } if ($matched && (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] == 'off')) { $destURL = str_replace('http:', 'https:', Director::absoluteURL($_SERVER['REQUEST_URI'])); // This coupling to SapphireTest is necessary to test the destination URL and to not interfere with tests if (class_exists('SapphireTest', false) && SapphireTest::is_running_test()) { return $destURL; } else { if (!headers_sent()) { header("Location: {$destURL}"); } die("<h1>Your browser is not accepting header redirects</h1><p>Please <a href=\"{$destURL}\">click here</a>"); } } else { return false; } }
/** * * @param File $file * @return void */ public function sendFileToBrowser($file) { $path = $file->getFullPath(); if (SapphireTest::is_running_test()) { return file_get_contents($path); } $basename = basename($path); $length = $file->getAbsoluteSize(); $type = HTTP::get_mime_type($file->getRelativePath()); //handling time limitation if ($threshold = $this->config()->bandwidth_threshold) { increase_time_limit_to((int) ($length / $threshold)); } else { increase_time_limit_to(); } // send header header('Content-Description: File Transfer'); /* * allow inline 'save as' popup, double quotation is present to prevent browser (eg. Firefox) from handling * wrongly a file with a name with whitespace, through a file in SilverStripe should not contain any whitespace * if the file is uploaded through SS interface * http://kb.mozillazine.org/Filenames_with_spaces_are_truncated_upon_download */ header('Content-Type: ' . $type); header('Content-Disposition: inline; filename=' . $basename); header('Content-Transfer-Encoding: binary'); header('Content-Length: ' . $length); /** * issue fixes for IE6,7,8 when downloading a file over HTTPS (http://support.microsoft.com/kb/812935) * http://www.dotvoid.com/2009/10/problem-with-downloading-files-with-internet-explorer-over-https/ */ if (Director::is_https()) { header('Pragma: '); } header('Expires: 0'); header('Cache-Control: must-revalidate'); /** * unload the php session file * see http://konrness.com/php5/how-to-prevent-blocking-php-requests */ session_write_close(); // if output buffering is active, we clear it to prevent the script from trying to to allocate memory for entire file. while (ob_get_level() > 0) { ob_end_clean(); } flush(); readfile($path); exit(0); }
public function tearDown() { // Preserve memory settings ini_set('memory_limit', $this->originalMemoryLimit ? $this->originalMemoryLimit : -1); // Restore email configuration $this->originalMailer = null; $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 && $controller->response && $controller->response->getHeader('Location')) { $controller->response->setStatusCode(200); $controller->response->removeHeader('Location'); } Versioned::set_reading_mode($this->originalReadingMode); //unnest injector / config now that tests are over Injector::unnest(); Config::unnest(); }
/** * See {@link combine_files()} * */ function process_combined_files() { // The class_exists call prevents us from loading SapphireTest.php (slow) just to know that // SapphireTest isn't running :-) if (class_exists('SapphireTest', false)) { $runningTest = SapphireTest::is_running_test(); } else { $runningTest = false; } if (Director::isDev() && !$runningTest || !$this->combined_files_enabled) { return; } // Make a map of files that could be potentially combined $combinerCheck = array(); foreach ($this->combine_files as $combinedFile => $sourceItems) { foreach ($sourceItems as $sourceItem) { if (isset($combinerCheck[$sourceItem]) && $combinerCheck[$sourceItem] != $combinedFile) { user_error("Requirements_Backend::process_combined_files - file '{$sourceItem}' appears in two combined files:" . " '{$combinerCheck[$sourceItem]}' and '{$combinedFile}'", E_USER_WARNING); } $combinerCheck[$sourceItem] = $combinedFile; } } // Work out the relative URL for the combined files from the base folder $combinedFilesFolder = $this->getCombinedFilesFolder() ? $this->getCombinedFilesFolder() . '/' : ''; // Figure out which ones apply to this pageview $combinedFiles = array(); $newJSRequirements = array(); $newCSSRequirements = array(); foreach ($this->javascript as $file => $dummy) { if (isset($combinerCheck[$file])) { $newJSRequirements[$combinedFilesFolder . $combinerCheck[$file]] = true; $combinedFiles[$combinerCheck[$file]] = true; } else { $newJSRequirements[$file] = true; } } foreach ($this->css as $file => $params) { if (isset($combinerCheck[$file])) { $newCSSRequirements[$combinedFilesFolder . $combinerCheck[$file]] = true; $combinedFiles[$combinerCheck[$file]] = true; } else { $newCSSRequirements[$file] = $params; } } // Process the combined files $base = Director::baseFolder() . '/'; foreach (array_diff_key($combinedFiles, $this->blocked) as $combinedFile => $dummy) { $fileList = $this->combine_files[$combinedFile]; $combinedFilePath = $base . $combinedFilesFolder . '/' . $combinedFile; // Make the folder if necessary if (!file_exists(dirname($combinedFilePath))) { Filesystem::makeFolder(dirname($combinedFilePath)); } // If the file isn't writebale, don't even bother trying to make the combined file // Complex test because is_writable fails if the file doesn't exist yet. if (file_exists($combinedFilePath) && !is_writable($combinedFilePath) || !file_exists($combinedFilePath) && !is_writable(dirname($combinedFilePath))) { user_error("Requirements_Backend::process_combined_files(): Couldn't create '{$combinedFilePath}'", E_USER_WARNING); continue; } // Determine if we need to build the combined include if (file_exists($combinedFilePath) && !isset($_GET['flush'])) { // file exists, check modification date of every contained file $srcLastMod = 0; foreach ($fileList as $file) { $srcLastMod = max(filemtime($base . $file), $srcLastMod); } $refresh = $srcLastMod > filemtime($combinedFilePath); } else { // file doesn't exist, or refresh was explicitly required $refresh = true; } if (!$refresh) { continue; } $combinedData = ""; foreach (array_diff($fileList, $this->blocked) as $file) { $fileContent = file_get_contents($base . $file); // if we have a javascript file and jsmin is enabled, minify the content $isJS = stripos($file, '.js'); if ($isJS && $this->combine_js_with_jsmin) { require_once 'thirdparty/jsmin/jsmin.php'; increase_time_limit_to(); $fileContent = JSMin::minify($fileContent); } // write a header comment for each file for easier identification and debugging // also the semicolon between each file is required for jQuery to be combinable properly $combinedData .= "/****** FILE: {$file} *****/\n" . $fileContent . "\n" . ($isJS ? ';' : '') . "\n"; } $successfulWrite = false; $fh = fopen($combinedFilePath, 'wb'); if ($fh) { if (fwrite($fh, $combinedData) == strlen($combinedData)) { $successfulWrite = true; } fclose($fh); unset($fh); } // Unsuccessful write - just include the regular JS files, rather than the combined one if (!$successfulWrite) { user_error("Requirements_Backend::process_combined_files(): Couldn't create '{$combinedFilePath}'", E_USER_WARNING); continue; } } // @todo Alters the original information, which means you can't call this // method repeatedly - it will behave different on the second call! $this->javascript = $newJSRequirements; $this->css = $newCSSRequirements; }
/** * Support function for backwards compatibility purposes. * Caution: Volatile API, might be removed in 3.1 or later. * * @param String $tabname Path to a tab, e.g. "Root.Content.Main" * @return String Rewritten path, based on {@link tabPathRewrites} */ protected function rewriteTabPath($name) { $isRunningTest = class_exists('SapphireTest', false) && SapphireTest::is_running_test(); foreach ($this->getTabPathRewrites() as $regex => $replace) { if (preg_match($regex, $name)) { $newName = preg_replace($regex, $replace, $name); Deprecation::notice('3.0.0', sprintf('Using outdated tab path "%s", please use the new location "%s" instead', $name, $newName), Deprecation::SCOPE_GLOBAL); return $newName; } } // No match found, return original path return $name; }
/** * Force the site to run on SSL. * * To use, call from _config.php. For example: * <code> * if (Director::isLive()) Director::forceSSL(); * </code> * * If you don't want your entire site to be on SSL, you can pass an array of PCRE regular expression * patterns for matching relative URLs. For example: * <code> * if (Director::isLive()) Director::forceSSL(array('/^admin/', '/^Security/')); * </code> * * If you want certain parts of your site protected under a different domain, you can specify * the domain as an argument: * <code> * if (Director::isLive()) Director::forceSSL(array('/^admin/', '/^Security/'), 'secure.mysite.com'); * </code> * * Note that the session data will be lost when moving from HTTP to HTTPS. It is your responsibility * to ensure that this won't cause usability problems. * * CAUTION: This does not respect the site environment mode. You should check this * as per the above examples using Director::isLive() or Director::isTest() for example. * * @param array $patterns Array of regex patterns to match URLs that should be HTTPS. * @param string $secureDomain Secure domain to redirect to. Defaults to the current domain. * * @return bool|string String of URL when unit tests running, boolean FALSE if patterns don't match request URI. */ public static function forceSSL($patterns = null, $secureDomain = null) { if (!isset($_SERVER['REQUEST_URI'])) { return false; } $matched = false; if ($patterns) { // Calling from the command-line? if (!isset($_SERVER['REQUEST_URI'])) { return; } $relativeURL = self::makeRelative(Director::absoluteURL($_SERVER['REQUEST_URI'])); // protect portions of the site based on the pattern foreach ($patterns as $pattern) { if (preg_match($pattern, $relativeURL)) { $matched = true; break; } } } else { // protect the entire site $matched = true; } if ($matched && !self::is_https()) { // if an domain is specified, redirect to that instead of the current domain if ($secureDomain) { $url = 'https://' . $secureDomain . $_SERVER['REQUEST_URI']; } else { $url = $_SERVER['REQUEST_URI']; } $destURL = str_replace('http:', 'https:', Director::absoluteURL($url)); // This coupling to SapphireTest is necessary to test the destination URL and to not interfere with tests if (class_exists('SapphireTest', false) && SapphireTest::is_running_test()) { return $destURL; } else { self::force_redirect($destURL); } } else { return false; } }
function bulkimport($data, $form) { $fh = fopen($data['SourceFile']['tmp_name'], 'r'); Versioned::reading_stage('Stage'); if (isset($data['DeleteExisting']) && $data['DeleteExisting']) { foreach (Page::get() as $page) { $page->deleteFromStage('Stage'); $page->deleteFromStage('Live'); } } $parentRefs = array(); while ($line = fgets($fh, 10000)) { // Skip comments if (preg_match('/^#/', $line)) { continue; } // Split up indentation, title and optional JSON if (preg_match("/^(\t*)([^{]*)({.*})?/", $line, $matches)) { $numTabs = strlen($matches[1]); $title = trim($matches[2]); $json = isset($matches[3]) && trim($matches[3]) ? json_decode(trim($matches[3]), true) : array(); // Either extract the URL from provided meta data, or generate it $url = array_key_exists('URLSegment', $json) ? $json['URLSegment'] : $title; $url = Convert::raw2url($url); // Allow custom classes based on meta data $className = array_key_exists('ClassName', $json) ? $json['ClassName'] : 'Page'; // If we've got too many tabs, then outdent until we find a page to attach to. while (!isset($parentRefs[$numTabs - 1]) && $numTabs > 0) { $numTabs--; } $parentID = $numTabs > 0 ? $parentRefs[$numTabs - 1] : 0; // Try to find an existing page, or create a new one $page = Page::get()->filter(array('URLSegment' => $url, 'ParentID' => $parentID))->First(); if (!$page) { $page = new $className(); } // Apply any meta data properties to the page $page->ParentID = $parentID; $page->Title = $title; $page->URLSegment = $url; if ($json) { $page->update($json); } $page->write(); // Optionall publish if (isset($data['PublishAll']) && $data['PublishAll']) { $page->publish('Stage', 'Live'); } if (!SapphireTest::is_running_test()) { echo "<li>Written ID# {$page->ID}: {$page->Title}"; if ($page->ParentID) { echo " (ParentID# {$page->ParentID})"; } echo "</li>"; } // Populate parentRefs with the most recent page at every level. Necessary to build tree // Children of home should be placed at the top level if (strtolower($title) == 'home') { $parentRefs[$numTabs] = 0; } else { $parentRefs[$numTabs] = $page->ID; } // Remove no-longer-relevant children from the parentRefs. Allows more graceful acceptance of files // with errors for ($i = sizeof($parentRefs) - 1; $i > $numTabs; $i--) { unset($parentRefs[$i]); } // Memory cleanup $page->destroy(); unset($page); } } if (!SapphireTest::is_running_test()) { $complete = $this->complete(); echo $complete['Content']; } else { $this->redirect($this->Link() . 'complete'); } }