2007-07-19 12:40:28 +02:00
< ? php
2008-02-25 03:10:37 +01:00
/**
* @ package sapphire
* @ subpackage control
*/
2007-07-19 12:40:28 +02:00
/**
2008-03-03 00:24:10 +01:00
* The most common kind of controller ; effectively a controller linked to a { @ link DataObject } .
2007-07-19 12:40:28 +02:00
*
* ContentControllers are most useful in the content - focused areas of a site . This is generally
* the bulk of a site ; however , they may be less appropriate in , for example , the user management
* section of an application .
*
* On its own , content controller does very little . Its constructor is passed a { @ link DataObject }
2007-09-14 21:10:18 +02:00
* which is stored in $this -> dataRecord . Any unrecognised method calls , for example , Title ()
* and Content (), will be passed along to the data record ,
*
2007-07-19 12:40:28 +02:00
* Subclasses of ContentController are generally instantiated by ModelAsController ; this will create
* a controller based on the URLSegment action variable , by looking in the SiteTree table .
2008-03-03 00:24:10 +01:00
*
* @ todo Can this be used for anything other than SiteTree controllers ?
2008-02-25 03:10:37 +01:00
*
* @ package sapphire
* @ subpackage control
2007-07-19 12:40:28 +02:00
*/
class ContentController extends Controller {
protected $dataRecord ;
/**
* The ContentController will take the URLSegment parameter from the URL and use that to look
* up a SiteTree record .
*/
public function __construct ( $dataRecord ) {
$this -> dataRecord = $dataRecord ;
$this -> failover = $this -> dataRecord ;
parent :: __construct ();
}
2007-09-14 21:10:18 +02:00
2007-07-19 12:40:28 +02:00
public function Link ( $action = null ) {
return Director :: baseURL () . $this -> RelativeLink ( $action );
}
public function RelativeLink ( $action = null ) {
if ( $this -> URLSegment ){
if ( $action == " index " ) $action = " " ;
2007-09-14 21:10:18 +02:00
2007-07-19 12:40:28 +02:00
// '&' in a URL is apparently naughty
2007-07-24 05:43:21 +02:00
$action = preg_replace ( '/&/' , '&' , $action );
2007-07-19 12:40:28 +02:00
return $this -> URLSegment . " / $action " ;
2007-09-08 05:18:26 +02:00
} else {
2007-07-19 12:40:28 +02:00
user_error ( " ContentController::RelativeLink() No URLSegment given on a ' $this->class ' object. Perhaps you should overload it? " , E_USER_WARNING );
}
}
2007-09-14 21:10:18 +02:00
2007-07-19 12:40:28 +02:00
//----------------------------------------------------------------------------------//
// These flexible data methods remove the need for custom code to do simple stuff
2007-09-14 21:10:18 +02:00
2007-07-19 12:40:28 +02:00
/*
* Return the children of the given page .
* $parentRef can be a page number or a URLSegment
*/
public function ChildrenOf ( $parentRef ) {
$SQL_parentRef = Convert :: raw2sql ( $parentRef );
$parent = DataObject :: get_one ( 'SiteTree' , " URLSegment = ' $SQL_parentRef ' " );
if ( ! $parent && is_numeric ( $parentRef )) $parent = DataObject :: get_by_id ( 'SiteTree' , $SQL_parentRef );
if ( $parent ) {
return $parent -> Children ();
} else {
user_error ( " Error running <% control ChildrenOf( $parentRef ) %>: page ' $parentRef ' couldn't be found " , E_USER_WARNING );
}
}
2007-09-14 21:10:18 +02:00
2007-07-19 12:40:28 +02:00
public function Page ( $url ) {
$SQL_url = Convert :: raw2sql ( $url );
return DataObject :: get_one ( 'SiteTree' , " URLSegment = ' $SQL_url ' " );
}
2007-09-14 21:10:18 +02:00
2007-07-19 12:40:28 +02:00
public function init () {
parent :: init ();
2007-08-16 08:27:32 +02:00
2007-09-16 17:37:33 +02:00
//Log page views
2007-10-25 02:37:09 +02:00
Statistics :: collect ();
2007-09-16 17:37:33 +02:00
2007-07-19 12:40:28 +02:00
// If we've accessed the homepage as /home/, then we should redirect to /.
2007-11-15 23:35:02 +01:00
if ( $this -> dataRecord && $this -> dataRecord instanceof SiteTree && RootURLController :: should_be_on_root ( $this -> dataRecord ) && ! $this -> urlParams [ 'Action' ] && ! $_POST && ! $_FILES ) {
2007-07-19 12:40:28 +02:00
$getVars = $_GET ;
unset ( $getVars [ 'url' ]);
2007-08-28 04:49:31 +02:00
if ( $getVars ) $url = " ? " . http_build_query ( $getVars );
else $url = " " ;
2007-07-19 12:40:28 +02:00
Director :: redirect ( $url );
2007-08-17 05:09:46 +02:00
return ;
2007-07-19 12:40:28 +02:00
}
2007-08-16 08:27:32 +02:00
singleton ( 'SiteTree' ) -> extend ( 'contentcontrollerInit' , $this );
2007-07-19 12:40:28 +02:00
Director :: set_site_mode ( 'site' );
2007-09-14 21:10:18 +02:00
2007-11-09 04:42:04 +01:00
// Check page permissions
2007-11-02 02:11:13 +01:00
if ( $this -> dataRecord && $this -> URLSegment != 'Security' && ! $this -> dataRecord -> can ( 'View' )) {
2007-10-02 06:40:08 +02:00
Security :: permissionFailure ( $this );
}
2007-11-09 04:42:04 +01:00
// Draft/Archive security check - only CMS users should be able to look at stage/archived content
if ( $this -> URLSegment != 'Security' && ( Versioned :: current_archived_date () || ( Versioned :: current_stage () && Versioned :: current_stage () != 'Live' ))) {
if ( ! Permission :: check ( 'CMS_ACCESS_CMSMain' )) {
$link = $this -> Link ();
$message = _t ( " ContentController.DRAFT_SITE_ACCESS_RESTRICTION " , " You must log in with your CMS password in order to view the draft or archived content. <a href= \" %s \" >Click here to go back to the published site.</a> " );
Security :: permissionFailure ( $this , sprintf ( $message , " $link ?stage=Live " ));
return ;
}
}
2007-07-20 06:05:51 +02:00
}
2007-09-14 21:10:18 +02:00
2007-07-20 06:05:51 +02:00
/**
* Get the project name
*
* @ return string
*/
function project () {
global $project ;
return $project ;
2007-07-19 12:40:28 +02:00
}
/**
* Returns the associated database record
*/
public function data () {
return $this -> dataRecord ;
}
2007-09-14 21:10:18 +02:00
2007-07-19 12:40:28 +02:00
/*--------------------------------------------------------------------------------*/
2007-09-14 21:10:18 +02:00
2007-07-19 12:40:28 +02:00
/**
* Returns a fixed navigation menu of the given level .
*/
public function getMenu ( $level ) {
if ( $level == 1 ) {
2007-07-24 05:43:21 +02:00
$result = DataObject :: get ( " SiteTree " , " ShowInMenus = 1 AND ParentID = 0 " );
2007-07-19 12:40:28 +02:00
} else {
$parent = $this -> data ();
$stack = array ( $parent );
2007-07-24 05:43:21 +02:00
while ( $parent = $parent -> Parent )
array_unshift ( $stack , $parent );
2007-07-19 12:40:28 +02:00
if ( isset ( $stack [ $level - 2 ]))
2007-07-24 05:43:21 +02:00
$result = $stack [ $level - 2 ] -> Children ();
2007-07-19 12:40:28 +02:00
}
2007-07-24 05:43:21 +02:00
$visible = array ();
// Remove all entries the can not be viewed by the current user
// We might need to create a show in menu permission
2007-12-13 23:31:58 +01:00
if ( isset ( $result )) {
2007-07-24 05:43:21 +02:00
foreach ( $result as $page ) {
if ( $page -> can ( 'view' )) {
$visible [] = $page ;
}
}
}
return new DataObjectSet ( $visible );
2007-07-19 12:40:28 +02:00
}
2007-09-14 21:10:18 +02:00
2007-07-19 12:40:28 +02:00
public function Menu ( $level ) {
return $this -> getMenu ( $level );
}
2007-09-14 21:10:18 +02:00
2007-07-19 12:40:28 +02:00
public function Section2 () {
return $this -> Level ( 2 ) -> URLSegment ;
}
2007-09-14 21:10:18 +02:00
2007-07-19 12:40:28 +02:00
/**
* Returns the default log - in form .
2007-09-14 21:10:18 +02:00
*
* @ todo Check if here should be returned just the default log - in form or
* all available log - in forms ( also OpenID ... )
*/
2007-07-19 12:40:28 +02:00
public function LoginForm () {
2007-09-16 03:48:38 +02:00
return MemberAuthenticator :: get_login_form ( $this );
2007-07-19 12:40:28 +02:00
}
2007-09-14 21:10:18 +02:00
2007-07-19 12:40:28 +02:00
public function SilverStripeNavigator () {
$member = Member :: currentUser ();
2007-09-14 21:10:18 +02:00
2007-11-09 04:42:04 +01:00
if ( Director :: isDev () || Permission :: check ( 'CMS_ACCESS_CMSMain' )) {
2007-07-19 12:40:28 +02:00
Requirements :: css ( 'sapphire/css/SilverStripeNavigator.css' );
Requirements :: javascript ( 'jsparty/behaviour.js' );
// Requirements::javascript('jsparty/prototype.js');
Requirements :: customScript ( <<< JS
Behaviour . register ({
'#switchView a' : {
onclick : function () {
var w = window . open ( this . href , windowName ( this . target ));
w . focus ();
return false ;
2007-09-14 21:10:18 +02:00
}
}
2007-07-19 12:40:28 +02:00
});
function windowName ( suffix ) {
var base = document . getElementsByTagName ( 'base' )[ 0 ] . href . replace ( 'http://' , '' ) . replace ( / \ //g,'_').replace(/\./g,'_');
return base + suffix ;
}
window . name = windowName ( 'site' );
JS
);
if ( $this -> dataRecord ){
$thisPage = $this -> dataRecord -> Link ();
$cmsLink = 'admin/show/' . $this -> dataRecord -> ID ;
$cmsLink = " <a href= \" $cmsLink\ " target = \ " cms \" >CMS</a> " ;
} else {
/**
* HGS : If this variable is missing a notice is raised . Subclasses of ContentController
* are required to implement RelativeLink anyway , so this should work even if the
* dataRecord isn ' t set .
*/
$thisPage = $this -> Link ();
$cmsLink = '' ;
}
2007-09-14 21:10:18 +02:00
2007-07-19 12:40:28 +02:00
$archiveLink = " " ;
2007-09-14 21:10:18 +02:00
2007-07-19 12:40:28 +02:00
if ( $date = Versioned :: current_archived_date ()) {
$dateObj = Object :: create ( 'Datetime' , $date , null );
// $dateObj->setVal($date);
$archiveLink = " <a class= \" current \" >Archived Site</a> " ;
$liveLink = " <a href= \" $thisPage ?stage=Live \" target= \" site \" style= \" left : -3px; \" >Published Site</a> " ;
$stageLink = " <a href= \" $thisPage ?stage=Stage \" target= \" site \" style= \" left : -1px; \" >Draft Site</a> " ;
2008-02-25 03:10:37 +01:00
$message = " <div id= \" SilverStripeNavigatorMessage \" title= \" Note: this message won't be shown to your visitors \" >Archived site from<br> " . $dateObj -> Nice () . " </div> " ;
2007-09-14 21:10:18 +02:00
2007-07-19 12:40:28 +02:00
} else if ( Versioned :: current_stage () == 'Stage' ) {
$stageLink = " <a class= \" current \" >Draft Site</a> " ;
$liveLink = " <a href= \" $thisPage ?stage=Live \" target= \" site \" style= \" left : -3px; \" >Published Site</a> " ;
2008-02-25 03:10:37 +01:00
$message = " <div id= \" SilverStripeNavigatorMessage \" title= \" Note: this message won't be shown to your visitors \" >DRAFT SITE</div> " ;
2007-07-19 12:40:28 +02:00
} else {
$liveLink = " <a class= \" current \" >Published Site</a> " ;
$stageLink = " <a href= \" $thisPage ?stage=Stage \" target= \" site \" style= \" left : -1px; \" >Draft Site</a> " ;
2008-02-25 03:10:37 +01:00
$message = " <div id= \" SilverStripeNavigatorMessage \" title= \" Note: this message won't be shown to your visitors \" >PUBLISHED SITE</div> " ;
2007-07-19 12:40:28 +02:00
}
2007-09-14 21:10:18 +02:00
2007-07-19 12:40:28 +02:00
if ( $member ) {
$firstname = Convert :: raw2xml ( $member -> FirstName );
$surname = Convert :: raw2xml ( $member -> Surame );
$logInMessage = " Logged in as { $firstname } { $surname } - <a href= \" Security/logout \" >log out</a> " ;
} else {
$logInMessage = " Not logged in - <a href= \" Security/login \" >log in</a> " ;
}
/**
* HGS : cmsLink is now only set if there is a dataRecord . You can ' t view the page in the
* CMS if there is no dataRecord
*/
return <<< HTML
< div id = " SilverStripeNavigator " >
< div class = " holder " >
< div id = " logInStatus " >
$logInMessage
</ div >
2007-09-14 21:10:18 +02:00
2007-07-19 12:40:28 +02:00
< div id = " switchView " class = " bottomTabs " >
< div class = " blank " > View page in : </ div >
$cmsLink
$stageLink
2007-09-15 02:26:21 +02:00
< div class = " blank " style = " width:1em; " > </ div >
2007-07-19 12:40:28 +02:00
$liveLink
$archiveLink
</ div >
</ div >
</ div >
$message
HTML ;
// On live sites we should still see the archived message
} else {
if ( $date = Versioned :: current_archived_date ()) {
Requirements :: css ( 'sapphire/css/SilverStripeNavigator.css' );
$dateObj = Object :: create ( 'Datetime' , $date , null );
// $dateObj->setVal($date);
return " <div id= \" SilverStripeNavigatorMessage \" >Archived site from<br> " . $dateObj -> Nice () . " </div> " ;
}
}
}
/**
* Returns a page comment system
*/
function PageComments () {
if ( $this -> data () -> ProvideComments ) {
return new PageCommentInterface ( $this , 'PageComments' , $this -> data ());
} else {
if ( isset ( $_REQUEST [ 'executeForm' ]) && $_REQUEST [ 'executeForm' ] == 'PageComments.PostCommentForm' ) {
echo " Comments have been disabled for this page " ;
die ();
}
}
}
2007-09-14 21:10:18 +02:00
2007-09-16 18:12:42 +02:00
/**
* Returns the xml : lang and lang attributes
*/
function LangAttributes () {
$lang = Translatable :: current_lang ();
return " xml:lang= \" $lang\ " lang = \ " $lang\ " " ;
}
2007-09-14 21:10:18 +02:00
2007-07-19 12:40:28 +02:00
/**
* Throw an error to test the error system
*/
function throwerror () {
user_error ( " This is a test of the error handler - nothing to worry about. " , E_USER_ERROR );
}
2007-09-14 21:10:18 +02:00
2007-07-19 12:40:28 +02:00
/**
* Throw a warning to test the error system
*/
function throwwarning () {
user_error ( " This is a test of the warning handler - nothing to worry about. " , E_USER_WARNING );
}
2007-09-16 03:48:38 +02:00
2007-07-19 12:40:28 +02:00
/**
* This action is called by the installation system
*/
function successfullyinstalled () {
2007-08-20 07:21:39 +02:00
// The manifest should be built by now, so it's safe to publish the 404 page
$fourohfour = Versioned :: get_one_by_stage ( 'ErrorPage' , 'Stage' , 'ErrorCode = 404' );
if ( $fourohfour ) {
$fourohfour -> Status = " Published " ;
$fourohfour -> write ();
$fourohfour -> publish ( " Stage " , " Live " );
}
2007-10-02 06:51:22 +02:00
if ( isset ( $_SESSION [ 'StatsID' ]) && $_SESSION [ 'StatsID' ]) {
$url = 'http://ss2stat.silverstripe.com/Installation/installed?ID=' . $_SESSION [ 'StatsID' ];
@ file_get_contents ( $url );
}
2007-07-19 12:40:28 +02:00
$title = new Varchar ( " Title " );
$content = new HTMLText ( " Content " );
$username = Session :: get ( 'username' );
$password = Session :: get ( 'password' );
$title -> setValue ( " Installation Successful " );
global $project ;
$tutorialOnly = ( $project == 'tutorial' ) ? " <p>This website is a simplistic version of a SilverStripe 2 site. To extend this, please take a look at <a href= \" http://doc.silverstripe.com/doku.php?id=tutorial:1-building-a-basic-site \" >our new tutorials</a>.</p> " : '' ;
$content -> setValue ( <<< HTML
< p style = " margin: 1em 0 " >< b > Congratulations , SilverStripe has been successfully installed .</ b ></ p >
$tutorialOnly
< p > You can start editing your site ' s content by opening < a href = " admin/ " > the CMS </ a >. < br />
& nbsp ; & nbsp ; Email : $username < br />
& nbsp ; & nbsp ; Password : $password < br />
</ p >
< div style = " background:#ddd; border:1px solid #ccc; padding:5px; margin:5px; " >< img src = " cms/images/dialogs/alert.gif " style = " border: none; margin-right: 10px; float: left; " />< p style = " color:red; " > For security reasons you should now delete the install files , unless you are planning to reinstall later . The web server also now only needs write access to the " assets " folder , you can remove write access from all other folders .</ p >
< div style = " margin-left: auto; margin-right: auto; width: 50%; " >< p >< a href = " home/deleteinstallfiles " style = " text-align: center; " > Click here to delete the install files .</ a ></ p ></ div ></ div >
HTML
);
2007-09-14 21:10:18 +02:00
2007-07-19 12:40:28 +02:00
return array (
" Title " => $title ,
" Content " => $content ,
);
}
2007-09-14 21:10:18 +02:00
2007-07-19 12:40:28 +02:00
function deleteinstallfiles () {
$title = new Varchar ( " Title " );
$content = new HTMLText ( " Content " );
$tempcontent = '' ;
$username = Session :: get ( 'username' );
$password = Session :: get ( 'password' );
2007-09-16 03:48:38 +02:00
2007-07-19 12:40:28 +02:00
$installfiles = array (
'index.php' ,
'install.php' ,
'rewritetest.php' ,
'check-php.php' ,
'config-form.css' ,
'config-form.html' ,
'index.html'
);
2007-09-16 03:48:38 +02:00
2007-07-19 12:40:28 +02:00
foreach ( $installfiles as $installfile ) {
if ( file_exists ( '../' . $installfile )) {
2007-10-29 03:53:53 +01:00
@ unlink ( '../' . $installfile );
2007-07-19 12:40:28 +02:00
}
2007-09-16 03:48:38 +02:00
2007-07-19 12:40:28 +02:00
if ( file_exists ( '../' . $installfile )) {
$unsuccessful [] = $installfile ;
}
}
2007-09-16 03:48:38 +02:00
2007-07-19 12:40:28 +02:00
if ( isset ( $unsuccessful )) {
$title -> setValue ( " Unable to delete installation files " );
$tempcontent = " <p style= \" margin: 1em 0 \" >Unable to delete installation files. Please delete the files below manually:</p><ul> " ;
foreach ( $unsuccessful as $unsuccessfulFile ) {
$tempcontent .= " <li> $unsuccessfulFile </li> " ;
}
$tempcontent .= " </ul> " ;
} else {
$title -> setValue ( " Deleted installation files " );
$tempcontent = <<< HTML
< p style = " margin: 1em 0 " > Installation files have been successfully deleted .</ p >
HTML
;
}
$tempcontent .= <<< HTML
< p style = " margin: 1em 0 " > You can start editing your site ' s content by opening < a href = " admin/ " > the CMS </ a >. < br />
& nbsp ; & nbsp ; Email : $username < br />
& nbsp ; & nbsp ; Password : $password < br />
</ p >
HTML
;
$content -> setValue ( $tempcontent );
2007-09-14 21:10:18 +02:00
2007-07-19 12:40:28 +02:00
return array (
" Title " => $title ,
" Content " => $content ,
);
}
}
2007-07-24 05:43:21 +02:00
2007-09-16 17:37:33 +02:00
?>