2011-12-20 15:57:02 +01:00
< ? php
2016-06-16 16:57:19 +12:00
2024-10-17 12:49:24 +13:00
namespace SilverStripe\CMS\Forms ;
2016-07-22 11:32:32 +12:00
2024-10-17 12:49:24 +13:00
use SilverStripe\CMS\Controllers\CMSMain ;
use SilverStripe\CMS\Controllers\CMSPageEditController ;
2016-08-23 14:36:06 +12:00
use SilverStripe\CMS\Model\SiteTree ;
2016-09-09 11:26:24 +12:00
use SilverStripe\Control\HTTPResponse ;
2019-01-14 13:16:30 +13:00
use SilverStripe\Core\Config\Config ;
2017-08-24 10:39:25 +01:00
use SilverStripe\Core\Convert ;
2016-08-23 14:36:06 +12:00
use SilverStripe\Forms\FieldList ;
use SilverStripe\Forms\Form ;
use SilverStripe\Forms\FormAction ;
use SilverStripe\Forms\LiteralField ;
use SilverStripe\Forms\OptionsetField ;
use SilverStripe\Forms\SelectionGroup ;
use SilverStripe\Forms\SelectionGroup_Item ;
use SilverStripe\Forms\TreeDropdownField ;
2016-06-16 16:57:19 +12:00
use SilverStripe\ORM\DataObject ;
2016-07-14 11:49:22 +12:00
use SilverStripe\ORM\FieldType\DBField ;
2016-06-23 11:51:20 +12:00
use SilverStripe\Security\Security ;
2020-10-22 21:21:15 +13:00
use SilverStripe\SiteConfig\SiteConfig ;
2016-06-16 16:57:19 +12:00
2024-10-17 12:49:24 +13:00
class CMSMainAddForm extends Form
2017-01-26 09:59:25 +13:00
{
2024-10-17 12:49:24 +13:00
public function __construct ( CMSMain $controller )
2017-01-26 09:59:25 +13:00
{
2024-10-17 12:49:24 +13:00
$modelClass = $controller -> getModelClass ();
2020-04-19 16:18:01 +12:00
$pageTypes = [];
2024-10-17 12:49:24 +13:00
$defaultIcon = Config :: inst () -> get ( $modelClass , 'icon_class' ); // @TODO need a better place for default - maybe try default on class, and fallback to default on cmsmain?
2019-05-08 16:13:33 +12:00
2024-10-17 12:49:24 +13:00
foreach ( $controller -> RecordTypes () as $type ) {
2019-05-08 16:13:33 +12:00
$class = $type -> getField ( 'ClassName' );
$icon = Config :: inst () -> get ( $class , 'icon_class' ) ? : $defaultIcon ;
2024-10-17 12:49:24 +13:00
// If the icon is the default and there's some specific icon being provided by `getPageIconURL`
2019-05-08 16:13:33 +12:00
// then we don't need to add the icon class. Otherwise the class take precedence.
if ( $icon === $defaultIcon && ! empty ( singleton ( $class ) -> getPageIconURL ())) {
$icon = '' ;
}
2017-01-26 09:59:25 +13:00
$html = sprintf (
2019-01-14 13:16:30 +13:00
'<span class="page-icon %s class-%s"></span><span class="title">%s</span><span class="form__field-description">%s</span>' ,
2019-05-08 16:13:33 +12:00
$icon ,
Convert :: raw2htmlid ( $class ),
2017-01-26 09:59:25 +13:00
$type -> getField ( 'AddAction' ),
$type -> getField ( 'Description' )
);
2019-05-08 16:13:33 +12:00
$pageTypes [ $class ] = DBField :: create_field ( 'HTMLFragment' , $html );
2017-01-26 09:59:25 +13:00
}
// Ensure generic page type shows on top
if ( isset ( $pageTypes [ 'Page' ])) {
$pageTitle = $pageTypes [ 'Page' ];
2020-04-19 16:18:01 +12:00
$pageTypes = array_merge ([ 'Page' => $pageTitle ], $pageTypes );
2017-01-26 09:59:25 +13:00
}
$numericLabelTmpl = '<span class="step-label"><span class="flyout">Step %d. </span><span class="title">%s</span></span>' ;
2024-10-17 12:49:24 +13:00
$topTitle = _t ( __CLASS__ . '.ParentMode_top' , 'Top level' );
$childTitle = _t (
__CLASS__ . '.ParentMode_child' ,
'Under another {type}' ,
[ 'type' => mb_strtolower ( DataObject :: singleton ( $modelClass ) -> i18n_singular_name ())]
);
2017-01-26 09:59:25 +13:00
2024-10-17 12:49:24 +13:00
$fields = FieldList :: create (
$parentModeField = SelectionGroup :: create (
'ParentModeField' ,
2020-04-19 16:18:01 +12:00
[
2024-10-17 12:49:24 +13:00
$topField = SelectionGroup_Item :: create (
'top' ,
2017-01-26 09:59:25 +13:00
null ,
$topTitle
),
2024-10-17 12:49:24 +13:00
SelectionGroup_Item :: create (
2017-01-26 09:59:25 +13:00
'child' ,
2024-10-17 12:49:24 +13:00
$parentField = TreeDropdownField :: create (
'ParentID' ,
'' ,
$modelClass ,
2017-01-26 09:59:25 +13:00
'ID' ,
'TreeTitle'
),
$childTitle
)
2020-04-19 16:18:01 +12:00
]
2017-01-26 09:59:25 +13:00
),
2024-10-17 12:49:24 +13:00
LiteralField :: create (
2017-01-26 09:59:25 +13:00
'RestrictedNote' ,
sprintf (
2019-05-03 15:35:08 +12:00
'<p class="alert alert-info message-restricted">%s</p>' ,
2017-01-26 09:59:25 +13:00
_t (
2017-04-20 13:15:29 +12:00
'SilverStripe\\CMS\\Controllers\\CMSMain.AddPageRestriction' ,
2017-01-26 09:59:25 +13:00
'Note: Some page types are not allowed for this selection'
)
)
),
2024-10-17 12:49:24 +13:00
OptionsetField :: create (
'PageType' ,
2017-01-26 09:59:25 +13:00
DBField :: create_field (
'HTMLFragment' ,
2022-04-13 17:07:59 +12:00
sprintf ( $numericLabelTmpl ? ? '' , 2 , _t ( 'SilverStripe\\CMS\\Controllers\\CMSMain.ChoosePageType' , 'Choose page type' ))
2017-01-26 09:59:25 +13:00
),
$pageTypes ,
'Page'
)
);
$parentModeField -> setTitle ( DBField :: create_field (
'HTMLFragment' ,
2022-04-13 17:07:59 +12:00
sprintf ( $numericLabelTmpl ? ? '' , 1 , _t ( 'SilverStripe\\CMS\\Controllers\\CMSMain.ChoosePageParentMode' , 'Choose where to create this page' ))
2017-01-26 09:59:25 +13:00
));
$parentField -> setSearchFunction ( function ( $sourceObject , $labelField , $search ) {
return DataObject :: get ( $sourceObject )
-> filterAny ([
'MenuTitle:PartialMatch' => $search ,
'Title:PartialMatch' => $search ,
]);
});
$parentModeField -> addExtraClass ( 'parent-mode' );
2024-10-17 12:49:24 +13:00
// CMSMain->currentRecordID() automatically sets the homepage,
2017-01-26 09:59:25 +13:00
// which we need to counteract in the default selection (which should default to root, ID=0)
2024-10-17 12:49:24 +13:00
if ( $parentID = $controller -> getRequest () -> getVar ( 'ParentID' )) {
2017-01-26 09:59:25 +13:00
$parentModeField -> setValue ( 'child' );
$parentField -> setValue (( int ) $parentID );
} else {
$parentModeField -> setValue ( 'top' );
}
2020-10-22 21:21:15 +13:00
// Check if the current user has enough permissions to create top level pages
// If not, then disable the option to do that
2024-10-17 12:49:24 +13:00
if ( is_a ( $modelClass , SiteTree :: class , true ) && ! SiteConfig :: current_site_config () -> canCreateTopLevel ()) { // @TODO probably need to make this generic
2020-10-22 21:21:15 +13:00
$topField -> setDisabled ( true );
$parentModeField -> setValue ( 'child' );
}
2024-10-17 12:49:24 +13:00
$actions = FieldList :: create (
FormAction :: create ( 'doAdd' , _t ( 'SilverStripe\\CMS\\Controllers\\CMSMain.Create' , 'Create' ))
2017-01-26 09:59:25 +13:00
-> addExtraClass ( 'btn-primary font-icon-plus-circled' )
-> setUseButtonTag ( true ),
2024-10-17 12:49:24 +13:00
FormAction :: create ( 'doCancel' , _t ( 'SilverStripe\\CMS\\Controllers\\CMSMain.Cancel' , 'Cancel' ))
2017-01-26 09:59:25 +13:00
-> addExtraClass ( 'btn-secondary' )
-> setUseButtonTag ( true )
);
2024-10-17 12:49:24 +13:00
$controller -> extend ( 'updatePageOptions' , $fields );
parent :: __construct ( $controller , 'AddForm' , $fields , $actions );
$negotiator = $controller -> getResponseNegotiator ();
$this -> setHTMLID ( 'Form_AddForm' ) -> setStrictFormMethodCheck ( false );
$this -> setAttribute ( 'data-hints' , $controller -> TreeHints ());
$this -> setAttribute ( 'data-childfilter' , $controller -> Link ( 'childfilter' ));
$this -> setValidationResponseCallback ( function () use ( $negotiator , $controller ) {
$request = $controller -> getRequest ();
2017-01-26 09:59:25 +13:00
if ( $request -> isAjax () && $negotiator ) {
2024-10-17 12:49:24 +13:00
$result = $this -> forTemplate ();
2020-04-19 16:18:01 +12:00
return $negotiator -> respond ( $request , [
2017-01-26 09:59:25 +13:00
'CurrentForm' => function () use ( $result ) {
return $result ;
}
2020-04-19 16:18:01 +12:00
]);
2017-01-26 09:59:25 +13:00
}
return null ;
});
2024-10-17 12:49:24 +13:00
$this -> addExtraClass ( 'flexbox-area-grow fill-height cms-add-form cms-content cms-edit-form ' . $controller -> BaseCSSClasses ());
$this -> setTemplate ( $controller -> getTemplatesWithSuffix ( '_AddForm' ));
2017-01-26 09:59:25 +13:00
}
2022-10-18 18:21:09 +13:00
public function doAdd ( array $data , Form $form ) : HTTPResponse
2017-01-26 09:59:25 +13:00
{
2024-10-17 12:49:24 +13:00
$controller = $this -> getController ();
$modelClass = $controller -> getModelClass ();
2017-01-26 09:59:25 +13:00
$className = isset ( $data [ 'PageType' ]) ? $data [ 'PageType' ] : " Page " ;
$parentID = isset ( $data [ 'ParentID' ]) ? ( int ) $data [ 'ParentID' ] : 0 ;
if ( ! $parentID && isset ( $data [ 'Parent' ])) {
2024-10-17 12:49:24 +13:00
$page = $modelClass :: get_by_link ( $data [ 'Parent' ]); // @TODO Obviously no good
2017-01-26 09:59:25 +13:00
if ( $page ) {
$parentID = $page -> ID ;
}
}
if ( is_numeric ( $parentID ) && $parentID > 0 ) {
2024-10-17 12:49:24 +13:00
$parentObj = DataObject :: get ( $modelClass ) -> byID ( $parentID );
2017-01-26 09:59:25 +13:00
} else {
$parentObj = null ;
}
if ( ! $parentObj || ! $parentObj -> ID ) {
$parentID = 0 ;
}
2020-04-19 16:18:01 +12:00
if ( ! singleton ( $className ) -> canCreate ( Security :: getCurrentUser (), [ 'Parent' => $parentObj ])) {
2024-10-17 12:49:24 +13:00
return Security :: permissionFailure ( $controller );
2017-01-26 09:59:25 +13:00
}
2024-10-17 12:49:24 +13:00
$record = $controller -> getNewItem ( " new- $className - $parentID " , false );
$controller -> extend ( 'updateDoAdd' , $record , $form );
2017-01-26 09:59:25 +13:00
$record -> write ();
$editController = CMSPageEditController :: singleton ();
2024-10-17 12:49:24 +13:00
$editController -> setRequest ( $controller -> getRequest ());
$editController -> setCurrentRecordID ( $record -> ID );
2017-01-26 09:59:25 +13:00
2017-06-08 18:02:18 +12:00
$session = $this -> getRequest () -> getSession ();
$session -> set (
2017-01-26 09:59:25 +13:00
" FormInfo.Form_EditForm.formError.message " ,
2017-04-20 13:15:29 +12:00
_t ( 'SilverStripe\\CMS\\Controllers\\CMSMain.PageAdded' , 'Successfully created page' )
2017-01-26 09:59:25 +13:00
);
2017-06-08 18:02:18 +12:00
$session -> set ( " FormInfo.Form_EditForm.formError.type " , 'good' );
2017-01-26 09:59:25 +13:00
2024-10-17 12:49:24 +13:00
return $controller -> redirect ( $editController -> Link ( 'show/' . $record -> ID ));
2017-01-26 09:59:25 +13:00
}
2024-10-17 12:49:24 +13:00
public function doCancel () : HTTPResponse
2017-01-26 09:59:25 +13:00
{
2024-10-17 12:49:24 +13:00
return $this -> getController () -> redirect ( CMSMain :: singleton () -> Link ()); // @TODO when there's no CMSPageEditController anymore, change this to $this->getController()->Link()
2017-01-26 09:59:25 +13:00
}
2012-04-12 19:23:20 +12:00
}