Merge pull request #4772 from assertchris/improve-php-doc-comments

Improved PHPDoc comments
This commit is contained in:
Damian Mooyman 2015-11-16 10:01:08 +13:00
commit 1dfa2dc1c1
6 changed files with 549 additions and 334 deletions

View File

@ -1,62 +1,72 @@
<?php
/**
* The content negotiator performs "text/html" or "application/xhtml+xml" switching.
* It does this through the public static function ContentNegotiator::process().
* By default, ContentNegotiator will comply to the Accept headers the clients
* sends along with the HTTP request, which is most likely "application/xhtml+xml"
* (see "Order of selection" below).
* The content negotiator performs "text/html" or "application/xhtml+xml" switching. It does this through
* the public static function ContentNegotiator::process(). By default, ContentNegotiator will comply to
* the Accept headers the clients sends along with the HTTP request, which is most likely
* "application/xhtml+xml" (see "Order of selection" below).
*
* Order of selection between html or xhtml is as follows:
* - if PHP has already sent the HTTP headers, default to "html" (we can't send HTTP Content-Type headers any longer)
* - if PHP has already sent the HTTP headers, default to "html" (we can't send HTTP Content-Type headers
* any longer)
* - if a GET variable ?forceFormat is set, it takes precedence (for testing purposes)
* - if the user agent is detected as W3C Validator we always deliver "xhtml"
* - if an HTTP Accept header is sent from the client, we respect its order (this is the most common case)
* - if none of the above matches, fallback is "html"
*
* ContentNegotiator doesn't enable you to send content as a true XML document
* through the "text/xml" or "application/xhtml+xml" Content-Type.
* ContentNegotiator doesn't enable you to send content as a true XML document through the "text/xml"
* or "application/xhtml+xml" Content-Type.
*
* Please see http://webkit.org/blog/68/understanding-html-xml-and-xhtml/ for further information.
*
* @package framework
*
* @subpackage control
*
* @todo Check for correct XHTML doctype in xhtml()
* @todo Allow for other HTML4 doctypes (e.g. Transitional) in html()
* @todo Make content replacement and doctype setting two separately configurable behaviours - some
* devs might know what they're doing and don't want contentnegotiator messing with their HTML4 doctypes,
* but still find it useful to have self-closing tags removed.
* @todo Make content replacement and doctype setting two separately configurable behaviours
*
* Some developers might know what they're doing and don't want ContentNegotiator messing with their
* HTML4 doctypes, but still find it useful to have self-closing tags removed.
*/
class ContentNegotiator extends Object {
/**
* @config
*
* @var string
*/
private static $content_type = '';
/**
* @config
*
* @var string
*/
private static $encoding = 'utf-8';
/**
* @config
* @var boolean
*
* @var bool
*/
private static $enabled = false;
/**
* @config
*
* @var string
*/
private static $default_format = 'html';
/**
* Set the character set encoding for this page. By default it's utf-8, but you could change it to, say,
* windows-1252, to improve interoperability with extended characters being imported from windows excel.
* Set the character set encoding for this page. By default it's utf-8, but you could change it to,
* say, windows-1252, to improve interoperability with extended characters being imported from windows
* excel.
*
* @deprecated 4.0 Use the "ContentNegotiator.encoding" config setting instead
*
* @param string $encoding
*/
public static function set_encoding($encoding) {
Deprecation::notice('4.0', 'Use the "ContentNegotiator.encoding" config setting instead');
@ -64,10 +74,12 @@ class ContentNegotiator extends Object {
}
/**
* Return the character encoding set bhy ContentNegotiator::set_encoding(). It's recommended that all classes
* that need to specify the character set make use of this function.
* Return the character encoding set bhy ContentNegotiator::set_encoding(). It's recommended that all
* classes that need to specify the character set make use of this function.
*
* @deprecated 4.0 Use the "ContentNegotiator.encoding" config setting instead
* @deprecated 4.0 Use the "ContentNegotiator.encoding" config setting instead.
*
* @return string
*/
public static function get_encoding() {
Deprecation::notice('4.0', 'Use the "ContentNegotiator.encoding" config setting instead');
@ -95,13 +107,13 @@ class ContentNegotiator extends Object {
}
/**
* Returns true if negotation is enabled for the given response.
* By default, negotiation is only enabled for pages that have the xml header.
* Returns true if negotiation is enabled for the given response. By default, negotiation is only
* enabled for pages that have the xml header.
*/
public static function enabled_for($response) {
$contentType = $response->getHeader("Content-Type");
// Disable content negotation for other content types
// Disable content negotiation for other content types
if($contentType && substr($contentType, 0,9) != 'text/html'
&& substr($contentType, 0,21) != 'application/xhtml+xml') {
return false;
@ -111,6 +123,9 @@ class ContentNegotiator extends Object {
else return (substr($response->getBody(),0,5) == '<' . '?xml');
}
/**
* @param SS_HTTPResponse $response
*/
public static function process(SS_HTTPResponse $response) {
if(!self::enabled_for($response)) return;
@ -126,8 +141,8 @@ class ContentNegotiator extends Object {
$chosenFormat = $_GET['forceFormat'];
} else {
// The W3C validator doesn't send an HTTP_ACCEPT header, but it can support xhtml. We put this special
// case in here so that designers don't get worried that their templates are HTML4.
// The W3C validator doesn't send an HTTP_ACCEPT header, but it can support xhtml. We put this
// special case in here so that designers don't get worried that their templates are HTML4.
if(isset($_SERVER['HTTP_USER_AGENT']) && substr($_SERVER['HTTP_USER_AGENT'], 0, 14) == 'W3C_Validator/') {
$chosenFormat = "xhtml";
@ -159,8 +174,8 @@ class ContentNegotiator extends Object {
* Replaces a few common tags and entities with their XHTML representations (<br>, <img>, &nbsp;
* <input>, checked, selected).
*
* @param $response SS_HTTPResponse
* @return string
* @param SS_HTTPResponse $response
*
* @todo Search for more xhtml replacement
*/
public function xhtml(SS_HTTPResponse $response) {
@ -191,12 +206,15 @@ class ContentNegotiator extends Object {
$response->setBody($content);
}
/*
* Check user defined content type and use it, if it's empty use the text/html.
* If find a XML header replaces it and existing doctypes with HTML4.01 Strict.
* Replaces self-closing tags like <img /> with unclosed solitary tags like <img>.
* Replaces all occurrences of "application/xhtml+xml" with "text/html" in the template.
* Removes "xmlns" attributes and any <?xml> Pragmas.
/**
* Performs the following replacements:
* - Check user defined content type and use it, if it's empty use the text/html.
* - If find a XML header replaces it and existing doctypes with HTML4.01 Strict.
* - Replaces self-closing tags like <img /> with unclosed solitary tags like <img>.
* - Replaces all occurrences of "application/xhtml+xml" with "text/html" in the template.
* - Removes "xmlns" attributes and any <?xml> Pragmas.
*
* @param SS_HTTPResponse $response
*/
public function html(SS_HTTPResponse $response) {
$encoding = Config::inst()->get('ContentNegotiator', 'encoding');

View File

@ -1,63 +1,81 @@
<?php
/**
* Base controller class.
* Controllers are the cornerstone of all site functionality in SilverStripe. The {@link Director}
* selects a controller to pass control to, and then calls {@link run()}. This method will execute
* Controllers are the cornerstone of all site functionality in SilverStripe. The {@link Director}
* selects a controller to pass control to, and then calls {@link run()}. This method will execute
* the appropriate action - either by calling the action method, or displaying the action's template.
*
* See {@link getTemplate()} for information on how the template is chosen.
*
* @package framework
*
* @subpackage control
*/
class Controller extends RequestHandler implements TemplateGlobalProvider {
/**
* @var array $urlParams An array of arguments extracted from the URL
* An array of arguments extracted from the URL.
*
* @var array
*/
protected $urlParams;
/**
* @var array $requestParams Contains all GET and POST parameters
* passed to the current {@link SS_HTTPRequest}.
* @uses SS_HTTPRequest->requestVars()
* Contains all GET and POST parameters passed to the current {@link SS_HTTPRequest}.
*
* @var array
*/
protected $requestParams;
/**
* @var string $action The URL part matched on the current controller as
* determined by the "$Action" part of the {@link $url_handlers} definition.
* Should correlate to a public method on this controller.
* Used in {@link render()} and {@link getViewer()} to determine
* action-specific templates.
* The URL part matched on the current controller as determined by the "$Action" part of the
* {@link $url_handlers} definition. Should correlate to a public method on this controller.
*
* Used in {@link render()} and {@link getViewer()} to determine action-specific templates.
*
* @var string
*/
protected $action;
/**
* The {@link Session} object for this controller
* The {@link Session} object for this controller.
*
* @var Session
*/
protected $session;
/**
* Stack of current controllers.
* Controller::$controller_stack[0] is the current controller.
* Stack of current controllers. Controller::$controller_stack[0] is the current controller.
*
* @var array
*/
protected static $controller_stack = array();
/**
* @var bool
*/
protected $basicAuthEnabled = true;
/**
* @var SS_HTTPResponse $response The response object that the controller returns.
* The response object that the controller returns.
*
* Set in {@link handleRequest()}.
*
* @var SS_HTTPResponse
*/
protected $response;
/**
* Default URL handlers - (Action)/(ID)/(OtherID)
* Default URL handlers.
*
* @var array
*/
private static $url_handlers = array(
'$Action//$ID/$OtherID' => 'handleAction',
);
/**
* @var array
*/
private static $allowed_actions = array(
'handleAction',
'handleIndex',
@ -76,7 +94,9 @@ class Controller extends RequestHandler implements TemplateGlobalProvider {
}
/**
* Returns a link to this controller. Overload with your own Link rules if they exist.
* Returns a link to this controller. Overload with your own Link rules if they exist.
*
* @return string
*/
public function Link() {
return get_class($this) .'/';
@ -86,32 +106,29 @@ class Controller extends RequestHandler implements TemplateGlobalProvider {
* Executes this controller, and return an {@link SS_HTTPResponse} object with the result.
*
* This method first does a few set-up activities:
* - Push this controller ont to the controller stack -
* see {@link Controller::curr()} for information about this.
* - Call {@link init()}
* - Defer to {@link RequestHandler->handleRequest()} to determine which action
* should be executed
* - Push this controller ont to the controller stack - see {@link Controller::curr()} for
* information about this.
* - Call {@link init()}
* - Defer to {@link RequestHandler->handleRequest()} to determine which action should be executed.
*
* Note: $requestParams['executeForm'] support was removed, make the following change in your URLs:
* "/?executeForm=FooBar" -> "/FooBar".
*
* Note: $requestParams['executeForm'] support was removed,
* make the following change in your URLs:
* "/?executeForm=FooBar" -> "/FooBar"
* Also make sure "FooBar" is in the $allowed_actions of your controller class.
*
* Note: You should rarely need to overload run() -
* this kind of change is only really appropriate for things like nested
* controllers - {@link ModelAsController} and {@link RootURLController}
* are two examples here. If you want to make more
* orthodox functionality, it's better to overload {@link init()} or {@link index()}.
* Note: You should rarely need to overload run() - this kind of change is only really appropriate
* for things like nested controllers - {@link ModelAsController} and {@link RootURLController}
* are two examples here. If you want to make more orthodox functionality, it's better to overload
* {@link init()} or {@link index()}.
*
* Important: If you are going to overload handleRequest,
* make sure that you start the method with $this->pushCurrent()
* and end the method with $this->popCurrent().
* Failure to do this will create weird session errors.
* Important: If you are going to overload handleRequest, make sure that you start the method with
* $this->pushCurrent() and end the method with $this->popCurrent(). Failure to do this will create
* weird session errors.
*
* @param $request The {@link SS_HTTPRequest} object that is responsible
* for distributing request parsing.
* @return SS_HTTPResponse The response that this controller produces,
* including HTTP headers such as redirection info
* @param SS_HTTPRequest $request
* @param DataModel $model
*
* @return SS_HTTPResponse
*/
public function handleRequest(SS_HTTPRequest $request, DataModel $model) {
if(!$request) user_error("Controller::handleRequest() not passed a request!", E_USER_ERROR);
@ -171,8 +188,13 @@ class Controller extends RequestHandler implements TemplateGlobalProvider {
}
/**
* Controller's default action handler. It will call the method named in $Action, if that method exists.
* If $Action isn't given, it will use "index" as a default.
* Controller's default action handler. It will call the method named in "$Action", if that method
* exists. If "$Action" isn't given, it will use "index" as a default.
*
* @param SS_HTTPRequest $request
* @param string $action
*
* @return HTMLText|SS_HTTPResponse
*/
protected function handleAction($request, $action) {
$this->extend('beforeCallActionHandler', $request, $action);
@ -198,20 +220,27 @@ class Controller extends RequestHandler implements TemplateGlobalProvider {
}
}
/**
* @param array $urlParams
*/
public function setURLParams($urlParams) {
$this->urlParams = $urlParams;
}
/**
* @return array The parameters extracted from the URL by the {@link Director}.
* Returns the parameters extracted from the URL by the {@link Director}.
*
* @return array
*/
public function getURLParams() {
return $this->urlParams;
}
/**
* Returns the SS_HTTPResponse object that this controller is building up.
* Can be used to set the status code and headers
* Returns the SS_HTTPResponse object that this controller is building up. Can be used to set the
* status code and headers.
*
* @return SS_HTTPResponse
*/
public function getResponse() {
if (!$this->response) {
@ -224,21 +253,27 @@ class Controller extends RequestHandler implements TemplateGlobalProvider {
* Sets the SS_HTTPResponse object that this controller is building up.
*
* @param SS_HTTPResponse $response
* @return Controller
*
* @return $this
*/
public function setResponse(SS_HTTPResponse $response) {
$this->response = $response;
return $this;
}
/**
* @var bool
*/
protected $baseInitCalled = false;
/**
* Return the object that is going to own a form that's being processed, and handle its execution.
* Note that the result needn't be an actual controller object.
* Note that the result need not be an actual controller object.
*
* @return mixed
*/
public function getFormOwner() {
// Get the appropraite ocntroller: sometimes we want to get a form from another controller
// Get the appropriate controller: sometimes we want to get a form from another controller
if(isset($this->requestParams['formController'])) {
$formController = Director::getControllerForURL($this->requestParams['formController']);
@ -253,8 +288,12 @@ class Controller extends RequestHandler implements TemplateGlobalProvider {
}
/**
* This is the default action handler used if a method doesn't exist.
* It will process the controller object with the template returned by {@link getViewer()}
* This is the default action handler used if a method doesn't exist. It will process the
* controller object with the template returned by {@link getViewer()}.
*
* @param string $action
*
* @return HTMLText
*/
public function defaultAction($action) {
return $this->getViewer($action)->process($this);
@ -262,14 +301,19 @@ class Controller extends RequestHandler implements TemplateGlobalProvider {
/**
* Returns the action that is being executed on this controller.
*
* @return string
*/
public function getAction() {
return $this->action;
}
/**
* Return an SSViewer object to process the data
* @return SSViewer The viewer identified being the default handler for this Controller/Action combination
* Return the viewer identified being the default handler for this Controller/Action combination.
*
* @param string $action
*
* @return SSViewer
*/
public function getViewer($action) {
// Hard-coded templates
@ -308,14 +352,22 @@ class Controller extends RequestHandler implements TemplateGlobalProvider {
return new SSViewer($templates);
}
/**
* @param string $action
*
* @return bool
*/
public function hasAction($action) {
return parent::hasAction($action) || $this->hasActionTemplate($action);
}
/**
* Removes all the "action" part of the current URL and returns the result.
* If no action parameter is present, returns the full URL
* @static
* Removes all the "action" part of the current URL and returns the result. If no action parameter
* is present, returns the full URL.
*
* @param string $fullURL
* @param null|string $action
*
* @return string
*/
public function removeAction($fullURL, $action = null) {
@ -331,7 +383,11 @@ class Controller extends RequestHandler implements TemplateGlobalProvider {
/**
* Return the class that defines the given action, so that we know where to check allowed_actions.
* Overrides RequestHandler to also look at defined templates
* Overrides RequestHandler to also look at defined templates.
*
* @param string $action
*
* @return string
*/
protected function definingClassForAction($action) {
$definingClass = parent::definingClassForAction($action);
@ -347,9 +403,11 @@ class Controller extends RequestHandler implements TemplateGlobalProvider {
}
/**
* Returns TRUE if this controller has a template that is specifically designed to handle a specific action.
* Returns TRUE if this controller has a template that is specifically designed to handle a
* specific action.
*
* @param string $action
*
* @return bool
*/
public function hasActionTemplate($action) {
@ -367,11 +425,11 @@ class Controller extends RequestHandler implements TemplateGlobalProvider {
}
/**
* Render the current controller with the templates determined
* by {@link getViewer()}.
* Render the current controller with the templates determined by {@link getViewer()}.
*
* @param array $params Key-value array for custom template variables (Optional)
* @return string Parsed template content
* @param array $params
*
* @return string
*/
public function render($params = null) {
$template = $this->getViewer($this->getAction());
@ -385,16 +443,17 @@ class Controller extends RequestHandler implements TemplateGlobalProvider {
}
/**
* Call this to disable site-wide basic authentication for a specific contoller.
* This must be called before Controller::init(). That is, you must call it in your controller's
* init method before it calls parent::init().
* Call this to disable site-wide basic authentication for a specific controller. This must be
* called before Controller::init(). That is, you must call it in your controller's init method
* before it calls parent::init().
*/
public function disableBasicAuth() {
$this->basicAuthEnabled = false;
}
/**
* Returns the current controller
* Returns the current controller.
*
* @return Controller
*/
public static function curr() {
@ -406,19 +465,23 @@ class Controller extends RequestHandler implements TemplateGlobalProvider {
}
/**
* Tests whether we have a currently active controller or not
* @return boolean True if there is at least 1 controller in the stack.
* Tests whether we have a currently active controller or not. True if there is at least 1
* controller in the stack.
*
* @return bool
*/
public static function has_curr() {
return Controller::$controller_stack ? true : false;
}
/**
* Returns true if the member is allowed to do the given action.
* @param perm The permission to be checked, such as 'View'.
* @param member The member whose permissions need checking. Defaults to the currently logged
* Returns true if the member is allowed to do the given action. Defaults to the currently logged
* in user.
* @return boolean
*
* @param string $perm
* @param null|member $member
*
* @return bool
*/
public function can($perm, $member = null) {
if(!$member) $member = Member::currentUser();
@ -433,12 +496,10 @@ class Controller extends RequestHandler implements TemplateGlobalProvider {
}
}
//---------------------------------------------------------------------------------------------------------------
/**
* Pushes this controller onto the stack of current controllers.
* This means that any redirection, session setting, or other things that rely on Controller::curr() will now
* write to this controller object.
* Pushes this controller onto the stack of current controllers. This means that any redirection,
* session setting, or other things that rely on Controller::curr() will now write to this
* controller object.
*/
public function pushCurrent() {
array_unshift(self::$controller_stack, $this);
@ -467,6 +528,9 @@ class Controller extends RequestHandler implements TemplateGlobalProvider {
/**
* Redirect to the given URL.
*
* @param string $url
* @param int $code
*
* @return SS_HTTPResponse
*/
public function redirect($url, $code=302) {
@ -486,12 +550,14 @@ class Controller extends RequestHandler implements TemplateGlobalProvider {
}
/**
* 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
* Redirect back. Uses either the HTTP-Referer or a manually set request-variable called "BackURL".
* This variable is needed in scenarios where HTTP-Referer is not 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()
*
* @return bool|SS_HTTPResponse
*/
public function redirectBack() {
// Don't cache the redirect back ever
@ -525,16 +591,18 @@ class Controller extends RequestHandler implements TemplateGlobalProvider {
}
/**
* Tests whether a redirection has been requested.
* @return string If redirect() has been called, it will return the URL redirected to. Otherwise, it will
* return null;
* Tests whether a redirection has been requested. If redirect() has been called, it will return
* the URL redirected to. Otherwise, it will return null.
*
* @return null|string
*/
public function redirectedTo() {
return $this->getResponse() && $this->getResponse()->getHeader('Location');
}
/**
* Get the Session object representing this Controller's session
* Get the Session object representing this Controller's session.
*
* @return Session
*/
public function getSession() {
@ -543,20 +611,22 @@ class Controller extends RequestHandler implements TemplateGlobalProvider {
/**
* Set the Session object.
*
* @param Session $session
*/
public function setSession(Session $session) {
$this->session = $session;
}
/**
* Joins two or more link segments together, putting a slash between them if necessary.
* Use this for building the results of {@link Link()} methods.
* If either of the links have query strings,
* Joins two or more link segments together, putting a slash between them if necessary. Use this
* for building the results of {@link Link()} methods. If either of the links have query strings,
* then they will be combined and put at the end of the resulting url.
*
* Caution: All parameters are expected to be URI-encoded already.
*
* @param string
*
* @return string
*/
public static function join_links() {
@ -590,6 +660,9 @@ class Controller extends RequestHandler implements TemplateGlobalProvider {
return $result;
}
/**
* @return array
*/
public static function get_template_global_variables() {
return array(
'CurrentPage' => 'curr',

View File

@ -3,35 +3,41 @@
* A set of static methods for manipulating cookies.
*
* @package framework
*
* @subpackage misc
*/
class Cookie {
/**
* @config
* @var boolean
*
* @var bool
*/
private static $report_errors = true;
/**
* Fetch the current instance of the cookie backend
* Fetch the current instance of the cookie backend.
*
* @return Cookie_Backend The cookie backend
* @return Cookie_Backend
*/
public static function get_inst() {
return Injector::inst()->get('Cookie_Backend');
}
/**
* Set a cookie variable
* Set a cookie variable.
*
* @param string $name The variable name
* @param mixed $value The variable value.
* @param int $expiry The expiry time, in days. Defaults to 90.
* @param string $path See http://php.net/set_session
* @param string $domain See http://php.net/set_session
* @param boolean $secure See http://php.net/set_session
* @param boolean $httpOnly See http://php.net/set_session
* Expiry time is set in days, and defaults to 90.
*
* @param string $name
* @param mixed $value
* @param int $expiry
* @param string $path
* @param string $domain
* @param bool $secure
* @param bool $httpOnly
*
* See http://php.net/set_session
*/
public static function set($name, $value, $expiry = 90, $path = null, $domain = null, $secure = false,
$httpOnly = true
@ -40,31 +46,34 @@ class Cookie {
}
/**
* Get the cookie value by name
* Get the cookie value by name. Returns null if not set.
*
* @param string $name The name of the cookie to get
* @param boolean $includeUnsent Include cookies we've yet to send when fetching values
* @param string $name
* @param bool $includeUnsent
*
* @return string|null The cookie value or null if unset
* @return null|string
*/
public static function get($name, $includeUnsent = true) {
return self::get_inst()->get($name, $includeUnsent);
}
/**
* Get all the cookies
* Get all the cookies.
*
* @param boolean $includeUnsent Include cookies we've yet to send
* @return array All the cookies
* @param bool $includeUnsent
*
* @return array
*/
public static function get_all($includeUnsent = true) {
return self::get_inst()->getAll($includeUnsent);
}
/**
* @param string
* @param string
* @param string
* @param string $name
* @param null|string $path
* @param null|string $domain
* @param bool $secure
* @param bool $httpOnly
*/
public static function force_expiry($name, $path = null, $domain = null, $secure = false, $httpOnly = true) {
return self::get_inst()->forceExpiry($name, $path, $domain, $secure, $httpOnly);

View File

@ -2,14 +2,16 @@
/**
* Director is responsible for processing URLs, and providing environment information.
*
* The most important part of director is {@link Director::direct()}, which is passed a URL and will execute the
* appropriate controller.
* The most important part of director is {@link Director::direct()}, which is passed a URL and will
* execute the appropriate controller.
*
* Director also has a number of static methods that provide information about the environment, such as
* {@link Director::$environment_type}.
*
* @package framework
*
* @subpackage control
*
* @see Director::direct()
* @see Director::$rules
* @see Director::$environment_type
@ -17,22 +19,34 @@
class Director implements TemplateGlobalProvider {
/**
* Specifies this url is relative to the base
* Specifies this url is relative to the base.
*
* @var string
*/
const BASE = 'BASE';
/**
* Specifies this url is relative to the site root
* Specifies this url is relative to the site root.
*
* @var string
*/
const ROOT = 'ROOT';
/**
* specifies this url is relative to the current request
* specifies this url is relative to the current request.
*
* @var string
*/
const REQUEST = 'REQUEST';
/**
* @var array
*/
static private $urlParams;
/**
* @var array
*/
static private $rules = array();
/**
@ -42,52 +56,61 @@ class Director implements TemplateGlobalProvider {
/**
* @config
*
* @var string
*/
private static $alternate_base_folder;
/**
* @config
*
* @var array
*/
private static $dev_servers = array();
/**
* @config
*
* @var array
*/
private static $test_servers = array();
/**
* Setting this explicitly specifies the protocol (http or https) used, overriding
* the normal behaviour of Director::is_https introspecting it from the request
* Setting this explicitly specifies the protocol ("http" or "https") used, overriding the normal
* behaviour of Director::is_https introspecting it from the request. False values imply default
* introspection.
*
* @config
* @var string - "http" or "https" to force the protocol, or false-ish to use default introspection from request
*
* @var string
*/
private static $alternate_protocol;
/**
* @config
*
* @var string
*/
private static $alternate_base_url;
/**
* @config
*
* @var string
*/
private static $environment_type;
/**
* Add URL matching rules to the Director.
* Add URL matching rules to the Director. The director is responsible for turning URLs into
* Controller objects.
*
* The director is responsible for turning URLs into Controller objects.
* Higher $priority values will get your rule checked first. We recommend priority 100 for your
* site's rules. The built-in rules are priority 10, standard modules are priority 50.
*
* @deprecated 4.0 Use the "Director.rules" config setting instead
* @param $priority The priority of the rules; higher values will get your rule checked first. We recommend
* priority 100 for your site's rules. The built-in rules are priority 10, standard modules are
* priority 50.
*
* @param int $priority
* @param array $rules
*/
public static function addRules($priority, $rules) {
Deprecation::notice('4.0', 'Use the "Director.rules" config setting instead');
@ -99,20 +122,25 @@ class Director implements TemplateGlobalProvider {
* Process the given URL, creating the appropriate controller and executing it.
*
* Request processing is handled as follows:
* - Director::direct() creates a new SS_HTTPResponse object and passes this to Director::handleRequest().
* - Director::handleRequest($request) checks each of the Director rules and identifies a controller to handle
* this request.
* - Controller::handleRequest($request) is then called. This will find a rule to handle the URL, and call the
* rule handling method.
* - RequestHandler::handleRequest($request) is recursively called whenever a rule handling method returns a
* RequestHandler object.
* - Director::direct() creates a new SS_HTTPResponse object and passes this to
* Director::handleRequest().
* - Director::handleRequest($request) checks each of the Director rules and identifies a controller
* to handle this request.
* - Controller::handleRequest($request) is then called. This will find a rule to handle the URL,
* and call the rule handling method.
* - RequestHandler::handleRequest($request) is recursively called whenever a rule handling method
* returns a RequestHandler object.
*
* In addition to request processing, Director will manage the session, and perform the output of the actual
* response to the browser.
* In addition to request processing, Director will manage the session, and perform the output of
* the actual response to the browser.
*
* @param $url String, the URL the user is visiting, without the querystring.
* @uses handleRequest() rule-lookup logic is handled by this.
* @uses Controller::run() Controller::run() handles the page logic for a Director::direct() call.
*
* @param string $url
* @param DataModel $model
*
* @throws SS_HTTPResponse_Exception
*/
public static function direct($url, DataModel $model) {
// Validate $_FILES array before merging it with $_POST
@ -209,25 +237,28 @@ class Director implements TemplateGlobalProvider {
}
/**
* 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 SS_HTTPResponse object.
*
* @param string $url The URL to visit
* @param array $postVars The $_POST & $_FILES variables
* @param 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 HTTP_Request $request The {@see HTTP_Request} object generated as a part of this request
* @return SS_HTTPResponse
* 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 SS_HTTPResponse object.
*
* @uses getControllerForURL() The rule-lookup logic is handled by this.
* @uses Controller::run() Controller::run() handles the page logic for a Director::direct() call.
* @uses Controller::run() 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 HTTP_Request $request The {@see HTTP_Request} object generated as a part of this request.
*
* @return SS_HTTPResponse
*
* @throws SS_HTTPResponse_Exception
*/
public static function test($url, $postVars = null, $session = array(), $httpMethod = null, $body = null,
$headers = array(), $cookies = array(), &$request = null) {
@ -235,8 +266,8 @@ class Director implements TemplateGlobalProvider {
Config::nest();
Injector::nest();
// These are needed so that calling Director::test() doesnt muck with whoever is calling it.
// Really, it's some inappropriate coupling and should be resolved by making less use of statics
// 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.
$oldStage = Versioned::current_stage();
$getVars = array();
@ -265,7 +296,7 @@ class Director implements TemplateGlobalProvider {
$existingRequestVars, $existingGetVars, $existingPostVars, $existingSessionVars,
$existingCookies, $existingServer, $existingRequirementsBackend, $oldStage
) {
// Restore the superglobals
// Restore the super globals
$_REQUEST = $existingRequestVars;
$_GET = $existingGetVars;
$_POST = $existingPostVars;
@ -275,7 +306,7 @@ class Director implements TemplateGlobalProvider {
Requirements::set_backend($existingRequirementsBackend);
// These are needed so that calling Director::test() doesnt muck with whoever is calling it.
// 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::reading_stage($oldStage);
@ -290,8 +321,7 @@ class Director implements TemplateGlobalProvider {
// 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 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 {
@ -309,7 +339,7 @@ class Director implements TemplateGlobalProvider {
parse_str($getVarsEncoded, $getVars);
}
// Replace the superglobals with appropriate test values
// Replace the super globals with appropriate test values
$_REQUEST = ArrayLib::array_merge_recursive((array) $getVars, (array) $postVars);
$_GET = (array) $getVars;
$_POST = (array) $postVars;
@ -358,6 +388,10 @@ class Director implements TemplateGlobalProvider {
/**
* Handle an HTTP request, defined with a SS_HTTPRequest object.
*
* @param SS_HTTPRequest $request
* @param Session $session
* @param DataModel $model
*
* @return SS_HTTPResponse|string
*/
protected static function handleRequest(SS_HTTPRequest $request, Session $session, DataModel $model) {
@ -382,12 +416,12 @@ class Director implements TemplateGlobalProvider {
// Find the controller name
if(isset($arguments['Controller'])) $controller = $arguments['Controller'];
// Pop additional tokens from the tokeniser if necessary
// Pop additional tokens from the tokenizer if necessary
if(isset($controllerOptions['_PopTokeniser'])) {
$request->shift($controllerOptions['_PopTokeniser']);
}
// Handle redirections
// Handle redirection
if(isset($arguments['Redirect'])) {
return "redirect:" . Director::absoluteURL($arguments['Redirect'], true);
@ -416,15 +450,15 @@ class Director implements TemplateGlobalProvider {
/**
* Set url parameters (should only be called internally by RequestHandler->handleRequest()).
*
* @param $params array
* @param array $params
*/
public static function setUrlParams($params) {
Director::$urlParams = $params;
}
/**
* Return the {@link SiteTree} object that is currently being viewed. If there is no SiteTree object to return,
* then this will return the current controller.
* Return the {@link SiteTree} object that is currently being viewed. If there is no SiteTree
* object to return, then this will return the current controller.
*
* @return SiteTree
*/
@ -442,15 +476,16 @@ class Director implements TemplateGlobalProvider {
}
/**
* Turns the given URL into an absolute URL.
* By default non-site root relative urls will be evaluated relative to the current base_url
* Turns the given URL into an absolute URL. By default non-site root relative urls will be
* evaluated relative to the current base_url.
*
* @param string $url URL To transform to absolute
* @param string $url URL To transform to absolute.
* @param string $relativeParent Method to use for evaluating relative urls.
* Either one of BASE (baseurl), ROOT (site root), or REQUEST (requested page).
* Defaults to BASE, which is the same behaviour as template url resolution.
* Igored if the url is absolute or site root.
* @return string The fully qualified URL
* Ignored if the url is absolute or site root.
*
* @return string
*/
public static function absoluteURL($url, $relativeParent = self::BASE) {
if(is_bool($relativeParent)) {
@ -496,10 +531,10 @@ class Director implements TemplateGlobalProvider {
}
/**
* Returns the part of the URL, 'http://www.mysite.com'.
* Returns the domain part of the URL 'http://www.mysite.com'. Returns FALSE is this environment
* variable isn't set.
*
* @return boolean|string The domain from the PHP environment. Returns FALSE is this environment variable isn't
* set.
* @return bool|string
*/
public static function protocolAndHost() {
$alternate = Config::inst()->get('Director', 'alternate_base_url');
@ -538,7 +573,7 @@ class Director implements TemplateGlobalProvider {
/**
* Return whether the site is running as under HTTPS.
*
* @return boolean
* @return bool
*/
public static function is_https() {
$return = false;
@ -577,10 +612,8 @@ class Director implements TemplateGlobalProvider {
}
/**
* Returns the root URL for the site.
*
* It will be automatically calculated unless it is overridden with
* {@link setBaseURL()}.
* Returns the root URL for the site. It will be automatically calculated unless it is overridden
* with {@link setBaseURL()}.
*
* @return string
*/
@ -607,10 +640,12 @@ class Director implements TemplateGlobalProvider {
}
/**
* Sets the root URL for the website.
* If the site isn't accessible from the URL you provide, weird things will happen.
* Sets the root URL for the website. If the site isn't accessible from the URL you provide,
* weird things will happen.
*
* @deprecated 4.0 Use the "Director.alternate_base_url" config setting instead
* @deprecated 4.0 Use the "Director.alternate_base_url" config setting instead.
*
* @param string $baseURL
*/
public static function setBaseURL($baseURL) {
Deprecation::notice('4.0', 'Use the "Director.alternate_base_url" config setting instead');
@ -618,8 +653,10 @@ class Director implements TemplateGlobalProvider {
}
/**
* Returns the root filesystem folder for the site.
* It will be automatically calculated unless it is overridden with {@link setBaseFolder()}.
* Returns the root filesystem folder for the site. It will be automatically calculated unless
* it is overridden with {@link setBaseFolder()}.
*
* @return string
*/
public static function baseFolder() {
$alternate = Config::inst()->get('Director', 'alternate_base_folder');
@ -627,10 +664,12 @@ class Director implements TemplateGlobalProvider {
}
/**
* Sets the root folder for the website.
* If the site isn't accessible from the folder you provide, weird things will happen.
* Sets the root folder for the website. If the site isn't accessible from the folder you provide,
* weird things will happen.
*
* @deprecated 4.0 Use the "Director.alternate_base_folder" config setting instead
* @deprecated 4.0 Use the "Director.alternate_base_folder" config setting instead.
*
* @param string $baseFolder
*/
public static function setBaseFolder($baseFolder) {
Deprecation::notice('4.0', 'Use the "Director.alternate_base_folder" config setting instead');
@ -638,13 +677,12 @@ class Director implements TemplateGlobalProvider {
}
/**
* Turns an absolute URL or folder into one that's relative to the root of
* the site. This is useful when turning a URL into a filesystem reference,
* or vice versa.
* Turns an absolute URL or folder into one that's relative to the root of the site. This is useful
* when turning a URL into a filesystem reference, or vice versa.
*
* @param string $url Accepts both a URL or a filesystem path
* @return string Either a relative URL if the checks succeeded, or the
* original (possibly absolute) URL.
* @param string $url Accepts both a URL or a filesystem path.
*
* @return string
*/
public static function makeRelative($url) {
// Allow for the accidental inclusion whitespace and // in the URL
@ -695,10 +733,10 @@ class Director implements TemplateGlobalProvider {
}
/**
* Returns true if a given path is absolute. Works under both *nix and windows
* systems
* Returns true if a given path is absolute. Works under both *nix and windows systems.
*
* @param string $path
*
* @return bool
*/
public static function is_absolute($path) {
@ -708,30 +746,30 @@ class Director implements TemplateGlobalProvider {
}
/**
* Determine if the url is root relative (i.e. starts with /, but not with //)
* SilverStripe considers root relative urls as a subset of relative urls
* Determine if the url is root relative (i.e. starts with /, but not with //) SilverStripe
* considers root relative urls as a subset of relative urls.
*
* @param string $url
* @return bool True if this url is root relative
*
* @return bool
*/
public static function is_root_relative_url($url) {
return strpos($url, '/') === 0 && strpos($url, '//') !== 0;
}
/**
* Checks if a given URL is absolute (e.g. starts with 'http://' etc.).
* URLs beginning with "//" are treated as absolute, as browsers take this to mean
* the same protocol as currently being used.
* Checks if a given URL is absolute (e.g. starts with 'http://' etc.). URLs beginning with "//"
* are treated as absolute, as browsers take this to mean the same protocol as currently being used.
*
* Useful to check before redirecting based on a URL from user submissions
* through $_GET or $_POST, and avoid phishing attacks by redirecting
* to an attackers server.
* Useful to check before redirecting based on a URL from user submissions through $_GET or $_POST,
* and avoid phishing attacks by redirecting to an attackers server.
*
* Note: Can't solely rely on PHP's parse_url() , since it is not intended to work with relative URLs
* or for security purposes. filter_var($url, FILTER_VALIDATE_URL) has similar problems.
*
* @param string $url
* @return boolean
*
* @return bool
*/
public static function is_absolute_url($url) {
// Strip off the query and fragment parts of the URL before checking
@ -760,26 +798,27 @@ class Director implements TemplateGlobalProvider {
}
/**
* Checks if a given URL is relative (or root relative) by checking {@link is_absolute_url()}
* Checks if a given URL is relative (or root relative) by checking {@link is_absolute_url()}.
*
* @param string $url
* @return boolean
*
* @return bool
*/
public static function is_relative_url($url) {
return !static::is_absolute_url($url);
}
/**
* Checks if the given URL is belonging to this "site" (not an external link).
* That's the case if the URL is relative, as defined by {@link is_relative_url()},
* or if the host matches {@link protocolAndHost()}.
* Checks if the given URL is belonging to this "site" (not an external link). That's the case if
* the URL is relative, as defined by {@link is_relative_url()}, or if the host matches
* {@link protocolAndHost()}.
*
* Useful to check before redirecting based on a URL from user submissions
* through $_GET or $_POST, and avoid phishing attacks by redirecting
* to an attackers server.
* Useful to check before redirecting based on a URL from user submissions through $_GET or $_POST,
* and avoid phishing attacks by redirecting to an attackers server.
*
* @param string $url
* @return boolean
*
* @return bool
*/
public static function is_site_url($url) {
$urlHost = parse_url($url, PHP_URL_HOST);
@ -795,6 +834,7 @@ class Director implements TemplateGlobalProvider {
* Takes a $_SERVER data array and extracts HTTP request headers.
*
* @param array $server
*
* @return array
*/
public static function extract_request_headers(array $server) {
@ -819,6 +859,7 @@ class Director implements TemplateGlobalProvider {
* Given a filesystem reference relative to the site root, return the full file-system path.
*
* @param string $file
*
* @return string
*/
public static function getAbsFile($file) {
@ -826,8 +867,11 @@ class Director implements TemplateGlobalProvider {
}
/**
* Returns true if the given file exists.
* @param $file Filename specified relative to the site root
* Returns true if the given file exists. Filename should be relative to the site root.
*
* @param $file
*
* @return bool
*/
public static function fileExists($file) {
// replace any appended query-strings, e.g. /path/to/foo.php?bar=1 to /path/to/foo.php
@ -848,7 +892,10 @@ class Director implements TemplateGlobalProvider {
}
/**
* Returns the Absolute URL of the site root, embedding the current basic-auth credentials into the URL.
* Returns the Absolute URL of the site root, embedding the current basic-auth credentials into
* the URL.
*
* @return string
*/
public static function absoluteBaseURLWithAuth() {
$s = "";
@ -862,7 +909,7 @@ class Director implements TemplateGlobalProvider {
/**
* Skip any further processing and immediately respond with a redirect to the passed URL.
*
* @param string $destURL - The URL to redirect to
* @param string $destURL
*/
protected static function force_redirect($destURL) {
$response = new SS_HTTPResponse();
@ -895,15 +942,16 @@ class Director implements TemplateGlobalProvider {
* 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.
* 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 boolean|string String of URL when unit tests running, boolean FALSE if patterns don't match request URI
* @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;
@ -963,11 +1011,10 @@ class Director implements TemplateGlobalProvider {
}
/**
* Checks if the current HTTP-Request is an "Ajax-Request"
* by checking for a custom header set by jQuery or
* wether a manually set request-parameter 'ajax' is present.
* Checks if the current HTTP-Request is an "Ajax-Request" by checking for a custom header set by
* jQuery or whether a manually set request-parameter 'ajax' is present.
*
* @return boolean
* @return bool
*/
public static function is_ajax() {
if(Controller::has_curr()) {
@ -981,50 +1028,50 @@ class Director implements TemplateGlobalProvider {
}
/**
* Returns true if this script is being run from the command line rather than the webserver.
* Returns true if this script is being run from the command line rather than the web server.
*
* @return boolean
* @return bool
*/
public static function is_cli() {
return (php_sapi_name() == "cli");
}
////////////////////////////////////////////////////////////////////////////////////////////
// Environment type methods
////////////////////////////////////////////////////////////////////////////////////////////
/**
* Set the environment type of the current site.
*
* Typically, a SilverStripe site have a number of environments:
* - development environments, such a copy on your local machine.
* - test sites, such as the one you show the client before going live.
* - the live site itself.
* - Development environments, such a copy on your local machine.
* - Test sites, such as the one you show the client before going live.
* - The live site itself.
*
* The behaviour of these environments often varies slightly. For example, development sites may have errors
* dumped to the screen, and order confirmation emails might be sent to the developer instead of the client.
* The behaviour of these environments often varies slightly. For example, development sites may
* have errors dumped to the screen, and order confirmation emails might be sent to the developer
* instead of the client.
*
* To help with this, SilverStripe supports the notion of an environment type. The environment type can be dev,
* test, or live.
* To help with this, SilverStripe supports the notion of an environment type. The environment
* type can be dev, test, or live.
*
* You can set it explicitly with Director::set_environment_tpye(). Or you can use
* {@link Director::$dev_servers} and {@link Director::$test_servers} to set it implicitly, based on the
* value of $_SERVER['HTTP_HOST']. If the HTTP_HOST value is one of the servers listed, then the environment type
* will be test or dev. Otherwise, the environment type will be live.
* You can set it explicitly with {@link Director::set_environment_type()}. Or you can use
* {@link Director::$dev_servers} and {@link Director::$test_servers} to set it implicitly, based
* on the value of $_SERVER['HTTP_HOST']. If the HTTP_HOST value is one of the servers listed,
* then the environment type will be test or dev. Otherwise, the environment type will be live.
*
* Dev mode can also be forced by putting ?isDev=1 in your URL, which will ask you to log in and then push the
* site into dev mode for the remainder of the session. Putting ?isDev=0 onto the URL can turn it back.
* Dev mode can also be forced by putting ?isDev=1 in your URL, which will ask you to log in and
* then push the site into dev mode for the remainder of the session. Putting ?isDev=0 onto the URL
* can turn it back.
*
* Test mode can also be forced by putting ?isTest=1 in your URL, which will ask you to log in and then push the
* site into test mode for the remainder of the session. Putting ?isTest=0 onto the URL can turn it back.
* Test mode can also be forced by putting ?isTest=1 in your URL, which will ask you to log in and
* then push the site into test mode for the remainder of the session. Putting ?isTest=0 onto the URL
* can turn it back.
*
* Generally speaking, these methods will be called from your _config.php file.
*
* Once the environment type is set, it can be checked with {@link Director::isDev()}, {@link Director::isTest()},
* and {@link Director::isLive()}.
* Once the environment type is set, it can be checked with {@link Director::isDev()},
* {@link Director::isTest()}, and {@link Director::isLive()}.
*
* @deprecated 4.0 Use the "Director.environment_type" config setting instead
* @param $et string The environment type: dev, test, or live.
*
* @param $et string
*/
public static function set_environment_type($et) {
if($et != 'dev' && $et != 'test' && $et != 'live') {
@ -1037,9 +1084,10 @@ class Director implements TemplateGlobalProvider {
}
/**
* Can also be checked with {@link Director::isDev()}, {@link Director::isTest()}, and {@link Director::isLive()}.
* Can also be checked with {@link Director::isDev()}, {@link Director::isTest()}, and
* {@link Director::isLive()}.
*
* @return string 'dev', 'test' or 'live'
* @return bool|string
*/
public static function get_environment_type() {
if(Director::isLive()) {
@ -1053,17 +1101,21 @@ class Director implements TemplateGlobalProvider {
}
}
/*
* This function will return true if the site is in a live environment.
* For information about environment types, see {@link Director::set_environment_type()}.
/**
* This function will return true if the site is in a live environment. For information about
* environment types, see {@link Director::set_environment_type()}.
*
* @return bool
*/
public static function isLive() {
return !(Director::isDev() || Director::isTest());
}
/**
* This function will return true if the site is in a development environment.
* For information about environment types, see {@link Director::set_environment_type()}.
* This function will return true if the site is in a development environment. For information about
* environment types, see {@link Director::set_environment_type()}.
*
* @return bool
*/
public static function isDev() {
// Check session
@ -1082,8 +1134,10 @@ class Director implements TemplateGlobalProvider {
}
/**
* This function will return true if the site is in a test environment.
* For information about environment types, see {@link Director::set_environment_type()}.
* This function will return true if the site is in a test environment. For information about
* environment types, see {@link Director::set_environment_type()}.
*
* @return bool
*/
public static function isTest() {
// In case of isDev and isTest both being set, dev has higher priority
@ -1105,9 +1159,9 @@ class Director implements TemplateGlobalProvider {
}
/**
* Check or update any temporary environment specified in the session
* Check or update any temporary environment specified in the session.
*
* @return string 'test', 'dev', or null
* @return null|string
*/
protected static function session_environment() {
// Set session from querystring
@ -1135,8 +1189,10 @@ class Director implements TemplateGlobalProvider {
}
/**
* @return array Returns an array of strings of the method names of methods on the call that should be exposed
* Returns an array of strings of the method names of methods on the call that should be exposed
* as global variables in the templates.
*
* @return array
*/
public static function get_template_global_variables() {
return array(

View File

@ -3,10 +3,20 @@
* Triggers a call to flush() on all implementors of Flushable.
*
* @package framework
*
* @subpackage control
*/
class FlushRequestFilter implements RequestFilter {
/**
* @inheritdoc
*
* @param SS_HTTPRequest $request
* @param Session $session
* @param DataModel $model
*
* @return bool
*/
public function preRequest(SS_HTTPRequest $request, Session $session, DataModel $model) {
if(array_key_exists('flush', $request->getVars())) {
foreach(ClassInfo::implementorsOf('Flushable') as $class) {
@ -17,6 +27,15 @@ class FlushRequestFilter implements RequestFilter {
return true;
}
/**
* @inheritdoc
*
* @param SS_HTTPRequest $request
* @param SS_HTTPResponse $response
* @param DataModel $model
*
* @return bool
*/
public function postRequest(SS_HTTPRequest $request, SS_HTTPResponse $response, DataModel $model) {
return true;
}

View File

@ -1,39 +1,42 @@
<?php
/**
* A class with HTTP-related helpers.
* Like Debug, this is more a bundle of methods than a class ;-)
* A class with HTTP-related helpers. Like Debug, this is more a bundle of methods than a class.
*
* @package framework
*
* @subpackage misc
*/
class HTTP {
/**
* @var int $cache_age
* @var int
*/
protected static $cache_age = 0;
/**
* @var timestamp $modification_date
* @var int
*/
protected static $modification_date = null;
/**
* @var string $etag
* @var string
*/
protected static $etag = null;
/**
* @config
*
* @var bool
*/
private static $cache_ajax_requests = true;
/**
* Turns a local system filename into a URL by comparing it to the script
* filename.
* Turns a local system filename into a URL by comparing it to the script filename.
*
* @param string
* @param string $filename
*
* @return string
*/
public static function filename2url($filename) {
$slashPos = -1;
@ -62,7 +65,11 @@ class HTTP {
}
/**
* Turn all relative URLs in the content to absolute URLs
* Turn all relative URLs in the content to absolute URLs.
*
* @param string $html
*
* @return string
*/
public static function absoluteURLs($html) {
$html = str_replace('$CurrentPageURL', $_SERVER['REQUEST_URI'], $html);
@ -78,28 +85,26 @@ class HTTP {
/**
* Rewrite all the URLs in the given content, evaluating the given string as PHP code.
*
* Put $URL where you want the URL to appear, however, you can't embed $URL in strings
* Some example code:
* Put $URL where you want the URL to appear, however, you can't embed $URL in strings, for example:
* <ul>
* <li><code>'"../../" . $URL'</code></li>
* <li><code>'myRewriter($URL)'</code></li>
* <li><code>'(substr($URL, 0, 1)=="/") ? "../" . substr($URL, 1) : $URL'</code></li>
* </ul>
*
* As of 3.2 $code should be a callable which takes a single parameter and returns
* the rewritten URL. e.g.
*
* As of 3.2 $code should be a callable which takes a single parameter and returns the rewritten,
* for example:
* <code>
* function($url) {
* return Director::absoluteURL($url, true);
* }
* </code>
*
* @param string $content The HTML to search for links to rewrite
* @param string|callable $code Either a string that can evaluate to an expression
* to rewrite links (depreciated), or a callable that takes a single
* parameter and returns the rewritten URL
* @return The content with all links rewritten as per the logic specified in $code
* @param string $content The HTML to search for links to rewrite.
* @param string|callable $code Either a string that can evaluate to an expression to rewrite links
* (depreciated), or a callable that takes a single parameter and returns the rewritten URL.
*
* @return The content with all links rewritten as per the logic specified in $code.
*/
public static function urlRewriter($content, $code) {
if(!is_callable($code)) {
@ -146,23 +151,21 @@ class HTTP {
}
/**
* Will try to include a GET parameter for an existing URL,
* preserving existing parameters and fragments.
* If no URL is given, falls back to $_SERVER['REQUEST_URI'].
* Uses parse_url() to dissect the URL, and http_build_query() to reconstruct it
* with the additional parameter. Converts any '&' (ampersand)
* URL parameter separators to the more XHTML compliant '&amp;'.
* Will try to include a GET parameter for an existing URL, preserving existing parameters and
* fragments. If no URL is given, falls back to $_SERVER['REQUEST_URI']. Uses parse_url() to
* dissect the URL, and http_build_query() to reconstruct it with the additional parameter.
* Converts any '&' (ampersand) URL parameter separators to the more XHTML compliant '&amp;'.
*
* CAUTION: If the URL is determined to be relative,
* it is prepended with Director::absoluteBaseURL().
* This method will always return an absolute URL because
* Director::makeRelative() can lead to inconsistent results.
* CAUTION: If the URL is determined to be relative, it is prepended with Director::absoluteBaseURL().
* This method will always return an absolute URL because Director::makeRelative() can lead to
* inconsistent results.
*
* @param string $varname
* @param string $varvalue
* @param string $currentURL Relative or absolute URL (Optional).
* @param string $separator Separator for http_build_query(). (Optional).
* @return string Absolute URL
* @param string $currentURL Relative or absolute URL.
* @param string $separator Separator for http_build_query().
*
* @return string
*/
public static function setGetVar($varname, $varvalue, $currentURL = null, $separator = '&amp;') {
$uri = $currentURL ? $currentURL : Director::makeRelative($_SERVER['REQUEST_URI']);
@ -212,16 +215,25 @@ class HTTP {
return $newUri;
}
/**
* @param string $varname
* @param string $varvalue
* @param null|string $currentURL
*
* @return string
*/
public static function RAW_setGetVar($varname, $varvalue, $currentURL = null) {
$url = self::setGetVar($varname, $varvalue, $currentURL);
return Convert::xml2raw($url);
}
/**
* Search for all tags with a specific attribute, then return the value of that attribute in a flat array.
* Search for all tags with a specific attribute, then return the value of that attribute in a
* flat array.
*
* @param string $content
* @param array $attributes an array of tags to attributes, for example "[a] => 'href', [div] => 'id'"
* @param array $attributes An array of tags to attributes, for example "[a] => 'href', [div] => 'id'"
*
* @return array
*/
public static function findByTagAndAttribute($content, $attributes) {
@ -243,23 +255,32 @@ class HTTP {
return count($result) ? $result : null;
}
/**
* @param string $content
*
* @return array
*/
public static function getLinksIn($content) {
return self::findByTagAndAttribute($content, array("a" => "href"));
}
/**
* @param string $content
*
* @return array
*/
public static function getImagesIn($content) {
return self::findByTagAndAttribute($content, array("img" => "src"));
}
/**
* Get the MIME type based on a file's extension.
* Get the MIME type based on a file's extension. If the finfo class exists in PHP, and the file
* exists relative to the project root, then use that extension, otherwise fallback to a list of
* commonly known MIME types.
*
* If the finfo class exists in PHP, and the file actually exists, then use that
* extension, otherwise fallback to a list of commonly known MIME types.
* @param string $filename
*
* @uses finfo
* @param string $filename Relative path to filename from project root, e.g. "mysite/tests/file.csv"
* @return string MIME type
* @return string
*/
public static function get_mime_type($filename) {
// If the finfo module is compiled into PHP, use it.
@ -284,23 +305,34 @@ class HTTP {
}
/**
* Set the maximum age of this page in web caches, in seconds
* Set the maximum age of this page in web caches, in seconds.
*
* @param int $age
*/
public static function set_cache_age($age) {
self::$cache_age = $age;
}
/**
* @param string $dateString
*/
public static function register_modification_date($dateString) {
$timestamp = strtotime($dateString);
if($timestamp > self::$modification_date)
self::$modification_date = $timestamp;
}
/**
* @param int $timestamp
*/
public static function register_modification_timestamp($timestamp) {
if($timestamp > self::$modification_date)
self::$modification_date = $timestamp;
}
/**
* @param string $etag
*/
public static function register_etag($etag) {
self::$etag = $etag;
}
@ -309,10 +341,13 @@ class HTTP {
* Add the appropriate caching headers to the response, including If-Modified-Since / 304 handling.
* Note that setting HTTP::$cache_age will overrule any cache headers set by PHP's
* session_cache_limiter functionality. It is your responsibility to ensure only cacheable data
* is in fact cached, and HTTP::$cache_age isn't set when the HTTP body contains session-specific content.
* is in fact cached, and HTTP::$cache_age isn't set when the HTTP body contains session-specific
* content.
*
* @param SS_HTTPResponse $body The SS_HTTPResponse object to augment. Omitted the argument or passing a string is
* deprecated; in these cases, the headers are output directly.
* Omitting the $body argument or passing a string is deprecated; in these cases, the headers are
* output directly.
*
* @param SS_HTTPResponse $body
*/
public static function add_cache_headers($body = null) {
$cacheAge = self::$cache_age;
@ -461,16 +496,21 @@ class HTTP {
/**
* Return an {@link http://www.faqs.org/rfcs/rfc2822 RFC 2822} date in the
* GMT timezone (a timestamp is always in GMT: the number of seconds
* since January 1 1970 00:00:00 GMT)
* Return an {@link http://www.faqs.org/rfcs/rfc2822 RFC 2822} date in the GMT timezone (a timestamp
* is always in GMT: the number of seconds since January 1 1970 00:00:00 GMT)
*
* @param int $timestamp
*
* @return string
*/
public static function gmt_date($timestamp) {
return gmdate('D, d M Y H:i:s', $timestamp) . ' GMT';
}
/*
/**
* Return static variable cache_age in second
*
* @return int
*/
public static function get_cache_age() {
return self::$cache_age;