Webylon 3.2 API Docs
  • Package
  • Class
  • Tree
  • Deprecated
  • Download
Version: current
  • 3.2
  • 3.1

Packages

  • 1c
    • exchange
      • catalog
  • auth
  • Booking
  • building
    • company
  • cart
    • shipping
    • steppedcheckout
  • Catalog
    • monument
  • cms
    • assets
    • batchaction
    • batchactions
    • bulkloading
    • comments
    • content
    • core
    • export
    • newsletter
    • publishers
    • reports
    • security
    • tasks
  • Dashboard
  • DataObjectManager
  • event
  • faq
  • forms
    • actions
    • core
    • fields-basic
    • fields-dataless
    • fields-datetime
    • fields-files
    • fields-formatted
    • fields-formattedinput
    • fields-relational
    • fields-structural
    • transformations
    • validators
  • googlesitemaps
  • guestbook
  • installer
  • newsletter
  • None
  • photo
    • gallery
  • PHP
  • polls
  • recaptcha
  • sapphire
    • api
    • bulkloading
    • control
    • core
    • cron
    • dev
    • email
    • fields-formattedinput
    • filesystem
    • formatters
    • forms
    • i18n
    • integration
    • misc
    • model
    • parsers
    • search
    • security
    • tasks
    • testing
    • tools
    • validation
    • view
    • widgets
  • seo
    • open
      • graph
  • sfDateTimePlugin
  • spamprotection
  • stealth
    • captha
  • subsites
  • userform
    • pagetypes
  • userforms
  • webylon
  • widgets

Classes

  • Announcement_Controller
  • AnnouncementHolder_Controller
  • BookingAdminPage_Controller
  • BookingPage_Controller
  • Cart_Controller
  • CartPage_Controller
  • Catalog_Controller
  • CheckoutPage_Controller
  • ChequePayment_Handler
  • ContactsPage_Controller
  • ContentController
  • ContentNegotiator
  • Controller
  • DataObjectManager_Controller
  • DatePickerField_Controller
  • Director
  • DocPage_Controller
  • DocumentsPage_Controller
  • Event_Controller
  • EventHolder_Controller
  • FavoritePage_Controller
  • FileDataObjectManager_Controller
  • FindCyrillic_Controller
  • HomePage_Controller
  • Import1C_Controller
  • ImportCatalog1C_Controller
  • LastDoc_Controller
  • LiveCalendarWidget_Controller
  • MapObject_Controller
  • MapObjectGroup_Controller
  • MapPage_Controller
  • MediawebPage_Controller
  • ModelAsController
  • Monument_Controller
  • MonumentCatalog_Controller
  • MonumentForm_Controller
  • MultiUploadControls
  • NewsArchive_Controller
  • NewsEntry_Controller
  • NewsHolder_Controller
  • Orders1CExchange_Controller
  • Page_Controller
  • Payment_Handler
  • PhotoAlbumManager_Controller
  • Product_Controller
  • ProductSearchPage_Controller
  • ProfilePage_Controller
  • PublHolder_Controller
  • Publication_Controller
  • RatingExtension_Controller
  • RegistrationPage_Controller
  • RemoveOrphanedPagesTask
  • RequestHandler
  • Room_Controller
  • RoomCatalog_Controller
  • RootURLController
  • SapphireInfo
  • Search_Controller
  • Session
  • SimpleOrderPage_Controller
  • SiteMap_Controller
  • Socle_Controller
  • SocleSize_Controller
  • SpecialCatalog_Controller
  • SS_HTTPRequest
  • SS_HTTPResponse
  • StartCatalog_Controller
  • SubsitesSelectorPage_Controller
  • VideoBankPage_Controller

Interfaces

  • NestedController

Exceptions

  • SS_HTTPResponse_Exception
  1 <?php
  2 /**
  3  * Director is responsible for processing URLs, and providing environment information.
  4  * 
  5  * The most important part of director is {@link Director::direct()}, which is passed a URL and will execute the appropriate
  6  * controller.
  7  * 
  8  * Director also has a number of static methods that provide information about the environment, such as {@link Director::set_environment_type()}.
  9  *
 10  * @package sapphire
 11  * @subpackage control
 12  * @see Director::direct(),Director::addRules(),Director::set_environment_type()
 13  */
 14 class Director {
 15     
 16     static private $urlParams;
 17 
 18     static private $rules = array();
 19     
 20     /**
 21      * @var SiteTree
 22      */
 23     private static $current_page;
 24     
 25     /**
 26      * @deprecated 2.4
 27      */
 28     static $siteMode;
 29     
 30     static $alternateBaseFolder;
 31 
 32     static $alternateBaseURL;
 33     
 34     static $dev_servers = array(
 35         'localhost',
 36         '127.0.0.1'
 37     );
 38     
 39     static $test_servers = array();
 40     
 41     static protected $environment_type;
 42 
 43     /** 
 44      * @deprecated 2.4
 45      */ 
 46     static protected $callbacks;
 47 
 48     function __construct() {
 49         if(isset($_GET['debug_profile'])) Profiler::mark("Director", "construct");
 50         Session::addToArray('history', substr($_SERVER['REQUEST_URI'], strlen(Director::baseURL())));
 51         if(isset($_GET['debug_profile'])) Profiler::unmark("Director", "construct");
 52     }
 53 
 54     /**
 55      * Return a URL from this user's navigation history.
 56      * @param pagesBack The number of pages back to go.  The default, 1, returns the previous
 57      * page.
 58      */
 59     static function history($pagesBack = 1) {
 60         return Session::get('history.' . intval(sizeof(Session::get('history')) - $pagesBack - 1));
 61     }
 62 
 63 
 64     /**
 65      * Add URL matching rules to the Director.
 66      * 
 67      * The director is responsible for turning URLs into Controller objects.  It does thi
 68      * 
 69      * @param $priority The priority of the rules; higher values will get your rule checked first.  
 70      * We recommend priority 100 for your site's rules.  The built-in rules are priority 10, standard modules are priority 50.
 71      */
 72     static function addRules($priority, $rules) {
 73         Director::$rules[$priority] = isset(Director::$rules[$priority]) ? array_merge($rules, (array)Director::$rules[$priority]) : $rules;
 74     }
 75 
 76     /**
 77      * Process the given URL, creating the appropriate controller and executing it.
 78      * 
 79      * Request processing is handled as folows:
 80      *  - Director::direct() creates a new SS_HTTPResponse object and passes this to Director::handleRequest().
 81      *  - Director::handleRequest($request) checks each of the Director rules and identifies a controller to handle this 
 82      *    request.
 83      *  - Controller::handleRequest($request) is then called.  This will find a rule to handle the URL, and call the rule
 84      *    handling method.
 85      *  - RequestHandler::handleRequest($request) is recursively called whenever a rule handling method returns a
 86      *    RequestHandler object.
 87      *
 88      * In addition to request processing, Director will manage the session, and perform the output of the actual response
 89      * to the browser.
 90      * 
 91      * @param $url String, the URL the user is visiting, without the querystring.
 92      * @uses handleRequest() rule-lookup logic is handled by this.
 93      * @uses Controller::run() Controller::run() handles the page logic for a Director::direct() call.
 94      */
 95     static function direct($url) {
 96         // Validate $_FILES array before merging it with $_POST
 97         foreach($_FILES as $k => $v) {
 98             if(is_array($v['tmp_name'])) {
 99                 foreach($v['tmp_name'] as $tmpFile) {
100                     if($tmpFile && !is_uploaded_file($tmpFile)) {
101                         user_error("File upload '$k' doesn't appear to be a valid upload", E_USER_ERROR);
102                     }
103                 }
104             } else {
105                 if($v['tmp_name'] && !is_uploaded_file($v['tmp_name'])) {
106                     user_error("File upload '$k' doesn't appear to be a valid upload", E_USER_ERROR);
107                 }
108             }
109         }
110         
111         $req = new SS_HTTPRequest(
112             (isset($_SERVER['X-HTTP-Method-Override'])) ? $_SERVER['X-HTTP-Method-Override'] : $_SERVER['REQUEST_METHOD'],
113             $url, 
114             $_GET, 
115             array_merge((array)$_POST, (array)$_FILES),
116             @file_get_contents('php://input')
117         );
118         
119         // @todo find better way to extract HTTP headers
120         if(isset($_SERVER['HTTP_ACCEPT'])) $req->addHeader("Accept", $_SERVER['HTTP_ACCEPT']);
121         if(isset($_SERVER['CONTENT_TYPE'])) $req->addHeader("Content-Type", $_SERVER['CONTENT_TYPE']);
122         if(isset($_SERVER['HTTP_REFERER'])) $req->addHeader("Referer", $_SERVER['HTTP_REFERER']);
123 
124         // Load the session into the controller
125         $session = new Session(Session::get_all());
126 
127         
128         $result = Director::handleRequest($req, $session);
129         $session->inst_save();
130 
131         // Return code for a redirection request
132         if(is_string($result) && substr($result,0,9) == 'redirect:') {
133             $response = new SS_HTTPResponse();
134             $response->redirect(substr($result, 9));
135             $response->output();
136 
137         // Handle a controller
138         } else if($result) {
139             if($result instanceof SS_HTTPResponse) {
140                 $response = $result;
141                 
142             } else {
143                 $response = new SS_HTTPResponse();
144                 $response->setBody($result);
145             }
146             
147             // ?debug_memory=1 will output the number of bytes of memory used for this request
148             if(isset($_REQUEST['debug_memory']) && $_REQUEST['debug_memory']) {
149                 Debug::message(sprintf(
150                     "Peak memory usage in bytes: %s", 
151                     number_format(memory_get_peak_usage(),0)
152                 ));
153             } else {
154                 $response->output();
155             }
156 
157             //$controllerObj->getSession()->inst_save();
158         }
159     }
160     
161     /**
162      * Test a URL request, returning a response object.
163      * 
164      * This method is the counterpart of Director::direct() that is used in functional testing.  It will execute the URL given,
165      * 
166      * @param string $url The URL to visit
167      * @param array $postVars The $_POST & $_FILES variables
168      * @param Session $session The {@link Session} object representing the current session.  By passing the same object to multiple
169      * calls of Director::test(), you can simulate a peristed session.
170      * @param string $httpMethod The HTTP method, such as GET or POST.  It will default to POST if postVars is set, GET otherwise.
171      *  Overwritten by $postVars['_method'] if present.
172      * @param string $body The HTTP body
173      * @param array $headers HTTP headers with key-value pairs
174      * @param array $cookies to populate $_COOKIE
175      * @return SS_HTTPResponse
176      * 
177      * @uses getControllerForURL() The rule-lookup logic is handled by this.
178      * @uses Controller::run() Controller::run() handles the page logic for a Director::direct() call.
179      */
180     static function test($url, $postVars = null, $session = null, $httpMethod = null, $body = null, $headers = null, $cookies = null) {
181         // These are needed so that calling Director::test() doesnt muck with whoever is calling it.
182         // Really, it's some inapproriate coupling and should be resolved by making less use of statics
183         $oldStage = Versioned::current_stage();
184         $getVars = array();
185         
186         if(!$httpMethod) $httpMethod = ($postVars || is_array($postVars)) ? "POST" : "GET";
187         
188         if(!$session) $session = new Session(null);
189 
190         // Back up the current values of the superglobals
191         $existingRequestVars = $_REQUEST; 
192         $existingGetVars = $_GET; 
193         $existingPostVars = $_POST; 
194         $existingSessionVars = $_SESSION; 
195         $existingCookies = $_COOKIE;
196         $existingServer = $_SERVER;
197         $existingCookieReportErrors = Cookie::report_errors();
198         $existingRequirementsBackend = Requirements::backend();
199 
200         Cookie::set_report_errors(false);
201         Requirements::set_backend(new Requirements_Backend());
202 
203         // Handle absolute URLs
204         if (@parse_url($url, PHP_URL_HOST) != '') {
205             $bits = parse_url($url);
206             $_SERVER['HTTP_HOST'] = $bits['host'];
207             $url = Director::makeRelative($url);
208         }
209 
210         $urlWithQuerystring = $url;
211         if(strpos($url, '?') !== false) {
212             list($url, $getVarsEncoded) = explode('?', $url, 2);
213             parse_str($getVarsEncoded, $getVars);
214         }
215         
216         // Replace the superglobals with appropriate test values
217         $_REQUEST = array_merge((array)$getVars, (array)$postVars); 
218         $_GET = (array)$getVars; 
219         $_POST = (array)$postVars; 
220         $_SESSION = $session ? $session->inst_getAll() : array();
221         $_COOKIE = (array) $cookies;
222         $_SERVER['REQUEST_URI'] = Director::baseURL() . $urlWithQuerystring;
223 
224         $req = new SS_HTTPRequest($httpMethod, $url, $getVars, $postVars, $body);
225         if($headers) foreach($headers as $k => $v) $req->addHeader($k, $v);
226         $result = Director::handleRequest($req, $session);
227         
228         // Restore the superglobals
229         $_REQUEST = $existingRequestVars; 
230         $_GET = $existingGetVars; 
231         $_POST = $existingPostVars; 
232         $_SESSION = $existingSessionVars;   
233         $_COOKIE = $existingCookies;
234         $_SERVER = $existingServer;
235 
236         Cookie::set_report_errors($existingCookieReportErrors); 
237         Requirements::set_backend($existingRequirementsBackend);
238 
239         // These are needed so that calling Director::test() doesnt muck with whoever is calling it.
240         // Really, it's some inapproriate coupling and should be resolved by making less use of statics
241         Versioned::reading_stage($oldStage);
242         
243         return $result;
244     }
245         
246     /**
247      * Handle an HTTP request, defined with a SS_HTTPRequest object.
248      *
249      * @return SS_HTTPResponse|string
250      */
251     protected static function handleRequest(SS_HTTPRequest $request, Session $session) {
252         krsort(Director::$rules);
253                    
254         if(isset($_REQUEST['debug'])) Debug::show(Director::$rules);
255         foreach(Director::$rules as $priority => $rules) {
256             foreach($rules as $pattern => $controllerOptions) {
257                 if(is_string($controllerOptions)) {
258                     if(substr($controllerOptions,0,2) == '->') $controllerOptions = array('Redirect' => substr($controllerOptions,2));
259                     else $controllerOptions = array('Controller' => $controllerOptions);
260                 }
261                 
262                 if(($arguments = $request->match($pattern, true)) !== false) {
263                     // controllerOptions provide some default arguments
264                     $arguments = array_merge($controllerOptions, $arguments);
265                     
266                     // Find the controller name
267                     if(isset($arguments['Controller'])) $controller = $arguments['Controller'];
268                     
269                     // Pop additional tokens from the tokeniser if necessary
270                     if(isset($controllerOptions['_PopTokeniser'])) {
271                         $request->shift($controllerOptions['_PopTokeniser']);
272                     }
273 
274                     // Handle redirections
275                     if(isset($arguments['Redirect'])) {
276                         return "redirect:" . Director::absoluteURL($arguments['Redirect'], true);
277 
278                     } else {
279                         Director::$urlParams = $arguments;
280 
281                         $controllerObj = new $controller();
282                         $controllerObj->setSession($session);
283 
284                         $result = $controllerObj->handleRequest($request);
285                         if(!is_object($result) || $result instanceof SS_HTTPResponse) return $result;
286                         
287                         user_error("Bad result from url " . $request->getURL() . " handled by " . 
288                             get_class($controllerObj)." controller: ".get_class($result), E_USER_WARNING);
289                         
290                     }
291                 }
292             }
293         }
294     }
295     
296     /**
297      * Returns the urlParam with the given name
298      */
299     static function urlParam($name) {
300         if(isset(Director::$urlParams[$name])) return Director::$urlParams[$name];
301     }
302     
303     /**
304      * Returns an array of urlParams
305      */
306     static function urlParams() {
307         return Director::$urlParams;
308     }
309     
310     /**
311      * Return the {@link SiteTree} object that is currently being viewed. If there is no sitetree object to return,
312      * then this will return the current controller.
313      *
314      * @return SiteTree
315      */
316     public static function get_current_page() {
317         return self::$current_page ? self::$current_page : Controller::curr();
318     }
319     
320     /**
321      * Set the currently active {@link SiteTree} object that is being used to respond to the request.
322      *
323      * @param SiteTree $page
324      */
325     public static function set_current_page($page) {
326         self::$current_page = $page;
327     }
328     
329     /**
330      * @deprecated 2.4 Use {@link Director::get_current_page()}.
331      */
332     static function currentPage() {
333         return self::get_current_page();
334     }
335 
336     /**
337      * Turns the given URL into an absolute URL.
338      * @todo Document how relativeToSiteBase works
339      */
340     static function absoluteURL($url, $relativeToSiteBase = false) {
341         if(strpos($url,'/') === false && !$relativeToSiteBase) $url = dirname($_SERVER['REQUEST_URI'] . 'x') . '/' . $url;
342 
343         if(substr($url,0,4) != "http") {
344             if($url[0] != "/") $url = Director::baseURL()  . $url;
345             // Sometimes baseURL() can return a full URL instead of just a path
346             if(substr($url,0,4) != "http") $url = self::protocolAndHost() . $url;
347         }
348 
349         return $url;
350     }
351 
352     /**
353      * Returns the part of the URL, 'http://www.mysite.com'.
354      * 
355      * @return boolean|string The domain from the PHP environment. Returns FALSE is this environment variable isn't set.
356      */
357     static function protocolAndHost() {
358         if(self::$alternateBaseURL) {
359             if(preg_match('/^(http[^:]*:\/\/[^\/]+)(\/|$)/', self::$alternateBaseURL, $matches)) {
360                 return $matches[1];
361             }
362         }
363 
364         $s = (isset($_SERVER['SSL']) || (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] && $_SERVER['HTTPS'] != 'off')) ? 's' : '';
365         
366         if(isset($_SERVER['HTTP_HOST'])) {
367             return "http$s://" . $_SERVER['HTTP_HOST'];
368         } else {
369             global $_FILE_TO_URL_MAPPING;
370             if(Director::is_cli() && isset($_FILE_TO_URL_MAPPING)) $errorSuggestion = '  You probably want to define '.
371                 'an entry in $_FILE_TO_URL_MAPPING that covers "' . Director::baseFolder() . '"';
372             else if(Director::is_cli()) $errorSuggestion = '  You probably want to define $_FILE_TO_URL_MAPPING in '.
373                 'your _ss_environment.php as instructed on the "sake" page of the doc.silverstripe.com wiki';
374             else $errorSuggestion = "";
375             
376             user_error("Director::protocolAndHost() lacks sufficient information - HTTP_HOST not set.$errorSuggestion", E_USER_WARNING);
377             return false;
378             
379         }
380     }
381 
382 
383     /**
384      * Redirect to another page.
385      *  - $url can be an absolute URL
386      *  - or it can be a URL relative to the "site base"
387      *  - if it is just a word without an slashes, then it redirects to another action on the current controller.
388      */
389     static function redirect($url, $code=302) {
390         Controller::curr()->redirect($url, $code);
391     }
392 
393     /**
394      * Tests whether a redirection has been requested.
395      * @return string If redirect() has been called, it will return the URL redirected to.  Otherwise, it will return null;
396      */
397     static function redirected_to() {
398         return Controller::curr()->redirectedTo();
399     }
400     
401     /**
402      * Sets the HTTP status code
403      */
404     static function set_status_code($code) {
405         return Controller::curr()->getResponse()->setStatusCode($code);
406     }
407     
408     /**
409      * Returns the current HTTP status code
410      */
411     static function get_status_code() {
412         return Controller::curr()->getResponse()->getStatusCode();
413     }
414 
415     /**
416      * @deprecated 2.5 Use Controller->redirectBack()
417      */
418     static function redirectBack() {
419         Controller::curr()->redirectBack();
420     }
421 
422     /**
423      * Returns the root URL for the site.
424      * It will be automatically calculated unless it is overridden with {@link setBaseURL()}.
425      */
426     static function baseURL() {
427         if(self::$alternateBaseURL) return self::$alternateBaseURL;
428         else {
429             $base = BASE_URL;
430             if($base == '/' || $base == '/.' || $base == '\\') $baseURL = '/';
431             else $baseURL = $base . '/';
432             
433             if(defined('BASE_SCRIPT_URL')) return $baseURL . BASE_SCRIPT_URL;
434             else return $baseURL;
435         }
436     }
437     
438     /**
439      * Sets the root URL for the website.
440      * If the site isn't accessible from the URL you provide, weird things will happen.
441      */
442     static function setBaseURL($baseURL) {
443         self::$alternateBaseURL = $baseURL;
444     }
445 
446     /**
447      * Returns the root filesystem folder for the site.
448      * It will be automatically calculated unless it is overridden with {@link setBaseFolder()}.
449      */
450     static function baseFolder() {
451         if(self::$alternateBaseFolder) return self::$alternateBaseFolder;
452         else return BASE_PATH;
453     }
454 
455     /**
456      * Sets the root folder for the website.
457      * If the site isn't accessible from the folder you provide, weird things will happen.
458      */
459     static function setBaseFolder($baseFolder) {
460         self::$alternateBaseFolder = $baseFolder;
461     }
462 
463     /**
464      * Turns an absolute URL or folder into one that's relative to the root of the site.
465      * This is useful when turning a URL into a filesystem reference, or vice versa.
466      * 
467      * @todo Implement checking across http/https protocols
468      * 
469      * @param string $url Accepts both a URL or a filesystem path
470      * @return string Either a relative URL if the checks succeeded, or the original (possibly absolute) URL.
471      */
472     static function makeRelative($url) {
473         // Allow for the accidental inclusion of a // in the URL
474         $url = ereg_replace('([^:])//','\\1/',$url);
475         $url = trim($url);
476 
477         // Only bother comparing the URL to the absolute version if $url looks like a URL.
478         if(preg_match('/^https?[^:]*:\/\//',$url)) {
479             $base1 = self::absoluteBaseURL();
480             if(substr($url,0,strlen($base1)) == $base1) return substr($url,strlen($base1));
481             // Convert http://www.mydomain.com/mysitedir to ''
482             else if(substr($base1,-1)=="/" && $url == substr($base1,0,-1)) return "";
483         }
484         
485         // test for base folder, e.g. /var/www
486         $base2 = self::baseFolder();
487         if(substr($url,0,strlen($base2)) == $base2) return substr($url,strlen($base2));
488 
489         // Test for relative base url, e.g. mywebsite/ if the full URL is http://localhost/mywebsite/
490         $base3 = self::baseURL();
491         if(substr($url,0,strlen($base3)) == $base3) return substr($url,strlen($base3));
492         
493         // Nothing matched, fall back to returning the original URL
494         return $url;
495     }
496     
497     /**
498      * Returns true if a given path is absolute. Works under both *nix and windows
499      * systems
500      *
501      * @param string $path
502      * @return bool
503      */
504     public static function is_absolute($path) {
505         if($path[0] == '/' || $path[0] == '\\') return true;
506         return preg_match('/^[a-zA-Z]:[\\\\\/]/', $path) == 1;
507     }
508     
509     /**
510      * Checks if a given URL is absolute (e.g. starts with 'http://' etc.).
511      * 
512      * @param string $url
513      * @return boolean
514      */
515     public static function is_absolute_url($url) {
516         $url = trim($url);
517         // remove all query strings to avoid parse_url choking on URLs like 'test.com?url=http://test.com'
518         $url = preg_replace('/(.*)\?.*/', '$1', $url);
519         $parsed = parse_url($url);
520         return (isset($parsed['scheme']));
521     }
522     
523     /**
524      * Checks if a given URL is relative by checking
525      * {@link is_absolute_url()}.
526      * 
527      * @param string $url
528      * @return boolean
529      */
530     public static function is_relative_url($url) {
531         return (!Director::is_absolute_url($url));
532     }
533     
534     /**
535      * Checks if the given URL is belonging to this "site",
536      * as defined by {@link makeRelative()} and {@link absoluteBaseUrl()}.
537      * Useful to check before redirecting based on a URL from user submissions
538      * through $_GET or $_POST, and avoid phishing attacks by redirecting
539      * to an attackers server.
540      * 
541      * @param string $url
542      * @return boolean
543      */
544     public static function is_site_url($url) {
545         $relativeUrl = Director::makeRelative($url);
546         return (bool)self::is_relative_url($relativeUrl);
547     }
548     
549     /**
550      * Given a filesystem reference relative to the site root, return the full file-system path.
551      * 
552      * @param string $file
553      * @return string
554      */
555     public static function getAbsFile($file) {
556         return self::is_absolute($file) ? $file : Director::baseFolder() . '/' . $file;
557     }
558     
559     /**
560      * Returns true if the given file exists.
561      * @param $file Filename specified relative to the site root
562      */
563     static function fileExists($file) {
564         // replace any appended query-strings, e.g. /path/to/foo.php?bar=1 to /path/to/foo.php
565         $file = preg_replace('/([^\?]*)?.*/','$1',$file);
566         return file_exists(Director::getAbsFile($file));
567     }
568 
569     /**
570      * Returns the Absolute URL of the site root.
571      */
572      static function absoluteBaseURL() {
573              if(Object::has_extension('SiteTree', 'SiteTreeSubsites')){
574                 return Director::absoluteURL('/');
575              }
576              return Director::absoluteURL(Director::baseURL());
577      }
578      
579     /**
580      * Returns the Absolute URL of the site root, embedding the current basic-auth credentials into the URL.
581      */
582      static function absoluteBaseURLWithAuth() {
583         $s = "";
584         $login = "";
585         
586         if(isset($_SERVER['PHP_AUTH_USER'])) $login = "$_SERVER[PHP_AUTH_USER]:$_SERVER[PHP_AUTH_PW]@";
587         if(isset($_SERVER['SSL']) && $_SERVER['SSL'] != 'Off') $s = "s";
588         
589         return "http$s://" . $login .  $_SERVER['HTTP_HOST'] . Director::baseURL();
590      }
591 
592     /**
593      * Force the site to run on SSL.  To use, call from _config.php.
594      * 
595      * For example:
596      * <code>
597      * if(Director::isLive()) Director::forceSSL();
598      * </code>
599      */
600     static function forceSSL() {
601         if((!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] == 'off') && !Director::isDev() && !Director::is_cli()) {
602             $destURL = str_replace('http:', 'https:', Director::absoluteURL($_SERVER['REQUEST_URI']));
603 
604             header("Location: $destURL", true, 301);
605             die("<h1>Your browser is not accepting header redirects</h1><p>Please <a href=\"$destURL\">click here</a>");
606         }
607     }
608 
609     /**
610      * Force a redirect to a domain starting with "www."
611      */
612     static function forceWWW() {
613         if(!Director::isDev() && !Director::isTest() && strpos($_SERVER['HTTP_HOST'], 'www') !== 0) {
614             if(isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') {
615                 $destURL = str_replace('https://', 'https://www.', Director::absoluteURL($_SERVER['REQUEST_URI']));
616             } else {
617                 $destURL = str_replace('http://', 'http://www.', Director::absoluteURL($_SERVER['REQUEST_URI']));
618             }
619 
620             header("Location: $destURL", true, 301);
621             die("<h1>Your browser is not accepting header redirects</h1><p>Please <a href=\"$destURL\">click here</a>");
622         }
623     }
624 
625     /**
626      * Checks if the current HTTP-Request is an "Ajax-Request"
627      * by checking for a custom header set by prototype.js or
628      * wether a manually set request-parameter 'ajax' is present.
629      *
630      * @return boolean
631      */
632     static function is_ajax() {
633         if(Controller::has_curr()) {
634             return Controller::curr()->isAjax();
635         } else {
636             return (
637                 isset($_REQUEST['ajax']) ||
638                 (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] == "XMLHttpRequest")
639             );
640         }
641     }
642     
643     /**
644      * Returns true if this script is being run from the command line rather than the webserver.
645      * 
646      * @return boolean
647      */
648     public static function is_cli() {
649         return (php_sapi_name() == "cli");
650     }
651 
652     ////////////////////////////////////////////////////////////////////////////////////////////
653     // Site mode methods
654     ////////////////////////////////////////////////////////////////////////////////////////////
655 
656     /**
657      * @deprecated 2.4
658      */
659     static function set_site_mode($mode) {
660         user_error (
661             'Director::set_site_mode() is deprecated as the functionality is no longer neccesary.', E_USER_NOTICE
662         );
663         
664         Director::$siteMode = $mode;
665         
666         if(isset(self::$callbacks[$mode])) {
667             foreach(self::$callbacks[$mode] as $extension) {
668                 call_user_func($extension);
669             }
670         }
671     }
672     
673     /**
674      * @deprecated 2.4
675      */
676     static function get_site_mode() {
677         user_error (
678             'Director::set_site_mode() is deprecated as the functionality is no longer neccesary.', E_USER_NOTICE
679         );
680         
681         return Director::$siteMode;
682     }
683 
684     /**
685      * @deprecated 2.4 Use a custom extension on your controller.
686      */
687     static function add_callback($function, $mode = 'site') {
688         user_error (
689             'Director::add_callback() is deprecated, please use a custom extension on your controller', E_USER_NOTICE
690         );
691         
692         self::$callbacks[$mode][] = $function;
693     }
694 
695     ////////////////////////////////////////////////////////////////////////////////////////////
696     // Environment type methods
697     ////////////////////////////////////////////////////////////////////////////////////////////
698 
699     /**
700      * Set the environment type of the current site.
701      *
702      * Typically, a SilverStripe site have a number of environments: 
703      *  - development environments, such a copy on your local machine.
704      *  - test sites, such as the one you show the client before going live.
705      *  - the live site itself.
706      * 
707      * The behaviour of these environments often varies slightly.  For example, development sites may have errors dumped to the screen,
708      * and order confirmation emails might be sent to the developer instead of the client.
709      * 
710      * To help with this, Sapphire support the notion of an environment type.  The environment type can be dev, test, or live.
711      * 
712      * You can set it explicitly with Director::set_environment_tpye().  Or you can use {@link Director::set_dev_servers()} and {@link Director::set_test_servers()}
713      * to set it implicitly, based on the value of $_SERVER['HTTP_HOST'].  If the HTTP_HOST value is one of the servers listed, then
714      * the environment type will be test or dev.  Otherwise, the environment type will be live.
715      *
716      * 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
717      * mode for the remainder of the session. Putting ?isDev=0 onto the URL can turn it back.
718      * 
719      * 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
720      * mode for the remainder of the session. Putting ?isTest=0 onto the URL can turn it back.
721      * 
722      * Generally speaking, these methods will be called from your _config.php file.
723      * 
724      * Once the environment type is set, it can be checked with {@link Director::isDev()}, {@link Director::isTest()}, and
725      * {@link Director::isLive()}.
726      * 
727      * @param $et string The environment type: dev, test, or live.
728      */
729     static function set_environment_type($et) {
730         if($et != 'dev' && $et != 'test' && $et != 'live') {
731             SS_Backtrace::backtrace();
732             user_error("Director::set_environment_type passed '$et'.  It should be passed dev, test, or live", E_USER_WARNING);
733         } else {
734             self::$environment_type = $et;
735         }
736     }
737     
738     /**
739      * Can also be checked with {@link Director::isDev()}, {@link Director::isTest()}, and {@link Director::isLive()}.
740      * 
741      * @return string 'dev', 'test' or 'live'
742      */
743     static function get_environment_type() {
744         if(Director::isLive()) {
745             return 'live';
746         } elseif(Director::isTest()) {
747             return 'test';
748         } elseif(Director::isDev()) {
749             return 'dev';
750         } else {
751             return false;
752         }
753     }
754 
755     /**
756      * Specify HTTP_HOST values that are development environments.
757      * For information about environment types, see {@link Director::set_environment_type()}.
758      * @param $servers array An array of HTTP_HOST values that should be treated as development environments.
759      */
760     static function set_dev_servers($servers) {
761         Director::$dev_servers = $servers;
762     }
763     
764     /**
765      * Specify HTTP_HOST values that are test environments.
766      * For information about environment types, see {@link Director::set_environment_type()}.
767      * @param $servers array An array of HTTP_HOST values that should be treated as test environments.
768      */
769     static function set_test_servers($servers) {
770         Director::$test_servers = $servers;
771     }
772 
773     /*
774      * This function will return true if the site is in a live environment.
775      * For information about environment types, see {@link Director::set_environment_type()}.
776      */
777     static function isLive() {
778         return !(Director::isDev() || Director::isTest());
779     }
780     
781     /**
782      * This function will return true if the site is in a development environment.
783      * For information about environment types, see {@link Director::set_environment_type()}.
784      */
785     static function isDev() {
786         // This variable is used to supress repetitions of the isDev security message below.
787         static $firstTimeCheckingGetVar = true;
788         
789         // Use ?isDev=1 to get development access on the live server
790         if (isset($_GET['isDev']) && $firstTimeCheckingGetVar) {
791             if(Security::database_is_ready()) {
792                 $firstTimeCheckingGetVar = false;
793                 if(!Permission::check('ADMIN')){
794                     BasicAuth::requireLogin("SilverStripe developer access. Use your CMS login", "ADMIN");
795                 }
796                 $_SESSION['isDev'] = $_GET['isDev'];
797             } 
798             elseif(DB::connection_attempted()) {
799                 $firstTimeCheckingGetVar = false;
800                 echo "<p style=\"padding: 3px; margin: 3px; background-color: orange; 
801                     color: white; font-weight: bold\">Sorry, you can't use ?isDev=1 until your
802                     Member and Group tables database are available.  Perhaps your database
803                     connection is failing?</p>";
804             }
805         }
806 
807         if(isset($_SESSION['isDev']) && $_SESSION['isDev']) return true;
808 
809         if(self::$environment_type) return self::$environment_type == 'dev';
810         
811         // Check if we are running on one of the development servers
812         if(isset($_SERVER['HTTP_HOST']) && in_array($_SERVER['HTTP_HOST'], Director::$dev_servers))  {
813             return true;
814         }
815         
816         return false;
817     }
818     
819     /**
820      * This function will return true if the site is in a test environment.
821      * For information about environment types, see {@link Director::set_environment_type()}.
822      */
823     static function isTest() {
824         // Use ?isTest=1 to get test access on the live server, or explicitly set your environment
825         if(isset($_GET['isTest'])) {
826             if(Security::database_is_ready()) {
827                 BasicAuth::requireLogin("SilverStripe developer access. Use your CMS login", "ADMIN");
828                 $_SESSION['isTest'] = $_GET['isTest'];
829             } else {
830                 return true;
831             }
832         }
833         if(self::isDev()) return false;
834         
835         if(self::$environment_type) {
836             return self::$environment_type == 'test';
837         }
838         
839         // Check if we are running on one of the test servers
840         if(isset($_SERVER['HTTP_HOST']) && in_array($_SERVER['HTTP_HOST'], Director::$test_servers))  {
841             return true;
842         }
843         
844         return false;
845     }
846 
847 }
848 ?>
849 
[Raise a SilverStripe Framework issue/bug](https://github.com/silverstripe/silverstripe-framework/issues/new)
- [Raise a SilverStripe CMS issue/bug](https://github.com/silverstripe/silverstripe-cms/issues/new)
- Please use the Silverstripe Forums to ask development related questions. -
Webylon 3.2 API Docs API documentation generated by ApiGen 2.8.0