2007-07-19 12:40:05 +02:00
< ? php
/**
* The main " content " area of the CMS .
* This class creates a 2 - frame layout - left - tree and right - form - to sit beneath the main
* admin menu .
2008-06-15 15:33:53 +02:00
*
2008-02-25 03:10:37 +01:00
* @ package cms
* @ subpackage content
2007-07-19 12:40:05 +02:00
* @ todo Create some base classes to contain the generic functionality that will be replicated .
*/
class CMSMain extends LeftAndMain implements CurrentPageIdentifier , PermissionProvider {
2008-02-20 10:41:33 +01:00
2008-11-02 22:27:55 +01:00
static $url_segment = '' ;
static $url_rule = '/$Action/$ID/$OtherID' ;
// Maintain a lower priority than other administration sections
// so that Director does not think they are actions of CMSMain
static $url_priority = 40 ;
2010-04-14 00:19:49 +02:00
static $menu_title = 'Pages' ;
2008-11-02 22:27:55 +01:00
static $menu_priority = 10 ;
2007-07-19 12:40:05 +02:00
static $tree_class = " SiteTree " ;
2007-09-27 22:56:55 +02:00
2007-07-19 12:40:05 +02:00
static $subitem_class = " Member " ;
2007-09-27 22:56:55 +02:00
2008-02-25 03:10:37 +01:00
static $allowed_actions = array (
'addpage' ,
'buildbrokenlinks' ,
'compareversions' ,
'deleteitems' ,
2009-01-06 03:18:33 +01:00
'DeleteItemsForm' ,
2008-02-25 03:10:37 +01:00
'dialog' ,
'duplicate' ,
'duplicatewithchildren' ,
'getversion' ,
'publishall' ,
'publishitems' ,
2009-01-06 03:18:33 +01:00
'PublishItemsForm' ,
2010-06-10 08:40:40 +02:00
'RootForm' ,
2008-02-25 03:10:37 +01:00
'sidereport' ,
2011-02-24 05:03:24 +01:00
'SideReportsForm' ,
2008-02-25 03:10:37 +01:00
'submit' ,
'versions' ,
2011-03-15 10:30:28 +01:00
'VersionsForm' ,
2008-08-09 05:54:55 +02:00
'EditForm' ,
2009-11-21 04:18:51 +01:00
'AddForm' ,
2011-02-21 22:52:56 +01:00
'SearchTreeForm' ,
2008-09-25 16:50:33 +02:00
'SiteTreeAsUL' ,
2009-05-14 08:11:18 +02:00
'getshowdeletedsubtree' ,
'getfilteredsubtree' ,
2010-12-22 21:00:33 +01:00
'batchactions' ,
2008-02-25 03:10:37 +01:00
);
2007-09-16 17:19:17 +02:00
/**
* SiteTree Columns that can be filtered using the the Site Tree Search button
*/
2007-09-27 22:56:55 +02:00
static $site_tree_filter_options = array (
2009-04-29 03:44:28 +02:00
'Title' => array ( 'CMSMain.TITLE' , 'Title' ),
'MenuTitle' => array ( 'CMSMain.MENUTITLE' , 'Navigation Label' ),
2007-11-07 00:28:54 +01:00
'ClassName' => array ( 'CMSMain.PAGETYPE' , 'Page Type' ),
'Status' => array ( 'CMSMain.STATUS' , 'Status' ),
'MetaDescription' => array ( 'CMSMain.METADESC' , 'Description' ),
'MetaKeywords' => array ( 'CMSMain.METAKEYWORDS' , 'Keywords' )
2007-09-27 22:56:55 +02:00
);
2007-11-07 07:05:52 +01:00
static function T_SiteTreeFilterOptions (){
return array (
2009-04-29 03:44:28 +02:00
'Title' => _t ( 'CMSMain.TITLEOPT' , 'Title' , 0 , 'The dropdown title in CMSMain left SiteTreeFilterOptions' ),
'MenuTitle' => _t ( 'CMSMain.MENUTITLEOPT' , 'Navigation Label' , 0 , 'The dropdown title in CMSMain left SiteTreeFilterOptions' ),
2007-11-07 07:05:52 +01:00
'Status' => _t ( 'CMSMain.STATUSOPT' , 'Status' , 0 , " The dropdown title in CMSMain left SiteTreeFilterOptions " ),
'MetaDescription' => _t ( 'CMSMain.METADESCOPT' , 'Description' , 0 , " The dropdown title in CMSMain left SiteTreeFilterOptions " ),
2009-04-29 03:44:28 +02:00
'MetaKeywords' => _t ( 'CMSMain.METAKEYWORDSOPT' , 'Keywords' , 0 , " The dropdown title in CMSMain left SiteTreeFilterOptions " )
2007-11-07 07:05:52 +01:00
);
}
2009-05-14 08:11:18 +02:00
2007-07-19 12:40:05 +02:00
public function init () {
2011-03-29 07:00:21 +02:00
// set reading lang
if ( Object :: has_extension ( 'SiteTree' , 'Translatable' ) && ! $this -> isAjax ()) {
Translatable :: choose_site_locale ( array_keys ( Translatable :: get_existing_content_languages ( 'SiteTree' )));
}
2007-07-19 12:40:05 +02:00
parent :: init ();
2009-05-18 02:23:52 +02:00
ENHANCEMENT Using jQuery layout manager plugin to size panels in main CMS interface. Removed custom javascript resizing and CSS rules.
API CHANGE Removed custom resizing javascript methods: window.ontabschanged, window.onresize, fixRightWidth(), fixHeight_left()
API CHANGE Removed DraggableSeparator, SideTabs, SideTabItem javascript classes
API CHANGE Removed Effect.ReSize and Highlighter javascript helper classes
API CHANGE Modified template structure in CMSMain_left.ss, CMSMain_right.ss and LeftAndMain.ss
API CHANGE Modified markup IDs in LeftAndMain/CMSMain templates, removed "left", "right", "contentPanel", "bottom"
ENHANCEMENT Using jquery-latest (currently 1.3) in CMSMain and LeftAndMain
ENHANCEMENT Added jQuery UI library and "smoothness" theme to default CMS interface
git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/trunk@92581 467b73ca-7a2a-4603-9d3b-597d59a354a9
2009-11-21 03:35:20 +01:00
Requirements :: javascript ( CMS_DIR . '/javascript/CMSMain.js' );
2009-11-21 04:16:03 +01:00
Requirements :: javascript ( CMS_DIR . '/javascript/CMSMain.EditForm.js' );
2011-03-23 11:08:04 +01:00
Requirements :: add_i18n_javascript ( CMS_DIR . '/javascript/lang' );
2009-11-21 03:38:05 +01:00
Requirements :: css ( CMS_DIR . '/css/CMSMain.css' );
2009-11-21 04:19:02 +01:00
2011-03-23 11:08:04 +01:00
// navigator
Requirements :: css ( CMS_DIR . '/css/SilverStripeNavigator.css' );
Requirements :: javascript ( CMS_DIR . '/javascript/SilverStripeNavigator.js' );
2009-11-21 04:19:02 +01:00
CMSBatchActionHandler :: register ( 'publish' , 'CMSBatchAction_Publish' );
CMSBatchActionHandler :: register ( 'unpublish' , 'CMSBatchAction_Unpublish' );
CMSBatchActionHandler :: register ( 'delete' , 'CMSBatchAction_Delete' );
CMSBatchActionHandler :: register ( 'deletefromlive' , 'CMSBatchAction_DeleteFromLive' );
2007-07-19 12:40:05 +02:00
}
2008-06-24 05:22:39 +02:00
/**
* If this is set to true , the " switchView " context in the
* template is shown , with links to the staging and publish site .
*
* @ return boolean
*/
function ShowSwitchView () {
return true ;
}
2010-06-03 04:45:23 +02:00
2010-10-13 06:15:18 +02:00
/**
* Overloads the LeftAndMain :: ShowView . Allows to pass a page as a parameter , so we are able
* to switch view also for archived versions .
*/
function SwitchView ( $page = null ) {
if ( ! $page ) {
$page = $this -> currentPage ();
}
if ( $page ) {
2010-06-03 04:45:23 +02:00
$nav = SilverStripeNavigator :: get_for_record ( $page );
return $nav [ 'items' ];
}
}
2007-09-15 23:54:24 +02:00
2007-07-19 12:40:05 +02:00
//------------------------------------------------------------------------------------------//
// Main controllers
//------------------------------------------------------------------------------------------//
// Main UI components
2007-09-15 23:54:24 +02:00
2008-11-18 02:48:50 +01:00
/**
* Override { @ link LeftAndMain } Link to allow blank URL segment for CMSMain .
*
* @ return string
*/
public function Link ( $action = null ) {
return Controller :: join_links (
$this -> stat ( 'url_base' , true ),
$this -> stat ( 'url_segment' , true ), // in case we want to change the segment
'/' , // trailing slash needed if $action is null!
" $action "
);
}
2007-07-19 12:40:05 +02:00
/**
* Return the entire site tree as a nested set of ULs
*/
public function SiteTreeAsUL () {
$this -> generateDataTreeHints ();
$this -> generateTreeStylingJS ();
2007-09-15 23:54:24 +02:00
2009-02-03 03:50:25 +01:00
// Pre-cache sitetree version numbers for querying efficiency
Versioned :: prepopulate_versionnumber_cache ( " SiteTree " , " Stage " );
Versioned :: prepopulate_versionnumber_cache ( " SiteTree " , " Live " );
2009-11-21 04:21:00 +01:00
return $this -> getSiteTreeFor ( $this -> stat ( 'tree_class' ));
2007-07-19 12:40:05 +02:00
}
2009-08-04 05:09:26 +02:00
2009-05-01 00:47:28 +02:00
/**
2009-08-04 05:09:26 +02:00
* Use a CMSSiteTreeFilter to only get certain nodes
*
* @ return string
2009-05-01 00:47:28 +02:00
*/
2009-05-14 08:11:18 +02:00
public function getfilteredsubtree () {
2009-08-04 05:09:26 +02:00
// Sanity and security checks
if ( ! isset ( $_REQUEST [ 'filter' ])) die ( 'No filter passed' );
if ( ! ClassInfo :: exists ( $_REQUEST [ 'filter' ])) die ( 'That filter class does not exist' );
if ( ! is_subclass_of ( $_REQUEST [ 'filter' ], 'CMSSiteTreeFilter' )) die ( 'That is not a valid filter' );
2009-05-14 08:11:18 +02:00
2009-08-04 05:09:26 +02:00
// Do eeet!
$filter = new $_REQUEST [ 'filter' ]();
return $filter -> getTree ();
}
/**
* Returns a list of batch actions
*/
function SiteTreeFilters () {
$filters = ClassInfo :: subclassesFor ( 'CMSSiteTreeFilter' );
array_shift ( $filters );
$doSet = new DataObjectSet ();
$doSet -> push ( new ArrayData ( array (
'ClassName' => 'all' ,
2010-04-15 00:04:06 +02:00
'Title' => _t ( 'CMSSiteTreeFilter.ALL' , 'All items' )
2009-08-04 05:09:26 +02:00
)));
foreach ( $filters as $filter ) {
if ( call_user_func ( array ( $filter , 'showInList' ))) {
$doSet -> push ( new ArrayData ( array (
'ClassName' => $filter ,
'Title' => call_user_func ( array ( $filter , 'title' ))
)));
}
}
return $doSet ;
2009-05-14 08:11:18 +02:00
}
2007-09-16 17:19:17 +02:00
/**
* Returns the SiteTree columns that can be filtered using the the Site Tree Search button as a DataObjectSet
*/
public function SiteTreeFilterOptions () {
$filter_options = new DataObjectSet ();
2007-11-07 07:05:52 +01:00
foreach ( self :: T_SiteTreeFilterOptions () as $key => $value ) {
2007-09-16 17:19:17 +02:00
$record = array (
'Column' => $key ,
2007-11-07 07:05:52 +01:00
'Title' => $value ,
2007-09-16 17:19:17 +02:00
);
$filter_options -> push ( new ArrayData ( $record ));
}
return $filter_options ;
}
public function SiteTreeFilterDateField () {
2010-02-17 00:10:25 +01:00
$dateField = new DateField ( 'SiteTreeFilterDate' );
2010-07-12 08:45:11 +02:00
// TODO Enabling this means we load jQuery UI by default in the CMS,
// which is a pretty big performance hit in 2.4 (where the library isn't used for other parts
// of the interface).
// $dateField->setConfig('showcalendar', true);
2007-09-16 17:19:17 +02:00
return $dateField -> Field ();
}
2009-05-14 08:11:18 +02:00
public function SiteTreeFilterPageTypeField () {
$types = SiteTree :: page_type_classes (); array_unshift ( $types , 'All' );
2009-07-09 07:41:30 +02:00
$source = array_combine ( $types , $types );
asort ( $source );
$optionsetField = new DropdownField ( 'ClassName' , 'ClassName' , $source , 'Any' );
2009-05-14 08:11:18 +02:00
return $optionsetField -> Field ();
}
2010-10-04 08:13:58 +02:00
2007-07-19 12:40:05 +02:00
public function generateDataTreeHints () {
$classes = ClassInfo :: subclassesFor ( $this -> stat ( 'tree_class' ) );
2007-09-15 23:54:24 +02:00
2007-07-19 12:40:05 +02:00
$def [ 'Root' ] = array ();
2007-09-15 23:54:24 +02:00
2007-07-19 12:40:05 +02:00
foreach ( $classes as $class ) {
$obj = singleton ( $class );
if ( $obj instanceof HiddenClass ) continue ;
2007-09-15 23:54:24 +02:00
2007-07-19 12:40:05 +02:00
$allowedChildren = $obj -> allowedChildren ();
if ( $allowedChildren != " none " ) $def [ $class ][ 'allowedChildren' ] = $allowedChildren ;
$def [ $class ][ 'defaultChild' ] = $obj -> defaultChild ();
2009-10-11 02:08:05 +02:00
$def [ $class ][ 'defaultParent' ] = isset ( SiteTree :: get_by_link ( $obj -> defaultParent ()) -> ID ) ? SiteTree :: get_by_link ( $obj -> defaultParent ()) -> ID : null ;
2007-07-19 12:40:05 +02:00
if ( is_array ( $allowedChildren )) foreach ( $allowedChildren as $allowedChild ) {
$def [ $allowedChild ][ 'allowedParents' ][] = $class ;
}
if ( $obj -> stat ( 'can_be_root' )) {
$def [ 'Root' ][ 'allowedChildren' ][] = $class ;
}
}
2007-09-15 23:54:24 +02:00
2007-07-19 12:40:05 +02:00
// Put data hints into a script tag at the top
2009-11-21 03:39:04 +01:00
Requirements :: customScript ( " siteTreeHints = " . Convert :: raw2json ( $def ) . " ; " );
2007-07-19 12:40:05 +02:00
}
public function generateTreeStylingJS () {
2009-11-21 04:21:00 +01:00
$classes = ClassInfo :: subclassesFor ( $this -> stat ( 'tree_class' ));
2007-07-19 12:40:05 +02:00
foreach ( $classes as $class ) {
$obj = singleton ( $class );
if ( $obj instanceof HiddenClass ) continue ;
if ( $icon = $obj -> stat ( 'icon' )) $iconInfo [ $class ] = $icon ;
}
$iconInfo [ 'BrokenLink' ] = 'cms/images/treeicons/brokenlink' ;
2007-09-15 23:54:24 +02:00
2007-07-19 12:40:05 +02:00
$js = " var _TREE_ICONS = []; \n " ;
2007-09-15 23:54:24 +02:00
2007-07-19 12:40:05 +02:00
foreach ( $iconInfo as $class => $icon ) {
// SiteTree::$icon can be set to array($icon, $option)
// $option can be "file" or "folder" to force the icon to always be the file or the folder form
$option = null ;
if ( is_array ( $icon )) list ( $icon , $option ) = $icon ;
$fileImage = ( $option == " folder " ) ? $icon . '-openfolder.gif' : $icon . '-file.gif' ;
$openFolderImage = $icon . '-openfolder.gif' ;
2010-04-14 03:36:57 +02:00
if ( ! Director :: fileExists ( $openFolderImage ) || $option == " file " ) $openFolderImage = $fileImage ;
2007-07-19 12:40:05 +02:00
$closedFolderImage = $icon . '-closedfolder.gif' ;
2010-04-14 03:36:57 +02:00
if ( ! Director :: fileExists ( $closedFolderImage ) || $option == " file " ) $closedFolderImage = $fileImage ;
2007-09-15 23:54:24 +02:00
2007-07-19 12:40:05 +02:00
$js .= <<< JS
_TREE_ICONS [ '$class' ] = {
fileIcon : '$fileImage' ,
openFolderIcon : '$openFolderImage' ,
closedFolderIcon : '$closedFolderImage'
};
2007-09-15 23:54:24 +02:00
2007-07-19 12:40:05 +02:00
JS ;
}
2007-09-15 23:54:24 +02:00
2007-07-19 12:40:05 +02:00
Requirements :: customScript ( $js );
}
/**
2008-10-16 11:37:28 +02:00
* Populates an array of classes in the CMS
* which allows the user to change the page type .
*
* @ return DataObjectSet
2007-07-19 12:40:05 +02:00
*/
public function PageTypes () {
2009-02-03 04:22:20 +01:00
$classes = SiteTree :: page_type_classes ();
2007-07-19 12:40:05 +02:00
2009-02-03 04:22:20 +01:00
$result = new DataObjectSet ();
2008-01-17 06:31:38 +01:00
2007-07-19 12:40:05 +02:00
foreach ( $classes as $class ) {
2008-10-16 11:37:28 +02:00
$instance = singleton ( $class );
if ( $instance instanceof HiddenClass ) continue ;
2007-09-15 23:54:24 +02:00
2008-10-16 11:37:28 +02:00
if ( ! $instance -> canCreate ()) continue ;
2007-09-15 23:54:24 +02:00
2007-07-19 12:40:05 +02:00
// skip this type if it is restricted
2008-10-16 11:37:28 +02:00
if ( $instance -> stat ( 'need_permission' ) && ! $this -> can ( singleton ( $class ) -> stat ( 'need_permission' ))) continue ;
2008-02-25 03:10:37 +01:00
$addAction = $instance -> i18n_singular_name ();
2009-01-05 07:17:59 +01:00
// if we're in translation mode, the link between the translated pagetype
// title and the actual classname might not be obvious, so we add it in parantheses
// Example: class "RedirectorPage" has the title "Weiterleitung" in German,
// so it shows up as "Weiterleitung (RedirectorPage)"
if ( i18n :: get_locale () != 'en_US' ) {
$addAction .= " ( { $class } ) " ;
}
2007-09-15 23:54:24 +02:00
2007-07-19 12:40:05 +02:00
$result -> push ( new ArrayData ( array (
2008-10-16 11:37:28 +02:00
'ClassName' => $class ,
'AddAction' => $addAction ,
2007-07-19 12:40:05 +02:00
)));
}
2008-10-16 11:37:28 +02:00
2008-02-25 03:10:37 +01:00
$result -> sort ( 'AddAction' );
2007-07-19 12:40:05 +02:00
return $result ;
}
2007-09-15 23:54:24 +02:00
2010-06-03 03:34:52 +02:00
/**
* Save the current sites { @ link SiteConfig } into the database
*
* @ param array $data
* @ param Form $form
* @ return FormResponse
*/
2009-10-16 00:33:14 +02:00
function save_siteconfig ( $data , $form ) {
$siteConfig = SiteConfig :: current_site_config ();
$form -> saveInto ( $siteConfig );
$siteConfig -> write ();
2010-08-03 05:57:55 +02:00
$this -> response -> addHeader ( 'X-Status' , _t ( 'LeftAndMain.SAVEDUP' ));
return $form -> formHtmlContent ();
2009-10-16 00:33:14 +02:00
}
2007-07-19 12:40:05 +02:00
/**
2009-03-18 18:18:52 +01:00
* Get a database record to be managed by the CMS
2007-07-19 12:40:05 +02:00
*/
2009-03-18 18:18:52 +01:00
public function getRecord ( $id ) {
2007-07-19 12:40:05 +02:00
$treeClass = $this -> stat ( 'tree_class' );
2007-09-15 23:54:24 +02:00
2011-03-16 04:39:49 +01:00
if ( $id instanceof $treeClass ) {
return $id ;
} else if ( $id && is_numeric ( $id )) {
2011-01-12 00:00:59 +01:00
$version = isset ( $_REQUEST [ 'Version' ]) ? $_REQUEST [ 'Version' ] : null ;
if ( is_numeric ( $version )) {
$record = Versioned :: get_version ( $treeClass , $id , $version );
} else {
$record = DataObject :: get_one ( $treeClass , " \" $treeClass\ " . \ " ID \" = $id " );
}
2007-09-15 23:54:24 +02:00
2009-05-01 00:47:28 +02:00
// Then, try getting a record from the live site
2007-07-19 12:40:05 +02:00
if ( ! $record ) {
2008-11-23 23:58:18 +01:00
// $record = Versioned::get_one_by_stage($treeClass, "Live", "\"$treeClass\".\"ID\" = $id");
2007-07-19 12:40:05 +02:00
Versioned :: reading_stage ( 'Live' );
singleton ( $treeClass ) -> flushCache ();
2009-01-08 00:01:47 +01:00
2008-11-23 23:58:18 +01:00
$record = DataObject :: get_one ( $treeClass , " \" $treeClass\ " . \ " ID \" = $id " );
2010-10-04 07:27:08 +02:00
if ( $record ) Versioned :: set_reading_mode ( '' );
2007-07-19 12:40:05 +02:00
}
2009-05-01 00:47:28 +02:00
// Then, try getting a deleted record
if ( ! $record ) {
$record = Versioned :: get_latest_version ( $treeClass , $id );
}
// Don't open a page from a different locale
2010-10-04 08:16:50 +02:00
/** The record ' s Locale is saved in database in 2.4 , and not related with Session ,
* we should not check their locale matches the Translatable :: get_current_locale ,
* here as long as we all the HTTPRequest is init with right locale .
* This bit breaks the all FileIFrameField functions if the field is used in CMS
* and its relevent ajax calles , like loading the tree dropdown for TreeSelectorField .
2010-10-04 08:16:17 +02:00
*/
/* if ( $record && Object :: has_extension ( 'SiteTree' , 'Translatable' ) && $record -> Locale && $record -> Locale != Translatable :: get_current_locale ()) {
2009-05-01 00:47:28 +02:00
$record = null ;
2010-10-04 08:16:17 +02:00
} */
2009-05-01 00:47:28 +02:00
2007-07-19 12:40:05 +02:00
return $record ;
2007-09-15 23:54:24 +02:00
2007-07-19 12:40:05 +02:00
} else if ( substr ( $id , 0 , 3 ) == 'new' ) {
return $this -> getNewItem ( $id );
}
}
2009-11-21 04:17:16 +01:00
2009-11-21 03:38:35 +01:00
/**
* Calls { @ link SiteTree -> getCMSFields ()}
*/
2009-11-21 04:15:13 +01:00
public function getEditForm ( $id = null ) {
// Include JavaScript to ensure HtmlEditorField works.
HtmlEditorField :: include_js ();
2009-11-21 04:19:47 +01:00
2011-03-16 04:39:49 +01:00
if ( ! $id ) $id = $this -> currentPageID ();
2009-11-21 04:20:26 +01:00
$form = parent :: getEditForm ( $id );
// TODO Duplicate record fetching (see parent implementation)
2011-03-16 04:39:49 +01:00
$record = $this -> getRecord ( $id );
if ( $record && ! $record -> canView ()) return Security :: permissionFailure ( $this );
2010-04-14 05:28:42 +02:00
2009-11-21 04:20:26 +01:00
$fields = $form -> Fields ();
$actions = $form -> Actions ();
2007-09-15 23:54:24 +02:00
2007-07-19 12:40:05 +02:00
if ( $record ) {
2009-11-21 03:38:37 +01:00
$fields -> push ( $idField = new HiddenField ( " ID " , false , $id ));
2010-04-12 11:41:45 +02:00
// Necessary for different subsites
$fields -> push ( $liveURLField = new HiddenField ( " AbsoluteLink " , false , $record -> AbsoluteLink ()));
2007-07-19 12:40:05 +02:00
$fields -> push ( $liveURLField = new HiddenField ( " LiveURLSegment " ));
$fields -> push ( $stageURLField = new HiddenField ( " StageURLSegment " ));
2009-11-21 04:20:36 +01:00
$fields -> push ( new HiddenField ( " TreeTitle " , false , $record -> TreeTitle ));
2007-09-15 23:54:24 +02:00
2009-11-21 03:38:37 +01:00
$fields -> push ( new HiddenField ( 'Sort' , '' , $record -> Sort ));
2007-09-15 23:54:24 +02:00
2007-09-05 08:42:26 +02:00
if ( $record -> ID && is_numeric ( $record -> ID ) ) {
2008-11-23 23:58:18 +01:00
$liveRecord = Versioned :: get_one_by_stage ( 'SiteTree' , 'Live' , " \" SiteTree \" . \" ID \" = $record->ID " );
2007-09-05 08:42:26 +02:00
if ( $liveRecord ) $liveURLField -> setValue ( $liveRecord -> AbsoluteLink ());
}
2008-12-17 23:41:07 +01:00
if ( ! $record -> IsDeletedFromStage ) {
2007-09-05 08:42:26 +02:00
$stageURLField -> setValue ( $record -> AbsoluteLink ());
}
2007-07-19 12:40:05 +02:00
// getAllCMSActions can be used to completely redefine the action list
if ( $record -> hasMethod ( 'getAllCMSActions' )) {
$actions = $record -> getAllCMSActions ();
} else {
2008-12-04 23:38:58 +01:00
$actions = $record -> getCMSActions ();
2007-07-19 12:40:05 +02:00
}
2009-03-18 14:03:52 +01:00
// Add a default or custom validator.
// @todo Currently the default Validator.js implementation
// adds javascript to the document body, meaning it won't
// be included properly if the associated fields are loaded
// through ajax. This means only serverside validation
// will kick in for pages+validation loaded through ajax.
// This will be solved by using less obtrusive javascript validation
// in the future, see http://open.silverstripe.com/ticket/2915 and http://open.silverstripe.com/ticket/3386
if ( $record -> hasMethod ( 'getCMSValidator' )) {
$validator = $record -> getCMSValidator ();
} else {
$validator = new RequiredFields ();
}
// The clientside (mainly LeftAndMain*.js) rely on ajax responses
// which can be evaluated as javascript, hence we need
// to override any global changes to the validation handler.
$validator -> setJavascriptValidationHandler ( 'prototype' );
2009-11-21 03:39:12 +01:00
2009-03-18 14:03:52 +01:00
$form = new Form ( $this , " EditForm " , $fields , $actions , $validator );
2007-07-19 12:40:05 +02:00
$form -> loadDataFrom ( $record );
$form -> disableDefaultAction ();
2009-01-05 07:17:59 +01:00
if ( ! $record -> canEdit () || $record -> IsDeletedFromStage ) {
$readonlyFields = $form -> Fields () -> makeReadonly ();
$form -> setFields ( $readonlyFields );
}
2010-02-11 02:20:20 +01:00
$this -> extend ( 'updateEditForm' , $form );
2007-07-19 12:40:05 +02:00
return $form ;
2010-02-23 04:32:18 +01:00
} if ( $id == 0 || $id == 'root' ) {
2010-02-24 03:00:06 +01:00
return $this -> RootForm ();
2007-07-19 12:40:05 +02:00
} else if ( $id ) {
return new Form ( $this , " EditForm " , new FieldSet (
2011-03-16 04:41:46 +01:00
new LabelField ( 'PageDoesntExistLabel' , _t ( 'CMSMain.PAGENOTEXISTS' , " This page doesn't exist " ))), new FieldSet ()
);
2007-07-19 12:40:05 +02:00
}
}
2007-09-15 23:54:24 +02:00
2010-02-23 04:32:18 +01:00
/**
* @ return Form
*/
function RootForm () {
$siteConfig = SiteConfig :: current_site_config ();
2010-09-05 04:32:07 +02:00
$fields = $siteConfig -> getCMSFields ();
2010-06-10 08:40:40 +02:00
$form = new Form ( $this , 'RootForm' , $fields , $siteConfig -> getCMSActions ());
$form -> setHTMLID ( 'Form_EditForm' );
2010-02-23 04:32:18 +01:00
$form -> loadDataFrom ( $siteConfig );
2010-09-05 04:32:07 +02:00
2010-02-23 04:32:18 +01:00
$this -> extend ( 'updateEditForm' , $form );
2010-02-24 03:00:06 +01:00
2009-11-21 04:15:00 +01:00
return $form ;
2007-07-19 12:40:05 +02:00
}
2007-09-15 23:54:24 +02:00
2007-07-19 12:40:05 +02:00
//------------------------------------------------------------------------------------------//
// Data saving handlers
2009-11-21 04:20:26 +01:00
/**
* Save and Publish page handler
*/
public function save ( $data , $form ) {
$className = $this -> stat ( 'tree_class' );
// Existing or new record?
$SQL_id = Convert :: raw2sql ( $data [ 'ID' ]);
if ( substr ( $SQL_id , 0 , 3 ) != 'new' ) {
$record = DataObject :: get_by_id ( $className , $SQL_id );
if ( $record && ! $record -> canEdit ()) return Security :: permissionFailure ( $this );
} else {
if ( ! singleton ( $this -> stat ( 'tree_class' )) -> canCreate ()) return Security :: permissionFailure ( $this );
$record = $this -> getNewItem ( $SQL_id , false );
}
// TODO Coupling to SiteTree
$record -> HasBrokenLink = 0 ;
$record -> HasBrokenFile = 0 ;
$record -> writeWithoutVersion ();
// Update the class instance if necessary
if ( $data [ 'ClassName' ] != $record -> ClassName ) {
$newClassName = $record -> ClassName ;
// The records originally saved attribute was overwritten by $form->saveInto($record) before.
// This is necessary for newClassInstance() to work as expected, and trigger change detection
// on the ClassName attribute
$record -> setClassName ( $data [ 'ClassName' ]);
// Replace $record with a new instance
$record = $record -> newClassInstance ( $newClassName );
}
// save form data into record
$form -> saveInto ( $record , true );
$record -> write ();
// If the 'Save & Publish' button was clicked, also publish the page
if ( isset ( $data [ 'publish' ]) && $data [ 'publish' ] == 1 ) {
$record -> doPublish ();
// Update classname with original and get new instance (see above for explanation)
$record -> setClassName ( $data [ 'ClassName' ]);
$publishedRecord = $record -> newClassInstance ( $record -> ClassName );
$this -> response -> addHeader (
'X-Status' ,
sprintf (
_t (
'LeftAndMain.STATUSPUBLISHEDSUCCESS' ,
" Published '%s' successfully " ,
PR_MEDIUM ,
'Status message after publishing a page, showing the page title'
),
$publishedRecord -> Title
)
);
2011-03-16 04:41:46 +01:00
// Reload form, data and actions might have changed
$form = $this -> getEditForm ( $publishedRecord -> ID );
2009-11-21 04:20:26 +01:00
} else {
$this -> response -> addHeader ( 'X-Status' , _t ( 'LeftAndMain.SAVEDUP' ));
2011-03-16 04:41:46 +01:00
// Reload form, data and actions might have changed
$form = $this -> getEditForm ( $record -> ID );
2009-11-21 04:20:26 +01:00
}
return $form -> formHtmlContent ();
}
2007-07-19 12:40:05 +02:00
2009-11-21 04:18:59 +01:00
public function doAdd ( $data , $form ) {
2009-11-21 03:39:12 +01:00
$className = isset ( $data [ 'PageType' ]) ? $data [ 'PageType' ] : " Page " ;
$parentID = isset ( $data [ 'ParentID' ]) ? ( int ) $data [ 'ParentID' ] : 0 ;
$suffix = isset ( $data [ 'Suffix' ]) ? " - " . $data [ 'Suffix' ] : null ;
2007-09-15 23:54:24 +02:00
2009-11-21 03:39:12 +01:00
if ( ! $parentID && isset ( $data [ 'Parent' ])) {
$page = SiteTree :: get_by_link ( Convert :: raw2sql ( $data [ 'Parent' ]));
if ( $page ) $parentID = $page -> ID ;
2009-01-10 12:36:30 +01:00
}
2007-09-15 23:54:24 +02:00
2010-04-14 05:06:22 +02:00
if ( is_numeric ( $parentID ) && $parentID > 0 ) $parentObj = DataObject :: get_by_id ( " SiteTree " , $parentID );
else $parentObj = null ;
2008-11-03 15:56:36 +01:00
2010-04-14 05:06:22 +02:00
if ( ! $parentObj || ! $parentObj -> ID ) $parentID = 0 ;
2010-04-14 03:36:42 +02:00
if ( $parentObj ) {
if ( ! $parentObj -> canAddChildren ()) return Security :: permissionFailure ( $this );
if ( ! singleton ( $className ) -> canCreate ()) return Security :: permissionFailure ( $this );
} else {
if ( ! SiteConfig :: current_site_config () -> canCreateTopLevel ())
return Security :: permissionFailure ( $this );
}
2010-04-14 05:06:22 +02:00
$record = $this -> getNewItem ( " new- $className - $parentID " . $suffix , false );
2011-03-22 09:30:10 +01:00
if ( class_exists ( 'Translatable' ) && $record -> hasExtension ( 'Translatable' )) $record -> Locale = $data [ 'Locale' ];
2010-04-14 05:06:22 +02:00
$record -> write ();
2009-11-21 03:39:12 +01:00
2010-04-14 05:06:22 +02:00
$form = $this -> getEditForm ( $record -> ID );
2009-11-21 03:39:12 +01:00
2010-04-14 05:06:22 +02:00
if ( isset ( $data [ 'returnID' ])) {
return $record -> ID ;
} else if ( Director :: is_ajax ()) {
$form = $this -> getEditForm ( $record -> ID );
return $form -> formHtmlContent ();
} else {
return $this -> redirect ( Controller :: join_links ( $this -> Link ( 'show' ), $record -> ID ));
}
2007-07-19 12:40:05 +02:00
}
2007-09-15 23:54:24 +02:00
2008-11-07 13:21:10 +01:00
/**
2011-04-15 11:37:15 +02:00
* @ uses LeftAndMainExtension -> augmentNewSiteTreeItem ()
2008-11-07 13:21:10 +01:00
*/
2007-07-19 12:40:05 +02:00
public function getNewItem ( $id , $setID = true ) {
2008-11-18 02:48:50 +01:00
list ( $dummy , $className , $parentID , $suffix ) = array_pad ( explode ( '-' , $id ), 4 , null );
2009-01-10 12:36:30 +01:00
2007-07-19 12:40:05 +02:00
$newItem = new $className ();
2007-09-15 23:54:24 +02:00
2007-07-19 12:40:05 +02:00
if ( ! $suffix ) {
$sessionTag = " NewItems. " . $parentID . " . " . $className ;
if ( Session :: get ( $sessionTag )) {
$suffix = '-' . Session :: get ( $sessionTag );
Session :: set ( $sessionTag , Session :: get ( $sessionTag ) + 1 );
}
else
Session :: set ( $sessionTag , 1 );
2007-09-15 23:54:24 +02:00
2007-07-19 12:40:05 +02:00
$id = $id . $suffix ;
}
2007-09-15 23:54:24 +02:00
2007-09-15 22:21:13 +02:00
$newItem -> Title = _t ( 'CMSMain.NEW' , " New " , PR_MEDIUM , '"New " followed by a className' ) . $className ;
2007-07-19 12:40:05 +02:00
$newItem -> URLSegment = " new- " . strtolower ( $className );
$newItem -> ClassName = $className ;
$newItem -> ParentID = $parentID ;
2007-09-15 23:54:24 +02:00
2008-02-25 03:10:37 +01:00
// DataObject::fieldExists only checks the current class, not the hierarchy
// This allows the CMS to set the correct sort value
2010-10-04 08:06:50 +02:00
if ( $newItem -> castingHelper ( 'Sort' )) {
2008-11-24 10:30:41 +01:00
$newItem -> Sort = DB :: query ( " SELECT MAX( \" Sort \" ) FROM \" SiteTree \" WHERE \" ParentID \" = ' " . Convert :: raw2sql ( $parentID ) . " ' " ) -> value () + 1 ;
2007-07-19 12:40:05 +02:00
}
2007-09-15 23:54:24 +02:00
2007-07-19 12:40:05 +02:00
if ( $setID ) $newItem -> ID = $id ;
2007-09-15 23:54:24 +02:00
2008-02-25 03:10:37 +01:00
# Some modules like subsites add extra fields that need to be set when the new item is created
$this -> extend ( 'augmentNewSiteTreeItem' , $newItem );
2007-07-19 12:40:05 +02:00
return $newItem ;
}
2007-09-15 23:54:24 +02:00
2008-12-17 23:41:07 +01:00
/**
* Delete the page from live . This means a page in draft mode might still exist .
*
* @ see delete ()
*/
2009-11-21 03:39:12 +01:00
public function deletefromlive ( $data , $form ) {
2007-07-19 12:40:05 +02:00
Versioned :: reading_stage ( 'Live' );
2009-11-21 03:39:12 +01:00
$record = DataObject :: get_by_id ( " SiteTree " , $data [ 'ID' ]);
2010-10-04 08:14:05 +02:00
if ( $record && ! ( $record -> canDelete () && $record -> canDeleteFromLive ())) return Security :: permissionFailure ( $this );
2008-11-03 15:56:36 +01:00
2007-07-27 07:26:00 +02:00
$descRemoved = '' ;
2007-10-02 07:08:36 +02:00
$descendantsRemoved = 0 ;
2007-07-19 12:40:05 +02:00
// before deleting the records, get the descendants of this tree
if ( $record ) {
2010-05-28 04:37:58 +02:00
$descendantIDs = $record -> getDescendantIDList ();
2007-09-15 23:54:24 +02:00
2007-07-19 12:40:05 +02:00
// then delete them from the live site too
2007-09-15 23:54:24 +02:00
$descendantsRemoved = 0 ;
2007-07-19 12:40:05 +02:00
foreach ( $descendantIDs as $descID )
if ( $descendant = DataObject :: get_by_id ( 'SiteTree' , $descID ) ) {
2010-04-13 05:52:07 +02:00
$descendant -> doDeleteFromLive ();
2007-07-19 12:40:05 +02:00
$descendantsRemoved ++ ;
}
2007-09-15 23:54:24 +02:00
2007-07-19 12:40:05 +02:00
// delete the record
2010-04-13 05:52:07 +02:00
$record -> doDeleteFromLive ();
2007-07-19 12:40:05 +02:00
}
Versioned :: reading_stage ( 'Stage' );
2007-07-27 07:26:00 +02:00
if ( isset ( $descendantsRemoved )) {
2007-07-19 12:40:05 +02:00
$descRemoved = " and $descendantsRemoved descendants " ;
2008-02-25 03:10:37 +01:00
$descRemoved = sprintf ( ' ' . _t ( 'CMSMain.DESCREMOVED' , 'and %s descendants' ), $descendantsRemoved );
2007-09-15 02:46:22 +02:00
} else {
$descRemoved = '' ;
2007-07-19 12:40:05 +02:00
}
2007-09-15 23:54:24 +02:00
2009-11-21 03:39:12 +01:00
$this -> response -> addHeader (
'X-Status' ,
sprintf (
_t ( 'CMSMain.REMOVED' , 'Deleted \'%s\'%s from live site' ),
$record -> Title ,
$descRemoved
)
);
2007-07-19 12:40:05 +02:00
2009-11-21 03:39:12 +01:00
// nothing to return
return '' ;
2007-07-19 12:40:05 +02:00
}
2007-09-15 23:54:24 +02:00
2007-07-19 12:40:05 +02:00
/**
* Actually perform the publication step
*/
public function performPublish ( $record ) {
2008-11-03 15:56:36 +01:00
if ( $record && ! $record -> canPublish ()) return Security :: permissionFailure ( $this );
2008-08-12 04:59:27 +02:00
$record -> doPublish ();
2007-07-19 12:40:05 +02:00
}
2009-01-05 07:17:59 +01:00
/**
* Reverts a page by publishing it to live .
* Use { @ link restorepage ()} if you want to restore a page
* which was deleted from draft without publishing .
*
* @ uses SiteTree -> doRevertToLive ()
*/
2009-11-21 03:39:12 +01:00
public function revert ( $data , $form ) {
2010-06-03 02:00:14 +02:00
if ( ! isset ( $data [ 'ID' ])) return new SS_HTTPResponse ( " Please pass an ID in the form content " , 400 );
2009-11-21 03:39:12 +01:00
$restoredPage = Versioned :: get_latest_version ( " SiteTree " , $data [ 'ID' ]);
2010-06-03 02:00:14 +02:00
if ( ! $restoredPage ) return new SS_HTTPResponse ( " SiteTree # $id not found " , 400 );
2009-11-21 03:39:12 +01:00
$record = Versioned :: get_one_by_stage (
'SiteTree' ,
'Live' ,
sprintf ( " \" SiteTree_Live \" . \" ID \" = '%d' " , ( int ) $data [ 'ID' ])
);
2008-12-04 23:38:58 +01:00
2009-01-05 07:17:59 +01:00
// a user can restore a page without publication rights, as it just adds a new draft state
// (this action should just be available when page has been "deleted from draft")
2009-11-21 03:39:12 +01:00
if ( isset ( $record ) && $record && ! $record -> canEdit ()) {
return Security :: permissionFailure ( $this );
}
2009-01-05 07:17:59 +01:00
2008-11-18 02:48:50 +01:00
$record -> doRevertToLive ();
2009-11-21 03:39:12 +01:00
$this -> response -> addHeader (
'X-Status' ,
sprintf (
_t ( 'CMSMain.RESTORED' , " Restored '%s' successfully " , PR_MEDIUM , 'Param %s is a title' ),
$record -> Title
)
);
$form = $this -> getEditForm ( $record -> ID );
return $form -> formHtmlContent ();
2007-07-19 12:40:05 +02:00
}
2008-03-11 02:02:05 +01:00
/**
2008-12-17 23:41:07 +01:00
* Delete the current page from draft stage .
* @ see deletefromlive ()
2008-03-11 02:02:05 +01:00
*/
2009-09-10 01:47:56 +02:00
public function delete ( $data , $form ) {
$record = DataObject :: get_one (
" SiteTree " ,
sprintf ( " \" SiteTree \" . \" ID \" = %d " , Convert :: raw2sql ( $data [ 'ID' ]))
);
2008-11-03 15:56:36 +01:00
if ( $record && ! $record -> canDelete ()) return Security :: permissionFailure ();
2008-12-17 23:41:07 +01:00
// save ID and delete record
2008-03-11 02:02:05 +01:00
$recordID = $record -> ID ;
2007-07-19 12:40:05 +02:00
$record -> delete ();
2008-03-11 02:02:05 +01:00
2009-11-21 03:39:12 +01:00
$this -> response -> addHeader (
'X-Status' ,
sprintf (
_t ( 'CMSMain.REMOVEDPAGEFROMDRAFT' , " Removed '%s' from the draft site " ),
$record -> Title
)
);
2010-10-13 04:10:28 +02:00
if ( $this -> isAjax ()) {
2008-12-17 23:41:07 +01:00
// need a valid ID value even if the record doesn't have one in the database
// (its still present in the live tables)
2009-11-21 03:39:12 +01:00
$liveRecord = Versioned :: get_one_by_stage (
'SiteTree' ,
'Live' ,
" \" SiteTree_Live \" . \" ID \" = $recordID "
);
return ( $liveRecord ) ? $form -> formHtmlContent () : " " ;
2008-03-11 02:02:05 +01:00
} else {
2010-10-13 04:10:28 +02:00
$this -> redirectBack ();
2008-03-11 02:02:05 +01:00
}
2007-07-19 12:40:05 +02:00
}
2009-11-21 04:20:54 +01:00
2011-03-24 09:39:04 +01:00
/**
* Return the CMS ' s HTML - editor toolbar
*/
public function EditorToolbar () {
return Object :: create ( 'HtmlEditorField_Toolbar' , $this , " EditorToolbar " );
}
2010-05-28 04:23:10 +02:00
/**
* @ return Array
*/
function SideReports () {
2010-05-28 04:35:56 +02:00
return SS_Report :: get_reports ( 'SideReport' );
2009-11-21 04:20:54 +01:00
}
2010-05-28 04:23:10 +02:00
/**
* @ return Form
*/
2009-11-21 04:20:54 +01:00
function SideReportsForm () {
$record = $this -> currentPage ();
2010-05-28 04:23:10 +02:00
foreach ( $this -> SideReports () as $report ) {
if ( $report -> canView ()) {
$options [ $report -> group ()][ $report -> sort ()][ $report -> ID ()] = $report -> title ();
2009-10-29 03:50:47 +01:00
}
}
2010-05-28 04:23:10 +02:00
2009-11-21 04:20:54 +01:00
$finalOptions = array ();
foreach ( $options as $group => $weights ) {
ksort ( $weights );
foreach ( $weights as $weight => $reports ) {
foreach ( $reports as $class => $report ) {
$finalOptions [ $group ][ $class ] = $report ;
}
}
}
2010-05-28 04:23:10 +02:00
$selectorField = new GroupedDropdownField ( " ReportClass " , _t ( 'CMSMain.REPORT' , 'Report' ), $finalOptions );
2009-10-29 03:50:47 +01:00
2009-11-21 04:15:55 +01:00
$form = new Form (
$this ,
2009-11-21 04:20:54 +01:00
'SideReportsForm' ,
2009-11-21 04:15:55 +01:00
new FieldSet (
2009-11-21 04:20:54 +01:00
$selectorField ,
new HiddenField ( 'ID' , false , ( $record ) ? $record -> ID : null ),
2009-11-21 04:15:55 +01:00
new HiddenField ( 'Locale' , false , $this -> Locale )
),
new FieldSet (
2009-11-21 04:20:54 +01:00
new FormAction ( 'doShowSideReport' , _t ( 'CMSMain_left.ss.GO' , 'Go' ))
2009-11-21 04:15:55 +01:00
)
);
$form -> unsetValidator ();
2009-11-21 04:21:08 +01:00
$form -> addExtraClass ( 'oneline' );
2009-11-21 04:15:55 +01:00
2011-03-22 09:30:10 +01:00
$this -> extend ( 'updateSideReportsForm' , $form );
2009-11-21 04:15:55 +01:00
return $form ;
2007-07-19 12:40:05 +02:00
}
2009-10-16 00:43:58 +02:00
2010-02-16 04:36:58 +01:00
/**
* Generate the parameter HTML for SideReports that have params
*
* @ return LiteralField
*/
2009-10-16 00:43:58 +02:00
function ReportFormParameters () {
$forms = array ();
2010-02-04 05:50:38 +01:00
foreach ( $this -> SideReports () as $report ) {
if ( $report -> canView ()) {
if ( $fieldset = $report -> parameterFields ()) {
2009-10-16 00:43:58 +02:00
$formHtml = '' ;
foreach ( $fieldset as $field ) {
2009-10-16 00:44:24 +02:00
$formHtml .= $field -> FieldHolder ();
2009-10-16 00:43:58 +02:00
}
2010-02-04 05:50:38 +01:00
$forms [ $report -> ID ()] = $formHtml ;
2009-10-16 00:43:58 +02:00
}
}
}
$pageHtml = '' ;
foreach ( $forms as $class => $html ) {
$pageHtml .= " <div id= \" SideReportForm_ $class\ " style = \ " display:none \" > $html </div> \n \n " ;
}
return new LiteralField ( " ReportFormParameters " , '<div id="SideReportForms" style="display:none">' . $pageHtml . '</div>' );
}
2007-07-19 12:40:05 +02:00
/**
2009-11-21 04:20:54 +01:00
* @ return Form
2007-07-19 12:40:05 +02:00
*/
2011-03-15 10:30:28 +01:00
function doShowSideReport ( $data , $form ) {
$reportClass = ( isset ( $data [ 'ReportClass' ])) ? $data [ 'ReportClass' ] : $this -> urlParams [ 'ID' ];
2010-05-28 04:23:10 +02:00
$reports = $this -> SideReports ();
if ( isset ( $reports [ $reportClass ])) {
$report = $reports [ $reportClass ];
if ( $report ) {
$view = new SideReportView ( $this , $report );
$view -> setParameters ( $this -> request -> requestVars ());
return $view -> forTemplate ();
} else {
return false ;
}
}
2007-07-19 12:40:05 +02:00
}
2010-05-28 04:23:10 +02:00
2007-07-19 12:40:05 +02:00
/**
2009-11-21 04:16:09 +01:00
* @ return Form
2007-07-19 12:40:05 +02:00
*/
2009-11-21 04:16:09 +01:00
function VersionsForm () {
$pageID = ( $this -> request -> requestVar ( 'ID' )) ? $this -> request -> requestVar ( 'ID' ) : $this -> currentPageID ();
2007-07-19 12:40:05 +02:00
$page = $this -> getRecord ( $pageID );
if ( $page ) {
2009-11-21 04:16:09 +01:00
$versions = $page -> allVersions (
( $this -> request -> requestVar ( 'ShowUnpublished' )) ?
" " : " \" SiteTree \" . \" WasPublished \" = 1 "
2007-09-15 23:54:24 +02:00
);
2009-11-21 04:16:09 +01:00
// inject link to cms
if ( $versions ) foreach ( $versions as $k => $version ) {
$version -> CMSLink = sprintf ( '%s/%s/%s' ,
$this -> Link ( 'getversion' ),
$version -> ID ,
$version -> Version
);
}
$vd = new ViewableData ();
$versionsHtml = $vd -> customise (
array ( 'Versions' => $versions )
) -> renderWith ( 'CMSMain_versions' );
2007-07-19 12:40:05 +02:00
} else {
2009-11-21 04:16:09 +01:00
$versionsHtml = '' ;
2007-07-19 12:40:05 +02:00
}
2009-11-21 04:16:09 +01:00
$form = new Form (
$this ,
'VersionsForm' ,
new FieldSet (
new CheckboxField (
'ShowUnpublished' ,
_t ( 'CMSMain_left.ss.SHOWUNPUB' , 'Show unpublished versions' )
),
new LiteralField ( 'VersionsHtml' , $versionsHtml ),
new HiddenField ( 'ID' , false , $pageID ),
new HiddenField ( 'Locale' , false , $this -> Locale )
),
new FieldSet (
new FormAction (
'versions' ,
_t ( 'CMSMain.BTNREFRESH' , 'Refresh' )
),
new FormAction (
'compareversions' ,
_t ( 'CMSMain.BTNCOMPAREVERSIONS' , 'Compare Versions' )
)
)
);
$form -> loadDataFrom ( $this -> request -> requestVars ());
$form -> setFormMethod ( 'GET' );
$form -> unsetValidator ();
return $form ;
}
/**
* Get the versions of the current page
*/
function versions () {
$form = $this -> VersionsForm ();
return ( Director :: is_ajax ()) ? $form -> forTemplate () : $form ;
2007-07-19 12:40:05 +02:00
}
2007-09-15 23:54:24 +02:00
2007-07-19 12:40:05 +02:00
/**
* Roll a page back to a previous version
*/
2009-11-21 03:39:12 +01:00
function rollback ( $data , $form ) {
2010-04-13 05:28:36 +02:00
$this -> extend ( 'onBeforeRollback' , $data [ 'ID' ]);
2009-11-21 03:39:12 +01:00
if ( isset ( $data [ 'Version' ]) && ( bool ) $data [ 'Version' ]) {
$record = $this -> performRollback ( $data [ 'ID' ], $data [ 'Version' ]);
$message = sprintf (
_t ( 'CMSMain.ROLLEDBACKVERSION' , " Rolled back to version #%d. New version number is #%d " ),
$data [ 'Version' ],
$record -> Version
);
2007-07-19 12:40:05 +02:00
} else {
2009-11-21 03:39:12 +01:00
$record = $this -> performRollback ( $data [ 'ID' ], " Live " );
$message = sprintf (
_t ( 'CMSMain.ROLLEDBACKPUB' , " Rolled back to published version. New version number is #%d " ),
$record -> Version
);
2007-07-19 12:40:05 +02:00
}
2009-11-21 03:39:12 +01:00
$this -> response -> addHeader ( 'X-Status' , $message );
$form = $this -> getEditForm ( $record -> ID );
return $form -> formHtmlContent ();
2007-07-19 12:40:05 +02:00
}
2009-11-21 03:36:13 +01:00
2009-11-21 03:39:12 +01:00
function publish ( $data , $form ) {
$data [ 'publish' ] = '1' ;
2009-11-21 03:36:13 +01:00
2009-11-21 03:39:12 +01:00
return $this -> save ( $data , $form );
2009-11-21 03:36:13 +01:00
}
2007-09-15 23:54:24 +02:00
2009-11-21 03:39:12 +01:00
function unpublish ( $data , $form ) {
2011-03-16 04:41:46 +01:00
$className = $this -> stat ( 'tree_class' );
$record = DataObject :: get_by_id ( $className , $data [ 'ID' ]);
2010-04-13 05:56:00 +02:00
2011-03-16 04:41:46 +01:00
if ( $record && ! $record -> canDeleteFromLive ()) return Security :: permissionFailure ( $this );
2008-11-03 15:56:36 +01:00
2011-03-16 04:41:46 +01:00
$record -> doUnpublish ();
2008-10-16 05:21:49 +02:00
2009-11-21 03:39:12 +01:00
$this -> response -> addHeader (
'X-Status' ,
2011-03-16 04:41:46 +01:00
sprintf ( _t ( 'CMSMain.REMOVEDPAGE' , " Removed '%s' from the published site " ), $record -> Title )
2009-11-21 03:39:12 +01:00
);
2008-03-11 02:02:05 +01:00
2011-03-16 04:41:46 +01:00
// Reload form, data and actions might have changed
$form = $this -> getEditForm ( $record -> ID );
2008-03-11 02:02:05 +01:00
2009-11-21 03:39:12 +01:00
return $form -> formHtmlContent ();
2007-07-19 12:40:05 +02:00
}
2007-09-15 23:54:24 +02:00
2007-07-19 12:40:05 +02:00
function performRollback ( $id , $version ) {
$record = DataObject :: get_by_id ( $this -> stat ( 'tree_class' ), $id );
2009-11-05 02:15:15 +01:00
if ( $record && ! $record -> canEdit ()) return Security :: permissionFailure ( $this );
2008-11-03 15:56:36 +01:00
2008-10-16 05:21:49 +02:00
$record -> doRollbackTo ( $version );
2007-07-19 12:40:05 +02:00
return $record ;
}
2007-09-15 23:54:24 +02:00
2009-11-21 04:16:09 +01:00
/**
* Supports both direct URL links ( format : admin / getversion /< page - id >/< version > ),
* and through GET parameters : admin / getversion / ? ID =< page - id >& Versions [] =< version >
*/
2007-07-19 12:40:05 +02:00
function getversion () {
2009-11-21 04:16:09 +01:00
$id = ( $this -> request -> param ( 'ID' )) ?
$this -> request -> param ( 'ID' ) : $this -> request -> requestVar ( 'ID' );
$version = ( $this -> request -> param ( 'OtherID' )) ?
$this -> request -> param ( 'OtherID' ) : $this -> request -> requestVar ( 'Versions' );
2007-07-19 12:40:05 +02:00
$record = Versioned :: get_version ( " SiteTree " , $id , $version );
2009-09-04 03:18:07 +02:00
2007-07-19 12:40:05 +02:00
if ( $record ) {
2008-11-03 15:56:36 +01:00
if ( $record && ! $record -> canView ()) return Security :: permissionFailure ( $this );
2007-07-19 12:40:05 +02:00
$fields = $record -> getCMSFields ( $this );
$fields -> removeByName ( " Status " );
$fields -> push ( new HiddenField ( " ID " ));
$fields -> push ( new HiddenField ( " Version " ));
2009-09-04 03:18:07 +02:00
$versionAuthor = DataObject :: get_by_id ( 'Member' , $record -> AuthorID );
2009-11-05 02:10:38 +01:00
if ( ! $versionAuthor ) $versionAuthor = new ArrayData ( array ( 'Title' => 'Unknown author' ));
2009-01-05 07:17:59 +01:00
$fields -> insertBefore (
new LiteralField (
'YouAreViewingHeader' ,
'<p class="message notice">' .
sprintf (
_t (
'CMSMain.VIEWING' ,
" You are viewing version #%s, created %s by %s " ,
PR_MEDIUM ,
'Version number is a linked string, created is a relative time (e.g. 2 days ago), by a specific author'
),
2009-07-09 07:41:42 +02:00
" <a href= \" admin/getversion/ $record->ID / $version\ " title = \ " " . ( $versionAuthor ? $versionAuthor -> Title : '' ) . " \" > $version </a> " ,
2009-01-05 07:17:59 +01:00
$record -> obj ( 'LastEdited' ) -> Ago (),
2009-07-09 07:41:42 +02:00
( $versionAuthor ? $versionAuthor -> Title : '' )
2009-01-05 07:17:59 +01:00
) .
'</p>'
),
'Root'
);
2007-07-19 12:40:05 +02:00
2011-01-12 00:00:59 +01:00
$actions = $record -> getCMSActions ();
2007-09-15 23:54:24 +02:00
2007-07-19 12:40:05 +02:00
// encode the message to appear in the body of the email
2007-10-29 01:55:52 +01:00
$archiveURL = Director :: absoluteBaseURL () . $record -> URLSegment . '?archiveDate=' . $record -> obj ( 'LastEdited' ) -> URLDatetime ();
2009-05-06 08:37:45 +02:00
// Ensure that source file comments are disabled
SSViewer :: set_source_file_comments ( false );
2007-07-19 12:40:05 +02:00
$archiveEmailMessage = urlencode ( $this -> customise ( array ( 'ArchiveDate' => $record -> obj ( 'LastEdited' ), 'ArchiveURL' => $archiveURL ) ) -> renderWith ( 'ViewArchivedEmail' ) );
$archiveEmailMessage = preg_replace ( '/\+/' , '%20' , $archiveEmailMessage );
2007-09-15 23:54:24 +02:00
2007-07-19 12:40:05 +02:00
$fields -> push ( new HiddenField ( 'ArchiveEmailMessage' , '' , $archiveEmailMessage ) );
$fields -> push ( new HiddenField ( 'ArchiveEmailSubject' , '' , preg_replace ( '/\+/' , '%20' , urlencode ( 'Archived version of ' . $record -> Title ) ) ) );
$fields -> push ( new HiddenField ( 'ArchiveURL' , '' , $archiveURL ) );
2007-09-15 23:54:24 +02:00
2007-07-19 12:40:05 +02:00
$form = new Form ( $this , " EditForm " , $fields , $actions );
$form -> loadDataFrom ( $record );
$form -> loadDataFrom ( array (
" ID " => $id ,
" Version " => $version ,
));
2009-01-05 07:17:59 +01:00
// historical version shouldn't be editable
$readonlyFields = $form -> Fields () -> makeReadonly ();
$form -> setFields ( $readonlyFields );
2007-09-15 23:54:24 +02:00
2007-07-19 12:40:05 +02:00
$templateData = $this -> customise ( array (
" EditForm " => $form
));
2007-09-15 23:54:24 +02:00
2007-07-19 12:40:05 +02:00
SSViewer :: setOption ( 'rewriteHashlinks' , false );
2009-01-05 07:17:59 +01:00
2010-03-04 05:09:18 +01:00
if ( Director :: is_ajax ()) {
2011-03-15 10:30:28 +01:00
$result = $templateData -> renderWith ( array ( $this -> class . '_right' , 'LeftAndMain_right' ));
2009-01-05 07:17:59 +01:00
$parts = split ( '</?form[^>]*>' , $result );
2010-03-24 21:33:27 +01:00
$content = $parts [ sizeof ( $parts ) - 2 ];
2010-10-13 06:15:18 +02:00
if ( $this -> ShowSwitchView ()) {
$content .= '<div id="AjaxSwitchView">' . $this -> SwitchView ( $record ) . '</div>' ;
}
return $content ;
2009-01-05 07:17:59 +01:00
} else {
return $templateData -> renderWith ( 'LeftAndMain' );
}
2007-07-19 12:40:05 +02:00
}
}
2007-09-15 23:54:24 +02:00
2007-07-19 12:40:05 +02:00
function compareversions () {
2009-11-21 04:16:09 +01:00
$id = ( $this -> request -> param ( 'ID' )) ?
$this -> request -> param ( 'ID' ) : $this -> request -> requestVar ( 'ID' );
$versions = $this -> request -> requestVar ( 'Versions' );
$version1 = ( $versions && isset ( $versions [ 0 ])) ?
$versions [ 0 ] : $this -> request -> getVar ( 'From' );
$version2 = ( $versions && isset ( $versions [ 1 ])) ?
$versions [ 1 ] : $this -> request -> getVar ( 'To' );
2007-09-15 23:54:24 +02:00
2007-07-19 12:40:05 +02:00
if ( $version1 > $version2 ) {
$toVersion = $version1 ;
$fromVersion = $version2 ;
} else {
$toVersion = $version2 ;
$fromVersion = $version1 ;
}
2009-11-21 04:16:09 +01:00
if ( ! $toVersion || ! $toVersion ) return false ;
2007-07-19 12:40:05 +02:00
$page = DataObject :: get_by_id ( " SiteTree " , $id );
2008-11-03 15:56:36 +01:00
if ( $page && ! $page -> canView ()) return Security :: permissionFailure ( $this );
2007-07-19 12:40:05 +02:00
$record = $page -> compareVersions ( $fromVersion , $toVersion );
2010-04-13 05:28:36 +02:00
2009-01-05 07:17:59 +01:00
$fromVersionRecord = Versioned :: get_version ( 'SiteTree' , $id , $fromVersion );
$toVersionRecord = Versioned :: get_version ( 'SiteTree' , $id , $toVersion );
2009-05-23 05:30:57 +02:00
if ( ! $fromVersionRecord ) user_error ( " Can't find version $fromVersion of page $id " , E_USER_ERROR );
if ( ! $toVersionRecord ) user_error ( " Can't find version $toVersion of page $id " , E_USER_ERROR );
2009-01-05 07:17:59 +01:00
2007-07-19 12:40:05 +02:00
if ( $record ) {
2009-01-05 07:17:59 +01:00
$fromDateNice = $fromVersionRecord -> obj ( 'LastEdited' ) -> Ago ();
$toDateNice = $toVersionRecord -> obj ( 'LastEdited' ) -> Ago ();
$fromAuthor = DataObject :: get_by_id ( 'Member' , $fromVersionRecord -> AuthorID );
2009-05-23 05:30:57 +02:00
if ( ! $fromAuthor ) $fromAuthor = new ArrayData ( array ( 'Title' => 'Unknown author' ));
2009-01-05 07:17:59 +01:00
$toAuthor = DataObject :: get_by_id ( 'Member' , $toVersionRecord -> AuthorID );
2009-05-23 05:30:57 +02:00
if ( ! $toAuthor ) $toAuthor = new ArrayData ( array ( 'Title' => 'Unknown author' ));
2009-01-05 07:17:59 +01:00
2007-07-19 12:40:05 +02:00
$fields = $record -> getCMSFields ( $this );
$fields -> push ( new HiddenField ( " ID " ));
$fields -> push ( new HiddenField ( " Version " ));
2009-01-05 07:17:59 +01:00
$fields -> insertBefore (
new LiteralField (
'YouAreComparingHeader' ,
'<p class="message notice">' .
sprintf (
_t ( 'CMSMain.COMPARINGV' , " Comparing versions %s and %s " ),
" <a href= \" admin/getversion/ $id / $fromVersionRecord->Version\ " title = \ " $fromAuthor->Title\ " > $fromVersionRecord -> Version </ a > < small > ( $fromDateNice ) </ small > " ,
" <a href= \" admin/getversion/ $id / $toVersionRecord->Version\ " title = \ " $toAuthor->Title\ " > $toVersionRecord -> Version </ a > < small > ( $toDateNice ) </ small > "
) .
'</p>'
),
" Root "
);
2007-07-19 12:40:05 +02:00
$actions = new FieldSet ();
$form = new Form ( $this , " EditForm " , $fields , $actions );
$form -> loadDataFrom ( $record );
$form -> loadDataFrom ( array (
" ID " => $id ,
2008-02-25 03:10:37 +01:00
" Version " => $fromVersion ,
2007-07-19 12:40:05 +02:00
));
2011-03-15 22:14:23 +01:00
$form -> addExtraClass ( 'compare' );
2009-01-05 07:17:59 +01:00
// comparison views shouldn't be editable
$readonlyFields = $form -> Fields () -> makeReadonly ();
$form -> setFields ( $readonlyFields );
2007-07-19 12:40:05 +02:00
foreach ( $form -> Fields () -> dataFields () as $field ) {
$field -> dontEscape = true ;
}
2007-09-15 23:54:24 +02:00
2010-10-13 04:10:28 +02:00
if ( $this -> isAjax ()) {
2009-11-21 04:16:09 +01:00
return $form -> formHtmlContent ();
} else {
$templateData = $this -> customise ( array (
" EditForm " => $form
));
return $templateData -> renderWith ( 'LeftAndMain' );
2011-02-14 23:50:24 +01:00
}
2007-07-19 12:40:05 +02:00
}
}
2007-09-15 23:54:24 +02:00
2007-07-19 12:40:05 +02:00
function sendFormToBrowser ( $templateData ) {
2010-03-04 05:09:18 +01:00
if ( Director :: is_ajax ()) {
2007-07-19 12:40:05 +02:00
SSViewer :: setOption ( 'rewriteHashlinks' , false );
$result = $this -> customise ( $templateData ) -> renderWith ( $this -> class . '_right' );
$parts = split ( '</?form[^>]*>' , $result );
return $parts [ sizeof ( $parts ) - 2 ];
} else {
return array (
" Right " => $this -> customise ( $templateData ) -> renderWith ( $this -> class . '_right' ),
);
}
}
2007-09-15 23:54:24 +02:00
2007-09-16 17:04:09 +02:00
/**
2009-05-14 08:11:18 +02:00
* Batch Actions Handler
2007-09-16 17:04:09 +02:00
*/
2009-05-14 08:11:18 +02:00
function batchactions () {
return new CMSBatchActionHandler ( $this , 'batchactions' );
2007-09-16 17:04:09 +02:00
}
2009-01-06 03:18:33 +01:00
2009-10-16 00:43:58 +02:00
function BatchActionParameters () {
$batchActions = CMSBatchActionHandler :: $batch_actions ;
$forms = array ();
2009-10-16 00:44:08 +02:00
foreach ( $batchActions as $urlSegment => $batchAction ) {
2010-01-13 01:09:30 +01:00
$SNG_action = singleton ( $batchAction );
if ( $SNG_action -> canView () && $fieldset = $SNG_action -> getParameterFields ()) {
2009-10-16 00:43:58 +02:00
$formHtml = '' ;
foreach ( $fieldset as $field ) {
$formHtml .= $field -> Field ();
}
2009-10-16 00:44:08 +02:00
$forms [ $urlSegment ] = $formHtml ;
2009-10-16 00:43:58 +02:00
}
}
$pageHtml = '' ;
2009-10-16 00:44:08 +02:00
foreach ( $forms as $urlSegment => $html ) {
$pageHtml .= " <div class= \" params \" id= \" BatchActionParameters_ $urlSegment\ " > $html </ div > \n\n " ;
2009-10-16 00:43:58 +02:00
}
return new LiteralField ( " BatchActionParameters " , '<div id="BatchActionParameters" style="display:none">' . $pageHtml . '</div>' );
}
2007-07-19 12:40:05 +02:00
/**
2009-05-14 08:11:18 +02:00
* Returns a list of batch actions
2007-07-19 12:40:05 +02:00
*/
2009-05-14 08:11:18 +02:00
function BatchActionList () {
return $this -> batchactions () -> batchActionList ();
2007-07-19 12:40:05 +02:00
}
2009-01-06 03:18:33 +01:00
2010-11-01 02:29:02 +01:00
function buildbrokenlinks ( $request ) {
// Protect against CSRF on destructive action
if ( ! SecurityToken :: inst () -> checkRequest ( $request )) return $this -> httpError ( 400 );
2007-07-19 12:40:05 +02:00
if ( $this -> urlParams [ 'ID' ]) {
$newPageSet [] = DataObject :: get_by_id ( " Page " , $this -> urlParams [ 'ID' ]);
} else {
$pages = DataObject :: get ( " Page " );
foreach ( $pages as $page ) $newPageSet [] = $page ;
$pages = null ;
}
2007-09-15 23:54:24 +02:00
2007-07-19 12:40:05 +02:00
$content = new HtmlEditorField ( 'Content' );
$download = new HtmlEditorField ( 'Download' );
foreach ( $newPageSet as $i => $page ) {
$page -> HasBrokenLink = 0 ;
$page -> HasBrokenFile = 0 ;
$lastUsage = ( memory_get_usage () - $lastPoint );
$lastPoint = memory_get_usage ();
$content -> setValue ( $page -> Content );
$content -> saveInto ( $page );
$download -> setValue ( $page -> Download );
$download -> saveInto ( $page );
echo " <li> $page->Title (link: $page->HasBrokenLink , file: $page->HasBrokenFile ) " ;
2007-09-15 23:54:24 +02:00
2007-07-19 12:40:05 +02:00
$page -> writeWithoutVersion ();
$page -> destroy ();
$newPageSet [ $i ] = null ;
}
}
2009-11-21 04:18:51 +01:00
function AddForm () {
2007-07-19 12:40:05 +02:00
$pageTypes = array ();
2007-09-15 23:54:24 +02:00
2007-07-19 12:40:05 +02:00
foreach ( $this -> PageTypes () as $arrayData ) {
$pageTypes [ $arrayData -> getField ( 'ClassName' )] = $arrayData -> getField ( 'AddAction' );
}
2009-03-18 18:18:52 +01:00
$fields = new FieldSet (
2007-09-15 23:54:24 +02:00
new HiddenField ( " ParentID " ),
2009-02-03 04:22:20 +01:00
new DropdownField ( " PageType " , " " , $pageTypes , 'Page' )
2009-03-18 18:18:52 +01:00
);
2010-04-13 05:51:24 +02:00
$this -> extend ( 'updatePageOptions' , $fields );
2009-03-18 18:18:52 +01:00
$actions = new FieldSet (
2009-11-21 04:18:59 +01:00
new FormAction ( " doAdd " , _t ( 'CMSMain.GO' , " Go " ))
2009-03-18 18:18:52 +01:00
);
2009-11-21 04:18:51 +01:00
$form = new Form ( $this , " AddForm " , $fields , $actions );
2009-11-21 04:15:16 +01:00
$form -> addExtraClass ( 'actionparams' );
2009-11-21 04:21:08 +01:00
$form -> addExtraClass ( 'oneline' );
2009-11-21 04:15:16 +01:00
return $form ;
2007-07-19 12:40:05 +02:00
}
2011-02-21 22:52:56 +01:00
/**
* Form used to filter the sitetree . It can only be used via javascript for now .
*
* @ return Form
*/
function SearchTreeForm () {
// get all page types in a dropdown-compatible format
$pageTypes = SiteTree :: page_type_classes ();
array_unshift ( $pageTypes , 'All' );
$pageTypes = array_combine ( $pageTypes , $pageTypes );
asort ( $pageTypes );
// get all filter instances
$filters = ClassInfo :: subclassesFor ( 'CMSSiteTreeFilter' );
$filterMap = array ();
// remove base class
array_shift ( $filters );
// add filters to map
foreach ( $filters as $filter ) {
$filterMap [ $filter ] = call_user_func ( array ( $filter , 'title' ));
}
// ensure that 'all pages' filter is on top position
uasort ( $filterMap ,
create_function ( '$a,$b' , 'return ($a == "CMSSiteTreeFilter_Search") ? 1 : -1;' )
);
$showDefaultFields = array ();
$form = new Form (
$this ,
'SearchTreeForm' ,
new FieldSet (
$showDefaultFields [] = new DropdownField (
'FilterClass' ,
_t ( 'CMSMain.SearchTreeFormPagesDropdown' , 'Pages' ),
$filterMap
),
$showDefaultFields [] = new TextField (
'Title' ,
_t ( 'CMSMain.TITLEOPT' , 'Title' )
),
2011-03-19 21:59:26 +01:00
new TextField ( 'Content' , _t ( 'CMSMain.TEXTOPT' , 'Text' , PR_MEDIUM , 'Text field for fulltext search in page content' )),
2011-02-21 22:52:56 +01:00
new DateField ( 'EditedSince' , _t ( 'CMSMain_left.ss.EDITEDSINCE' , 'Edited Since' )),
2011-03-19 21:59:26 +01:00
new DropdownField (
'ClassName' ,
_t ( 'CMSMain.PAGETYPEOPT' , 'Page Type' , PR_MEDIUM , 'Dropdown for limiting search to a page type' ),
$pageTypes ,
null ,
null ,
_t ( 'CMSMain.PAGETYPEANYOPT' , 'Any' )
),
2011-02-21 22:52:56 +01:00
new TextField (
'MenuTitle' ,
_t ( 'CMSMain.MENUTITLEOPT' , 'Navigation Label' )
),
new TextField (
'Status' ,
_t ( 'CMSMain.STATUSOPT' , 'Status' )
),
new TextField (
'MetaDescription' ,
_t ( 'CMSMain.METADESCOPT' , 'Description' )
),
new TextField (
'MetaKeywords' ,
_t ( 'CMSMain.METAKEYWORDSOPT' , 'Keywords' )
)
),
new FieldSet (
new ResetFormAction (
'clear' ,
_t ( 'CMSMain_left.ss.CLEAR' , 'Clear' )
),
new FormAction (
'doSearchTree' ,
_t ( 'CMSMain_left.ss.SEARCH' , 'Search' )
)
)
);
$form -> setFormMethod ( 'GET' );
$form -> disableSecurityToken ();
$form -> unsetValidator ();
foreach ( $showDefaultFields as $f ) $f -> addExtraClass ( 'show-default' );
return $form ;
}
2009-11-21 03:37:06 +01:00
2011-02-21 22:52:56 +01:00
function doSearchTree ( $data , $form ) {
return $this -> getsubtree ( $this -> request );
}
2009-11-21 03:37:06 +01:00
/**
2007-07-19 12:40:05 +02:00
* Helper function to get page count
2009-11-21 03:37:06 +01:00
*/
2007-07-19 12:40:05 +02:00
function getpagecount () {
2008-11-10 06:06:08 +01:00
ini_set ( 'max_execution_time' , 0 );
2007-07-19 12:40:05 +02:00
$excludePages = split ( " *, * " , $_GET [ 'exclude' ]);
2007-09-15 23:54:24 +02:00
2008-11-24 10:30:41 +01:00
$pages = DataObject :: get ( " SiteTree " , " \" ParentID \" = 0 " );
2007-07-19 12:40:05 +02:00
foreach ( $pages as $page ) $pageArr [] = $page ;
2007-09-15 23:54:24 +02:00
2007-07-19 12:40:05 +02:00
while ( list ( $i , $page ) = each ( $pageArr )) {
if ( ! in_array ( $page -> URLSegment , $excludePages )) {
if ( $children = $page -> AllChildren ()) {
foreach ( $children as $child ) $pageArr [] = $child ;
}
if ( ! $_GET [ 'onlywithcontent' ] || strlen ( Convert :: xml2raw ( $page -> Content )) > 100 ) {
echo " <li> " . $page -> Breadcrumbs ( null , true ) . " </li> " ;
$count ++ ;
} else {
2007-09-15 22:21:13 +02:00
echo " <li style= \" color: #777 \" > " . $page -> Breadcrumbs ( null , true ) . " - " . _t ( 'CMSMain.NOCONTENT' , " no content " ) . " </li> " ;
2007-07-19 12:40:05 +02:00
}
2007-09-15 23:54:24 +02:00
2007-07-19 12:40:05 +02:00
}
2009-11-21 04:15:43 +01:00
}
2009-11-22 09:23:12 +01:00
2007-09-15 22:21:13 +02:00
echo '<p>' . _t ( 'CMSMain.TOTALPAGES' , " Total pages: " ) . " $count </p> " ;
2009-11-21 03:37:06 +01:00
}
2007-09-15 23:54:24 +02:00
2010-11-01 02:29:02 +01:00
function publishall ( $request ) {
2008-10-08 23:33:07 +02:00
ini_set ( " memory_limit " , - 1 );
2008-11-10 06:06:08 +01:00
ini_set ( 'max_execution_time' , 0 );
2008-08-12 04:59:27 +02:00
$response = " " ;
2007-09-15 23:54:24 +02:00
2008-08-12 04:59:27 +02:00
if ( isset ( $this -> requestParams [ 'confirm' ])) {
2010-11-01 02:29:02 +01:00
// Protect against CSRF on destructive action
if ( ! SecurityToken :: inst () -> checkRequest ( $request )) return $this -> httpError ( 400 );
2008-02-25 03:10:37 +01:00
$start = 0 ;
$pages = DataObject :: get ( " SiteTree " , " " , " " , " " , " $start ,30 " );
2007-07-19 12:40:05 +02:00
$count = 0 ;
2010-12-14 02:29:38 +01:00
while ( $pages ) {
foreach ( $pages as $page ) {
if ( $page && ! $page -> canPublish ()) return Security :: permissionFailure ( $this );
$page -> doPublish ();
$page -> destroy ();
unset ( $page );
$count ++ ;
$response .= " <li> $count </li> " ;
}
if ( $pages -> Count () > 29 ) {
$start += 30 ;
$pages = DataObject :: get ( " SiteTree " , " " , " " , " " , " $start ,30 " );
} else {
break ;
2008-02-25 03:10:37 +01:00
}
2007-07-19 12:40:05 +02:00
}
2008-08-12 04:59:27 +02:00
$response .= sprintf ( _t ( 'CMSMain.PUBPAGES' , " Done: Published %d pages " ), $count );
2007-09-15 23:54:24 +02:00
2007-07-19 12:40:05 +02:00
} else {
2010-11-01 02:29:02 +01:00
$token = SecurityToken :: inst ();
2010-11-02 20:22:50 +01:00
$fields = new FieldSet ();
$token -> updateFieldSet ( $fields );
$tokenField = $fields -> First ();
$tokenHtml = ( $tokenField ) ? $tokenField -> FieldHolder () : '' ;
2008-08-12 04:59:27 +02:00
$response .= '<h1>' . _t ( 'CMSMain.PUBALLFUN' , '"Publish All" functionality' ) . ' </ h1 >
2007-09-15 22:21:13 +02:00
< p > ' . _t(' CMSMain . PUBALLFUN2 ', ' Pressing this button will do the equivalent of going to every page and pressing " publish " . It\ ' s
2007-07-19 12:40:05 +02:00
intended to be used after there have been massive edits of the content , such as when the site was
2007-09-15 22:21:13 +02:00
first built . ') . ' </ p >
2007-07-19 12:40:05 +02:00
< form method = " post " action = " publishall " >
2007-09-15 23:54:24 +02:00
< input type = " submit " name = " confirm " value = " '
2010-11-01 02:29:02 +01:00
. _t ( 'CMSMain.PUBALLCONFIRM' , " Please publish every page in the site, copying content stage to live " , PR_LOW , 'Confirmation button' ) . '" />'
2010-11-02 20:22:50 +01:00
. $tokenHtml .
2010-11-01 02:29:02 +01:00
'</form>' ;
2007-07-19 12:40:05 +02:00
}
2008-08-12 04:59:27 +02:00
return $response ;
2007-07-19 12:40:05 +02:00
}
2009-01-10 12:36:30 +01:00
2009-01-05 07:17:59 +01:00
/**
2009-05-01 00:47:28 +02:00
* Restore a completely deleted page from the SiteTree_versions table .
2009-01-05 07:17:59 +01:00
*/
2009-11-21 03:39:12 +01:00
function restore ( $data , $form ) {
if ( ! isset ( $data [ 'ID' ]) || ! is_numeric ( $data [ 'ID' ])) {
2010-06-03 02:00:14 +02:00
return new SS_HTTPResponse ( " Please pass an ID in the form content " , 400 );
2007-07-19 12:40:05 +02:00
}
2009-11-21 03:39:12 +01:00
2009-11-21 04:19:49 +01:00
$id = ( int ) $data [ 'ID' ];
2009-11-21 03:39:12 +01:00
$restoredPage = Versioned :: get_latest_version ( " SiteTree " , $id );
2010-06-03 02:00:14 +02:00
if ( ! $restoredPage ) return new SS_HTTPResponse ( " SiteTree # $id not found " , 400 );
2009-11-21 03:39:12 +01:00
$restoredPage = $restoredPage -> doRestoreToStage ();
$this -> response -> addHeader (
'X-Status' ,
sprintf (
_t ( 'CMSMain.RESTORED' , " Restored '%s' successfully " , PR_MEDIUM , 'Param %s is a title' ),
$restoredPage -> TreeTitle
)
);
2011-03-16 04:41:46 +01:00
// Reload form, data and actions might have changed
$form = $this -> getEditForm ( $restoredPage -> ID );
2009-11-21 03:39:12 +01:00
return $form -> formHtmlContent ();
2007-07-19 12:40:05 +02:00
}
2007-09-15 23:54:24 +02:00
2010-11-01 02:29:02 +01:00
function duplicate ( $request ) {
// Protect against CSRF on destructive action
if ( ! SecurityToken :: inst () -> checkRequest ( $request )) return $this -> httpError ( 400 );
2007-07-19 12:40:05 +02:00
if (( $id = $this -> urlParams [ 'ID' ]) && is_numeric ( $id )) {
$page = DataObject :: get_by_id ( " SiteTree " , $id );
2009-08-25 07:52:52 +02:00
if ( $page && ( ! $page -> canEdit () || ! $page -> canCreate ())) {
return Security :: permissionFailure ( $this );
}
2007-07-19 12:40:05 +02:00
$newPage = $page -> duplicate ();
2008-02-25 03:10:37 +01:00
// ParentID can be hard-set in the URL. This is useful for pages with multiple parents
if ( $_GET [ 'parentID' ] && is_numeric ( $_GET [ 'parentID' ])) {
$newPage -> ParentID = $_GET [ 'parentID' ];
$newPage -> write ();
}
2009-11-21 03:39:12 +01:00
2011-03-16 04:41:46 +01:00
// Reload form, data and actions might have changed
2009-11-21 03:39:12 +01:00
$form = $this -> getEditForm ( $newPage -> ID );
2011-03-16 04:41:46 +01:00
2009-11-21 03:39:12 +01:00
return $form -> formHtmlContent ();
2008-02-25 03:10:37 +01:00
} else {
user_error ( " CMSMain::duplicate() Bad ID: ' $id ' " , E_USER_WARNING );
}
}
2010-11-01 02:29:02 +01:00
function duplicatewithchildren ( $request ) {
// Protect against CSRF on destructive action
if ( ! SecurityToken :: inst () -> checkRequest ( $request )) return $this -> httpError ( 400 );
2008-02-25 03:10:37 +01:00
if (( $id = $this -> urlParams [ 'ID' ]) && is_numeric ( $id )) {
$page = DataObject :: get_by_id ( " SiteTree " , $id );
2009-08-25 07:52:52 +02:00
if ( $page && ( ! $page -> canEdit () || ! $page -> canCreate ())) {
return Security :: permissionFailure ( $this );
}
2008-02-25 03:10:37 +01:00
$newPage = $page -> duplicateWithChildren ();
2008-01-24 01:01:52 +01:00
2011-03-16 04:41:46 +01:00
// Reload form, data and actions might have changed
2009-11-21 03:39:12 +01:00
$form = $this -> getEditForm ( $newPage -> ID );
2011-03-16 04:41:46 +01:00
2009-11-21 03:39:12 +01:00
return $form -> formHtmlContent ();
2008-01-24 01:01:52 +01:00
} else {
user_error ( " CMSMain::duplicate() Bad ID: ' $id ' " , E_USER_WARNING );
}
}
2011-03-29 10:35:00 +02:00
/**
* Return the version number of this application .
* Uses the subversion path information in < mymodule >/ silverstripe_version
* ( automacially replaced $URL $ placeholder ) .
*
* @ return string
*/
public function CMSVersion () {
$sapphireVersionFile = file_get_contents ( BASE_PATH . '/sapphire/silverstripe_version' );
$cmsVersionFile = file_get_contents ( BASE_PATH . '/cms/silverstripe_version' );
$sapphireVersion = $this -> versionFromVersionFile ( $sapphireVersionFile );
$cmsVersion = $this -> versionFromVersionFile ( $cmsVersionFile );
return " cms: $cmsVersion , sapphire: $sapphireVersion " ;
}
2007-07-19 12:40:05 +02:00
/**
* Provide the permission codes used by LeftAndMain .
* Can 't put it on LeftAndMain since that' s an abstract base class .
*/
function providePermissions () {
$classes = ClassInfo :: subclassesFor ( 'LeftAndMain' );
2007-09-15 23:54:24 +02:00
2009-10-29 01:55:20 +01:00
foreach ( $classes as $i => $class ) {
2009-01-05 07:17:59 +01:00
$title = _t ( " { $class } .MENUTITLE " , LeftAndMain :: menu_title_for_class ( $class ));
2010-10-13 06:12:59 +02:00
$perms [ " CMS_ACCESS_ " . $class ] = array (
2009-10-29 01:55:20 +01:00
'name' => sprintf ( _t (
2009-01-05 07:17:59 +01:00
'CMSMain.ACCESS' ,
2010-10-13 06:12:59 +02:00
" Access to '%s' section " ,
2009-01-05 07:17:59 +01:00
PR_MEDIUM ,
2010-05-26 01:41:18 +02:00
" Item in permission selection identifying the admin section. Example: Access to 'Files & Images' "
2010-04-13 22:37:34 +02:00
), $title , null ),
2009-10-31 01:58:30 +01:00
'category' => _t ( 'Permission.CMS_ACCESS_CATEGORY' , 'CMS Access' )
2009-01-05 07:17:59 +01:00
);
2007-07-19 12:40:05 +02:00
}
2009-10-29 01:55:20 +01:00
$perms [ " CMS_ACCESS_LeftAndMain " ] = array (
'name' => _t ( 'CMSMain.ACCESSALLINTERFACES' , 'Access to all CMS sections' ),
2009-10-31 01:58:30 +01:00
'category' => _t ( 'Permission.CMS_ACCESS_CATEGORY' , 'CMS Access' ),
2010-10-04 08:06:32 +02:00
'help' => _t ( 'CMSMain.ACCESSALLINTERFACESHELP' , 'Overrules more specific access settings.' ),
2009-10-29 01:55:20 +01:00
'sort' => - 100
2009-01-05 07:17:59 +01:00
);
2010-10-13 06:12:59 +02:00
$perms [ 'CMS_ACCESS_CMSMain' ][ 'help' ] = _t (
'CMSMain.ACCESS_HELP' ,
'Allow viewing of the section containing page tree and content. View and edit permissions can be handled through page specific dropdowns, as well as the separate "Content permissions".'
);
$perms [ 'CMS_ACCESS_SecurityAdmin' ][ 'help' ] = _t (
'SecurityAdmin.ACCESS_HELP' ,
'Allow viewing, adding and editing users, as well as assigning permissions and roles to them.'
);
2009-10-29 01:55:20 +01:00
if ( isset ( $perms [ 'CMS_ACCESS_ModelAdmin' ])) unset ( $perms [ 'CMS_ACCESS_ModelAdmin' ]);
2010-10-04 08:04:21 +02:00
2007-07-19 12:40:05 +02:00
return $perms ;
}
2007-09-16 22:53:31 +02:00
2007-07-19 12:40:05 +02:00
}
2007-09-19 16:04:50 +02:00
2010-04-23 03:30:33 +02:00
/**
* @ package cms
* @ subpackage content
*/
2009-05-18 01:19:51 +02:00
class CMSMainMarkingFilter {
function __construct () {
$this -> ids = array ();
$this -> expanded = array ();
$where = array ();
// Match against URLSegment, Title, MenuTitle & Content
if ( isset ( $_REQUEST [ 'SiteTreeSearchTerm' ])) {
$term = Convert :: raw2sql ( $_REQUEST [ 'SiteTreeSearchTerm' ]);
$where [] = " \" URLSegment \" LIKE '% $term %' OR \" Title \" LIKE '% $term %' OR \" MenuTitle \" LIKE '% $term %' OR \" Content \" LIKE '% $term %' " ;
2007-11-15 23:46:52 +01:00
}
2009-05-18 01:19:51 +02:00
// Match against date
if ( isset ( $_REQUEST [ 'SiteTreeFilterDate' ])) {
$date = $_REQUEST [ 'SiteTreeFilterDate' ];
$date = (( int ) substr ( $date , 6 , 4 )) . '-' . (( int ) substr ( $date , 3 , 2 )) . '-' . (( int ) substr ( $date , 0 , 2 ));
$where [] = " \" LastEdited \" > ' $date ' " ;
2007-09-16 17:19:17 +02:00
}
2009-05-18 01:19:51 +02:00
// Match against exact ClassName
if ( isset ( $_REQUEST [ 'ClassName' ]) && $_REQUEST [ 'ClassName' ] != 'All' ) {
$klass = Convert :: raw2sql ( $_REQUEST [ 'ClassName' ]);
$where [] = " \" ClassName \" = ' $klass ' " ;
2007-09-16 17:19:17 +02:00
}
2007-11-15 23:46:52 +01:00
2009-05-18 01:19:51 +02:00
// Partial string match against a variety of fields
foreach ( CMSMain :: T_SiteTreeFilterOptions () as $key => $value ) {
if ( ! empty ( $_REQUEST [ $key ])) {
$match = Convert :: raw2sql ( $_REQUEST [ $key ]);
$where [] = " \" $key\ " LIKE '%$match%' " ;
2007-09-16 17:19:17 +02:00
}
}
2009-05-18 01:19:51 +02:00
$where = empty ( $where ) ? '' : 'WHERE (' . implode ( ') AND (' , $where ) . ')' ;
$parents = array ();
/* Do the actual search */
$res = DB :: query ( 'SELECT "ParentID", "ID" FROM "SiteTree" ' . $where );
if ( ! $res ) return ;
/* And keep a record of parents we don't need to get parents of themselves, as well as IDs to mark */
foreach ( $res as $row ) {
if ( $row [ 'ParentID' ]) $parents [ $row [ 'ParentID' ]] = true ;
$this -> ids [ $row [ 'ID' ]] = true ;
2007-09-16 17:19:17 +02:00
}
2007-11-15 23:46:52 +01:00
2009-05-18 01:19:51 +02:00
/* We need to recurse up the tree, finding ParentIDs for each ID until we run out of parents */
while ( ! empty ( $parents )) {
$res = DB :: query ( 'SELECT "ParentID", "ID" FROM "SiteTree" WHERE "ID" in (' . implode ( ',' , array_keys ( $parents )) . ')' );
$parents = array ();
foreach ( $res as $row ) {
if ( $row [ 'ParentID' ]) $parents [ $row [ 'ParentID' ]] = true ;
$this -> ids [ $row [ 'ID' ]] = true ;
$this -> expanded [ $row [ 'ID' ]] = true ;
}
}
}
function mark ( $node ) {
$id = $node -> ID ;
2009-05-26 06:06:33 +02:00
if ( array_key_exists (( int ) $id , $this -> expanded )) $node -> markOpened ();
return array_key_exists (( int ) $id , $this -> ids ) ? $this -> ids [ $id ] : false ;
2007-09-16 17:19:17 +02:00
}
}
2007-07-19 12:40:05 +02:00
2009-04-29 03:44:28 +02:00
?>