/** * add requirements for frontend editing only when logged in * @todo Use TinyMCEs Compressor 4.0.2 PHP */ public function onBeforeInit() { $canEdit = FrontendEditing::ShowAdmin(); $editingEnabled = FrontendEditing::editingEnabled(); $minExt = Director::isDev() ? "" : ".min"; if ($canEdit) { // Enable front-end fly-out menu // //Flexslider imports easing, which breaks? Requirements::block('flexslider/javascript/jquery.easing.1.3.js'); Requirements::javascript(FRAMEWORK_DIR . '/thirdparty/jquery/jquery.js'); Requirements::javascript(FRAMEWORK_DIR . '/thirdparty/jquery-ui/jquery-ui.js'); Requirements::javascript(FRAMEWORK_ADMIN_DIR . '/javascript/ssui.core.js'); Requirements::javascript(THIRDPARTY_DIR . '/jquery-entwine/dist/jquery.entwine-dist.js'); Requirements::javascriptTemplate(FRONTEND_ADMIN_DIR . '/javascript/dist/FrontEndAdminTemplate' . $minExt . '.js', $this->getConfig($this->owner->data())); Requirements::css(FRAMEWORK_DIR . '/thirdparty/jquery-ui-themes/smoothness/jquery-ui.css'); Requirements::javascript(FRONTEND_ADMIN_DIR . '/javascript/dist/FrontEndAdmin' . $minExt . '.js'); Requirements::css(FRONTEND_ADMIN_DIR . '/css/frontend-admin' . $minExt . '.css'); $this->owner->getResponse()->addHeader("X-DynamicCache-OptOut", true); } if ($canEdit && $editingEnabled) { // Disable mode pagespeed while editing $this->owner->getResponse()->addHeader("PageSpeed", "off"); // Disable HTTP cache while editing HTTP::set_cache_age(0); // Enable TinyMCE when editing has been enabled Requirements::javascript(FRONTEND_ADMIN_DIR . '/bower_components/tinymce/jquery.tinymce.min.js'); Requirements::javascript(FRONTEND_ADMIN_DIR . '/javascript/dist/FrontEndEditor' . $minExt . '.js'); Requirements::css(FRONTEND_ADMIN_DIR . '/css/frontend-editor' . $minExt . '.css'); } }
public function testAddCacheHeaders() { $body = "<html><head></head><body><h1>Mysite</h1></body></html>"; $response = new SS_HTTPResponse($body, 200); $this->assertEmpty($response->getHeader('Cache-Control')); HTTP::set_cache_age(30); HTTP::add_cache_headers($response); $this->assertNotEmpty($response->getHeader('Cache-Control')); // Ensure max-age is zero for development. Config::inst()->update('Director', 'environment_type', 'dev'); $response = new SS_HTTPResponse($body, 200); HTTP::add_cache_headers($response); $this->assertContains('max-age=0', $response->getHeader('Cache-Control')); // Ensure max-age setting is respected in production. Config::inst()->update('Director', 'environment_type', 'live'); $response = new SS_HTTPResponse($body, 200); HTTP::add_cache_headers($response); $this->assertContains('max-age=30', explode(', ', $response->getHeader('Cache-Control'))); $this->assertNotContains('max-age=0', $response->getHeader('Cache-Control')); // Still "live": Ensure header's aren't overridden if already set (using purposefully different values). $headers = array('Vary' => '*', 'Pragma' => 'no-cache', 'Cache-Control' => 'max-age=0, no-cache, no-store'); $response = new SS_HTTPResponse($body, 200); foreach ($headers as $name => $value) { $response->addHeader($name, $value); } HTTP::add_cache_headers($response); foreach ($headers as $name => $value) { $this->assertEquals($value, $response->getHeader($name)); } }
public function getJobStatus() { // Set headers HTTP::set_cache_age(0); HTTP::add_cache_headers($this->response); $this->response->addHeader('Content-Type', 'application/json')->addHeader('Content-Encoding', 'UTF-8')->addHeader('X-Content-Type-Options', 'nosniff'); // Format status $track = BrokenExternalPageTrackStatus::get_latest(); if ($track) { return json_encode(array('TrackID' => $track->ID, 'Status' => $track->Status, 'Completed' => $track->getCompletedPages(), 'Total' => $track->getTotalPages())); } }
public function run($request) { HTTP::set_cache_age(0); increase_time_limit_to(); // This can be a time consuming task $conn = DB::getConn(); $classes = ClassInfo::subclassesFor('DataObject'); $dbTables = $conn->tableList(); $go = $request->getVar('go'); if (!$go) { echo 'Set ?go=1 to really delete the tables'; echo '<hr/>'; } //make all lowercase $dbTablesLc = array_map('strtolower', $dbTables); $dbTablesMap = array(); foreach ($dbTables as $k => $v) { $dbTablesMap[strtolower($v)] = $v; } foreach ($classes as $class) { if (ClassInfo::hasTable($class)) { $lcClass = strtolower($class); self::removeFromArray($lcClass, $dbTablesLc); //page modules self::removeFromArray($lcClass . '_live', $dbTablesLc); self::removeFromArray($lcClass . '_versions', $dbTablesLc); //relations $hasMany = Config::inst()->get($class, 'has_many'); $manyMany = Config::inst()->get($class, 'many_many'); if (!empty($hasMany)) { foreach ($hasMany as $rel => $obj) { self::removeFromArray($lcClass . '_' . strtolower($rel), $dbTablesLc); } } if (!empty($manyMany)) { foreach ($manyMany as $rel => $obj) { self::removeFromArray($lcClass . '_' . strtolower($rel), $dbTablesLc); } } } } //at this point, we should only have orphans table in dbTables var foreach ($dbTablesLc as $i => $lcTable) { $table = $dbTablesMap[$lcTable]; if ($go) { DB::query('DROP TABLE `' . $table . '`'); DB::alteration_message("Dropped {$table}", 'obsolete'); } else { DB::alteration_message("Would drop {$table}", 'obsolete'); } } }
public function testAddCacheHeaders() { $body = "<html><head></head><body><h1>Mysite</h1></body></html>"; $response = new SS_HTTPResponse($body, 200); $this->assertEmpty($response->getHeader('Cache-Control')); HTTP::set_cache_age(30); HTTP::add_cache_headers($response); $this->assertNotEmpty($response->getHeader('Cache-Control')); Config::inst()->update('Director', 'environment_type', 'dev'); HTTP::add_cache_headers($response); $this->assertContains('max-age=0', $response->getHeader('Cache-Control')); Config::inst()->update('Director', 'environment_type', 'live'); HTTP::add_cache_headers($response); $this->assertContains('max-age=30', explode(', ', $response->getHeader('Cache-Control'))); $this->assertNotContains('max-age=0', $response->getHeader('Cache-Control')); }
public function testConfigVary() { $body = "<html><head></head><body><h1>Mysite</h1></body></html>"; $response = new SS_HTTPResponse($body, 200); Config::inst()->update('Director', 'environment_type', 'live'); HTTP::set_cache_age(30); HTTP::add_cache_headers($response); $v = $response->getHeader('Vary'); $this->assertNotEmpty($v); $this->assertContains("Cookie", $v); $this->assertContains("X-Forwarded-Protocol", $v); $this->assertContains("User-Agent", $v); $this->assertContains("Accept", $v); Config::inst()->update('HTTP', 'vary', ''); $response = new SS_HTTPResponse($body, 200); HTTP::add_cache_headers($response); $v = $response->getHeader('Vary'); $this->assertEmpty($v); }
public function run($request) { HTTP::set_cache_age(0); set_time_limit(0); $classes = SubsiteDataObjectMany::extendedClasses(); foreach ($classes as $cl) { $s = singleton($cl); $rec = $cl::get(); foreach ($rec as $r) { $oldList = $r->SubsiteList; $list = $r->buildSubsiteList(); if ($list != $oldList) { $qry = "UPDATE {$cl} SET SubsiteList = '{$list}' WHERE ID = {$r->ID}"; DB::query($qry); echo "{$qry}<br/>"; } } } echo 'All done!'; }
public function run($request) { HTTP::set_cache_age(0); increase_time_limit_to(); // This can be a time consuming task $classes = ClassInfo::dataClassesFor('DataObject'); $conn = DB::getConn(); $go = $request->getVar('go'); if (!$go) { echo 'Set ?go=1 to really delete the fields'; echo '<hr/>'; } foreach ($classes as $class) { $hasTable = ClassInfo::hasTable($class); if (!$hasTable) { continue; } $toDrop = array(); $fields = $class::database_fields($class); $list = $conn->fieldList($class); foreach ($list as $fieldName => $type) { if ($fieldName == 'ID') { continue; } if (!isset($fields[$fieldName])) { $toDrop[] = $fieldName; } } if (empty($toDrop)) { continue; } if ($go) { $this->dropColumns($class, $toDrop); DB::alteration_message("Dropped " . implode(',', $toDrop) . " for {$class}", "obsolete"); } else { DB::alteration_message("Would drop " . implode(',', $toDrop) . " for {$class}", "obsolete"); } } }
public static function getRedirectBackUrl() { $url = null; // Don't cache the redirect back ever HTTP::set_cache_age(0); // In edge-cases, this will be called outside of a handleRequest() context; in that case, // redirect to the homepage - don't break into the global state at this stage because we'll // be calling from a test context or something else where the global state is inappropraite if ($request = Controller::curr()->getRequest()) { if ($request->requestVar('BackURL')) { $url = $request->requestVar('BackURL'); } else { if ($request->isAjax() && $request->getHeader('X-Backurl')) { $url = $request->getHeader('X-Backurl'); } } } $url = self::cleanBackUrl($url); if (strpos($url, '/Security/login') !== false) { $url = Director::baseURL(); } return $url; }
/** * Get the RSS feed * * This method will output the RSS feed with the last 50 posts to the * browser. */ function rss() { HTTP::set_cache_age(3600); // cache for one hour $threadID = null; $forumID = null; // optionally allow filtering of the forum posts by the url in the format // rss/thread/$ID or rss/forum/$ID if (isset($this->urlParams['ID']) && ($action = $this->urlParams['ID'])) { if (isset($this->urlParams['OtherID']) && ($id = $this->urlParams['OtherID'])) { switch ($action) { case 'forum': $forumID = (int) $id; break; case 'thread': $threadID = (int) $id; } } else { // fallback is that it is the ID of a forum like it was in // previous versions $forumID = (int) $action; } } $data = array('last_created' => null, 'last_id' => null); if (!isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && !isset($_SERVER['HTTP_IF_NONE_MATCH'])) { // just to get the version data.. $this->getNewPostsAvailable(null, null, $forumID, $threadID, &$data); // No information provided by the client, just return the last posts $rss = new RSSFeed($this->getRecentPosts(50, $forumID, $threadID), $this->Link() . 'rss', sprintf(_t('Forum.RSSFORUMPOSTSTO'), $this->Title), "", "Title", "RSSContent", "RSSAuthor", $data['last_created'], $data['last_id']); $rss->outputToBrowser(); } else { // Return only new posts, check the request headers! $since = null; $etag = null; if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) { // Split the If-Modified-Since (Netscape < v6 gets this wrong) $since = explode(';', $_SERVER['HTTP_IF_MODIFIED_SINCE']); // Turn the client request If-Modified-Since into a timestamp $since = @strtotime($since[0]); if (!$since) { $since = null; } } if (isset($_SERVER['HTTP_IF_NONE_MATCH']) && is_numeric($_SERVER['HTTP_IF_NONE_MATCH'])) { $etag = (int) $_SERVER['HTTP_IF_NONE_MATCH']; } if ($this->getNewPostsAvailable($since, $etag, $forumID, $threadID, $data)) { HTTP::register_modification_timestamp($data['last_created']); $rss = new RSSFeed($this->getRecentPosts(50, $forumID, $threadID, $etag), $this->Link() . 'rss', sprintf(_t('Forum.RSSFORUMPOSTSTO'), $this->Title), "", "Title", "RSSContent", "RSSAuthor", $data['last_created'], $data['last_id']); $rss->outputToBrowser(); } else { if ($data['last_created']) { HTTP::register_modification_timestamp($data['last_created']); } if ($data['last_id']) { HTTP::register_etag($data['last_id']); } // There are no new posts, just output an "304 Not Modified" message HTTP::add_cache_headers(); header('HTTP/1.1 304 Not Modified'); } } exit; }
function init() { parent::init(); HTTP::set_cache_age(0); }
/** * Returns the shopping cart. * @todo Does HTTP::set_cache_age() still need to be set here? * * @return Order */ function Cart() { HTTP::set_cache_age(0); return ShoppingCart::current_order(); }
/** * Redirect back. Uses either the HTTP_REFERER or a manually set request-variable called "BackURL". * This variable is needed in scenarios where not HTTP-Referer is sent ( * e.g when calling a page by location.href in IE). * If none of the two variables is available, it will redirect to the base * URL (see {@link Director::baseURL()}). * @uses redirect() */ public function redirectBack() { // Don't cache the redirect back ever HTTP::set_cache_age(0); $url = null; // In edge-cases, this will be called outside of a handleRequest() context; in that case, // redirect to the homepage - don't break into the global state at this stage because we'll // be calling from a test context or something else where the global state is inappropraite if ($this->request) { if ($this->request->requestVar('BackURL')) { $url = $this->request->requestVar('BackURL'); } else { if ($this->request->isAjax() && $this->request->getHeader('X-Backurl')) { $url = $this->request->getHeader('X-Backurl'); } else { if ($this->request->getHeader('Referer')) { $url = $this->request->getHeader('Referer'); } } } } if (!$url) { $url = Director::baseURL(); } // absolute redirection URLs not located on this site may cause phishing if (Director::is_site_url($url)) { $url = Director::absoluteURL($url, true); return $this->redirect($url); } else { return false; } }
/** * Return the attributes of the form tag - used by the templates. * * @return string The attribute string */ function FormAttributes() { $attributes = array(); // Forms shouldn't be cached, cos their error messages won't be shown HTTP::set_cache_age(0); // workaround to include javascript validation if ($this->validator && !$this->jsValidationIncluded) { $this->validator->includeJavascriptValidation(); } // compile attributes $attributes['id'] = $this->FormName(); $attributes['action'] = $this->FormAction(); $attributes['method'] = $this->FormMethod(); $attributes['enctype'] = $this->FormEncType(); if ($this->target) { $attributes['target'] = $this->target; } if ($this->extraClass()) { $attributes['class'] = $this->extraClass(); } if ($this->validator && $this->validator->getErrors()) { if (!isset($attributes['class'])) { $attributes['class'] = ''; } $attributes['class'] .= ' validationerror'; } // implode attributes into string $preparedAttributes = ''; foreach ($attributes as $k => $v) { // Note: as indicated by the $k == value item here; the decisions over what to include in the attributes can sometimes get finicky if (!empty($v) || $v === '0' || $k == 'value') { $preparedAttributes .= " {$k}=\"" . Convert::raw2att($v) . "\""; } } return $preparedAttributes; }
<?php global $project; $project = 'mysite'; // use the _ss_environment.php file for configuration require_once 'conf/ConfigureFromEnv.php'; // set default language i18n::set_locale('en_US'); define('PROJECT_THIRDPARTY_DIR', project() . '/thirdparty'); define('PROJECT_THIRDPARTY_PATH', BASE_PATH . '/' . PROJECT_THIRDPARTY_DIR); if (SS_IS_TEST_ENV) { BasicAuth::protect_entire_site(true); } if (Director::isLive()) { if (strpos(Director::absoluteBaseURL(), 'silverstripe-europe.org') !== false || strpos(Director::absoluteBaseURL(), 'www') !== false) { $response = new SS_HTTPResponse(); $response->redirect('https://stripecon.eu', 301); HTTP::add_cache_headers($response); $response->output(); die; } // we are in live mode, send errors per email, set cache and force WWW HTTP::set_cache_age(3600); // HTTP Header for CloudFlare Caching SS_Cache::set_cache_lifetime('any', 10800); // Serverside cache to 3 hours. SS_Log::add_writer(new SS_LogEmailWriter('*****@*****.**'), SS_Log::ERR); } Config::inst()->update('HtmlEditorField', 'use_gzip', false);
/** * Return the attributes of the form tag - used by the templates. * * @param Array Custom attributes to process. Falls back to {@link getAttributes()}. * If at least one argument is passed as a string, all arguments act as excludes by name. * @return String HTML attributes, ready for insertion into an HTML tag */ public function getAttributesHTML($attrs = null) { $exclude = is_string($attrs) ? func_get_args() : null; if (!$attrs || is_string($attrs)) { $attrs = $this->getAttributes(); } // Figure out if we can cache this form // - forms with validation shouldn't be cached, cos their error messages won't be shown // - forms with security tokens shouldn't be cached because security tokens expire $needsCacheDisabled = false; if ($this->getSecurityToken()->isEnabled()) { $needsCacheDisabled = true; } if ($this->FormMethod() != 'get') { $needsCacheDisabled = true; } if (!$this->validator instanceof RequiredFields || count($this->validator->getRequired())) { $needsCacheDisabled = true; } // If we need to disable cache, do it if ($needsCacheDisabled) { HTTP::set_cache_age(0); } $attrs = $this->getAttributes(); // Remove empty $attrs = array_filter((array) $attrs, create_function('$v', 'return ($v || $v === 0);')); // Remove excluded if ($exclude) { $attrs = array_diff_key($attrs, array_flip($exclude)); } // Create markkup $parts = array(); foreach ($attrs as $name => $value) { $parts[] = $value === true ? "{$name}=\"{$name}\"" : "{$name}=\"" . Convert::raw2att($value) . "\""; } return implode(' ', $parts); }
/** * * @standard SS method */ public function init() { HTTP::set_cache_age(0); parent::init(); // find the current order if any $orderID = 0; $overrideCanView = false; //WE HAVE THIS FOR SUBMITTING FORMS! if (isset($_REQUEST['OrderID'])) { $orderID = intval($_REQUEST['OrderID']); if ($orderID) { $this->currentOrder = Order::get()->byID($orderID); } } elseif ($this->request && $this->request->param('ID') && $this->request->param('Action')) { //we can not do intval here! $id = $this->request->param('ID'); $action = $this->request->param('Action'); $otherID = intval($this->request->param("OtherID")); //the code below is for submitted orders, but we still put it here so //we can do all the retrieval options in once. if ($action == "retrieveorder" && $id && $otherID) { $sessionID = Convert::raw2sql($id); $retrievedOrder = Order::get()->Filter(array("SessionID" => $sessionID, "ID" => $otherID))->First(); $this->currentOrder = $retrievedOrder; $overrideCanView = true; } elseif (intval($id) && in_array($action, $this->stat("allowed_actions"))) { $this->currentOrder = Order::get()->byID(intval($id)); } } if (!$this->currentOrder) { $this->currentOrder = ShoppingCart::current_order(); if ($this->currentOrder) { if ($this->currentOrder->IsSubmitted()) { $overrideCanView = true; } } } //redirect if we are viewing the order with the wrong page! if ($this->currentOrder) { //IMPORTANT SECURITY QUESTION! if ($this->currentOrder->canView() || $overrideCanView) { if ($this->currentOrder->IsSubmitted() && $this->onlyShowUnsubmittedOrders()) { $this->redirect($this->currentOrder->Link()); } elseif (!$this->currentOrder->IsSubmitted() && $this->onlyShowSubmittedOrders()) { $this->redirect($this->currentOrder->Link()); } } else { if (!$this->LoginToOrderLinkLabel) { $this->LoginToOrderLinkLabel = _t('CartPage.LOGINFIRST', 'You will need to log in before you can access the requested order order. '); } $messages = array('default' => '<p class="message good">' . $this->LoginToOrderLinkLabel . '</p>', 'logInAgain' => _t('CartPage.LOGINAGAIN', 'You have been logged out. If you would like to log in again, please do so below.')); Security::permissionFailure($this, $messages); return false; } if (!$this->currentOrder->IsSubmitted()) { //we always want to make sure the order is up-to-date. $this->currentOrder->init($force = false); $this->currentOrder->calculateOrderAttributes($force = true); $this->currentOrder->calculateOrderAttributes($force = true); } } else { $this->message = _t('CartPage.ORDERNOTFOUND', 'Order can not be found.'); } }
/** * Return the attributes of the form tag - used by the templates * @return string The attribute string */ function FormAttributes() { // Forms shouldn't be cached, cos their error messages won't be shown HTTP::set_cache_age(0); if ($this->validator) { $this->validator->includeJavascriptValidation(); } if ($this->target) { $target = " target=\"" . $this->target . "\""; } else { $target = ""; } return "id=\"" . $this->FormName() . "\" action=\"" . $this->FormAction() . "\" method=\"" . $this->FormMethod() . "\" enctype=\"" . $this->FormEncType() . "\"{$target}"; }
/** * Returns the shopping cart. * @todo Does HTTP::set_cache_age() still need to be set here? * * @return Order */ function getCart() { if (!self::$global_allow_purchase) { return false; } HTTP::set_cache_age(0); return ShoppingCart::current_order(); }
/** * Ensures the response has the correct headers */ protected function setHeaders() { // Set headers HTTP::set_cache_age(0); HTTP::add_cache_headers($this->response); $this->response->addHeader('Content-Type', 'application/json')->addHeader('Content-Encoding', 'UTF-8')->addHeader('X-Content-Type-Options', 'nosniff'); }
/** * Return the attributes of the form tag - used by the templates. * * @param Array Custom attributes to process. Falls back to {@link getAttributes()}. * If at least one argument is passed as a string, all arguments act as excludes by name. * @return String HTML attributes, ready for insertion into an HTML tag */ public function getAttributesHTML($attrs = null) { $exclude = (is_string($attrs)) ? func_get_args() : null; if(!$attrs || is_string($attrs)) $attrs = $this->getAttributes(); // Forms shouldn't be cached, cos their error messages won't be shown HTTP::set_cache_age(0); $attrs = $this->getAttributes(); // Remove empty $attrs = array_filter((array)$attrs, create_function('$v', 'return ($v || $v === 0);')); // Remove excluded if($exclude) $attrs = array_diff_key($attrs, array_flip($exclude)); // Create markkup $parts = array(); foreach($attrs as $name => $value) { $parts[] = ($value === true) ? "{$name}=\"{$name}\"" : "{$name}=\"" . Convert::raw2att($value) . "\""; } return implode(' ', $parts); }