2007-07-19 12:40:28 +02:00
< ? php
/**
* Base controller class .
* Controllers are the cornerstone of all site functionality in Sapphire . 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 .
2007-09-14 20:02:03 +02:00
*
2007-07-19 12:40:28 +02:00
* See { @ link getTemplate ()} for information on how the template is chosen .
2008-02-25 03:10:37 +01:00
* @ package sapphire
* @ subpackage control
2007-07-19 12:40:28 +02:00
*/
class Controller extends ViewableData {
2008-02-25 03:10:37 +01:00
/**
* Define a list of actions that are allowed to be called on this controller .
* The variable should be an array of action names . This sample shows the different values that it can contain :
*
* < code >
* array (
* 'someaction' , // someaction can be accessed by anyone, any time
* 'otheraction' => true , // So can otheraction
* 'restrictedaction' => 'ADMIN' , // restrictedaction can only be people with ADMIN privilege
* 'complexaction' '->canComplexAction' // complexaction can only be accessed if $this->canComplexAction() returns true
* );
* </ code >
*/
static $allowed_actions = null ;
2007-07-19 12:40:28 +02:00
protected $urlParams ;
protected $requestParams ;
protected $action ;
2007-08-17 07:45:15 +02:00
/**
* The { @ link Session } object for this controller
*/
protected $session ;
2007-07-19 12:40:28 +02:00
2007-08-17 07:45:15 +02:00
/**
* Stack of current controllers .
* Controller :: $controller_stack [ 0 ] is the current controller .
*/
protected static $controller_stack = array ();
2007-07-19 12:40:28 +02:00
protected $basicAuthEnabled = true ;
2007-08-17 05:09:46 +02:00
/**
* The HTTPResponse object that the controller returns
*/
protected $response ;
2007-07-19 12:40:28 +02:00
function setURLParams ( $urlParams ) {
$this -> urlParams = $urlParams ;
}
2007-08-21 01:22:30 +02:00
/**
2008-02-25 03:10:37 +01:00
* @ return array The parameters extracted from the URL by the { @ link Director } .
2007-08-21 01:22:30 +02:00
*/
2007-07-19 12:40:28 +02:00
function getURLParams () {
return $this -> urlParams ;
}
2007-12-02 22:29:31 +01:00
/**
* Returns the HTTPResponse object that this controller is building up .
* Can be used to set the status code and headers
*/
function getResponse () {
return $this -> response ;
}
2007-09-14 20:02:03 +02:00
2008-03-03 00:24:10 +01:00
protected $baseInitCalled = false ;
2007-07-19 12:40:28 +02:00
/**
2008-02-25 03:10:37 +01:00
* Executes this controller , and return an { @ link 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 ()}
*
* Then it looks for the action method . The action is taken from $this -> urlParams [ 'Action' ] - for this reason , it ' s important
* to have $Action included in your Director rule
*
* If $requestParams [ 'executeForm' ] is set , then the Controller assumes that we ' re processing a form . This is usually
* set by adding ? executeForm = XXX to the form ' s action URL . Form processing differs in the following ways :
* - The action name will be the name of the button clicked . If no button - click can be detected , the first button in the
* list will be assumed .
* - If the given action method doesn ' t exist on the controller , Controller will look for that method on the Form object .
* this lets developers package both a form and its action handlers in a single subclass of Form .
*
* 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 ()} .
*
2007-07-19 12:40:28 +02:00
* Execute the appropriate action handler . If none is given , use defaultAction to display
* a template . The default action will be appropriate in most cases where displaying data
* is the core goal ; the Viewer can call methods on the controller to get the data it needs .
2007-08-21 01:22:30 +02:00
*
2007-07-19 12:40:28 +02:00
* @ param array $requestParams GET and POST variables .
2007-08-21 01:22:30 +02:00
* @ return HTTPResponse The response that this controller produces , including HTTP headers such as redirection info
2007-07-19 12:40:28 +02:00
*/
function run ( $requestParams ) {
if ( isset ( $_GET [ 'debug_profile' ])) Profiler :: mark ( " Controller " , " run " );
2007-08-17 07:45:15 +02:00
$this -> pushCurrent ();
2007-08-17 05:09:46 +02:00
$this -> response = new HTTPResponse ();
2007-07-19 12:40:28 +02:00
$this -> requestParams = $requestParams ;
2007-08-17 05:09:46 +02:00
2008-04-26 08:52:49 +02:00
$this -> action = isset ( $this -> urlParams [ 'Action' ]) ? str_replace ( " - " , " _ " , $this -> urlParams [ 'Action' ]) : " " ;
2008-02-25 03:10:37 +01:00
if ( ! $this -> action ) $this -> action = 'index' ;
// Check security on the controller
if ( ! $this -> checkAccessAction ( $this -> action )) {
user_error ( " Disallowed action: ' $this->action ' on controller ' $this->class ' " , E_USER_ERROR );
}
2007-07-19 12:40:28 +02:00
// Init
$this -> baseInitCalled = false ;
$this -> init ();
if ( ! $this -> baseInitCalled ) user_error ( " init() method on class ' $this->class ' doesn't call Controller::init(). Make sure that you have parent::init() included. " , E_USER_WARNING );
2007-08-17 05:09:46 +02:00
// If we had a redirection or something, halt processing.
2007-08-17 07:45:15 +02:00
if ( $this -> response -> isFinished ()) {
$this -> popCurrent ();
return $this -> response ;
}
2007-07-19 12:40:28 +02:00
// Look at the action variables for forms
2007-09-14 20:02:03 +02:00
$funcName = null ;
2007-07-19 12:40:28 +02:00
foreach ( $this -> requestParams as $paramName => $paramVal ) {
if ( substr ( $paramName , 0 , 7 ) == 'action_' ) {
// Cleanup action_, _x and _y from image fields
$funcName = preg_replace ( array ( '/^action_/' , '/_x$|_y$/' ), '' , $paramName );
break ;
}
}
// Form handler
if ( isset ( $this -> requestParams [ 'executeForm' ]) && is_string ( $this -> requestParams [ 'executeForm' ])) {
if ( isset ( $funcName )) {
Form :: set_current_action ( $funcName );
}
2008-03-03 09:48:52 +01:00
$formOwner = $this -> getFormOwner ();
2007-07-19 12:40:28 +02:00
// Create the form object
2008-03-03 09:48:52 +01:00
$form = $formOwner ;
2008-02-25 03:10:37 +01:00
2007-07-19 12:40:28 +02:00
$formObjParts = explode ( '.' , $this -> requestParams [ 'executeForm' ]);
foreach ( $formObjParts as $formMethod ){
if ( isset ( $_GET [ 'debug_profile' ])) Profiler :: mark ( " Calling $formMethod " , " on $form->class " );
$form = $form -> $formMethod ();
if ( isset ( $_GET [ 'debug_profile' ])) Profiler :: unmark ( " Calling $formMethod " , " on $form->class " );
if ( ! $form ) break ; //user_error("Form method '" . $this->requestParams['executeForm'] . "' returns null in controller class '$this->class' ($_SERVER[REQUEST_URI])", E_USER_ERROR);
}
2007-09-14 20:02:03 +02:00
2008-02-25 03:10:37 +01:00
2007-07-19 12:40:28 +02:00
// Populate the form
2007-09-14 20:02:03 +02:00
if ( isset ( $_GET [ 'debug_profile' ])) Profiler :: mark ( " Controller " , " populate form " );
2007-07-19 12:40:28 +02:00
if ( $form ){
$form -> loadDataFrom ( $this -> requestParams , true );
// disregard validation if a single field is called
2007-08-23 07:47:54 +02:00
2007-07-19 12:40:28 +02:00
if ( ! isset ( $_REQUEST [ 'action_callfieldmethod' ])) {
$valid = $form -> beforeProcessing ();
2007-08-17 07:45:15 +02:00
if ( ! $valid ) {
$this -> popCurrent ();
return $this -> response ;
}
2007-08-23 07:47:54 +02:00
} else {
$fieldcaller = $form -> dataFieldByName ( $requestParams [ 'fieldName' ]);
if ( is_a ( $fieldcaller , " TableListField " )){
if ( $fieldcaller -> hasMethod ( 'php' )){
$valid = $fieldcaller -> php ( $requestParams );
if ( ! $valid ) exit ();
}
}
2007-07-19 12:40:28 +02:00
}
// If the action wasnt' set, choose the default on the form.
if ( ! isset ( $funcName ) && $defaultAction = $form -> defaultAction ()){
$funcName = $defaultAction -> actionName ();
}
if ( isset ( $funcName )) {
$form -> setButtonClicked ( $funcName );
}
} else {
2008-03-03 09:48:52 +01:00
user_error ( " No form ( " . Session :: get ( 'CMSMain.currentPage' ) . " ) returned by $formOwner->class -> $_REQUEST[executeForm] " , E_USER_WARNING );
2007-07-19 12:40:28 +02:00
}
if ( isset ( $_GET [ 'debug_profile' ])) Profiler :: unmark ( " Controller " , " populate form " );
if ( ! isset ( $funcName )) {
user_error ( " No action button has been clicked in this form executon, and no default has been allowed " , E_USER_ERROR );
}
2007-10-26 04:23:55 +02:00
// Protection against CSRF attacks
2007-10-28 22:44:38 +01:00
if ( $form -> securityTokenEnabled ()) {
2007-10-26 04:23:55 +02:00
$securityID = Session :: get ( 'SecurityID' );
if ( ! $securityID || ! isset ( $this -> requestParams [ 'SecurityID' ]) || $securityID != $this -> requestParams [ 'SecurityID' ]) {
2007-12-02 22:23:19 +01:00
// Don't show error on live sites, as spammers create a million of these
2008-04-26 08:49:14 +02:00
if ( ! Director :: isLive ()) {
2007-12-02 22:23:19 +01:00
trigger_error ( " Security ID doesn't match, possible CRSF attack. " , E_USER_ERROR );
} else {
die ();
}
2007-10-26 04:23:55 +02:00
}
}
2007-07-19 12:40:28 +02:00
2007-09-14 20:02:03 +02:00
2007-07-19 12:40:28 +02:00
// First, try a handler method on the controller
if ( $this -> hasMethod ( $funcName ) || ! $form ) {
if ( isset ( $_GET [ 'debug_controller' ])){
Debug :: show ( " Found function $funcName on the controller " );
}
2007-09-14 20:02:03 +02:00
if ( isset ( $_GET [ 'debug_profile' ])) Profiler :: mark ( " $this->class :: $funcName (controller action) " );
2007-07-19 12:40:28 +02:00
$result = $this -> $funcName ( $this -> requestParams , $form );
2007-09-14 20:02:03 +02:00
if ( isset ( $_GET [ 'debug_profile' ])) Profiler :: unmark ( " $this->class :: $funcName (controller action) " );
2008-03-03 09:48:52 +01:00
} else if ( isset ( $formOwner ) && $formOwner -> hasMethod ( $funcName )) {
$result = $formOwner -> $funcName ( $this -> requestParams , $form );
2007-09-14 20:02:03 +02:00
2007-07-19 12:40:28 +02:00
// Otherwise, try a handler method on the form object
} else {
if ( isset ( $_GET [ 'debug_controller' ])) {
Debug :: show ( " Found function $funcName on the form object " );
}
2007-09-14 20:02:03 +02:00
if ( isset ( $_GET [ 'debug_profile' ])) Profiler :: mark ( " $form->class :: $funcName (form action) " );
2007-07-19 12:40:28 +02:00
$result = $form -> $funcName ( $this -> requestParams , $form );
2007-09-14 20:02:03 +02:00
if ( isset ( $_GET [ 'debug_profile' ])) Profiler :: unmark ( " $form->class :: $funcName (form action) " );
2007-07-19 12:40:28 +02:00
}
// Normal action
} else {
if ( ! isset ( $funcName )) $funcName = $this -> action ;
2007-08-16 08:27:55 +02:00
if ( $this -> hasMethod ( $funcName )) {
2007-07-19 12:40:28 +02:00
if ( isset ( $_GET [ 'debug_controller' ])) Debug :: show ( " Found function $funcName on the $this->class controller " );
if ( isset ( $_GET [ 'debug_profile' ])) Profiler :: mark ( " $this->class :: $funcName (controller action) " );
2007-08-17 05:09:46 +02:00
2007-07-19 12:40:28 +02:00
$result = $this -> $funcName ( $this -> urlParams );
if ( isset ( $_GET [ 'debug_profile' ])) Profiler :: unmark ( " $this->class :: $funcName (controller action) " );
2007-09-14 20:02:03 +02:00
2007-07-19 12:40:28 +02:00
} else {
if ( isset ( $_GET [ 'debug_controller' ])) Debug :: show ( " Running default action for $funcName on the $this->class controller " );
if ( isset ( $_GET [ 'debug_profile' ])) Profiler :: mark ( " Controller::defaultAction( $funcName ) " );
$result = $this -> defaultAction ( $funcName , $this -> urlParams );
2007-09-14 20:02:03 +02:00
if ( isset ( $_GET [ 'debug_profile' ])) Profiler :: unmark ( " Controller::defaultAction( $funcName ) " );
2007-07-19 12:40:28 +02:00
}
}
2007-09-14 20:02:03 +02:00
2007-07-19 12:40:28 +02:00
// If your controller function returns an array, then add that data to the
// default template
2007-09-14 20:02:03 +02:00
2007-07-19 12:40:28 +02:00
if ( is_array ( $result )) {
$extended = $this -> customise ( $result );
$viewer = $this -> getViewer ( $funcName );
2007-09-14 20:02:03 +02:00
2007-07-19 12:40:28 +02:00
$result = $viewer -> process ( $extended );
}
2007-08-17 05:09:46 +02:00
$this -> response -> setBody ( $result );
2007-07-19 12:40:28 +02:00
2007-08-17 05:09:46 +02:00
if ( $result ) ContentNegotiator :: process ( $this -> response );
2007-07-19 12:40:28 +02:00
// Set up HTTP cache headers
2007-08-17 05:09:46 +02:00
HTTP :: add_cache_headers ( $this -> response );
2007-07-19 12:40:28 +02:00
if ( isset ( $_GET [ 'debug_profile' ])) Profiler :: unmark ( " Controller " , " run " );
2007-08-17 05:09:46 +02:00
2007-08-17 07:45:15 +02:00
$this -> popCurrent ();
2007-08-17 05:09:46 +02:00
return $this -> response ;
2007-07-19 12:40:28 +02:00
}
2008-03-03 09:48:52 +01:00
/**
* 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 .
*/
function getFormOwner () {
// Get the appropraite ocntroller: sometimes we want to get a form from another controller
if ( isset ( $this -> requestParams [ 'formController' ])) {
$formController = Director :: getControllerForURL ( $this -> requestParams [ 'formController' ]);
while ( is_a ( $formController , 'NestedController' )) {
$formController = $formController -> getNestedController ();
}
return $formController ;
} else {
return $this ;
}
}
2007-07-19 12:40:28 +02:00
2008-03-03 00:24:10 +01:00
/**
* 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 ()}
*/
2007-07-19 12:40:28 +02:00
function defaultAction ( $action ) {
return $this -> getViewer ( $action ) -> process ( $this );
}
2007-09-14 20:02:03 +02:00
2008-03-03 00:24:10 +01:00
/**
* Returns the action that is being executed on this controller .
*/
2007-07-19 12:40:28 +02:00
function getAction () {
return $this -> action ;
}
2007-09-14 20:02:03 +02:00
2007-07-19 12:40:28 +02:00
/**
* Return an SSViewer object to process the data
2007-08-21 01:22:30 +02:00
* @ return SSViewer The viewer identified being the default handler for this Controller / Action combination
2007-07-19 12:40:28 +02:00
*/
function getViewer ( $action ) {
// Hard-coded templates
if ( $this -> templates [ $action ]) {
$templates = $this -> templates [ $action ];
} else if ( $this -> templates [ 'index' ]) {
$templates = $this -> templates [ 'index' ];
} else if ( $this -> template ) {
$templates = $this -> template ;
} else {
$parentClass = $this -> class ;
while ( $parentClass != " Controller " ) {
$templateName = $parentClass ;
if (( $pos = strpos ( $templateName , '_' )) !== false ) $templateName = substr ( $templateName , 0 , $pos );
if ( $action && $action != " index " ) $templates [] = $templateName . '_' . $action ;
$templates [] = $templateName ;
2007-09-14 20:02:03 +02:00
2007-07-19 12:40:28 +02:00
$parentClass = get_parent_class ( $parentClass );
}
$templates = array_unique ( $templates );
}
if ( isset ( $_GET [ 'showtemplate' ])) Debug :: show ( $templates );
return new SSViewer ( $templates );
}
/**
2008-03-03 00:24:10 +01:00
* Call this to disable basic authentication on test sites .
2007-07-19 12:40:28 +02:00
* must be called in the init () method
2008-03-03 00:24:10 +01:00
* @ deprecated Use BasicAuth :: disable () instead ? This is used in CliController - it should be updated .
2007-07-19 12:40:28 +02:00
*/
function disableBasicAuth () {
$this -> basicAuthEnabled = false ;
}
/**
* Initialisation function that is run before any action on the controller is called .
2008-04-09 13:17:39 +02:00
*
* @ uses BasicAuth :: requireLogin ()
2007-07-19 12:40:28 +02:00
*/
function init () {
// Test and development sites should be secured, via basic-auth
2007-10-02 06:56:43 +02:00
if ( ClassInfo :: hasTable ( " Group " ) && ClassInfo :: hasTable ( " Member " ) && Director :: isTest () && $this -> basicAuthEnabled ) {
2007-07-19 12:40:28 +02:00
BasicAuth :: requireLogin ( " SilverStripe test website. Use your CMS login " , " ADMIN " );
}
//
Cookie :: set ( " PastVisitor " , true );
2007-10-02 06:56:43 +02:00
// ClassInfo::hasTable() called to ensure that we're not in a very-first-setup stage
if ( ClassInfo :: hasTable ( " Group " ) && ClassInfo :: hasTable ( " Member " ) && ( $member = Member :: currentUser ())) {
2007-07-19 12:40:28 +02:00
Cookie :: set ( " PastMember " , true );
DB :: query ( " UPDATE Member SET LastVisited = NOW() WHERE ID = $member->ID " , null );
}
// This is used to test that subordinate controllers are actually calling parent::init() - a common bug
$this -> baseInitCalled = true ;
}
2007-08-21 01:22:30 +02:00
/**
2008-02-25 03:10:37 +01:00
* @ deprecated use Controller :: curr () instead
2007-08-21 01:22:30 +02:00
* @ returns Controller
*/
2007-07-19 12:40:28 +02:00
public static function currentController () {
2008-02-25 03:10:37 +01:00
user_error ( 'Controller::currentController() is deprecated. Use Controller::curr() instead.' , E_USER_NOTICE );
2007-08-17 07:45:15 +02:00
return self :: curr ();
2007-07-19 12:40:28 +02:00
}
2007-08-17 05:09:46 +02:00
/**
* Returns the current controller
2007-08-21 01:22:30 +02:00
* @ returns Controller
2007-08-17 05:09:46 +02:00
*/
public static function curr () {
2007-08-17 07:45:15 +02:00
if ( Controller :: $controller_stack ) {
return Controller :: $controller_stack [ 0 ];
} else {
user_error ( " No current controller available " , E_USER_WARNING );
}
2007-08-17 05:09:46 +02:00
}
2007-08-21 00:39:44 +02:00
/**
* Tests whether we have a currently active controller or not
2007-08-21 01:22:30 +02:00
* @ return boolean True if there is at least 1 controller in the stack .
2007-08-21 00:39:44 +02:00
*/
public static function has_curr () {
return Controller :: $controller_stack ? true : false ;
}
2007-07-19 12:40:28 +02:00
/**
* 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
* in user .
2007-08-21 01:22:30 +02:00
* @ return boolean
2008-03-03 00:24:10 +01:00
* @ deprecated I don ' t believe that the system has widespread use / support of this .
2007-07-19 12:40:28 +02:00
*/
function can ( $perm , $member = null ) {
if ( ! $member ) $member = Member :: currentUser ();
if ( $this -> hasMethod ( $methodName = 'can' . $perm )) {
return $this -> $methodName ( $member );
} else {
return true ;
}
}
2007-09-14 20:02:03 +02:00
2007-07-19 12:40:28 +02:00
//-----------------------------------------------------------------------------------
2007-09-14 20:02:03 +02:00
2007-07-19 12:40:28 +02:00
/**
* returns a date object for use within a template
* Usage : $Now . Year - Returns 2006
2007-08-21 01:22:30 +02:00
* @ return Date The current date
2007-07-19 12:40:28 +02:00
*/
function Now () {
$d = new Date ( null );
$d -> setVal ( date ( " Y-m-d h:i:s " ));
return $d ;
}
2007-09-14 20:02:03 +02:00
2007-07-19 12:40:28 +02:00
/**
* Returns a link to any other page
2008-03-03 00:24:10 +01:00
* @ deprecated It ' s unclear what value this has ; construct a link manually or use your own custom link - gen functions .
2007-07-19 12:40:28 +02:00
*/
function LinkTo ( $a , $b ) {
return Director :: baseURL () . $a . '/' . $b ;
}
2007-09-14 20:02:03 +02:00
2008-03-03 00:24:10 +01:00
/**
* Returns an absolute link to this controller
*/
2007-07-19 12:40:28 +02:00
function AbsoluteLink () {
return Director :: absoluteURL ( $this -> Link ());
}
2007-09-14 20:02:03 +02:00
2007-07-19 12:40:28 +02:00
/**
* Returns the currently logged in user
*/
function CurrentMember () {
return Member :: currentUser ();
}
2007-09-14 20:02:03 +02:00
2007-07-19 12:40:28 +02:00
/**
* Returns true if the visitor has been here before
2007-08-21 01:22:30 +02:00
* @ return boolean
2007-07-19 12:40:28 +02:00
*/
function PastVisitor () {
return Cookie :: get ( " PastVisitor " ) ? true : false ;
}
2007-09-14 20:02:03 +02:00
2007-07-19 12:40:28 +02:00
/**
* Return true if the visitor has signed up for a login account before
2007-08-21 01:22:30 +02:00
* @ return boolean
2007-07-19 12:40:28 +02:00
*/
function PastMember () {
return Cookie :: get ( " PastMember " ) ? true : false ;
}
2007-08-17 07:45:15 +02:00
/**
* 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 .
*/
function pushCurrent () {
array_unshift ( self :: $controller_stack , $this );
// Create a new session object
2007-08-18 01:11:43 +02:00
if ( ! $this -> session ) {
2007-10-02 06:33:18 +02:00
if ( isset ( self :: $controller_stack [ 1 ])) {
$this -> session = self :: $controller_stack [ 1 ] -> getSession ();
} else {
$this -> session = new Session ( null );
}
2007-08-18 01:11:43 +02:00
}
2007-08-17 07:45:15 +02:00
}
/**
* Pop this controller off the top of the stack .
*/
function popCurrent () {
2007-08-18 01:31:51 +02:00
if ( $this === self :: $controller_stack [ 0 ]) {
2007-08-17 07:45:15 +02:00
array_shift ( self :: $controller_stack );
} else {
2007-08-18 01:14:30 +02:00
user_error ( " popCurrent called on $this->class controller, but it wasn't at the top of the stack " , E_USER_WARNING );
2007-08-17 07:45:15 +02:00
}
}
2007-08-17 05:09:46 +02:00
/**
2008-03-03 00:24:10 +01:00
* Redirct to the given URL .
* It is generally recommended to call Director :: redirect () rather than calling this function directly .
2007-08-17 05:09:46 +02:00
*/
2008-04-22 03:45:55 +02:00
function redirect ( $url , $code = 302 ) {
2008-02-25 03:10:37 +01:00
if ( $this -> response -> getHeader ( 'Location' )) {
2008-04-26 08:53:13 +02:00
user_error ( " Already directed to " . $this -> response -> getHeader ( 'Location' ) . " ; now trying to direct to $url " , E_USER_WARNING );
return ;
2008-02-25 03:10:37 +01:00
}
2007-08-17 05:09:46 +02:00
// Attach site-root to relative links, if they have a slash in them
2007-08-28 04:49:31 +02:00
if ( $url == " " || $url [ 0 ] == '?' || ( substr ( $url , 0 , 4 ) != " http " && $url [ 0 ] != " / " && strpos ( $url , '/' ) !== false )){
2007-08-17 05:09:46 +02:00
$url = Director :: baseURL () . $url ;
}
2008-04-22 03:45:55 +02:00
$this -> response -> redirect ( $url , $code );
2007-08-17 05:09:46 +02:00
}
2007-08-17 07:45:15 +02:00
2007-08-31 02:26:41 +02:00
/**
* 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 ;
*/
function redirectedTo () {
return $this -> response -> getHeader ( 'Location' );
}
2007-08-17 07:45:15 +02:00
/**
* Get the Session object representing this Controller ' s session
2007-08-21 01:22:30 +02:00
* @ return Session
2007-08-17 07:45:15 +02:00
*/
function getSession () {
return $this -> session ;
}
/**
* Set the Session object .
*/
function setSession ( Session $session ) {
$this -> session = $session ;
}
2007-08-21 00:39:44 +02:00
/**
* Returns true if this controller is processing an ajax request
2007-08-21 01:22:30 +02:00
* @ return boolean True if this controller is processing an ajax request
2007-08-21 00:39:44 +02:00
*/
function isAjax () {
return (
isset ( $this -> requestParams [ 'ajax' ]) ||
( isset ( $_SERVER [ 'HTTP_X_REQUESTED_WITH' ]) && $_SERVER [ 'HTTP_X_REQUESTED_WITH' ] == " XMLHttpRequest " )
);
}
2008-02-25 03:10:37 +01:00
/**
2008-03-03 00:24:10 +01:00
* Check that the given action is allowed to be called on this controller .
* This method is called by run () and makes use of { @ link self :: $allowed_actions } .
2008-02-25 03:10:37 +01:00
*/
function checkAccessAction ( $action ) {
2008-04-26 08:52:49 +02:00
$action = strtolower ( $action );
2008-02-25 03:10:37 +01:00
// Collate self::$allowed_actions from this class and all parent classes
$access = null ;
$className = $this -> class ;
while ( $className != 'Controller' ) {
// Merge any non-null parts onto $access.
$accessPart = eval ( " return $className :: \$ allowed_actions; " );
if ( $accessPart !== null ) $access = array_merge (( array ) $access , $accessPart );
// Build an array of parts for checking if part[0] == part[1], which means that this class doesn't directly define it.
$accessParts [] = $accessPart ;
$className = get_parent_class ( $className );
}
2008-03-11 02:30:19 +01:00
// Add $allowed_actions from extensions
if ( $this -> extension_instances ) {
foreach ( $this -> extension_instances as $inst ) {
$accessPart = $inst -> stat ( 'allowed_actions' );
if ( $accessPart !== null ) $access = array_merge (( array ) $access , $accessPart );
}
}
2008-03-11 02:31:24 +01:00
if ( $access === null || ( isset ( $accessParts [ 1 ]) && $accessParts [ 0 ] === $accessParts [ 1 ])) {
2008-02-25 03:10:37 +01:00
// user_error("Deprecated: please define static \$allowed_actions on your Controllers for security purposes", E_USER_NOTICE);
return true ;
}
if ( $action == 'index' ) return true ;
if ( isset ( $access [ $action ])) {
$test = $access [ $action ];
if ( $test === true ) return true ;
if ( substr ( $test , 0 , 2 ) == '->' ) {
$funcName = substr ( $test , 2 );
return $this -> $funcName ();
}
if ( Permission :: check ( $test )) return true ;
} else if ((( $key = array_search ( $action , $access )) !== false ) && is_numeric ( $key )) {
return true ;
}
return false ;
}
2007-07-19 12:40:28 +02:00
}
?>