mirror of
https://github.com/silverstripe/silverstripe-subsites
synced 2024-10-22 11:05:55 +02:00
reformat code and tests
This commit is contained in:
parent
2295501587
commit
c5f507b3f9
@ -13,30 +13,32 @@ use SilverStripe\Subsites\Model\Subsite;
|
|||||||
*
|
*
|
||||||
* @package subsites
|
* @package subsites
|
||||||
*/
|
*/
|
||||||
class SubsiteAdmin extends ModelAdmin {
|
class SubsiteAdmin extends ModelAdmin
|
||||||
|
{
|
||||||
|
|
||||||
private static $managed_models = array(Subsite::class);
|
private static $managed_models = [Subsite::class];
|
||||||
|
|
||||||
private static $url_segment = 'subsites';
|
private static $url_segment = 'subsites';
|
||||||
|
|
||||||
private static $menu_title = "Subsites";
|
private static $menu_title = "Subsites";
|
||||||
|
|
||||||
private static $menu_icon = "subsites/images/subsites.png";
|
private static $menu_icon = "subsites/images/subsites.png";
|
||||||
|
|
||||||
public $showImportForm=false;
|
public $showImportForm = false;
|
||||||
|
|
||||||
private static $tree_class = Subsite::class;
|
private static $tree_class = Subsite::class;
|
||||||
|
|
||||||
public function getEditForm($id = null, $fields = null) {
|
public function getEditForm($id = null, $fields = null)
|
||||||
$form = parent::getEditForm($id, $fields);
|
{
|
||||||
|
$form = parent::getEditForm($id, $fields);
|
||||||
|
|
||||||
$grid=$form->Fields()->dataFieldByName(Subsite::class);
|
$grid = $form->Fields()->dataFieldByName(Subsite::class);
|
||||||
if($grid) {
|
if ($grid) {
|
||||||
$grid->getConfig()->removeComponentsByType('SilverStripe\\Forms\\GridField\\GridFieldDetailForm');
|
$grid->getConfig()->removeComponentsByType('SilverStripe\\Forms\\GridField\\GridFieldDetailForm');
|
||||||
$grid->getConfig()->addComponent(new GridFieldSubsiteDetailForm());
|
$grid->getConfig()->addComponent(new GridFieldSubsiteDetailForm());
|
||||||
}
|
}
|
||||||
|
|
||||||
return $form;
|
return $form;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -10,43 +10,54 @@ use SilverStripe\Subsites\Model\Subsite;
|
|||||||
/**
|
/**
|
||||||
* Section-agnostic PJAX controller.
|
* Section-agnostic PJAX controller.
|
||||||
*/
|
*/
|
||||||
class SubsiteXHRController extends LeftAndMain {
|
class SubsiteXHRController extends LeftAndMain
|
||||||
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Relax the access permissions, so anyone who has access to any CMS subsite can access this controller.
|
* Relax the access permissions, so anyone who has access to any CMS subsite can access this controller.
|
||||||
*/
|
*/
|
||||||
public function canView($member = null) {
|
public function canView($member = null)
|
||||||
if (parent::canView()) return true;
|
{
|
||||||
|
if (parent::canView()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (Subsite::all_accessible_sites()->count()>0) return true;
|
if (Subsite::all_accessible_sites()->count() > 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Similar as above, but for the LeftAndMainSubsites - allow access if user allowed into the CMS at all.
|
* Similar as above, but for the LeftAndMainSubsites - allow access if user allowed into the CMS at all.
|
||||||
*/
|
*/
|
||||||
public function canAccess() {
|
public function canAccess()
|
||||||
if (Subsite::all_accessible_sites()->count()>0) return true;
|
{
|
||||||
}
|
if (Subsite::all_accessible_sites()->count() > 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function getResponseNegotiator() {
|
public function getResponseNegotiator()
|
||||||
$negotiator = parent::getResponseNegotiator();
|
{
|
||||||
$self = $this;
|
$negotiator = parent::getResponseNegotiator();
|
||||||
|
$self = $this;
|
||||||
|
|
||||||
// Register a new callback
|
// Register a new callback
|
||||||
$negotiator->setCallback('SubsiteList', function() use(&$self) {
|
$negotiator->setCallback('SubsiteList', function () use (&$self) {
|
||||||
return $self->SubsiteList();
|
return $self->SubsiteList();
|
||||||
});
|
});
|
||||||
|
|
||||||
return $negotiator;
|
return $negotiator;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provide the list of available subsites as a cms-section-agnostic PJAX handler.
|
* Provide the list of available subsites as a cms-section-agnostic PJAX handler.
|
||||||
*/
|
*/
|
||||||
public function SubsiteList() {
|
public function SubsiteList()
|
||||||
return $this->renderWith('Includes/SubsiteList');
|
{
|
||||||
}
|
return $this->renderWith('Includes/SubsiteList');
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -3,14 +3,16 @@
|
|||||||
namespace SilverStripe\Subsites\Extensions;
|
namespace SilverStripe\Subsites\Extensions;
|
||||||
|
|
||||||
|
|
||||||
use SilverStripe\Forms\HiddenField;
|
|
||||||
use SilverStripe\Core\Extension;
|
use SilverStripe\Core\Extension;
|
||||||
|
use SilverStripe\Forms\HiddenField;
|
||||||
use SilverStripe\Subsites\Model\Subsite;
|
use SilverStripe\Subsites\Model\Subsite;
|
||||||
|
|
||||||
class CMSPageAddControllerExtension extends Extension {
|
class CMSPageAddControllerExtension extends Extension
|
||||||
|
{
|
||||||
|
|
||||||
function updatePageOptions(&$fields) {
|
function updatePageOptions(&$fields)
|
||||||
$fields->push(new HiddenField('SubsiteID', 'SubsiteID', Subsite::currentSubsiteID()));
|
{
|
||||||
}
|
$fields->push(new HiddenField('SubsiteID', 'SubsiteID', Subsite::currentSubsiteID()));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -3,26 +3,30 @@
|
|||||||
namespace SilverStripe\Subsites\Extensions;
|
namespace SilverStripe\Subsites\Extensions;
|
||||||
|
|
||||||
|
|
||||||
use SilverStripe\View\SSViewer;
|
|
||||||
use SilverStripe\Core\Extension;
|
use SilverStripe\Core\Extension;
|
||||||
use SilverStripe\Subsites\Model\Subsite;
|
use SilverStripe\Subsites\Model\Subsite;
|
||||||
|
use SilverStripe\View\SSViewer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @package subsites
|
* @package subsites
|
||||||
*/
|
*/
|
||||||
class ControllerSubsites extends Extension {
|
class ControllerSubsites extends Extension
|
||||||
function controllerAugmentInit(){
|
{
|
||||||
if($subsite = Subsite::currentSubsite()){
|
function controllerAugmentInit()
|
||||||
if($theme = $subsite->Theme)
|
{
|
||||||
SSViewer::set_theme($theme);
|
if ($subsite = Subsite::currentSubsite()) {
|
||||||
}
|
if ($theme = $subsite->Theme) {
|
||||||
}
|
SSViewer::set_theme($theme);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function CurrentSubsite(){
|
function CurrentSubsite()
|
||||||
if($subsite = Subsite::currentSubsite()){
|
{
|
||||||
return $subsite;
|
if ($subsite = Subsite::currentSubsite()) {
|
||||||
}
|
return $subsite;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
@ -3,44 +3,46 @@
|
|||||||
namespace SilverStripe\Subsites\Extensions;
|
namespace SilverStripe\Subsites\Extensions;
|
||||||
|
|
||||||
|
|
||||||
use SilverStripe\ORM\DataObject;
|
|
||||||
use SilverStripe\ORM\DataExtension;
|
use SilverStripe\ORM\DataExtension;
|
||||||
|
use SilverStripe\ORM\DataObject;
|
||||||
use SilverStripe\Subsites\Model\Subsite;
|
use SilverStripe\Subsites\Model\Subsite;
|
||||||
|
|
||||||
|
|
||||||
class ErrorPageSubsite extends DataExtension {
|
class ErrorPageSubsite extends DataExtension
|
||||||
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Alter file path to generated a static (static) error page file to handle error page template on different sub-sites
|
* Alter file path to generated a static (static) error page file to handle error page template on different sub-sites
|
||||||
*
|
*
|
||||||
* {@see Error::get_error_filename()}
|
* {@see Error::get_error_filename()}
|
||||||
*
|
*
|
||||||
* FIXME since {@link Subsite::currentSubsite()} partly relies on Session, viewing other sub-site (including main site) between
|
* FIXME since {@link Subsite::currentSubsite()} partly relies on Session, viewing other sub-site (including main site) between
|
||||||
* opening ErrorPage in the CMS and publish ErrorPage causes static error page to get generated incorrectly.
|
* opening ErrorPage in the CMS and publish ErrorPage causes static error page to get generated incorrectly.
|
||||||
*
|
*
|
||||||
* @param string $name Filename to write to
|
* @param string $name Filename to write to
|
||||||
* @param int $statusCode Integer error code
|
* @param int $statusCode Integer error code
|
||||||
*/
|
*/
|
||||||
public function updateErrorFilename(&$name, $statusCode) {
|
public function updateErrorFilename(&$name, $statusCode)
|
||||||
|
{
|
||||||
|
|
||||||
// Try to get current subsite from session
|
// Try to get current subsite from session
|
||||||
$subsite = Subsite::currentSubsite(false);
|
$subsite = Subsite::currentSubsite(false);
|
||||||
|
|
||||||
// since this function is called from Page class before the controller is created, we have to get subsite from domain instead
|
// since this function is called from Page class before the controller is created, we have to get subsite from domain instead
|
||||||
if(!$subsite) {
|
if (!$subsite) {
|
||||||
$subsiteID = Subsite::getSubsiteIDForDomain();
|
$subsiteID = Subsite::getSubsiteIDForDomain();
|
||||||
if($subsiteID != 0) {
|
if ($subsiteID != 0) {
|
||||||
$subsite = DataObject::get_by_id(Subsite::class, $subsiteID);
|
$subsite = DataObject::get_by_id(Subsite::class, $subsiteID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Without subsite, don't rewrite
|
// Without subsite, don't rewrite
|
||||||
if($subsite) {
|
if ($subsite) {
|
||||||
// Add subdomain to end of filename, just before .html
|
// Add subdomain to end of filename, just before .html
|
||||||
// This should preserve translatable locale in the filename as well
|
// This should preserve translatable locale in the filename as well
|
||||||
$subdomain = $subsite->domain();
|
$subdomain = $subsite->domain();
|
||||||
$name = substr($name, 0, -5) . "-{$subdomain}.html";
|
$name = substr($name, 0, -5) . "-{$subdomain}.html";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -3,15 +3,15 @@
|
|||||||
namespace SilverStripe\Subsites\Extensions;
|
namespace SilverStripe\Subsites\Extensions;
|
||||||
|
|
||||||
|
|
||||||
use SilverStripe\Forms\FieldList;
|
|
||||||
use SilverStripe\Assets\Folder;
|
use SilverStripe\Assets\Folder;
|
||||||
use SilverStripe\Forms\DropdownField;
|
|
||||||
use SilverStripe\Forms\LiteralField;
|
|
||||||
use SilverStripe\ORM\Queries\SQLSelect;
|
|
||||||
use SilverStripe\ORM\DataQuery;
|
|
||||||
use SilverStripe\Control\Session;
|
use SilverStripe\Control\Session;
|
||||||
use SilverStripe\Security\Permission;
|
use SilverStripe\Forms\DropdownField;
|
||||||
|
use SilverStripe\Forms\FieldList;
|
||||||
|
use SilverStripe\Forms\LiteralField;
|
||||||
use SilverStripe\ORM\DataExtension;
|
use SilverStripe\ORM\DataExtension;
|
||||||
|
use SilverStripe\ORM\DataQuery;
|
||||||
|
use SilverStripe\ORM\Queries\SQLSelect;
|
||||||
|
use SilverStripe\Security\Permission;
|
||||||
use SilverStripe\Subsites\Model\Subsite;
|
use SilverStripe\Subsites\Model\Subsite;
|
||||||
|
|
||||||
|
|
||||||
@ -20,126 +20,142 @@ use SilverStripe\Subsites\Model\Subsite;
|
|||||||
*
|
*
|
||||||
* @package subsites
|
* @package subsites
|
||||||
*/
|
*/
|
||||||
class FileSubsites extends DataExtension {
|
class FileSubsites extends DataExtension
|
||||||
|
{
|
||||||
|
|
||||||
// If this is set to true, all folders created will be default be
|
// If this is set to true, all folders created will be default be
|
||||||
// considered 'global', unless set otherwise
|
// considered 'global', unless set otherwise
|
||||||
static $default_root_folders_global = false;
|
static $default_root_folders_global = false;
|
||||||
|
|
||||||
private static $has_one=array(
|
private static $has_one = [
|
||||||
'Subsite' => Subsite::class,
|
'Subsite' => Subsite::class,
|
||||||
);
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Amends the CMS tree title for folders in the Files & Images section.
|
* Amends the CMS tree title for folders in the Files & Images section.
|
||||||
* Prefixes a '* ' to the folders that are accessible from all subsites.
|
* Prefixes a '* ' to the folders that are accessible from all subsites.
|
||||||
*/
|
*/
|
||||||
function alternateTreeTitle() {
|
function alternateTreeTitle()
|
||||||
if($this->owner->SubsiteID == 0) return " * " . $this->owner->Title;
|
{
|
||||||
else return $this->owner->Title;
|
if ($this->owner->SubsiteID == 0) {
|
||||||
}
|
return " * " . $this->owner->Title;
|
||||||
|
} else {
|
||||||
|
return $this->owner->Title;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add subsites-specific fields to the folder editor.
|
* Add subsites-specific fields to the folder editor.
|
||||||
*/
|
*/
|
||||||
function updateCMSFields(FieldList $fields) {
|
function updateCMSFields(FieldList $fields)
|
||||||
if($this->owner instanceof Folder) {
|
{
|
||||||
$sites = Subsite::accessible_sites('CMS_ACCESS_AssetAdmin');
|
if ($this->owner instanceof Folder) {
|
||||||
$values = array();
|
$sites = Subsite::accessible_sites('CMS_ACCESS_AssetAdmin');
|
||||||
$values[0] = _t('FileSubsites.AllSitesDropdownOpt','All sites');
|
$values = [];
|
||||||
foreach ($sites as $site) {
|
$values[0] = _t('FileSubsites.AllSitesDropdownOpt', 'All sites');
|
||||||
$values[$site->ID] = $site->Title;
|
foreach ($sites as $site) {
|
||||||
}
|
$values[$site->ID] = $site->Title;
|
||||||
ksort($values);
|
}
|
||||||
if($sites){
|
ksort($values);
|
||||||
//Dropdown needed to move folders between subsites
|
if ($sites) {
|
||||||
$dropdown = new DropdownField(
|
//Dropdown needed to move folders between subsites
|
||||||
'SubsiteID',
|
$dropdown = new DropdownField(
|
||||||
_t('FileSubsites.SubsiteFieldLabel',Subsite::class),
|
'SubsiteID',
|
||||||
$values
|
_t('FileSubsites.SubsiteFieldLabel', Subsite::class),
|
||||||
);
|
$values
|
||||||
$dropdown->addExtraClass('subsites-move-dropdown');
|
);
|
||||||
$fields->push($dropdown);
|
$dropdown->addExtraClass('subsites-move-dropdown');
|
||||||
$fields->push(new LiteralField(
|
$fields->push($dropdown);
|
||||||
'Message',
|
$fields->push(new LiteralField(
|
||||||
'<p class="message notice">'.
|
'Message',
|
||||||
_t('ASSETADMIN.SUBSITENOTICE', 'Folders and files created in the main site are accessible by all subsites.')
|
'<p class="message notice">' .
|
||||||
.'</p>'
|
_t('ASSETADMIN.SUBSITENOTICE',
|
||||||
));
|
'Folders and files created in the main site are accessible by all subsites.')
|
||||||
}
|
. '</p>'
|
||||||
}
|
));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update any requests to limit the results to the current site
|
* Update any requests to limit the results to the current site
|
||||||
*/
|
*/
|
||||||
public function augmentSQL(SQLSelect $query, DataQuery $dataQuery = null) {
|
public function augmentSQL(SQLSelect $query, DataQuery $dataQuery = null)
|
||||||
if(Subsite::$disable_subsite_filter) return;
|
{
|
||||||
|
if (Subsite::$disable_subsite_filter) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// If you're querying by ID, ignore the sub-site - this is a bit ugly... (but it was WAYYYYYYYYY worse)
|
// If you're querying by ID, ignore the sub-site - this is a bit ugly... (but it was WAYYYYYYYYY worse)
|
||||||
//@TODO I don't think excluding if SiteTree_ImageTracking is a good idea however because of the SS 3.0 api and ManyManyList::removeAll() changing the from table after this function is called there isn't much of a choice
|
//@TODO I don't think excluding if SiteTree_ImageTracking is a good idea however because of the SS 3.0 api and ManyManyList::removeAll() changing the from table after this function is called there isn't much of a choice
|
||||||
|
|
||||||
$from = $query->getFrom();
|
$from = $query->getFrom();
|
||||||
if(isset($from['SiteTree_ImageTracking']) || $query->filtersOnID()) return;
|
if (isset($from['SiteTree_ImageTracking']) || $query->filtersOnID()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
$subsiteID = (int) Subsite::currentSubsiteID();
|
$subsiteID = (int)Subsite::currentSubsiteID();
|
||||||
|
|
||||||
// The foreach is an ugly way of getting the first key :-)
|
// The foreach is an ugly way of getting the first key :-)
|
||||||
foreach($query->getFrom() as $tableName => $info) {
|
foreach ($query->getFrom() as $tableName => $info) {
|
||||||
$where = "\"$tableName\".\"SubsiteID\" IN (0, $subsiteID)";
|
$where = "\"$tableName\".\"SubsiteID\" IN (0, $subsiteID)";
|
||||||
$query->addWhere($where);
|
$query->addWhere($where);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
$sect=array_values($query->getSelect());
|
$sect = array_values($query->getSelect());
|
||||||
$isCounting = strpos($sect[0], 'COUNT') !== false;
|
$isCounting = strpos($sect[0], 'COUNT') !== false;
|
||||||
|
|
||||||
// Ordering when deleting or counting doesn't apply
|
// Ordering when deleting or counting doesn't apply
|
||||||
if(!$isCounting) {
|
if (!$isCounting) {
|
||||||
$query->addOrderBy("\"SubsiteID\"");
|
$query->addOrderBy("\"SubsiteID\"");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function onBeforeWrite() {
|
function onBeforeWrite()
|
||||||
if (!$this->owner->ID && !$this->owner->SubsiteID) {
|
{
|
||||||
if (self::$default_root_folders_global) {
|
if (!$this->owner->ID && !$this->owner->SubsiteID) {
|
||||||
$this->owner->SubsiteID = 0;
|
if (self::$default_root_folders_global) {
|
||||||
} else {
|
$this->owner->SubsiteID = 0;
|
||||||
$this->owner->SubsiteID = Subsite::currentSubsiteID();
|
} else {
|
||||||
}
|
$this->owner->SubsiteID = Subsite::currentSubsiteID();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function onAfterUpload() {
|
function onAfterUpload()
|
||||||
// If we have a parent, use it's subsite as our subsite
|
{
|
||||||
if ($this->owner->Parent()) {
|
// If we have a parent, use it's subsite as our subsite
|
||||||
$this->owner->SubsiteID = $this->owner->Parent()->SubsiteID;
|
if ($this->owner->Parent()) {
|
||||||
} else {
|
$this->owner->SubsiteID = $this->owner->Parent()->SubsiteID;
|
||||||
$this->owner->SubsiteID = Subsite::currentSubsiteID();
|
} else {
|
||||||
}
|
$this->owner->SubsiteID = Subsite::currentSubsiteID();
|
||||||
$this->owner->write();
|
}
|
||||||
}
|
$this->owner->write();
|
||||||
|
}
|
||||||
|
|
||||||
function canEdit($member = null) {
|
function canEdit($member = null)
|
||||||
// Check the CMS_ACCESS_SecurityAdmin privileges on the subsite that owns this group
|
{
|
||||||
$subsiteID = Session::get('SubsiteID');
|
// Check the CMS_ACCESS_SecurityAdmin privileges on the subsite that owns this group
|
||||||
if($subsiteID&&$subsiteID == $this->owner->SubsiteID) {
|
$subsiteID = Session::get('SubsiteID');
|
||||||
return true;
|
if ($subsiteID && $subsiteID == $this->owner->SubsiteID) {
|
||||||
} else {
|
return true;
|
||||||
Session::set('SubsiteID', $this->owner->SubsiteID);
|
} else {
|
||||||
$access = Permission::check(array('CMS_ACCESS_AssetAdmin', 'CMS_ACCESS_LeftAndMain'));
|
Session::set('SubsiteID', $this->owner->SubsiteID);
|
||||||
Session::set('SubsiteID', $subsiteID);
|
$access = Permission::check(['CMS_ACCESS_AssetAdmin', 'CMS_ACCESS_LeftAndMain']);
|
||||||
|
Session::set('SubsiteID', $subsiteID);
|
||||||
|
|
||||||
return $access;
|
return $access;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a piece of text to keep DataObject cache keys appropriately specific
|
* Return a piece of text to keep DataObject cache keys appropriately specific
|
||||||
*/
|
*/
|
||||||
function cacheKeyComponent() {
|
function cacheKeyComponent()
|
||||||
return 'subsite-'.Subsite::currentSubsiteID();
|
{
|
||||||
}
|
return 'subsite-' . Subsite::currentSubsiteID();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,19 +3,19 @@
|
|||||||
namespace SilverStripe\Subsites\Extensions;
|
namespace SilverStripe\Subsites\Extensions;
|
||||||
|
|
||||||
|
|
||||||
use SilverStripe\ORM\DB;
|
|
||||||
use SilverStripe\Forms\FieldList;
|
|
||||||
use SilverStripe\Core\Convert;
|
|
||||||
use SilverStripe\Forms\OptionsetField;
|
|
||||||
use SilverStripe\Forms\CheckboxSetField;
|
|
||||||
use SilverStripe\Forms\ReadonlyField;
|
|
||||||
use SilverStripe\ORM\Queries\SQLSelect;
|
|
||||||
use SilverStripe\ORM\DataQuery;
|
|
||||||
use SilverStripe\Control\Cookie;
|
use SilverStripe\Control\Cookie;
|
||||||
|
use SilverStripe\Core\Convert;
|
||||||
|
use SilverStripe\Forms\CheckboxSetField;
|
||||||
|
use SilverStripe\Forms\FieldList;
|
||||||
|
use SilverStripe\Forms\OptionsetField;
|
||||||
|
use SilverStripe\Forms\ReadonlyField;
|
||||||
use SilverStripe\ORM\DataExtension;
|
use SilverStripe\ORM\DataExtension;
|
||||||
|
use SilverStripe\ORM\DataQuery;
|
||||||
|
use SilverStripe\ORM\DB;
|
||||||
|
use SilverStripe\ORM\Queries\SQLSelect;
|
||||||
|
use SilverStripe\Security\Group;
|
||||||
use SilverStripe\Security\PermissionProvider;
|
use SilverStripe\Security\PermissionProvider;
|
||||||
use SilverStripe\Subsites\Model\Subsite;
|
use SilverStripe\Subsites\Model\Subsite;
|
||||||
use SilverStripe\Security\Group;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -23,185 +23,206 @@ use SilverStripe\Security\Group;
|
|||||||
*
|
*
|
||||||
* @package subsites
|
* @package subsites
|
||||||
*/
|
*/
|
||||||
class GroupSubsites extends DataExtension implements PermissionProvider {
|
class GroupSubsites extends DataExtension implements PermissionProvider
|
||||||
|
{
|
||||||
|
|
||||||
private static $db = array(
|
private static $db = [
|
||||||
'AccessAllSubsites' => 'Boolean'
|
'AccessAllSubsites' => 'Boolean'
|
||||||
);
|
];
|
||||||
|
|
||||||
private static $many_many = array(
|
private static $many_many = [
|
||||||
'Subsites' => Subsite::class
|
'Subsites' => Subsite::class
|
||||||
);
|
];
|
||||||
|
|
||||||
private static $defaults = array(
|
private static $defaults = [
|
||||||
'AccessAllSubsites' => true
|
'AccessAllSubsites' => true
|
||||||
);
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Migrations for GroupSubsites data.
|
* Migrations for GroupSubsites data.
|
||||||
*/
|
*/
|
||||||
function requireDefaultRecords() {
|
function requireDefaultRecords()
|
||||||
// Migration for Group.SubsiteID data from when Groups only had a single subsite
|
{
|
||||||
|
// Migration for Group.SubsiteID data from when Groups only had a single subsite
|
||||||
$schema = $this->owner->getSchema();
|
$schema = $this->owner->getSchema();
|
||||||
$groupFields = DB::field_list($schema->tableName(Group::class));
|
$groupFields = DB::field_list($schema->tableName(Group::class));
|
||||||
|
|
||||||
// Detection of SubsiteID field is the trigger for old-style-subsiteID migration
|
// Detection of SubsiteID field is the trigger for old-style-subsiteID migration
|
||||||
if(isset($groupFields['SubsiteID'])) {
|
if (isset($groupFields['SubsiteID'])) {
|
||||||
// Migrate subsite-specific data
|
// Migrate subsite-specific data
|
||||||
DB::query('INSERT INTO "Group_Subsites" ("GroupID", "SubsiteID")
|
DB::query('INSERT INTO "Group_Subsites" ("GroupID", "SubsiteID")
|
||||||
SELECT "ID", "SubsiteID" FROM "Group" WHERE "SubsiteID" > 0');
|
SELECT "ID", "SubsiteID" FROM "Group" WHERE "SubsiteID" > 0');
|
||||||
|
|
||||||
// Migrate global-access data
|
// Migrate global-access data
|
||||||
DB::query('UPDATE "Group" SET "AccessAllSubsites" = 1 WHERE "SubsiteID" = 0');
|
DB::query('UPDATE "Group" SET "AccessAllSubsites" = 1 WHERE "SubsiteID" = 0');
|
||||||
|
|
||||||
// Move the field out of the way so that this migration doesn't get executed again
|
// Move the field out of the way so that this migration doesn't get executed again
|
||||||
DB::get_schema()->renameField(Group::class, 'SubsiteID', '_obsolete_SubsiteID');
|
DB::get_schema()->renameField(Group::class, 'SubsiteID', '_obsolete_SubsiteID');
|
||||||
|
|
||||||
// No subsite access on anything means that we've just installed the subsites module.
|
// No subsite access on anything means that we've just installed the subsites module.
|
||||||
// Make all previous groups global-access groups
|
// Make all previous groups global-access groups
|
||||||
} else if(!DB::query('SELECT "Group"."ID" FROM "Group"
|
} else {
|
||||||
|
if (!DB::query('SELECT "Group"."ID" FROM "Group"
|
||||||
LEFT JOIN "Group_Subsites" ON "Group_Subsites"."GroupID" = "Group"."ID" AND "Group_Subsites"."SubsiteID" > 0
|
LEFT JOIN "Group_Subsites" ON "Group_Subsites"."GroupID" = "Group"."ID" AND "Group_Subsites"."SubsiteID" > 0
|
||||||
WHERE "AccessAllSubsites" = 1
|
WHERE "AccessAllSubsites" = 1
|
||||||
OR "Group_Subsites"."GroupID" IS NOT NULL ')->value()) {
|
OR "Group_Subsites"."GroupID" IS NOT NULL ')->value()
|
||||||
|
) {
|
||||||
|
|
||||||
DB::query('UPDATE "Group" SET "AccessAllSubsites" = 1');
|
DB::query('UPDATE "Group" SET "AccessAllSubsites" = 1');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function updateCMSFields(FieldList $fields) {
|
function updateCMSFields(FieldList $fields)
|
||||||
if($this->owner->canEdit() ){
|
{
|
||||||
// i18n tab
|
if ($this->owner->canEdit()) {
|
||||||
$fields->findOrMakeTab('Root.Subsites',_t('GroupSubsites.SECURITYTABTITLE','Subsites'));
|
// i18n tab
|
||||||
|
$fields->findOrMakeTab('Root.Subsites', _t('GroupSubsites.SECURITYTABTITLE', 'Subsites'));
|
||||||
|
|
||||||
$subsites = Subsite::accessible_sites(array('ADMIN', 'SECURITY_SUBSITE_GROUP'), true);
|
$subsites = Subsite::accessible_sites(['ADMIN', 'SECURITY_SUBSITE_GROUP'], true);
|
||||||
$subsiteMap = $subsites->map();
|
$subsiteMap = $subsites->map();
|
||||||
|
|
||||||
// Prevent XSS injection
|
// Prevent XSS injection
|
||||||
$subsiteMap = Convert::raw2xml($subsiteMap);
|
$subsiteMap = Convert::raw2xml($subsiteMap);
|
||||||
|
|
||||||
// Interface is different if you have the rights to modify subsite group values on
|
// Interface is different if you have the rights to modify subsite group values on
|
||||||
// all subsites
|
// all subsites
|
||||||
if(isset($subsiteMap[0])) {
|
if (isset($subsiteMap[0])) {
|
||||||
$fields->addFieldToTab("Root.Subsites", new OptionsetField("AccessAllSubsites",
|
$fields->addFieldToTab("Root.Subsites", new OptionsetField("AccessAllSubsites",
|
||||||
_t('GroupSubsites.ACCESSRADIOTITLE', 'Give this group access to'),
|
_t('GroupSubsites.ACCESSRADIOTITLE', 'Give this group access to'),
|
||||||
array(
|
[
|
||||||
1 => _t('GroupSubsites.ACCESSALL', "All subsites"),
|
1 => _t('GroupSubsites.ACCESSALL', "All subsites"),
|
||||||
0 => _t('GroupSubsites.ACCESSONLY', "Only these subsites"),
|
0 => _t('GroupSubsites.ACCESSONLY', "Only these subsites"),
|
||||||
)
|
]
|
||||||
));
|
));
|
||||||
|
|
||||||
unset($subsiteMap[0]);
|
unset($subsiteMap[0]);
|
||||||
$fields->addFieldToTab("Root.Subsites", new CheckboxSetField("Subsites", "",
|
$fields->addFieldToTab("Root.Subsites", new CheckboxSetField("Subsites", "",
|
||||||
$subsiteMap));
|
$subsiteMap));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (sizeof($subsiteMap) <= 1) {
|
if (sizeof($subsiteMap) <= 1) {
|
||||||
$fields->addFieldToTab("Root.Subsites", new ReadonlyField("SubsitesHuman",
|
$fields->addFieldToTab("Root.Subsites", new ReadonlyField("SubsitesHuman",
|
||||||
_t('GroupSubsites.ACCESSRADIOTITLE', 'Give this group access to'),
|
_t('GroupSubsites.ACCESSRADIOTITLE', 'Give this group access to'),
|
||||||
reset($subsiteMap)));
|
reset($subsiteMap)));
|
||||||
} else {
|
} else {
|
||||||
$fields->addFieldToTab("Root.Subsites", new CheckboxSetField("Subsites",
|
$fields->addFieldToTab("Root.Subsites", new CheckboxSetField("Subsites",
|
||||||
_t('GroupSubsites.ACCESSRADIOTITLE', 'Give this group access to'),
|
_t('GroupSubsites.ACCESSRADIOTITLE', 'Give this group access to'),
|
||||||
$subsiteMap));
|
$subsiteMap));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If this group belongs to a subsite,
|
* If this group belongs to a subsite,
|
||||||
* append the subsites title to the group title
|
* append the subsites title to the group title
|
||||||
* to make it easy to distinguish in the tree-view
|
* to make it easy to distinguish in the tree-view
|
||||||
* of the security admin interface.
|
* of the security admin interface.
|
||||||
*/
|
*/
|
||||||
function alternateTreeTitle() {
|
function alternateTreeTitle()
|
||||||
if($this->owner->AccessAllSubsites) {
|
{
|
||||||
$title = _t('GroupSubsites.GlobalGroup', 'global group');
|
if ($this->owner->AccessAllSubsites) {
|
||||||
return htmlspecialchars($this->owner->Title, ENT_QUOTES) . ' <i>(' . $title . ')</i>';
|
$title = _t('GroupSubsites.GlobalGroup', 'global group');
|
||||||
} else {
|
return htmlspecialchars($this->owner->Title, ENT_QUOTES) . ' <i>(' . $title . ')</i>';
|
||||||
$subsites = Convert::raw2xml(implode(", ", $this->owner->Subsites()->column('Title')));
|
} else {
|
||||||
return htmlspecialchars($this->owner->Title) . " <i>($subsites)</i>";
|
$subsites = Convert::raw2xml(implode(", ", $this->owner->Subsites()->column('Title')));
|
||||||
}
|
return htmlspecialchars($this->owner->Title) . " <i>($subsites)</i>";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update any requests to limit the results to the current site
|
* Update any requests to limit the results to the current site
|
||||||
*/
|
*/
|
||||||
public function augmentSQL(SQLSelect $query, DataQuery $dataQuery = null) {
|
public function augmentSQL(SQLSelect $query, DataQuery $dataQuery = null)
|
||||||
if(Subsite::$disable_subsite_filter) return;
|
{
|
||||||
if(Cookie::get('noSubsiteFilter') == 'true') return;
|
if (Subsite::$disable_subsite_filter) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (Cookie::get('noSubsiteFilter') == 'true') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// If you're querying by ID, ignore the sub-site - this is a bit ugly...
|
// If you're querying by ID, ignore the sub-site - this is a bit ugly...
|
||||||
if(!$query->filtersOnID()) {
|
if (!$query->filtersOnID()) {
|
||||||
|
|
||||||
/*if($context = DataObject::context_obj()) $subsiteID = (int)$context->SubsiteID;
|
/*if($context = DataObject::context_obj()) $subsiteID = (int)$context->SubsiteID;
|
||||||
else */$subsiteID = (int)Subsite::currentSubsiteID();
|
else */
|
||||||
|
$subsiteID = (int)Subsite::currentSubsiteID();
|
||||||
|
|
||||||
// Don't filter by Group_Subsites if we've already done that
|
// Don't filter by Group_Subsites if we've already done that
|
||||||
$hasGroupSubsites = false;
|
$hasGroupSubsites = false;
|
||||||
foreach($query->getFrom() as $item) {
|
foreach ($query->getFrom() as $item) {
|
||||||
if((is_array($item) && strpos($item['table'], 'Group_Subsites')!==false) || (!is_array($item) && strpos($item, 'Group_Subsites')!==false)) {
|
if ((is_array($item) && strpos($item['table'],
|
||||||
$hasGroupSubsites = true;
|
'Group_Subsites') !== false) || (!is_array($item) && strpos($item,
|
||||||
break;
|
'Group_Subsites') !== false)
|
||||||
}
|
) {
|
||||||
}
|
$hasGroupSubsites = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(!$hasGroupSubsites) {
|
if (!$hasGroupSubsites) {
|
||||||
if($subsiteID) {
|
if ($subsiteID) {
|
||||||
$query->addLeftJoin("Group_Subsites", "\"Group_Subsites\".\"GroupID\"
|
$query->addLeftJoin("Group_Subsites", "\"Group_Subsites\".\"GroupID\"
|
||||||
= \"Group\".\"ID\" AND \"Group_Subsites\".\"SubsiteID\" = $subsiteID");
|
= \"Group\".\"ID\" AND \"Group_Subsites\".\"SubsiteID\" = $subsiteID");
|
||||||
$query->addWhere("(\"Group_Subsites\".\"SubsiteID\" IS NOT NULL OR
|
$query->addWhere("(\"Group_Subsites\".\"SubsiteID\" IS NOT NULL OR
|
||||||
\"Group\".\"AccessAllSubsites\" = 1)");
|
\"Group\".\"AccessAllSubsites\" = 1)");
|
||||||
} else {
|
} else {
|
||||||
$query->addWhere("\"Group\".\"AccessAllSubsites\" = 1");
|
$query->addWhere("\"Group\".\"AccessAllSubsites\" = 1");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WORKAROUND for databases that complain about an ORDER BY when the column wasn't selected (e.g. SQL Server)
|
// WORKAROUND for databases that complain about an ORDER BY when the column wasn't selected (e.g. SQL Server)
|
||||||
$select=$query->getSelect();
|
$select = $query->getSelect();
|
||||||
if(isset($select[0]) && !$select[0] == 'COUNT(*)') {
|
if (isset($select[0]) && !$select[0] == 'COUNT(*)') {
|
||||||
$query->orderby = "\"AccessAllSubsites\" DESC" . ($query->orderby ? ', ' : '') . $query->orderby;
|
$query->orderby = "\"AccessAllSubsites\" DESC" . ($query->orderby ? ', ' : '') . $query->orderby;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function onBeforeWrite() {
|
function onBeforeWrite()
|
||||||
// New record test approximated by checking whether the ID has changed.
|
{
|
||||||
// Note also that the after write test is only used when we're *not* on a subsite
|
// New record test approximated by checking whether the ID has changed.
|
||||||
if($this->owner->isChanged('ID') && !Subsite::currentSubsiteID()) {
|
// Note also that the after write test is only used when we're *not* on a subsite
|
||||||
$this->owner->AccessAllSubsites = 1;
|
if ($this->owner->isChanged('ID') && !Subsite::currentSubsiteID()) {
|
||||||
}
|
$this->owner->AccessAllSubsites = 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function onAfterWrite() {
|
function onAfterWrite()
|
||||||
// New record test approximated by checking whether the ID has changed.
|
{
|
||||||
// Note also that the after write test is only used when we're on a subsite
|
// New record test approximated by checking whether the ID has changed.
|
||||||
if($this->owner->isChanged('ID') && $currentSubsiteID = Subsite::currentSubsiteID()) {
|
// Note also that the after write test is only used when we're on a subsite
|
||||||
$subsites = $this->owner->Subsites();
|
if ($this->owner->isChanged('ID') && $currentSubsiteID = Subsite::currentSubsiteID()) {
|
||||||
$subsites->add($currentSubsiteID);
|
$subsites = $this->owner->Subsites();
|
||||||
}
|
$subsites->add($currentSubsiteID);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function alternateCanEdit() {
|
function alternateCanEdit()
|
||||||
// Find the sites that this group belongs to and the sites where we have appropriate perm.
|
{
|
||||||
$accessibleSites = Subsite::accessible_sites('CMS_ACCESS_SecurityAdmin')->column('ID');
|
// Find the sites that this group belongs to and the sites where we have appropriate perm.
|
||||||
$linkedSites = $this->owner->Subsites()->column('ID');
|
$accessibleSites = Subsite::accessible_sites('CMS_ACCESS_SecurityAdmin')->column('ID');
|
||||||
|
$linkedSites = $this->owner->Subsites()->column('ID');
|
||||||
|
|
||||||
// We are allowed to access this site if at we have CMS_ACCESS_SecurityAdmin permission on
|
// We are allowed to access this site if at we have CMS_ACCESS_SecurityAdmin permission on
|
||||||
// at least one of the sites
|
// at least one of the sites
|
||||||
return (bool)array_intersect($accessibleSites, $linkedSites);
|
return (bool)array_intersect($accessibleSites, $linkedSites);
|
||||||
}
|
}
|
||||||
|
|
||||||
function providePermissions() {
|
function providePermissions()
|
||||||
return array(
|
{
|
||||||
'SECURITY_SUBSITE_GROUP' => array(
|
return [
|
||||||
'name' => _t('GroupSubsites.MANAGE_SUBSITES', 'Manage subsites for groups'),
|
'SECURITY_SUBSITE_GROUP' => [
|
||||||
'category' => _t('Permissions.PERMISSIONS_CATEGORY', 'Roles and access permissions'),
|
'name' => _t('GroupSubsites.MANAGE_SUBSITES', 'Manage subsites for groups'),
|
||||||
'help' => _t('GroupSubsites.MANAGE_SUBSITES_HELP', 'Ability to limit the permissions for a group to one or more subsites.'),
|
'category' => _t('Permissions.PERMISSIONS_CATEGORY', 'Roles and access permissions'),
|
||||||
'sort' => 200
|
'help' => _t('GroupSubsites.MANAGE_SUBSITES_HELP',
|
||||||
)
|
'Ability to limit the permissions for a group to one or more subsites.'),
|
||||||
);
|
'sort' => 200
|
||||||
}
|
]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,21 +3,21 @@
|
|||||||
namespace SilverStripe\Subsites\Extensions;
|
namespace SilverStripe\Subsites\Extensions;
|
||||||
|
|
||||||
|
|
||||||
use SilverStripe\View\Requirements;
|
use SilverStripe\Admin\CMSMenu;
|
||||||
|
use SilverStripe\Control\Controller;
|
||||||
|
use SilverStripe\Control\Session;
|
||||||
|
use SilverStripe\Core\Config\Config;
|
||||||
use SilverStripe\Core\Convert;
|
use SilverStripe\Core\Convert;
|
||||||
|
use SilverStripe\Core\Extension;
|
||||||
use SilverStripe\Forms\HiddenField;
|
use SilverStripe\Forms\HiddenField;
|
||||||
use SilverStripe\Security\Member;
|
|
||||||
use SilverStripe\ORM\ArrayList;
|
use SilverStripe\ORM\ArrayList;
|
||||||
use SilverStripe\ORM\DataObject;
|
use SilverStripe\ORM\DataObject;
|
||||||
use SilverStripe\Core\Config\Config;
|
use SilverStripe\Security\Member;
|
||||||
use SilverStripe\View\ArrayData;
|
|
||||||
use SilverStripe\Security\Permission;
|
use SilverStripe\Security\Permission;
|
||||||
use SilverStripe\Control\Session;
|
|
||||||
use SilverStripe\Admin\CMSMenu;
|
|
||||||
use SilverStripe\Security\Security;
|
use SilverStripe\Security\Security;
|
||||||
use SilverStripe\Control\Controller;
|
|
||||||
use SilverStripe\Core\Extension;
|
|
||||||
use SilverStripe\Subsites\Model\Subsite;
|
use SilverStripe\Subsites\Model\Subsite;
|
||||||
|
use SilverStripe\View\ArrayData;
|
||||||
|
use SilverStripe\View\Requirements;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -25,303 +25,335 @@ use SilverStripe\Subsites\Model\Subsite;
|
|||||||
*
|
*
|
||||||
* @package subsites
|
* @package subsites
|
||||||
*/
|
*/
|
||||||
class LeftAndMainSubsites extends Extension {
|
class LeftAndMainSubsites extends Extension
|
||||||
|
{
|
||||||
|
|
||||||
private static $allowed_actions = array('CopyToSubsite');
|
private static $allowed_actions = ['CopyToSubsite'];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Normally SubsiteID=0 on a DataObject means it is only accessible from the special "main site".
|
* Normally SubsiteID=0 on a DataObject means it is only accessible from the special "main site".
|
||||||
* However in some situations SubsiteID=0 will be understood as a "globally accessible" object in which
|
* However in some situations SubsiteID=0 will be understood as a "globally accessible" object in which
|
||||||
* case this property is set to true (i.e. in AssetAdmin).
|
* case this property is set to true (i.e. in AssetAdmin).
|
||||||
*/
|
*/
|
||||||
private static $treats_subsite_0_as_global = false;
|
private static $treats_subsite_0_as_global = false;
|
||||||
|
|
||||||
function init() {
|
function init()
|
||||||
Requirements::css('subsites/css/LeftAndMain_Subsites.css');
|
{
|
||||||
Requirements::javascript('subsites/javascript/LeftAndMain_Subsites.js');
|
Requirements::css('subsites/css/LeftAndMain_Subsites.css');
|
||||||
Requirements::javascript('subsites/javascript/VirtualPage_Subsites.js');
|
Requirements::javascript('subsites/javascript/LeftAndMain_Subsites.js');
|
||||||
}
|
Requirements::javascript('subsites/javascript/VirtualPage_Subsites.js');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the title of the CMS tree
|
* Set the title of the CMS tree
|
||||||
*/
|
*/
|
||||||
function getCMSTreeTitle() {
|
function getCMSTreeTitle()
|
||||||
$subsite = Subsite::currentSubSite();
|
{
|
||||||
return $subsite ? Convert::raw2xml($subsite->Title) : _t('LeftAndMain.SITECONTENTLEFT');
|
$subsite = Subsite::currentSubSite();
|
||||||
}
|
return $subsite ? Convert::raw2xml($subsite->Title) : _t('LeftAndMain.SITECONTENTLEFT');
|
||||||
|
}
|
||||||
|
|
||||||
function updatePageOptions(&$fields) {
|
function updatePageOptions(&$fields)
|
||||||
$fields->push(new HiddenField('SubsiteID', 'SubsiteID', Subsite::currentSubsiteID()));
|
{
|
||||||
}
|
$fields->push(new HiddenField('SubsiteID', 'SubsiteID', Subsite::currentSubsiteID()));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find all subsites accessible for current user on this controller.
|
* Find all subsites accessible for current user on this controller.
|
||||||
*
|
*
|
||||||
* @return ArrayList of {@link Subsite} instances.
|
* @return ArrayList of {@link Subsite} instances.
|
||||||
*/
|
*/
|
||||||
function sectionSites($includeMainSite = true, $mainSiteTitle = "Main site", $member = null) {
|
function sectionSites($includeMainSite = true, $mainSiteTitle = "Main site", $member = null)
|
||||||
if($mainSiteTitle == 'Main site') {
|
{
|
||||||
$mainSiteTitle = _t('Subsites.MainSiteTitle', 'Main site');
|
if ($mainSiteTitle == 'Main site') {
|
||||||
}
|
$mainSiteTitle = _t('Subsites.MainSiteTitle', 'Main site');
|
||||||
|
}
|
||||||
|
|
||||||
// Rationalise member arguments
|
// Rationalise member arguments
|
||||||
if(!$member) $member = Member::currentUser();
|
if (!$member) {
|
||||||
if(!$member) return new ArrayList();
|
$member = Member::currentUser();
|
||||||
if(!is_object($member)) $member = DataObject::get_by_id('SilverStripe\\Security\\Member', $member);
|
}
|
||||||
|
if (!$member) {
|
||||||
|
return new ArrayList();
|
||||||
|
}
|
||||||
|
if (!is_object($member)) {
|
||||||
|
$member = DataObject::get_by_id('SilverStripe\\Security\\Member', $member);
|
||||||
|
}
|
||||||
|
|
||||||
// Collect permissions - honour the LeftAndMain::required_permission_codes, current model requires
|
// Collect permissions - honour the LeftAndMain::required_permission_codes, current model requires
|
||||||
// us to check if the user satisfies ALL permissions. Code partly copied from LeftAndMain::canView.
|
// us to check if the user satisfies ALL permissions. Code partly copied from LeftAndMain::canView.
|
||||||
$codes = array();
|
$codes = [];
|
||||||
$extraCodes = Config::inst()->get($this->owner->class, 'required_permission_codes');
|
$extraCodes = Config::inst()->get($this->owner->class, 'required_permission_codes');
|
||||||
if($extraCodes !== false) {
|
if ($extraCodes !== false) {
|
||||||
if($extraCodes) $codes = array_merge($codes, (array)$extraCodes);
|
if ($extraCodes) {
|
||||||
else $codes[] = "CMS_ACCESS_{$this->owner->class}";
|
$codes = array_merge($codes, (array)$extraCodes);
|
||||||
} else {
|
} else {
|
||||||
// Check overriden - all subsites accessible.
|
$codes[] = "CMS_ACCESS_{$this->owner->class}";
|
||||||
return Subsite::all_sites();
|
}
|
||||||
}
|
} else {
|
||||||
|
// Check overriden - all subsites accessible.
|
||||||
|
return Subsite::all_sites();
|
||||||
|
}
|
||||||
|
|
||||||
// Find subsites satisfying all permissions for the Member.
|
// Find subsites satisfying all permissions for the Member.
|
||||||
$codesPerSite = array();
|
$codesPerSite = [];
|
||||||
$sitesArray = array();
|
$sitesArray = [];
|
||||||
foreach ($codes as $code) {
|
foreach ($codes as $code) {
|
||||||
$sites = Subsite::accessible_sites($code, $includeMainSite, $mainSiteTitle, $member);
|
$sites = Subsite::accessible_sites($code, $includeMainSite, $mainSiteTitle, $member);
|
||||||
foreach ($sites as $site) {
|
foreach ($sites as $site) {
|
||||||
// Build the structure for checking how many codes match.
|
// Build the structure for checking how many codes match.
|
||||||
$codesPerSite[$site->ID][$code] = true;
|
$codesPerSite[$site->ID][$code] = true;
|
||||||
|
|
||||||
// Retain Subsite objects for later.
|
// Retain Subsite objects for later.
|
||||||
$sitesArray[$site->ID] = $site;
|
$sitesArray[$site->ID] = $site;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find sites that satisfy all codes conjuncitvely.
|
// Find sites that satisfy all codes conjuncitvely.
|
||||||
$accessibleSites = new ArrayList();
|
$accessibleSites = new ArrayList();
|
||||||
foreach ($codesPerSite as $siteID => $siteCodes) {
|
foreach ($codesPerSite as $siteID => $siteCodes) {
|
||||||
if (count($siteCodes)==count($codes)) {
|
if (count($siteCodes) == count($codes)) {
|
||||||
$accessibleSites->push($sitesArray[$siteID]);
|
$accessibleSites->push($sitesArray[$siteID]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $accessibleSites;
|
return $accessibleSites;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns a list of the subsites accessible to the current user.
|
* Returns a list of the subsites accessible to the current user.
|
||||||
* It's enough for any section to be accessible for the section to be included.
|
* It's enough for any section to be accessible for the section to be included.
|
||||||
*/
|
*/
|
||||||
public function Subsites() {
|
public function Subsites()
|
||||||
return Subsite::all_accessible_sites();
|
{
|
||||||
}
|
return Subsite::all_accessible_sites();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Generates a list of subsites with the data needed to
|
* Generates a list of subsites with the data needed to
|
||||||
* produce a dropdown site switcher
|
* produce a dropdown site switcher
|
||||||
* @return ArrayList
|
* @return ArrayList
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public function ListSubsites(){
|
public function ListSubsites()
|
||||||
$list = $this->Subsites();
|
{
|
||||||
$currentSubsiteID = Subsite::currentSubsiteID();
|
$list = $this->Subsites();
|
||||||
|
$currentSubsiteID = Subsite::currentSubsiteID();
|
||||||
|
|
||||||
if($list == null || $list->Count() == 1 && $list->First()->DefaultSite == true){
|
if ($list == null || $list->Count() == 1 && $list->First()->DefaultSite == true) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Requirements::javascript('subsites/javascript/LeftAndMain_Subsites.js');
|
Requirements::javascript('subsites/javascript/LeftAndMain_Subsites.js');
|
||||||
|
|
||||||
$output = new ArrayList();
|
$output = new ArrayList();
|
||||||
|
|
||||||
foreach($list as $subsite) {
|
foreach ($list as $subsite) {
|
||||||
$CurrentState = $subsite->ID == $currentSubsiteID ? 'selected' : '';
|
$CurrentState = $subsite->ID == $currentSubsiteID ? 'selected' : '';
|
||||||
|
|
||||||
$output->push(new ArrayData(array(
|
$output->push(new ArrayData([
|
||||||
'CurrentState' => $CurrentState,
|
'CurrentState' => $CurrentState,
|
||||||
'ID' => $subsite->ID,
|
'ID' => $subsite->ID,
|
||||||
'Title' => Convert::raw2xml($subsite->Title)
|
'Title' => Convert::raw2xml($subsite->Title)
|
||||||
)));
|
]));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $output;
|
return $output;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function alternateMenuDisplayCheck($controllerName) {
|
public function alternateMenuDisplayCheck($controllerName)
|
||||||
if(!class_exists($controllerName)){
|
{
|
||||||
return false;
|
if (!class_exists($controllerName)) {
|
||||||
}
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Check subsite support.
|
// Check subsite support.
|
||||||
if(Subsite::currentSubsiteID() == 0){
|
if (Subsite::currentSubsiteID() == 0) {
|
||||||
// Main site always supports everything.
|
// Main site always supports everything.
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
$controller = singleton($controllerName);
|
$controller = singleton($controllerName);
|
||||||
if($controller->hasMethod('subsiteCMSShowInMenu') && $controller->subsiteCMSShowInMenu()){
|
if ($controller->hasMethod('subsiteCMSShowInMenu') && $controller->subsiteCMSShowInMenu()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// It's not necessary to check access permissions here. Framework calls canView on the controller,
|
// It's not necessary to check access permissions here. Framework calls canView on the controller,
|
||||||
// which in turn uses the Permission API which is augmented by our GroupSubsites.
|
// which in turn uses the Permission API which is augmented by our GroupSubsites.
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function CanAddSubsites() {
|
public function CanAddSubsites()
|
||||||
return Permission::check("ADMIN", "any", null, "all");
|
{
|
||||||
}
|
return Permission::check("ADMIN", "any", null, "all");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper for testing if the subsite should be adjusted.
|
* Helper for testing if the subsite should be adjusted.
|
||||||
*/
|
*/
|
||||||
public function shouldChangeSubsite($adminClass, $recordSubsiteID, $currentSubsiteID) {
|
public function shouldChangeSubsite($adminClass, $recordSubsiteID, $currentSubsiteID)
|
||||||
if (Config::inst()->get($adminClass, 'treats_subsite_0_as_global') && $recordSubsiteID==0) return false;
|
{
|
||||||
if ($recordSubsiteID!=$currentSubsiteID) return true;
|
if (Config::inst()->get($adminClass, 'treats_subsite_0_as_global') && $recordSubsiteID == 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if ($recordSubsiteID != $currentSubsiteID) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the current controller is accessible for this user on this subsite.
|
* Check if the current controller is accessible for this user on this subsite.
|
||||||
*/
|
*/
|
||||||
function canAccess() {
|
function canAccess()
|
||||||
// Admin can access everything, no point in checking.
|
{
|
||||||
$member = Member::currentUser();
|
// Admin can access everything, no point in checking.
|
||||||
if($member &&
|
$member = Member::currentUser();
|
||||||
(
|
if ($member &&
|
||||||
Permission::checkMember($member, 'ADMIN') || // 'Full administrative rights' in SecurityAdmin
|
(
|
||||||
Permission::checkMember($member, 'CMS_ACCESS_LeftAndMain') // 'Access to all CMS sections' in SecurityAdmin
|
Permission::checkMember($member, 'ADMIN') || // 'Full administrative rights' in SecurityAdmin
|
||||||
)) {
|
Permission::checkMember($member,
|
||||||
return true;
|
'CMS_ACCESS_LeftAndMain') // 'Access to all CMS sections' in SecurityAdmin
|
||||||
}
|
)
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// Check if we have access to current section on the current subsite.
|
// Check if we have access to current section on the current subsite.
|
||||||
$accessibleSites = $this->owner->sectionSites(true, "Main site", $member);
|
$accessibleSites = $this->owner->sectionSites(true, "Main site", $member);
|
||||||
if ($accessibleSites->count() && $accessibleSites->find('ID', Subsite::currentSubsiteID())) {
|
if ($accessibleSites->count() && $accessibleSites->find('ID', Subsite::currentSubsiteID())) {
|
||||||
// Current section can be accessed on the current site, all good.
|
// Current section can be accessed on the current site, all good.
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prevent accessing disallowed resources. This happens after onBeforeInit has executed,
|
* Prevent accessing disallowed resources. This happens after onBeforeInit has executed,
|
||||||
* so all redirections should've already taken place.
|
* so all redirections should've already taken place.
|
||||||
*/
|
*/
|
||||||
public function alternateAccessCheck() {
|
public function alternateAccessCheck()
|
||||||
return $this->owner->canAccess();
|
{
|
||||||
}
|
return $this->owner->canAccess();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Redirect the user to something accessible if the current section/subsite is forbidden.
|
* Redirect the user to something accessible if the current section/subsite is forbidden.
|
||||||
*
|
*
|
||||||
* This is done via onBeforeInit as it needs to be done before the LeftAndMain::init has a
|
* This is done via onBeforeInit as it needs to be done before the LeftAndMain::init has a
|
||||||
* chance to forbids access via alternateAccessCheck.
|
* chance to forbids access via alternateAccessCheck.
|
||||||
*
|
*
|
||||||
* If we need to change the subsite we force the redirection to /admin/ so the frontend is
|
* If we need to change the subsite we force the redirection to /admin/ so the frontend is
|
||||||
* fully re-synchronised with the internal session. This is better than risking some panels
|
* fully re-synchronised with the internal session. This is better than risking some panels
|
||||||
* showing data from another subsite.
|
* showing data from another subsite.
|
||||||
*/
|
*/
|
||||||
public function onBeforeInit() {
|
public function onBeforeInit()
|
||||||
// We are accessing the CMS, so we need to let Subsites know we will be using the session.
|
{
|
||||||
Subsite::$use_session_subsiteid = true;
|
// We are accessing the CMS, so we need to let Subsites know we will be using the session.
|
||||||
|
Subsite::$use_session_subsiteid = true;
|
||||||
|
|
||||||
// FIRST, check if we need to change subsites due to the URL.
|
// FIRST, check if we need to change subsites due to the URL.
|
||||||
|
|
||||||
// Catch forced subsite changes that need to cause CMS reloads.
|
// Catch forced subsite changes that need to cause CMS reloads.
|
||||||
if(isset($_GET['SubsiteID'])) {
|
if (isset($_GET['SubsiteID'])) {
|
||||||
// Clear current page when subsite changes (or is set for the first time)
|
// Clear current page when subsite changes (or is set for the first time)
|
||||||
if(!Session::get('SubsiteID') || $_GET['SubsiteID'] != Session::get('SubsiteID')) {
|
if (!Session::get('SubsiteID') || $_GET['SubsiteID'] != Session::get('SubsiteID')) {
|
||||||
Session::clear("{$this->owner->class}.currentPage");
|
Session::clear("{$this->owner->class}.currentPage");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update current subsite in session
|
// Update current subsite in session
|
||||||
Subsite::changeSubsite($_GET['SubsiteID']);
|
Subsite::changeSubsite($_GET['SubsiteID']);
|
||||||
|
|
||||||
//Redirect to clear the current page
|
//Redirect to clear the current page
|
||||||
if ($this->owner->canView(Member::currentUser())) {
|
if ($this->owner->canView(Member::currentUser())) {
|
||||||
//Redirect to clear the current page
|
//Redirect to clear the current page
|
||||||
return $this->owner->redirect($this->owner->Link());
|
return $this->owner->redirect($this->owner->Link());
|
||||||
}
|
}
|
||||||
//Redirect to the default CMS section
|
//Redirect to the default CMS section
|
||||||
return $this->owner->redirect('admin/');
|
return $this->owner->redirect('admin/');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Automatically redirect the session to appropriate subsite when requesting a record.
|
// Automatically redirect the session to appropriate subsite when requesting a record.
|
||||||
// This is needed to properly initialise the session in situations where someone opens the CMS via a link.
|
// This is needed to properly initialise the session in situations where someone opens the CMS via a link.
|
||||||
$record = $this->owner->currentPage();
|
$record = $this->owner->currentPage();
|
||||||
if($record && isset($record->SubsiteID) && is_numeric($record->SubsiteID) && isset($this->owner->urlParams['ID'])) {
|
if ($record && isset($record->SubsiteID) && is_numeric($record->SubsiteID) && isset($this->owner->urlParams['ID'])) {
|
||||||
|
|
||||||
if ($this->shouldChangeSubsite($this->owner->class, $record->SubsiteID, Subsite::currentSubsiteID())) {
|
if ($this->shouldChangeSubsite($this->owner->class, $record->SubsiteID, Subsite::currentSubsiteID())) {
|
||||||
// Update current subsite in session
|
// Update current subsite in session
|
||||||
Subsite::changeSubsite($record->SubsiteID);
|
Subsite::changeSubsite($record->SubsiteID);
|
||||||
|
|
||||||
if ($this->owner->canView(Member::currentUser())) {
|
if ($this->owner->canView(Member::currentUser())) {
|
||||||
//Redirect to clear the current page
|
//Redirect to clear the current page
|
||||||
return $this->owner->redirect($this->owner->Link());
|
return $this->owner->redirect($this->owner->Link());
|
||||||
}
|
}
|
||||||
//Redirect to the default CMS section
|
//Redirect to the default CMS section
|
||||||
return $this->owner->redirect('admin/');
|
return $this->owner->redirect('admin/');
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SECOND, check if we need to change subsites due to lack of permissions.
|
// SECOND, check if we need to change subsites due to lack of permissions.
|
||||||
|
|
||||||
if (!$this->owner->canAccess()) {
|
if (!$this->owner->canAccess()) {
|
||||||
|
|
||||||
$member = Member::currentUser();
|
$member = Member::currentUser();
|
||||||
|
|
||||||
// Current section is not accessible, try at least to stick to the same subsite.
|
// Current section is not accessible, try at least to stick to the same subsite.
|
||||||
$menu = CMSMenu::get_menu_items();
|
$menu = CMSMenu::get_menu_items();
|
||||||
foreach($menu as $candidate) {
|
foreach ($menu as $candidate) {
|
||||||
if($candidate->controller && $candidate->controller!=$this->owner->class) {
|
if ($candidate->controller && $candidate->controller != $this->owner->class) {
|
||||||
|
|
||||||
$accessibleSites = singleton($candidate->controller)->sectionSites(true, 'Main site', $member);
|
$accessibleSites = singleton($candidate->controller)->sectionSites(true, 'Main site', $member);
|
||||||
if ($accessibleSites->count() && $accessibleSites->find('ID', Subsite::currentSubsiteID())) {
|
if ($accessibleSites->count() && $accessibleSites->find('ID', Subsite::currentSubsiteID())) {
|
||||||
// Section is accessible, redirect there.
|
// Section is accessible, redirect there.
|
||||||
return $this->owner->redirect(singleton($candidate->controller)->Link());
|
return $this->owner->redirect(singleton($candidate->controller)->Link());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If no section is available, look for other accessible subsites.
|
// If no section is available, look for other accessible subsites.
|
||||||
foreach($menu as $candidate) {
|
foreach ($menu as $candidate) {
|
||||||
if($candidate->controller) {
|
if ($candidate->controller) {
|
||||||
$accessibleSites = singleton($candidate->controller)->sectionSites(true, 'Main site', $member);
|
$accessibleSites = singleton($candidate->controller)->sectionSites(true, 'Main site', $member);
|
||||||
if ($accessibleSites->count()) {
|
if ($accessibleSites->count()) {
|
||||||
Subsite::changeSubsite($accessibleSites->First()->ID);
|
Subsite::changeSubsite($accessibleSites->First()->ID);
|
||||||
return $this->owner->redirect(singleton($candidate->controller)->Link());
|
return $this->owner->redirect(singleton($candidate->controller)->Link());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// We have not found any accessible section or subsite. User should be denied access.
|
// We have not found any accessible section or subsite. User should be denied access.
|
||||||
return Security::permissionFailure($this->owner);
|
return Security::permissionFailure($this->owner);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Current site is accessible. Allow through.
|
// Current site is accessible. Allow through.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
function augmentNewSiteTreeItem(&$item) {
|
function augmentNewSiteTreeItem(&$item)
|
||||||
$item->SubsiteID = isset($_POST['SubsiteID']) ? $_POST['SubsiteID'] : Subsite::currentSubsiteID();
|
{
|
||||||
}
|
$item->SubsiteID = isset($_POST['SubsiteID']) ? $_POST['SubsiteID'] : Subsite::currentSubsiteID();
|
||||||
|
}
|
||||||
|
|
||||||
function onAfterSave($record) {
|
function onAfterSave($record)
|
||||||
if($record->hasMethod('NormalRelated') && ($record->NormalRelated() || $record->ReverseRelated())) {
|
{
|
||||||
$this->owner->response->addHeader('X-Status', rawurlencode(_t('LeftAndMainSubsites.Saved', 'Saved, please update related pages.')));
|
if ($record->hasMethod('NormalRelated') && ($record->NormalRelated() || $record->ReverseRelated())) {
|
||||||
}
|
$this->owner->response->addHeader('X-Status',
|
||||||
}
|
rawurlencode(_t('LeftAndMainSubsites.Saved', 'Saved, please update related pages.')));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function copytosubsite($data, $form) {
|
function copytosubsite($data, $form)
|
||||||
$page = DataObject::get_by_id('SilverStripe\\CMS\\Model\\SiteTree', $data['ID']);
|
{
|
||||||
$subsite = DataObject::get_by_id(Subsite::class, $data['CopyToSubsiteID']);
|
$page = DataObject::get_by_id('SilverStripe\\CMS\\Model\\SiteTree', $data['ID']);
|
||||||
$newPage = $page->duplicateToSubsite($subsite->ID, true);
|
$subsite = DataObject::get_by_id(Subsite::class, $data['CopyToSubsiteID']);
|
||||||
$response = $this->owner->getResponse();
|
$newPage = $page->duplicateToSubsite($subsite->ID, true);
|
||||||
$response->addHeader('X-Reload', true);
|
$response = $this->owner->getResponse();
|
||||||
return $this->owner->redirect(Controller::join_links($this->owner->Link('show'), $newPage->ID));
|
$response->addHeader('X-Reload', true);
|
||||||
}
|
return $this->owner->redirect(Controller::join_links($this->owner->Link('show'), $newPage->ID));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -3,60 +3,75 @@
|
|||||||
namespace SilverStripe\Subsites\Extensions;
|
namespace SilverStripe\Subsites\Extensions;
|
||||||
|
|
||||||
|
|
||||||
use SilverStripe\ORM\Queries\SQLSelect;
|
|
||||||
use SilverStripe\ORM\DataQuery;
|
|
||||||
use SilverStripe\Forms\FieldList;
|
use SilverStripe\Forms\FieldList;
|
||||||
use SilverStripe\Forms\HiddenField;
|
use SilverStripe\Forms\HiddenField;
|
||||||
use SilverStripe\ORM\DataExtension;
|
use SilverStripe\ORM\DataExtension;
|
||||||
use SilverStripe\Subsites\Model\Subsite;
|
use SilverStripe\ORM\DataQuery;
|
||||||
|
use SilverStripe\ORM\Queries\SQLSelect;
|
||||||
use SilverStripe\SiteConfig\SiteConfig;
|
use SilverStripe\SiteConfig\SiteConfig;
|
||||||
|
use SilverStripe\Subsites\Model\Subsite;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extension for the SiteConfig object to add subsites support
|
* Extension for the SiteConfig object to add subsites support
|
||||||
*/
|
*/
|
||||||
class SiteConfigSubsites extends DataExtension {
|
class SiteConfigSubsites extends DataExtension
|
||||||
|
{
|
||||||
|
|
||||||
private static $has_one = array(
|
private static $has_one = [
|
||||||
'Subsite' => Subsite::class, // The subsite that this page belongs to
|
'Subsite' => Subsite::class, // The subsite that this page belongs to
|
||||||
);
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update any requests to limit the results to the current site
|
* Update any requests to limit the results to the current site
|
||||||
*/
|
*/
|
||||||
public function augmentSQL(SQLSelect $query, DataQuery $dataQuery = null) {
|
public function augmentSQL(SQLSelect $query, DataQuery $dataQuery = null)
|
||||||
if(Subsite::$disable_subsite_filter) return;
|
{
|
||||||
|
if (Subsite::$disable_subsite_filter) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// If you're querying by ID, ignore the sub-site - this is a bit ugly...
|
// If you're querying by ID, ignore the sub-site - this is a bit ugly...
|
||||||
if($query->filtersOnID()) return;
|
if ($query->filtersOnID()) {
|
||||||
$regexp = '/^(.*\.)?("|`)?SubsiteID("|`)?\s?=/';
|
return;
|
||||||
foreach($query->getWhereParameterised($parameters) as $predicate) {
|
}
|
||||||
if(preg_match($regexp, $predicate)) return;
|
$regexp = '/^(.*\.)?("|`)?SubsiteID("|`)?\s?=/';
|
||||||
}
|
foreach ($query->getWhereParameterised($parameters) as $predicate) {
|
||||||
|
if (preg_match($regexp, $predicate)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*if($context = DataObject::context_obj()) $subsiteID = (int)$context->SubsiteID;
|
/*if($context = DataObject::context_obj()) $subsiteID = (int)$context->SubsiteID;
|
||||||
else */$subsiteID = (int)Subsite::currentSubsiteID();
|
else */
|
||||||
|
$subsiteID = (int)Subsite::currentSubsiteID();
|
||||||
|
|
||||||
$froms=$query->getFrom();
|
$froms = $query->getFrom();
|
||||||
$froms=array_keys($froms);
|
$froms = array_keys($froms);
|
||||||
$tableName = array_shift($froms);
|
$tableName = array_shift($froms);
|
||||||
if($tableName != SiteConfig::class) return;
|
if ($tableName != SiteConfig::class) {
|
||||||
$query->addWhere("\"$tableName\".\"SubsiteID\" IN ($subsiteID)");
|
return;
|
||||||
}
|
}
|
||||||
|
$query->addWhere("\"$tableName\".\"SubsiteID\" IN ($subsiteID)");
|
||||||
|
}
|
||||||
|
|
||||||
function onBeforeWrite() {
|
function onBeforeWrite()
|
||||||
if((!is_numeric($this->owner->ID) || !$this->owner->ID) && !$this->owner->SubsiteID) $this->owner->SubsiteID = Subsite::currentSubsiteID();
|
{
|
||||||
}
|
if ((!is_numeric($this->owner->ID) || !$this->owner->ID) && !$this->owner->SubsiteID) {
|
||||||
|
$this->owner->SubsiteID = Subsite::currentSubsiteID();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a piece of text to keep DataObject cache keys appropriately specific
|
* Return a piece of text to keep DataObject cache keys appropriately specific
|
||||||
*/
|
*/
|
||||||
function cacheKeyComponent() {
|
function cacheKeyComponent()
|
||||||
return 'subsite-'.Subsite::currentSubsiteID();
|
{
|
||||||
}
|
return 'subsite-' . Subsite::currentSubsiteID();
|
||||||
|
}
|
||||||
|
|
||||||
function updateCMSFields(FieldList $fields) {
|
function updateCMSFields(FieldList $fields)
|
||||||
$fields->push(new HiddenField('SubsiteID','SubsiteID', Subsite::currentSubsiteID()));
|
{
|
||||||
}
|
$fields->push(new HiddenField('SubsiteID', 'SubsiteID', Subsite::currentSubsiteID()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,364 +3,418 @@
|
|||||||
namespace SilverStripe\Subsites\Extensions;
|
namespace SilverStripe\Subsites\Extensions;
|
||||||
|
|
||||||
|
|
||||||
use SilverStripe\ORM\Queries\SQLSelect;
|
|
||||||
use SilverStripe\ORM\DataQuery;
|
|
||||||
use SilverStripe\Forms\FieldList;
|
|
||||||
use SilverStripe\Forms\DropdownField;
|
|
||||||
use SilverStripe\Forms\InlineFormAction;
|
|
||||||
use SilverStripe\Core\Config\Config;
|
|
||||||
use SilverStripe\Control\Director;
|
|
||||||
use SilverStripe\Control\Controller;
|
|
||||||
use SilverStripe\ORM\DataObject;
|
|
||||||
use SilverStripe\SiteConfig\SiteConfig;
|
|
||||||
use SilverStripe\Security\Member;
|
|
||||||
use SilverStripe\Control\HTTP;
|
|
||||||
use SilverStripe\Core\Convert;
|
|
||||||
use SilverStripe\ORM\DataExtension;
|
|
||||||
use SilverStripe\Subsites\Model\Subsite;
|
|
||||||
use Page;
|
use Page;
|
||||||
use SilverStripe\CMS\Model\SiteTree;
|
use SilverStripe\CMS\Model\SiteTree;
|
||||||
|
use SilverStripe\Control\Controller;
|
||||||
|
use SilverStripe\Control\Director;
|
||||||
|
use SilverStripe\Control\HTTP;
|
||||||
|
use SilverStripe\Core\Config\Config;
|
||||||
|
use SilverStripe\Core\Convert;
|
||||||
|
use SilverStripe\Forms\DropdownField;
|
||||||
|
use SilverStripe\Forms\FieldList;
|
||||||
|
use SilverStripe\Forms\InlineFormAction;
|
||||||
|
use SilverStripe\ORM\DataExtension;
|
||||||
|
use SilverStripe\ORM\DataObject;
|
||||||
|
use SilverStripe\ORM\DataQuery;
|
||||||
|
use SilverStripe\ORM\Queries\SQLSelect;
|
||||||
|
use SilverStripe\Security\Member;
|
||||||
|
use SilverStripe\SiteConfig\SiteConfig;
|
||||||
|
use SilverStripe\Subsites\Model\Subsite;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extension for the SiteTree object to add subsites support
|
* Extension for the SiteTree object to add subsites support
|
||||||
*/
|
*/
|
||||||
class SiteTreeSubsites extends DataExtension {
|
class SiteTreeSubsites extends DataExtension
|
||||||
|
{
|
||||||
|
|
||||||
private static $has_one = array(
|
private static $has_one = [
|
||||||
'Subsite' => Subsite::class, // The subsite that this page belongs to
|
'Subsite' => Subsite::class, // The subsite that this page belongs to
|
||||||
);
|
];
|
||||||
|
|
||||||
private static $many_many = array(
|
private static $many_many = [
|
||||||
'CrossSubsiteLinkTracking' => 'SilverStripe\\CMS\\Model\\SiteTree' // Stored separately, as the logic for URL rewriting is different
|
'CrossSubsiteLinkTracking' => 'SilverStripe\\CMS\\Model\\SiteTree'
|
||||||
);
|
// Stored separately, as the logic for URL rewriting is different
|
||||||
|
];
|
||||||
|
|
||||||
private static $many_many_extraFields = array(
|
private static $many_many_extraFields = [
|
||||||
"CrossSubsiteLinkTracking" => array("FieldName" => "Varchar")
|
"CrossSubsiteLinkTracking" => ["FieldName" => "Varchar"]
|
||||||
);
|
];
|
||||||
|
|
||||||
function isMainSite() {
|
function isMainSite()
|
||||||
if($this->owner->SubsiteID == 0) return true;
|
{
|
||||||
return false;
|
if ($this->owner->SubsiteID == 0) {
|
||||||
}
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update any requests to limit the results to the current site
|
* Update any requests to limit the results to the current site
|
||||||
*/
|
*/
|
||||||
public function augmentSQL(SQLSelect $query, DataQuery $dataQuery = null) {
|
public function augmentSQL(SQLSelect $query, DataQuery $dataQuery = null)
|
||||||
if(Subsite::$disable_subsite_filter) return;
|
{
|
||||||
if($dataQuery->getQueryParam('Subsite.filter') === false) return;
|
if (Subsite::$disable_subsite_filter) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ($dataQuery->getQueryParam('Subsite.filter') === false) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// If you're querying by ID, ignore the sub-site - this is a bit ugly...
|
// If you're querying by ID, ignore the sub-site - this is a bit ugly...
|
||||||
// if(!$query->where || (strpos($query->where[0], ".\"ID\" = ") === false && strpos($query->where[0], ".`ID` = ") === false && strpos($query->where[0], ".ID = ") === false && strpos($query->where[0], "ID = ") !== 0)) {
|
// if(!$query->where || (strpos($query->where[0], ".\"ID\" = ") === false && strpos($query->where[0], ".`ID` = ") === false && strpos($query->where[0], ".ID = ") === false && strpos($query->where[0], "ID = ") !== 0)) {
|
||||||
if($query->filtersOnID()) return;
|
if ($query->filtersOnID()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (Subsite::$force_subsite) $subsiteID = Subsite::$force_subsite;
|
if (Subsite::$force_subsite) {
|
||||||
else {
|
$subsiteID = Subsite::$force_subsite;
|
||||||
/*if($context = DataObject::context_obj()) $subsiteID = (int)$context->SubsiteID;
|
} else {
|
||||||
else */$subsiteID = (int)Subsite::currentSubsiteID();
|
/*if($context = DataObject::context_obj()) $subsiteID = (int)$context->SubsiteID;
|
||||||
}
|
else */
|
||||||
|
$subsiteID = (int)Subsite::currentSubsiteID();
|
||||||
|
}
|
||||||
|
|
||||||
// The foreach is an ugly way of getting the first key :-)
|
// The foreach is an ugly way of getting the first key :-)
|
||||||
foreach($query->getFrom() as $tableName => $info) {
|
foreach ($query->getFrom() as $tableName => $info) {
|
||||||
// The tableName should be SiteTree or SiteTree_Live...
|
// The tableName should be SiteTree or SiteTree_Live...
|
||||||
if(strpos($tableName,SiteTree::class) === false) break;
|
if (strpos($tableName, SiteTree::class) === false) {
|
||||||
$query->addWhere("\"$tableName\".\"SubsiteID\" IN ($subsiteID)");
|
break;
|
||||||
break;
|
}
|
||||||
}
|
$query->addWhere("\"$tableName\".\"SubsiteID\" IN ($subsiteID)");
|
||||||
}
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function onBeforeWrite() {
|
function onBeforeWrite()
|
||||||
if(!$this->owner->ID && !$this->owner->SubsiteID) $this->owner->SubsiteID = Subsite::currentSubsiteID();
|
{
|
||||||
|
if (!$this->owner->ID && !$this->owner->SubsiteID) {
|
||||||
|
$this->owner->SubsiteID = Subsite::currentSubsiteID();
|
||||||
|
}
|
||||||
|
|
||||||
parent::onBeforeWrite();
|
parent::onBeforeWrite();
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateCMSFields(FieldList $fields) {
|
function updateCMSFields(FieldList $fields)
|
||||||
$subsites = Subsite::accessible_sites("CMS_ACCESS_CMSMain");
|
{
|
||||||
$subsitesMap = array();
|
$subsites = Subsite::accessible_sites("CMS_ACCESS_CMSMain");
|
||||||
if($subsites && $subsites->Count()) {
|
$subsitesMap = [];
|
||||||
$subsitesMap = $subsites->map('ID', 'Title')->toArray();
|
if ($subsites && $subsites->Count()) {
|
||||||
unset($subsitesMap[$this->owner->SubsiteID]);
|
$subsitesMap = $subsites->map('ID', 'Title')->toArray();
|
||||||
}
|
unset($subsitesMap[$this->owner->SubsiteID]);
|
||||||
|
}
|
||||||
|
|
||||||
// Master page edit field (only allowed from default subsite to avoid inconsistent relationships)
|
// Master page edit field (only allowed from default subsite to avoid inconsistent relationships)
|
||||||
$isDefaultSubsite = $this->owner->SubsiteID == 0 || $this->owner->Subsite()->DefaultSite;
|
$isDefaultSubsite = $this->owner->SubsiteID == 0 || $this->owner->Subsite()->DefaultSite;
|
||||||
if($isDefaultSubsite && $subsitesMap) {
|
if ($isDefaultSubsite && $subsitesMap) {
|
||||||
$fields->addFieldToTab(
|
$fields->addFieldToTab(
|
||||||
'Root.Main',
|
'Root.Main',
|
||||||
new DropdownField(
|
new DropdownField(
|
||||||
"CopyToSubsiteID",
|
"CopyToSubsiteID",
|
||||||
_t('SiteTreeSubsites.CopyToSubsite', "Copy page to subsite"),
|
_t('SiteTreeSubsites.CopyToSubsite', "Copy page to subsite"),
|
||||||
$subsitesMap,
|
$subsitesMap,
|
||||||
''
|
''
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
$fields->addFieldToTab(
|
$fields->addFieldToTab(
|
||||||
'Root.Main',
|
'Root.Main',
|
||||||
$copyAction = new InlineFormAction(
|
$copyAction = new InlineFormAction(
|
||||||
"copytosubsite",
|
"copytosubsite",
|
||||||
_t('SiteTreeSubsites.CopyAction', "Copy")
|
_t('SiteTreeSubsites.CopyAction', "Copy")
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// replace readonly link prefix
|
// replace readonly link prefix
|
||||||
$subsite = $this->owner->Subsite();
|
$subsite = $this->owner->Subsite();
|
||||||
$nested_urls_enabled = Config::inst()->get('SilverStripe\\CMS\\Model\\SiteTree', 'nested_urls');
|
$nested_urls_enabled = Config::inst()->get('SilverStripe\\CMS\\Model\\SiteTree', 'nested_urls');
|
||||||
if($subsite && $subsite->ID) {
|
if ($subsite && $subsite->ID) {
|
||||||
$baseUrl = Director::protocol() . $subsite->domain() . '/';
|
$baseUrl = Director::protocol() . $subsite->domain() . '/';
|
||||||
$baseLink = Controller::join_links (
|
$baseLink = Controller::join_links(
|
||||||
$baseUrl,
|
$baseUrl,
|
||||||
($nested_urls_enabled && $this->owner->ParentID ? $this->owner->Parent()->RelativeLink(true) : null)
|
($nested_urls_enabled && $this->owner->ParentID ? $this->owner->Parent()->RelativeLink(true) : null)
|
||||||
);
|
);
|
||||||
|
|
||||||
$urlsegment = $fields->dataFieldByName('URLSegment');
|
$urlsegment = $fields->dataFieldByName('URLSegment');
|
||||||
$urlsegment->setURLPrefix($baseLink);
|
$urlsegment->setURLPrefix($baseLink);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function alternateSiteConfig() {
|
function alternateSiteConfig()
|
||||||
if(!$this->owner->SubsiteID) return false;
|
{
|
||||||
$sc = DataObject::get_one('SilverStripe\\SiteConfig\\SiteConfig', '"SubsiteID" = ' . $this->owner->SubsiteID);
|
if (!$this->owner->SubsiteID) {
|
||||||
if(!$sc) {
|
return false;
|
||||||
$sc = new SiteConfig();
|
}
|
||||||
$sc->SubsiteID = $this->owner->SubsiteID;
|
$sc = DataObject::get_one('SilverStripe\\SiteConfig\\SiteConfig', '"SubsiteID" = ' . $this->owner->SubsiteID);
|
||||||
$sc->Title = _t('Subsite.SiteConfigTitle','Your Site Name');
|
if (!$sc) {
|
||||||
$sc->Tagline = _t('Subsite.SiteConfigSubtitle','Your tagline here');
|
$sc = new SiteConfig();
|
||||||
$sc->write();
|
$sc->SubsiteID = $this->owner->SubsiteID;
|
||||||
}
|
$sc->Title = _t('Subsite.SiteConfigTitle', 'Your Site Name');
|
||||||
return $sc;
|
$sc->Tagline = _t('Subsite.SiteConfigSubtitle', 'Your tagline here');
|
||||||
}
|
$sc->write();
|
||||||
|
}
|
||||||
|
return $sc;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Only allow editing of a page if the member satisfies one of the following conditions:
|
* Only allow editing of a page if the member satisfies one of the following conditions:
|
||||||
* - Is in a group which has access to the subsite this page belongs to
|
* - Is in a group which has access to the subsite this page belongs to
|
||||||
* - Is in a group with edit permissions on the "main site"
|
* - Is in a group with edit permissions on the "main site"
|
||||||
*
|
*
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
function canEdit($member = null) {
|
function canEdit($member = null)
|
||||||
|
{
|
||||||
|
|
||||||
if(!$member) $member = Member::currentUser();
|
if (!$member) {
|
||||||
|
$member = Member::currentUser();
|
||||||
|
}
|
||||||
|
|
||||||
// Find the sites that this user has access to
|
// Find the sites that this user has access to
|
||||||
$goodSites = Subsite::accessible_sites('CMS_ACCESS_CMSMain',true,'all',$member)->column('ID');
|
$goodSites = Subsite::accessible_sites('CMS_ACCESS_CMSMain', true, 'all', $member)->column('ID');
|
||||||
|
|
||||||
if (!is_null($this->owner->SubsiteID)) {
|
if (!is_null($this->owner->SubsiteID)) {
|
||||||
$subsiteID = $this->owner->SubsiteID;
|
$subsiteID = $this->owner->SubsiteID;
|
||||||
} else {
|
} else {
|
||||||
// The relationships might not be available during the record creation when using a GridField.
|
// The relationships might not be available during the record creation when using a GridField.
|
||||||
// In this case the related objects will have empty fields, and SubsiteID will not be available.
|
// In this case the related objects will have empty fields, and SubsiteID will not be available.
|
||||||
//
|
//
|
||||||
// We do the second best: fetch the likely SubsiteID from the session. The drawback is this might
|
// We do the second best: fetch the likely SubsiteID from the session. The drawback is this might
|
||||||
// make it possible to force relations to point to other (forbidden) subsites.
|
// make it possible to force relations to point to other (forbidden) subsites.
|
||||||
$subsiteID = Subsite::currentSubsiteID();
|
$subsiteID = Subsite::currentSubsiteID();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return true if they have access to this object's site
|
// Return true if they have access to this object's site
|
||||||
if(!(in_array(0, $goodSites) || in_array($subsiteID, $goodSites))) return false;
|
if (!(in_array(0, $goodSites) || in_array($subsiteID, $goodSites))) {
|
||||||
}
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
function canDelete($member = null) {
|
function canDelete($member = null)
|
||||||
if(!$member && $member !== FALSE) $member = Member::currentUser();
|
{
|
||||||
|
if (!$member && $member !== FALSE) {
|
||||||
|
$member = Member::currentUser();
|
||||||
|
}
|
||||||
|
|
||||||
return $this->canEdit($member);
|
return $this->canEdit($member);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
function canAddChildren($member = null) {
|
function canAddChildren($member = null)
|
||||||
if(!$member && $member !== FALSE) $member = Member::currentUser();
|
{
|
||||||
|
if (!$member && $member !== FALSE) {
|
||||||
|
$member = Member::currentUser();
|
||||||
|
}
|
||||||
|
|
||||||
return $this->canEdit($member);
|
return $this->canEdit($member);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
function canPublish($member = null) {
|
function canPublish($member = null)
|
||||||
if(!$member && $member !== FALSE) $member = Member::currentUser();
|
{
|
||||||
|
if (!$member && $member !== FALSE) {
|
||||||
|
$member = Member::currentUser();
|
||||||
|
}
|
||||||
|
|
||||||
return $this->canEdit($member);
|
return $this->canEdit($member);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Does the basic duplication, but doesn't write anything
|
* Does the basic duplication, but doesn't write anything
|
||||||
* this means we can subclass this easier and do more complex
|
* this means we can subclass this easier and do more complex
|
||||||
* relation duplication.
|
* relation duplication.
|
||||||
*/
|
*/
|
||||||
public function duplicateToSubsitePrep($subsiteID) {
|
public function duplicateToSubsitePrep($subsiteID)
|
||||||
if (is_object($subsiteID)) {
|
{
|
||||||
$subsiteID = $subsiteID->ID;
|
if (is_object($subsiteID)) {
|
||||||
}
|
$subsiteID = $subsiteID->ID;
|
||||||
|
}
|
||||||
|
|
||||||
$oldSubsite = Subsite::currentSubsiteID();
|
$oldSubsite = Subsite::currentSubsiteID();
|
||||||
if ($subsiteID) {
|
if ($subsiteID) {
|
||||||
Subsite::changeSubsite($subsiteID);
|
Subsite::changeSubsite($subsiteID);
|
||||||
} else {
|
} else {
|
||||||
$subsiteID = $oldSubsite;
|
$subsiteID = $oldSubsite;
|
||||||
}
|
}
|
||||||
// doesn't write as we need to reset the SubsiteID, ParentID etc
|
// doesn't write as we need to reset the SubsiteID, ParentID etc
|
||||||
$clone = $this->owner->duplicate(false);
|
$clone = $this->owner->duplicate(false);
|
||||||
$clone->CheckedPublicationDifferences = $clone->AddedToStage = true;
|
$clone->CheckedPublicationDifferences = $clone->AddedToStage = true;
|
||||||
$subsiteID = ($subsiteID ? $subsiteID : $oldSubsite);
|
$subsiteID = ($subsiteID ? $subsiteID : $oldSubsite);
|
||||||
$clone->SubsiteID = $subsiteID;
|
$clone->SubsiteID = $subsiteID;
|
||||||
// We have no idea what the parentID should be, so as a workaround use the url-segment and subsite ID
|
// We have no idea what the parentID should be, so as a workaround use the url-segment and subsite ID
|
||||||
if ($this->owner->Parent()) {
|
if ($this->owner->Parent()) {
|
||||||
$parentSeg = $this->owner->Parent()->URLSegment;
|
$parentSeg = $this->owner->Parent()->URLSegment;
|
||||||
$newParentPage = Page::get()->filter('URLSegment', $parentSeg)->first();
|
$newParentPage = Page::get()->filter('URLSegment', $parentSeg)->first();
|
||||||
if ($newParentPage) {
|
if ($newParentPage) {
|
||||||
$clone->ParentID = $newParentPage->ID;
|
$clone->ParentID = $newParentPage->ID;
|
||||||
} else {
|
} else {
|
||||||
// reset it to the top level, so the user can decide where to put it
|
// reset it to the top level, so the user can decide where to put it
|
||||||
$clone->ParentID = 0;
|
$clone->ParentID = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// MasterPageID is here for legacy purposes, to satisfy the subsites_relatedpages module
|
// MasterPageID is here for legacy purposes, to satisfy the subsites_relatedpages module
|
||||||
$clone->MasterPageID = $this->owner->ID;
|
$clone->MasterPageID = $this->owner->ID;
|
||||||
return $clone;
|
return $clone;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a duplicate of this page and save it to another subsite
|
* Create a duplicate of this page and save it to another subsite
|
||||||
* @param $subsiteID int|Subsite The Subsite to copy to, or its ID
|
* @param $subsiteID int|Subsite The Subsite to copy to, or its ID
|
||||||
*/
|
*/
|
||||||
public function duplicateToSubsite($subsiteID = null) {
|
public function duplicateToSubsite($subsiteID = null)
|
||||||
$clone = $this->owner->duplicateToSubsitePrep($subsiteID);
|
{
|
||||||
$clone->invokeWithExtensions('onBeforeDuplicateToSubsite', $this->owner);
|
$clone = $this->owner->duplicateToSubsitePrep($subsiteID);
|
||||||
$clone->write();
|
$clone->invokeWithExtensions('onBeforeDuplicateToSubsite', $this->owner);
|
||||||
$clone->duplicateSubsiteRelations($this->owner);
|
$clone->write();
|
||||||
// new extension hooks which happens after write,
|
$clone->duplicateSubsiteRelations($this->owner);
|
||||||
// onAfterDuplicate isn't reliable due to
|
// new extension hooks which happens after write,
|
||||||
// https://github.com/silverstripe/silverstripe-cms/issues/1253
|
// onAfterDuplicate isn't reliable due to
|
||||||
$clone->invokeWithExtensions('onAfterDuplicateToSubsite', $this->owner);
|
// https://github.com/silverstripe/silverstripe-cms/issues/1253
|
||||||
return $clone;
|
$clone->invokeWithExtensions('onAfterDuplicateToSubsite', $this->owner);
|
||||||
}
|
return $clone;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Duplicate relations using a static property to define
|
* Duplicate relations using a static property to define
|
||||||
* which ones we want to duplicate
|
* which ones we want to duplicate
|
||||||
*
|
*
|
||||||
* It may be that some relations are not diostinct to sub site so can stay
|
* It may be that some relations are not diostinct to sub site so can stay
|
||||||
* whereas others may need to be duplicated
|
* whereas others may need to be duplicated
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public function duplicateSubsiteRelations($originalPage) {
|
public function duplicateSubsiteRelations($originalPage)
|
||||||
$thisClass = $originalPage->ClassName;
|
{
|
||||||
$relations = Config::inst()->get($thisClass, 'duplicate_to_subsite_relations');
|
$thisClass = $originalPage->ClassName;
|
||||||
|
$relations = Config::inst()->get($thisClass, 'duplicate_to_subsite_relations');
|
||||||
|
|
||||||
if($relations && !empty($relations)) {
|
if ($relations && !empty($relations)) {
|
||||||
foreach($relations as $relation) {
|
foreach ($relations as $relation) {
|
||||||
$items = $originalPage->$relation();
|
$items = $originalPage->$relation();
|
||||||
foreach($items as $item) {
|
foreach ($items as $item) {
|
||||||
$duplicateItem = $item->duplicate(false);
|
$duplicateItem = $item->duplicate(false);
|
||||||
$duplicateItem->{$thisClass.'ID'} = $this->owner->ID;
|
$duplicateItem->{$thisClass . 'ID'} = $this->owner->ID;
|
||||||
$duplicateItem->write();
|
$duplicateItem->write();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called by ContentController::init();
|
* Called by ContentController::init();
|
||||||
*/
|
*/
|
||||||
static function contentcontrollerInit($controller) {
|
static function contentcontrollerInit($controller)
|
||||||
$subsite = Subsite::currentSubsite();
|
{
|
||||||
|
$subsite = Subsite::currentSubsite();
|
||||||
|
|
||||||
if($subsite && $subsite->Theme){
|
if ($subsite && $subsite->Theme) {
|
||||||
Config::modify()->set('SilverStripe\\View\\SSViewer', 'theme', Subsite::currentSubsite()->Theme);
|
Config::modify()->set('SilverStripe\\View\\SSViewer', 'theme', Subsite::currentSubsite()->Theme);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function alternateAbsoluteLink() {
|
function alternateAbsoluteLink()
|
||||||
// Generate the existing absolute URL and replace the domain with the subsite domain.
|
{
|
||||||
// This helps deal with Link() returning an absolute URL.
|
// Generate the existing absolute URL and replace the domain with the subsite domain.
|
||||||
$url = Director::absoluteURL($this->owner->Link());
|
// This helps deal with Link() returning an absolute URL.
|
||||||
if($this->owner->SubsiteID) {
|
$url = Director::absoluteURL($this->owner->Link());
|
||||||
$url = preg_replace('/\/\/[^\/]+\//', '//' . $this->owner->Subsite()->domain() . '/', $url);
|
if ($this->owner->SubsiteID) {
|
||||||
}
|
$url = preg_replace('/\/\/[^\/]+\//', '//' . $this->owner->Subsite()->domain() . '/', $url);
|
||||||
return $url;
|
}
|
||||||
}
|
return $url;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use the CMS domain for iframed CMS previews to prevent single-origin violations
|
* Use the CMS domain for iframed CMS previews to prevent single-origin violations
|
||||||
* and SSL cert problems.
|
* and SSL cert problems.
|
||||||
*/
|
*/
|
||||||
function alternatePreviewLink($action = null) {
|
function alternatePreviewLink($action = null)
|
||||||
$url = Director::absoluteURL($this->owner->Link());
|
{
|
||||||
if($this->owner->SubsiteID) {
|
$url = Director::absoluteURL($this->owner->Link());
|
||||||
$url = HTTP::setGetVar('SubsiteID', $this->owner->SubsiteID, $url);
|
if ($this->owner->SubsiteID) {
|
||||||
}
|
$url = HTTP::setGetVar('SubsiteID', $this->owner->SubsiteID, $url);
|
||||||
return $url;
|
}
|
||||||
}
|
return $url;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inject the subsite ID into the content so it can be used by frontend scripts.
|
* Inject the subsite ID into the content so it can be used by frontend scripts.
|
||||||
*/
|
*/
|
||||||
function MetaTags(&$tags) {
|
function MetaTags(&$tags)
|
||||||
if($this->owner->SubsiteID) {
|
{
|
||||||
$tags .= "<meta name=\"x-subsite-id\" content=\"" . $this->owner->SubsiteID . "\" />\n";
|
if ($this->owner->SubsiteID) {
|
||||||
}
|
$tags .= "<meta name=\"x-subsite-id\" content=\"" . $this->owner->SubsiteID . "\" />\n";
|
||||||
|
}
|
||||||
|
|
||||||
return $tags;
|
return $tags;
|
||||||
}
|
}
|
||||||
|
|
||||||
function augmentSyncLinkTracking() {
|
function augmentSyncLinkTracking()
|
||||||
// Set LinkTracking appropriately
|
{
|
||||||
$links = HTTP::getLinksIn($this->owner->Content);
|
// Set LinkTracking appropriately
|
||||||
$linkedPages = array();
|
$links = HTTP::getLinksIn($this->owner->Content);
|
||||||
|
$linkedPages = [];
|
||||||
|
|
||||||
if($links) foreach($links as $link) {
|
if ($links) {
|
||||||
if(substr($link, 0, strlen('http://')) == 'http://') {
|
foreach ($links as $link) {
|
||||||
$withoutHttp = substr($link, strlen('http://'));
|
if (substr($link, 0, strlen('http://')) == 'http://') {
|
||||||
if(strpos($withoutHttp, '/') && strpos($withoutHttp, '/') < strlen($withoutHttp)) {
|
$withoutHttp = substr($link, strlen('http://'));
|
||||||
$domain = substr($withoutHttp, 0, strpos($withoutHttp, '/'));
|
if (strpos($withoutHttp, '/') && strpos($withoutHttp, '/') < strlen($withoutHttp)) {
|
||||||
$rest = substr($withoutHttp, strpos($withoutHttp, '/') + 1);
|
$domain = substr($withoutHttp, 0, strpos($withoutHttp, '/'));
|
||||||
|
$rest = substr($withoutHttp, strpos($withoutHttp, '/') + 1);
|
||||||
|
|
||||||
$subsiteID = Subsite::getSubsiteIDForDomain($domain);
|
$subsiteID = Subsite::getSubsiteIDForDomain($domain);
|
||||||
if($subsiteID == 0) continue; // We have no idea what the domain for the main site is, so cant track links to it
|
if ($subsiteID == 0) {
|
||||||
|
continue;
|
||||||
|
} // We have no idea what the domain for the main site is, so cant track links to it
|
||||||
|
|
||||||
$origDisableSubsiteFilter = Subsite::$disable_subsite_filter;
|
$origDisableSubsiteFilter = Subsite::$disable_subsite_filter;
|
||||||
Subsite::disable_subsite_filter(true);
|
Subsite::disable_subsite_filter(true);
|
||||||
$candidatePage = DataObject::get_one("SilverStripe\\CMS\\Model\\SiteTree", "\"URLSegment\" = '" . Convert::raw2sql(urldecode( $rest)) . "' AND \"SubsiteID\" = " . $subsiteID, false);
|
$candidatePage = DataObject::get_one("SilverStripe\\CMS\\Model\\SiteTree",
|
||||||
Subsite::disable_subsite_filter($origDisableSubsiteFilter);
|
"\"URLSegment\" = '" . Convert::raw2sql(urldecode($rest)) . "' AND \"SubsiteID\" = " . $subsiteID,
|
||||||
|
false);
|
||||||
|
Subsite::disable_subsite_filter($origDisableSubsiteFilter);
|
||||||
|
|
||||||
if($candidatePage) {
|
if ($candidatePage) {
|
||||||
$linkedPages[] = $candidatePage->ID;
|
$linkedPages[] = $candidatePage->ID;
|
||||||
} else {
|
} else {
|
||||||
$this->owner->HasBrokenLink = true;
|
$this->owner->HasBrokenLink = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$this->owner->CrossSubsiteLinkTracking()->setByIDList($linkedPages);
|
$this->owner->CrossSubsiteLinkTracking()->setByIDList($linkedPages);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a piece of text to keep DataObject cache keys appropriately specific
|
* Return a piece of text to keep DataObject cache keys appropriately specific
|
||||||
*/
|
*/
|
||||||
function cacheKeyComponent() {
|
function cacheKeyComponent()
|
||||||
return 'subsite-'.Subsite::currentSubsiteID();
|
{
|
||||||
}
|
return 'subsite-' . Subsite::currentSubsiteID();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Member
|
* @param Member
|
||||||
* @return boolean|null
|
* @return boolean|null
|
||||||
*/
|
*/
|
||||||
function canCreate($member = null) {
|
function canCreate($member = null)
|
||||||
// Typically called on a singleton, so we're not using the Subsite() relation
|
{
|
||||||
$subsite = Subsite::currentSubsite();
|
// Typically called on a singleton, so we're not using the Subsite() relation
|
||||||
if($subsite && $subsite->exists() && $subsite->PageTypeBlacklist) {
|
$subsite = Subsite::currentSubsite();
|
||||||
$blacklisted = explode(',', $subsite->PageTypeBlacklist);
|
if ($subsite && $subsite->exists() && $subsite->PageTypeBlacklist) {
|
||||||
// All subclasses need to be listed explicitly
|
$blacklisted = explode(',', $subsite->PageTypeBlacklist);
|
||||||
if(in_array($this->owner->class, $blacklisted)) return false;
|
// All subclasses need to be listed explicitly
|
||||||
}
|
if (in_array($this->owner->class, $blacklisted)) {
|
||||||
}
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,6 @@ namespace SilverStripe\Subsites\Extensions;
|
|||||||
use SilverStripe\Core\Extension;
|
use SilverStripe\Core\Extension;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Simple extension to show admins in the menu of subsites.
|
* Simple extension to show admins in the menu of subsites.
|
||||||
* If an admin area should be available to a subsite, you can attach
|
* If an admin area should be available to a subsite, you can attach
|
||||||
@ -17,10 +16,12 @@ use SilverStripe\Core\Extension;
|
|||||||
* Or you can include the subsiteCMSShowInMenu function in your admin class and have it return true
|
* Or you can include the subsiteCMSShowInMenu function in your admin class and have it return true
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class SubsiteMenuExtension extends Extension{
|
class SubsiteMenuExtension extends Extension
|
||||||
|
{
|
||||||
|
|
||||||
public function subsiteCMSShowInMenu(){
|
public function subsiteCMSShowInMenu()
|
||||||
return true;
|
{
|
||||||
}
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -3,61 +3,65 @@
|
|||||||
namespace SilverStripe\Subsites\Forms;
|
namespace SilverStripe\Subsites\Forms;
|
||||||
|
|
||||||
|
|
||||||
use SilverStripe\Forms\GridField\GridFieldDetailForm;
|
|
||||||
use SilverStripe\Forms\DropdownField;
|
use SilverStripe\Forms\DropdownField;
|
||||||
|
use SilverStripe\Forms\GridField\GridFieldDetailForm;
|
||||||
use SilverStripe\Forms\GridField\GridFieldDetailForm_ItemRequest;
|
use SilverStripe\Forms\GridField\GridFieldDetailForm_ItemRequest;
|
||||||
|
|
||||||
use SilverStripe\Subsites\Model\Subsite;
|
use SilverStripe\Subsites\Model\Subsite;
|
||||||
|
|
||||||
|
|
||||||
class GridFieldSubsiteDetailForm extends GridFieldDetailForm {
|
class GridFieldSubsiteDetailForm extends GridFieldDetailForm
|
||||||
protected $itemRequestClass=GridFieldSubsiteDetailForm_ItemRequest::class;
|
{
|
||||||
|
protected $itemRequestClass = GridFieldSubsiteDetailForm_ItemRequest::class;
|
||||||
}
|
}
|
||||||
|
|
||||||
class GridFieldSubsiteDetailForm_ItemRequest extends GridFieldDetailForm_ItemRequest {
|
class GridFieldSubsiteDetailForm_ItemRequest extends GridFieldDetailForm_ItemRequest
|
||||||
|
{
|
||||||
|
|
||||||
private static $allowed_actions = array(
|
private static $allowed_actions = [
|
||||||
'ItemEditForm',
|
'ItemEditForm',
|
||||||
);
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds an item edit form. The arguments to getCMSFields() are the popupController and
|
* Builds an item edit form. The arguments to getCMSFields() are the popupController and
|
||||||
* popupFormName, however this is an experimental API and may change.
|
* popupFormName, however this is an experimental API and may change.
|
||||||
*
|
*
|
||||||
* @todo In the future, we will probably need to come up with a tigher object representing a partially
|
* @todo In the future, we will probably need to come up with a tigher object representing a partially
|
||||||
* complete controller with gaps for extra functionality. This, for example, would be a better way
|
* complete controller with gaps for extra functionality. This, for example, would be a better way
|
||||||
* of letting Security/login put its log-in form inside a UI specified elsewhere.
|
* of letting Security/login put its log-in form inside a UI specified elsewhere.
|
||||||
*
|
*
|
||||||
* @return Form
|
* @return Form
|
||||||
* @see GridFieldDetailForm_ItemRequest::ItemEditForm()
|
* @see GridFieldDetailForm_ItemRequest::ItemEditForm()
|
||||||
*/
|
*/
|
||||||
function ItemEditForm() {
|
function ItemEditForm()
|
||||||
$form=parent::ItemEditForm();
|
{
|
||||||
|
$form = parent::ItemEditForm();
|
||||||
|
|
||||||
if($this->record->ID == 0) {
|
if ($this->record->ID == 0) {
|
||||||
$templates = Subsite::get()->sort('Title');
|
$templates = Subsite::get()->sort('Title');
|
||||||
$templateArray = array();
|
$templateArray = [];
|
||||||
if($templates) {
|
if ($templates) {
|
||||||
$templateArray = $templates->map('ID', 'Title');
|
$templateArray = $templates->map('ID', 'Title');
|
||||||
}
|
}
|
||||||
|
|
||||||
$templateDropdown = new DropdownField('TemplateID', _t('Subsite.COPYSTRUCTURE', 'Copy structure from:'), $templateArray);
|
$templateDropdown = new DropdownField('TemplateID', _t('Subsite.COPYSTRUCTURE', 'Copy structure from:'),
|
||||||
$templateDropdown->setEmptyString('(' . _t('Subsite.NOTEMPLATE', 'No template') . ')');
|
$templateArray);
|
||||||
$form->Fields()->addFieldToTab('Root.Configuration', $templateDropdown);
|
$templateDropdown->setEmptyString('(' . _t('Subsite.NOTEMPLATE', 'No template') . ')');
|
||||||
}
|
$form->Fields()->addFieldToTab('Root.Configuration', $templateDropdown);
|
||||||
|
}
|
||||||
|
|
||||||
return $form;
|
return $form;
|
||||||
}
|
}
|
||||||
|
|
||||||
function doSave($data, $form) {
|
function doSave($data, $form)
|
||||||
$new_record = $this->record->ID == 0;
|
{
|
||||||
if($new_record && isset($data['TemplateID']) && !empty($data['TemplateID'])) {
|
$new_record = $this->record->ID == 0;
|
||||||
$template = Subsite::get()->byID(intval($data['TemplateID']));
|
if ($new_record && isset($data['TemplateID']) && !empty($data['TemplateID'])) {
|
||||||
if($template) {
|
$template = Subsite::get()->byID(intval($data['TemplateID']));
|
||||||
$this->record = $template->duplicate();
|
if ($template) {
|
||||||
}
|
$this->record = $template->duplicate();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return parent::doSave($data, $form);
|
return parent::doSave($data, $form);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,11 +3,10 @@
|
|||||||
namespace SilverStripe\Subsites\Forms;
|
namespace SilverStripe\Subsites\Forms;
|
||||||
|
|
||||||
|
|
||||||
use SilverStripe\View\Requirements;
|
|
||||||
use SilverStripe\Control\HTTPRequest;
|
use SilverStripe\Control\HTTPRequest;
|
||||||
use SilverStripe\Control\Session;
|
use SilverStripe\Control\Session;
|
||||||
use SilverStripe\Forms\TreeDropdownField;
|
use SilverStripe\Forms\TreeDropdownField;
|
||||||
|
use SilverStripe\View\Requirements;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -16,40 +15,45 @@ use SilverStripe\Forms\TreeDropdownField;
|
|||||||
*
|
*
|
||||||
* @package subsites
|
* @package subsites
|
||||||
*/
|
*/
|
||||||
class SubsitesTreeDropdownField extends TreeDropdownField {
|
class SubsitesTreeDropdownField extends TreeDropdownField
|
||||||
|
{
|
||||||
|
|
||||||
private static $allowed_actions = array(
|
private static $allowed_actions = [
|
||||||
'tree'
|
'tree'
|
||||||
);
|
];
|
||||||
|
|
||||||
protected $subsiteID = 0;
|
protected $subsiteID = 0;
|
||||||
|
|
||||||
protected $extraClasses = array(SubsitesTreeDropdownField::class);
|
protected $extraClasses = [SubsitesTreeDropdownField::class];
|
||||||
|
|
||||||
function Field($properties = array()) {
|
function Field($properties = [])
|
||||||
$html = parent::Field($properties);
|
{
|
||||||
|
$html = parent::Field($properties);
|
||||||
|
|
||||||
Requirements::javascript('subsites/javascript/SubsitesTreeDropdownField.js');
|
Requirements::javascript('subsites/javascript/SubsitesTreeDropdownField.js');
|
||||||
|
|
||||||
return $html;
|
return $html;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setSubsiteID($id) {
|
function setSubsiteID($id)
|
||||||
$this->subsiteID = $id;
|
{
|
||||||
}
|
$this->subsiteID = $id;
|
||||||
|
}
|
||||||
|
|
||||||
function getSubsiteID() {
|
function getSubsiteID()
|
||||||
return $this->subsiteID;
|
{
|
||||||
}
|
return $this->subsiteID;
|
||||||
|
}
|
||||||
|
|
||||||
function tree(HTTPRequest $request) {
|
function tree(HTTPRequest $request)
|
||||||
$oldSubsiteID = Session::get('SubsiteID');
|
{
|
||||||
Session::set('SubsiteID', $this->subsiteID);
|
$oldSubsiteID = Session::get('SubsiteID');
|
||||||
|
Session::set('SubsiteID', $this->subsiteID);
|
||||||
|
|
||||||
$results = parent::tree($request);
|
$results = parent::tree($request);
|
||||||
|
|
||||||
Session::set('SubsiteID', $oldSubsiteID);
|
Session::set('SubsiteID', $oldSubsiteID);
|
||||||
|
|
||||||
return $results;
|
return $results;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,37 +3,34 @@
|
|||||||
namespace SilverStripe\Subsites\Model;
|
namespace SilverStripe\Subsites\Model;
|
||||||
|
|
||||||
|
|
||||||
use SilverStripe\i18n\Data\Intl\IntlLocales;
|
|
||||||
use SilverStripe\ORM\DataObject;
|
|
||||||
use SilverStripe\Control\Session;
|
|
||||||
use SilverStripe\i18n\i18n;
|
|
||||||
use SilverStripe\Security\Permission;
|
|
||||||
use SilverStripe\Security\Member;
|
|
||||||
use SilverStripe\Core\Convert;
|
|
||||||
use SilverStripe\ORM\ArrayList;
|
|
||||||
use SilverStripe\Admin\CMSMenu;
|
use SilverStripe\Admin\CMSMenu;
|
||||||
use SilverStripe\ORM\DataList;
|
|
||||||
use SilverStripe\Control\Director;
|
|
||||||
use SilverStripe\ORM\DB;
|
|
||||||
use SilverStripe\Forms\GridField\GridFieldConfig_RecordEditor;
|
|
||||||
use SilverStripe\Forms\GridField\GridField;
|
|
||||||
use SilverStripe\Forms\LiteralField;
|
|
||||||
use SilverStripe\Forms\DropdownField;
|
|
||||||
use SilverStripe\CMS\Model\SiteTree;
|
use SilverStripe\CMS\Model\SiteTree;
|
||||||
use SilverStripe\Forms\HeaderField;
|
use SilverStripe\Control\Director;
|
||||||
use SilverStripe\Forms\TextField;
|
use SilverStripe\Control\Session;
|
||||||
|
use SilverStripe\Core\Convert;
|
||||||
use SilverStripe\Forms\CheckboxField;
|
use SilverStripe\Forms\CheckboxField;
|
||||||
use SilverStripe\Forms\CheckboxSetField;
|
use SilverStripe\Forms\CheckboxSetField;
|
||||||
|
use SilverStripe\Forms\DropdownField;
|
||||||
|
use SilverStripe\Forms\FieldList;
|
||||||
|
use SilverStripe\Forms\GridField\GridField;
|
||||||
|
use SilverStripe\Forms\GridField\GridFieldConfig_RecordEditor;
|
||||||
|
use SilverStripe\Forms\HeaderField;
|
||||||
|
use SilverStripe\Forms\HiddenField;
|
||||||
|
use SilverStripe\Forms\LiteralField;
|
||||||
use SilverStripe\Forms\Tab;
|
use SilverStripe\Forms\Tab;
|
||||||
use SilverStripe\Forms\TabSet;
|
use SilverStripe\Forms\TabSet;
|
||||||
use SilverStripe\Forms\HiddenField;
|
use SilverStripe\Forms\TextField;
|
||||||
use SilverStripe\Forms\FieldList;
|
use SilverStripe\i18n\Data\Intl\IntlLocales;
|
||||||
|
use SilverStripe\i18n\i18n;
|
||||||
use SilverStripe\ORM\ArrayLib;
|
use SilverStripe\ORM\ArrayLib;
|
||||||
|
use SilverStripe\ORM\ArrayList;
|
||||||
|
use SilverStripe\ORM\DataList;
|
||||||
|
use SilverStripe\ORM\DataObject;
|
||||||
|
use SilverStripe\ORM\DB;
|
||||||
|
use SilverStripe\Security\Member;
|
||||||
|
use SilverStripe\Security\Permission;
|
||||||
use SilverStripe\Versioned\Versioned;
|
use SilverStripe\Versioned\Versioned;
|
||||||
use UnexpectedValueException;
|
use UnexpectedValueException;
|
||||||
use SilverStripe\Security\Group;
|
|
||||||
use SilverStripe\Security\PermissionRole;
|
|
||||||
use SilverStripe\Security\PermissionRoleCode;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -42,432 +39,513 @@ use SilverStripe\Security\PermissionRoleCode;
|
|||||||
*
|
*
|
||||||
* @package subsites
|
* @package subsites
|
||||||
*/
|
*/
|
||||||
class Subsite extends DataObject {
|
class Subsite extends DataObject
|
||||||
|
{
|
||||||
|
|
||||||
private static $table_name = 'Subsite';
|
private static $table_name = 'Subsite';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var $use_session_subsiteid Boolean Set to TRUE when using the CMS and FALSE
|
* @var $use_session_subsiteid Boolean Set to TRUE when using the CMS and FALSE
|
||||||
* when browsing the frontend of a website.
|
* when browsing the frontend of a website.
|
||||||
*
|
*
|
||||||
* @todo Remove flag once the Subsite CMS works without session state,
|
* @todo Remove flag once the Subsite CMS works without session state,
|
||||||
* similarly to the Translatable module.
|
* similarly to the Translatable module.
|
||||||
*/
|
*/
|
||||||
public static $use_session_subsiteid = false;
|
public static $use_session_subsiteid = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var boolean $disable_subsite_filter If enabled, bypasses the query decoration
|
* @var boolean $disable_subsite_filter If enabled, bypasses the query decoration
|
||||||
* to limit DataObject::get*() calls to a specific subsite. Useful for debugging.
|
* to limit DataObject::get*() calls to a specific subsite. Useful for debugging.
|
||||||
*/
|
*/
|
||||||
public static $disable_subsite_filter = false;
|
public static $disable_subsite_filter = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allows you to force a specific subsite ID, or comma separated list of IDs.
|
* Allows you to force a specific subsite ID, or comma separated list of IDs.
|
||||||
* Only works for reading. An object cannot be written to more than 1 subsite.
|
* Only works for reading. An object cannot be written to more than 1 subsite.
|
||||||
*/
|
*/
|
||||||
public static $force_subsite = null;
|
public static $force_subsite = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @var boolean
|
* @var boolean
|
||||||
*/
|
*/
|
||||||
public static $write_hostmap = true;
|
public static $write_hostmap = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Memory cache of accessible sites
|
* Memory cache of accessible sites
|
||||||
*
|
*
|
||||||
* @array
|
* @array
|
||||||
*/
|
*/
|
||||||
private static $_cache_accessible_sites = array();
|
private static $_cache_accessible_sites = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Memory cache of subsite id for domains
|
* Memory cache of subsite id for domains
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
private static $_cache_subsite_for_domain = array();
|
private static $_cache_subsite_for_domain = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array $allowed_themes Numeric array of all themes which are allowed to be selected for all subsites.
|
* @var array $allowed_themes Numeric array of all themes which are allowed to be selected for all subsites.
|
||||||
* Corresponds to subfolder names within the /themes folder. By default, all themes contained in this folder
|
* Corresponds to subfolder names within the /themes folder. By default, all themes contained in this folder
|
||||||
* are listed.
|
* are listed.
|
||||||
*/
|
*/
|
||||||
private static $allowed_themes = array();
|
private static $allowed_themes = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var Boolean If set to TRUE, don't assume 'www.example.com' and 'example.com' are the same.
|
* @var Boolean If set to TRUE, don't assume 'www.example.com' and 'example.com' are the same.
|
||||||
* Doesn't affect wildcard matching, so '*.example.com' will match 'www.example.com' (but not 'example.com')
|
* Doesn't affect wildcard matching, so '*.example.com' will match 'www.example.com' (but not 'example.com')
|
||||||
* in both TRUE or FALSE setting.
|
* in both TRUE or FALSE setting.
|
||||||
*/
|
*/
|
||||||
public static $strict_subdomain_matching = false;
|
public static $strict_subdomain_matching = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var boolean Respects the IsPublic flag when retrieving subsites
|
* @var boolean Respects the IsPublic flag when retrieving subsites
|
||||||
*/
|
*/
|
||||||
public static $check_is_public = true;
|
public static $check_is_public = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
private static $summary_fields = array(
|
private static $summary_fields = [
|
||||||
'Title',
|
'Title',
|
||||||
'PrimaryDomain',
|
'PrimaryDomain',
|
||||||
'IsPublic'
|
'IsPublic'
|
||||||
);
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set allowed themes
|
* Set allowed themes
|
||||||
*
|
*
|
||||||
* @param array $themes - Numeric array of all themes which are allowed to be selected for all subsites.
|
* @param array $themes - Numeric array of all themes which are allowed to be selected for all subsites.
|
||||||
*/
|
*/
|
||||||
public static function set_allowed_themes($themes) {
|
public static function set_allowed_themes($themes)
|
||||||
self::$allowed_themes = $themes;
|
{
|
||||||
}
|
self::$allowed_themes = $themes;
|
||||||
|
}
|
||||||
/**
|
|
||||||
* Gets the subsite currently set in the session.
|
/**
|
||||||
*
|
* Gets the subsite currently set in the session.
|
||||||
* @uses ControllerSubsites->controllerAugmentInit()
|
*
|
||||||
* @return Subsite
|
* @uses ControllerSubsites->controllerAugmentInit()
|
||||||
*/
|
* @return Subsite
|
||||||
public static function currentSubsite() {
|
*/
|
||||||
// get_by_id handles caching so we don't have to
|
public static function currentSubsite()
|
||||||
return DataObject::get_by_id(Subsite::class, self::currentSubsiteID());
|
{
|
||||||
}
|
// get_by_id handles caching so we don't have to
|
||||||
|
return DataObject::get_by_id(Subsite::class, self::currentSubsiteID());
|
||||||
/**
|
}
|
||||||
* This function gets the current subsite ID from the session. It used in the backend so Ajax requests
|
|
||||||
* use the correct subsite. The frontend handles subsites differently. It calls getSubsiteIDForDomain
|
/**
|
||||||
* directly from ModelAsController::getNestedController. Only gets Subsite instances which have their
|
* This function gets the current subsite ID from the session. It used in the backend so Ajax requests
|
||||||
* {@link IsPublic} flag set to TRUE.
|
* use the correct subsite. The frontend handles subsites differently. It calls getSubsiteIDForDomain
|
||||||
*
|
* directly from ModelAsController::getNestedController. Only gets Subsite instances which have their
|
||||||
* You can simulate subsite access without creating virtual hosts by appending ?SubsiteID=<ID> to the request.
|
* {@link IsPublic} flag set to TRUE.
|
||||||
*
|
*
|
||||||
* @todo Pass $request object from controller so we don't have to rely on $_GET
|
* You can simulate subsite access without creating virtual hosts by appending ?SubsiteID=<ID> to the request.
|
||||||
*
|
*
|
||||||
* @param boolean $cache
|
* @todo Pass $request object from controller so we don't have to rely on $_GET
|
||||||
* @return int ID of the current subsite instance
|
*
|
||||||
*/
|
* @param boolean $cache
|
||||||
public static function currentSubsiteID() {
|
* @return int ID of the current subsite instance
|
||||||
$id = NULL;
|
*/
|
||||||
|
public static function currentSubsiteID()
|
||||||
if(isset($_GET['SubsiteID'])) {
|
{
|
||||||
$id = (int)$_GET['SubsiteID'];
|
$id = NULL;
|
||||||
} else if (Subsite::$use_session_subsiteid) {
|
|
||||||
$id = Session::get('SubsiteID');
|
if (isset($_GET['SubsiteID'])) {
|
||||||
}
|
$id = (int)$_GET['SubsiteID'];
|
||||||
|
} else {
|
||||||
if($id === NULL) {
|
if (Subsite::$use_session_subsiteid) {
|
||||||
$id = self::getSubsiteIDForDomain();
|
$id = Session::get('SubsiteID');
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return (int)$id;
|
|
||||||
}
|
if ($id === NULL) {
|
||||||
|
$id = self::getSubsiteIDForDomain();
|
||||||
/**
|
}
|
||||||
* Switch to another subsite through storing the subsite identifier in the current PHP session.
|
|
||||||
* Only takes effect when {@link Subsite::$use_session_subsiteid} is set to TRUE.
|
return (int)$id;
|
||||||
*
|
}
|
||||||
* @param int|Subsite $subsite Either the ID of the subsite, or the subsite object itself
|
|
||||||
*/
|
/**
|
||||||
public static function changeSubsite($subsite) {
|
* Switch to another subsite through storing the subsite identifier in the current PHP session.
|
||||||
// Session subsite change only meaningful if the session is active.
|
* Only takes effect when {@link Subsite::$use_session_subsiteid} is set to TRUE.
|
||||||
// Otherwise we risk setting it to wrong value, e.g. if we rely on currentSubsiteID.
|
*
|
||||||
if (!Subsite::$use_session_subsiteid) return;
|
* @param int|Subsite $subsite Either the ID of the subsite, or the subsite object itself
|
||||||
|
*/
|
||||||
if(is_object($subsite)) $subsiteID = $subsite->ID;
|
public static function changeSubsite($subsite)
|
||||||
else $subsiteID = $subsite;
|
{
|
||||||
|
// Session subsite change only meaningful if the session is active.
|
||||||
Session::set('SubsiteID', (int)$subsiteID);
|
// Otherwise we risk setting it to wrong value, e.g. if we rely on currentSubsiteID.
|
||||||
|
if (!Subsite::$use_session_subsiteid) {
|
||||||
// Set locale
|
return;
|
||||||
if (is_object($subsite) && $subsite->Language != '') {
|
}
|
||||||
$locale = i18n::get_locale_from_lang($subsite->Language);
|
|
||||||
if($locale) {
|
if (is_object($subsite)) {
|
||||||
i18n::set_locale($locale);
|
$subsiteID = $subsite->ID;
|
||||||
}
|
} else {
|
||||||
}
|
$subsiteID = $subsite;
|
||||||
|
}
|
||||||
Permission::flush_permission_cache();
|
|
||||||
}
|
Session::set('SubsiteID', (int)$subsiteID);
|
||||||
|
|
||||||
/**
|
// Set locale
|
||||||
* Get a matching subsite for the given host, or for the current HTTP_HOST.
|
if (is_object($subsite) && $subsite->Language != '') {
|
||||||
* Supports "fuzzy" matching of domains by placing an asterisk at the start of end of the string,
|
$locale = i18n::get_locale_from_lang($subsite->Language);
|
||||||
* for example matching all subdomains on *.example.com with one subsite,
|
if ($locale) {
|
||||||
* and all subdomains on *.example.org on another.
|
i18n::set_locale($locale);
|
||||||
*
|
}
|
||||||
* @param $host The host to find the subsite for. If not specified, $_SERVER['HTTP_HOST'] is used.
|
}
|
||||||
* @return int Subsite ID
|
|
||||||
*/
|
Permission::flush_permission_cache();
|
||||||
public static function getSubsiteIDForDomain($host = null, $checkPermissions = true) {
|
}
|
||||||
if($host == null && isset($_SERVER['HTTP_HOST'])) {
|
|
||||||
$host = $_SERVER['HTTP_HOST'];
|
/**
|
||||||
}
|
* Get a matching subsite for the given host, or for the current HTTP_HOST.
|
||||||
|
* Supports "fuzzy" matching of domains by placing an asterisk at the start of end of the string,
|
||||||
$matchingDomains = null;
|
* for example matching all subdomains on *.example.com with one subsite,
|
||||||
$cacheKey = null;
|
* and all subdomains on *.example.org on another.
|
||||||
if ($host) {
|
*
|
||||||
if(!self::$strict_subdomain_matching) $host = preg_replace('/^www\./', '', $host);
|
* @param $host The host to find the subsite for. If not specified, $_SERVER['HTTP_HOST'] is used.
|
||||||
|
* @return int Subsite ID
|
||||||
$cacheKey = implode('_', array($host, Member::currentUserID(), self::$check_is_public));
|
*/
|
||||||
if(isset(self::$_cache_subsite_for_domain[$cacheKey])) return self::$_cache_subsite_for_domain[$cacheKey];
|
public static function getSubsiteIDForDomain($host = null, $checkPermissions = true)
|
||||||
|
{
|
||||||
$SQL_host = Convert::raw2sql($host);
|
if ($host == null && isset($_SERVER['HTTP_HOST'])) {
|
||||||
$matchingDomains = DataObject::get(
|
$host = $_SERVER['HTTP_HOST'];
|
||||||
SubsiteDomain::class,
|
}
|
||||||
"'$SQL_host' LIKE replace(\"SubsiteDomain\".\"Domain\",'*','%')",
|
|
||||||
"\"IsPrimary\" DESC"
|
$matchingDomains = null;
|
||||||
)->innerJoin('Subsite', "\"Subsite\".\"ID\" = \"SubsiteDomain\".\"SubsiteID\" AND \"Subsite\".\"IsPublic\"=1");
|
$cacheKey = null;
|
||||||
}
|
if ($host) {
|
||||||
|
if (!self::$strict_subdomain_matching) {
|
||||||
if($matchingDomains && $matchingDomains->Count()) {
|
$host = preg_replace('/^www\./', '', $host);
|
||||||
$subsiteIDs = array_unique($matchingDomains->column('SubsiteID'));
|
}
|
||||||
$subsiteDomains = array_unique($matchingDomains->column('Domain'));
|
|
||||||
if(sizeof($subsiteIDs) > 1) {
|
$cacheKey = implode('_', [$host, Member::currentUserID(), self::$check_is_public]);
|
||||||
throw new UnexpectedValueException(sprintf(
|
if (isset(self::$_cache_subsite_for_domain[$cacheKey])) {
|
||||||
"Multiple subsites match on '%s': %s",
|
return self::$_cache_subsite_for_domain[$cacheKey];
|
||||||
$host,
|
}
|
||||||
implode(',', $subsiteDomains)
|
|
||||||
));
|
$SQL_host = Convert::raw2sql($host);
|
||||||
}
|
$matchingDomains = DataObject::get(
|
||||||
|
SubsiteDomain::class,
|
||||||
$subsiteID = $subsiteIDs[0];
|
"'$SQL_host' LIKE replace(\"SubsiteDomain\".\"Domain\",'*','%')",
|
||||||
} else if($default = DataObject::get_one(Subsite::class, "\"DefaultSite\" = 1")) {
|
"\"IsPrimary\" DESC"
|
||||||
// Check for a 'default' subsite
|
)->innerJoin('Subsite',
|
||||||
$subsiteID = $default->ID;
|
"\"Subsite\".\"ID\" = \"SubsiteDomain\".\"SubsiteID\" AND \"Subsite\".\"IsPublic\"=1");
|
||||||
} else {
|
}
|
||||||
// Default subsite id = 0, the main site
|
|
||||||
$subsiteID = 0;
|
if ($matchingDomains && $matchingDomains->Count()) {
|
||||||
}
|
$subsiteIDs = array_unique($matchingDomains->column('SubsiteID'));
|
||||||
|
$subsiteDomains = array_unique($matchingDomains->column('Domain'));
|
||||||
if ($cacheKey) {
|
if (sizeof($subsiteIDs) > 1) {
|
||||||
self::$_cache_subsite_for_domain[$cacheKey] = $subsiteID;
|
throw new UnexpectedValueException(sprintf(
|
||||||
}
|
"Multiple subsites match on '%s': %s",
|
||||||
|
$host,
|
||||||
return $subsiteID;
|
implode(',', $subsiteDomains)
|
||||||
}
|
));
|
||||||
|
}
|
||||||
/**
|
|
||||||
*
|
$subsiteID = $subsiteIDs[0];
|
||||||
* @param string $className
|
} else {
|
||||||
* @param string $filter
|
if ($default = DataObject::get_one(Subsite::class, "\"DefaultSite\" = 1")) {
|
||||||
* @param string $sort
|
// Check for a 'default' subsite
|
||||||
* @param string $join
|
$subsiteID = $default->ID;
|
||||||
* @param string $limit
|
} else {
|
||||||
* @return DataList
|
// Default subsite id = 0, the main site
|
||||||
*/
|
$subsiteID = 0;
|
||||||
public static function get_from_all_subsites($className, $filter = "", $sort = "", $join = "", $limit = "") {
|
}
|
||||||
$result = DataObject::get($className, $filter, $sort, $join, $limit);
|
}
|
||||||
$result = $result->setDataQueryParam('Subsite.filter', false);
|
|
||||||
return $result;
|
if ($cacheKey) {
|
||||||
}
|
self::$_cache_subsite_for_domain[$cacheKey] = $subsiteID;
|
||||||
|
}
|
||||||
/**
|
|
||||||
* Disable the sub-site filtering; queries will select from all subsites
|
return $subsiteID;
|
||||||
*/
|
}
|
||||||
public static function disable_subsite_filter($disabled = true) {
|
|
||||||
self::$disable_subsite_filter = $disabled;
|
/**
|
||||||
}
|
*
|
||||||
|
* @param string $className
|
||||||
/**
|
* @param string $filter
|
||||||
* Flush caches on database reset
|
* @param string $sort
|
||||||
*/
|
* @param string $join
|
||||||
public static function on_db_reset() {
|
* @param string $limit
|
||||||
self::$_cache_accessible_sites = array();
|
* @return DataList
|
||||||
self::$_cache_subsite_for_domain = array();
|
*/
|
||||||
}
|
public static function get_from_all_subsites($className, $filter = "", $sort = "", $join = "", $limit = "")
|
||||||
|
{
|
||||||
/**
|
$result = DataObject::get($className, $filter, $sort, $join, $limit);
|
||||||
* Return all subsites, regardless of permissions (augmented with main site).
|
$result = $result->setDataQueryParam('Subsite.filter', false);
|
||||||
*
|
return $result;
|
||||||
* @return SS_List List of {@link Subsite} objects (DataList or ArrayList).
|
}
|
||||||
*/
|
|
||||||
public static function all_sites($includeMainSite = true, $mainSiteTitle = "Main site") {
|
/**
|
||||||
$subsites = Subsite::get();
|
* Disable the sub-site filtering; queries will select from all subsites
|
||||||
|
*/
|
||||||
if($includeMainSite) {
|
public static function disable_subsite_filter($disabled = true)
|
||||||
$subsites = $subsites->toArray();
|
{
|
||||||
|
self::$disable_subsite_filter = $disabled;
|
||||||
$mainSite = new Subsite();
|
}
|
||||||
$mainSite->Title = $mainSiteTitle;
|
|
||||||
array_unshift($subsites, $mainSite);
|
/**
|
||||||
|
* Flush caches on database reset
|
||||||
$subsites = ArrayList::create($subsites);
|
*/
|
||||||
}
|
public static function on_db_reset()
|
||||||
|
{
|
||||||
return $subsites;
|
self::$_cache_accessible_sites = [];
|
||||||
}
|
self::$_cache_subsite_for_domain = [];
|
||||||
|
}
|
||||||
/*
|
|
||||||
* Returns an ArrayList of the subsites accessible to the current user.
|
/**
|
||||||
* It's enough for any section to be accessible for the site to be included.
|
* Return all subsites, regardless of permissions (augmented with main site).
|
||||||
*
|
*
|
||||||
* @return ArrayList of {@link Subsite} instances.
|
* @return SS_List List of {@link Subsite} objects (DataList or ArrayList).
|
||||||
*/
|
*/
|
||||||
public static function all_accessible_sites($includeMainSite = true, $mainSiteTitle = "Main site", $member = null) {
|
public static function all_sites($includeMainSite = true, $mainSiteTitle = "Main site")
|
||||||
// Rationalise member arguments
|
{
|
||||||
if(!$member) $member = Member::currentUser();
|
$subsites = Subsite::get();
|
||||||
if(!$member) return new ArrayList();
|
|
||||||
if(!is_object($member)) $member = DataObject::get_by_id('SilverStripe\\Security\\Member', $member);
|
if ($includeMainSite) {
|
||||||
|
$subsites = $subsites->toArray();
|
||||||
$subsites = new ArrayList();
|
|
||||||
|
$mainSite = new Subsite();
|
||||||
// Collect subsites for all sections.
|
$mainSite->Title = $mainSiteTitle;
|
||||||
$menu = CMSMenu::get_viewable_menu_items();
|
array_unshift($subsites, $mainSite);
|
||||||
foreach($menu as $candidate) {
|
|
||||||
if ($candidate->controller) {
|
$subsites = ArrayList::create($subsites);
|
||||||
$accessibleSites = singleton($candidate->controller)->sectionSites(
|
}
|
||||||
$includeMainSite,
|
|
||||||
$mainSiteTitle,
|
return $subsites;
|
||||||
$member
|
}
|
||||||
);
|
|
||||||
|
/*
|
||||||
// Replace existing keys so no one site appears twice.
|
* Returns an ArrayList of the subsites accessible to the current user.
|
||||||
$subsites->merge($accessibleSites);
|
* It's enough for any section to be accessible for the site to be included.
|
||||||
}
|
*
|
||||||
}
|
* @return ArrayList of {@link Subsite} instances.
|
||||||
|
*/
|
||||||
$subsites->removeDuplicates();
|
public static function all_accessible_sites($includeMainSite = true, $mainSiteTitle = "Main site", $member = null)
|
||||||
|
{
|
||||||
return $subsites;
|
// Rationalise member arguments
|
||||||
}
|
if (!$member) {
|
||||||
|
$member = Member::currentUser();
|
||||||
/**
|
}
|
||||||
* Return the subsites that the current user can access by given permission.
|
if (!$member) {
|
||||||
* Sites will only be included if they have a Title.
|
return new ArrayList();
|
||||||
*
|
}
|
||||||
* @param $permCode array|string Either a single permission code or an array of permission codes.
|
if (!is_object($member)) {
|
||||||
* @param $includeMainSite If true, the main site will be included if appropriate.
|
$member = DataObject::get_by_id('SilverStripe\\Security\\Member', $member);
|
||||||
* @param $mainSiteTitle The label to give to the main site
|
}
|
||||||
* @param $member
|
|
||||||
* @return DataList of {@link Subsite} instances
|
$subsites = new ArrayList();
|
||||||
*/
|
|
||||||
public static function accessible_sites($permCode, $includeMainSite = true, $mainSiteTitle = "Main site", $member = null) {
|
// Collect subsites for all sections.
|
||||||
// Rationalise member arguments
|
$menu = CMSMenu::get_viewable_menu_items();
|
||||||
if(!$member) $member = Member::currentUser();
|
foreach ($menu as $candidate) {
|
||||||
if(!$member) return new ArrayList();
|
if ($candidate->controller) {
|
||||||
if(!is_object($member)) $member = DataObject::get_by_id('SilverStripe\\Security\\Member', $member);
|
$accessibleSites = singleton($candidate->controller)->sectionSites(
|
||||||
|
$includeMainSite,
|
||||||
// Rationalise permCode argument
|
$mainSiteTitle,
|
||||||
if(is_array($permCode)) $SQL_codes = "'" . implode("', '", Convert::raw2sql($permCode)) . "'";
|
$member
|
||||||
else $SQL_codes = "'" . Convert::raw2sql($permCode) . "'";
|
);
|
||||||
|
|
||||||
// Cache handling
|
// Replace existing keys so no one site appears twice.
|
||||||
$cacheKey = $SQL_codes . '-' . $member->ID . '-' . $includeMainSite . '-' . $mainSiteTitle;
|
$subsites->merge($accessibleSites);
|
||||||
if(isset(self::$_cache_accessible_sites[$cacheKey])) {
|
}
|
||||||
return self::$_cache_accessible_sites[$cacheKey];
|
}
|
||||||
}
|
|
||||||
|
$subsites->removeDuplicates();
|
||||||
$subsites = DataList::create(Subsite::class)
|
|
||||||
->where("\"Subsite\".\"Title\" != ''")
|
return $subsites;
|
||||||
->leftJoin('Group_Subsites', "\"Group_Subsites\".\"SubsiteID\" = \"Subsite\".\"ID\"")
|
}
|
||||||
->innerJoin('Group', "\"Group\".\"ID\" = \"Group_Subsites\".\"GroupID\" OR \"Group\".\"AccessAllSubsites\" = 1")
|
|
||||||
->innerJoin('Group_Members', "\"Group_Members\".\"GroupID\"=\"Group\".\"ID\" AND \"Group_Members\".\"MemberID\" = $member->ID")
|
/**
|
||||||
->innerJoin('Permission', "\"Group\".\"ID\"=\"Permission\".\"GroupID\" AND \"Permission\".\"Code\" IN ($SQL_codes, 'CMS_ACCESS_LeftAndMain', 'ADMIN')");
|
* Return the subsites that the current user can access by given permission.
|
||||||
|
* Sites will only be included if they have a Title.
|
||||||
if(!$subsites) $subsites = new ArrayList();
|
*
|
||||||
|
* @param $permCode array|string Either a single permission code or an array of permission codes.
|
||||||
$rolesSubsites = DataList::create(Subsite::class)
|
* @param $includeMainSite If true, the main site will be included if appropriate.
|
||||||
->where("\"Subsite\".\"Title\" != ''")
|
* @param $mainSiteTitle The label to give to the main site
|
||||||
->leftJoin('Group_Subsites', "\"Group_Subsites\".\"SubsiteID\" = \"Subsite\".\"ID\"")
|
* @param $member
|
||||||
->innerJoin('Group', "\"Group\".\"ID\" = \"Group_Subsites\".\"GroupID\" OR \"Group\".\"AccessAllSubsites\" = 1")
|
* @return DataList of {@link Subsite} instances
|
||||||
->innerJoin('Group_Members', "\"Group_Members\".\"GroupID\"=\"Group\".\"ID\" AND \"Group_Members\".\"MemberID\" = $member->ID")
|
*/
|
||||||
->innerJoin('Group_Roles', "\"Group_Roles\".\"GroupID\"=\"Group\".\"ID\"")
|
public static function accessible_sites(
|
||||||
->innerJoin('PermissionRole', "\"Group_Roles\".\"PermissionRoleID\"=\"PermissionRole\".\"ID\"")
|
$permCode,
|
||||||
->innerJoin('PermissionRoleCode', "\"PermissionRole\".\"ID\"=\"PermissionRoleCode\".\"RoleID\" AND \"PermissionRoleCode\".\"Code\" IN ($SQL_codes, 'CMS_ACCESS_LeftAndMain', 'ADMIN')");
|
$includeMainSite = true,
|
||||||
|
$mainSiteTitle = "Main site",
|
||||||
if(!$subsites && $rolesSubsites) return $rolesSubsites;
|
$member = null
|
||||||
|
)
|
||||||
$subsites = new ArrayList($subsites->toArray());
|
{
|
||||||
|
// Rationalise member arguments
|
||||||
if($rolesSubsites) foreach($rolesSubsites as $subsite) {
|
if (!$member) {
|
||||||
if(!$subsites->find('ID', $subsite->ID)) {
|
$member = Member::currentUser();
|
||||||
$subsites->push($subsite);
|
}
|
||||||
}
|
if (!$member) {
|
||||||
}
|
return new ArrayList();
|
||||||
|
}
|
||||||
if($includeMainSite) {
|
if (!is_object($member)) {
|
||||||
if(!is_array($permCode)) $permCode = array($permCode);
|
$member = DataObject::get_by_id('SilverStripe\\Security\\Member', $member);
|
||||||
if(self::hasMainSitePermission($member, $permCode)) {
|
}
|
||||||
$subsites=$subsites->toArray();
|
|
||||||
|
// Rationalise permCode argument
|
||||||
$mainSite = new Subsite();
|
if (is_array($permCode)) {
|
||||||
$mainSite->Title = $mainSiteTitle;
|
$SQL_codes = "'" . implode("', '", Convert::raw2sql($permCode)) . "'";
|
||||||
array_unshift($subsites, $mainSite);
|
} else {
|
||||||
$subsites=ArrayList::create($subsites);
|
$SQL_codes = "'" . Convert::raw2sql($permCode) . "'";
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
// Cache handling
|
||||||
self::$_cache_accessible_sites[$cacheKey] = $subsites;
|
$cacheKey = $SQL_codes . '-' . $member->ID . '-' . $includeMainSite . '-' . $mainSiteTitle;
|
||||||
|
if (isset(self::$_cache_accessible_sites[$cacheKey])) {
|
||||||
return $subsites;
|
return self::$_cache_accessible_sites[$cacheKey];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
$subsites = DataList::create(Subsite::class)
|
||||||
* Write a host->domain map to subsites/host-map.php
|
->where("\"Subsite\".\"Title\" != ''")
|
||||||
*
|
->leftJoin('Group_Subsites', "\"Group_Subsites\".\"SubsiteID\" = \"Subsite\".\"ID\"")
|
||||||
* This is used primarily when using subsites in conjunction with StaticPublisher
|
->innerJoin('Group',
|
||||||
*
|
"\"Group\".\"ID\" = \"Group_Subsites\".\"GroupID\" OR \"Group\".\"AccessAllSubsites\" = 1")
|
||||||
* @param string $file - filepath of the host map to be written
|
->innerJoin('Group_Members',
|
||||||
* @return void
|
"\"Group_Members\".\"GroupID\"=\"Group\".\"ID\" AND \"Group_Members\".\"MemberID\" = $member->ID")
|
||||||
*/
|
->innerJoin('Permission',
|
||||||
public static function writeHostMap($file = null) {
|
"\"Group\".\"ID\"=\"Permission\".\"GroupID\" AND \"Permission\".\"Code\" IN ($SQL_codes, 'CMS_ACCESS_LeftAndMain', 'ADMIN')");
|
||||||
if (!self::$write_hostmap) return;
|
|
||||||
|
if (!$subsites) {
|
||||||
if (!$file) $file = Director::baseFolder().'/subsites/host-map.php';
|
$subsites = new ArrayList();
|
||||||
$hostmap = array();
|
}
|
||||||
|
|
||||||
$subsites = DataObject::get(Subsite::class);
|
$rolesSubsites = DataList::create(Subsite::class)
|
||||||
|
->where("\"Subsite\".\"Title\" != ''")
|
||||||
if ($subsites) foreach($subsites as $subsite) {
|
->leftJoin('Group_Subsites', "\"Group_Subsites\".\"SubsiteID\" = \"Subsite\".\"ID\"")
|
||||||
$domains = $subsite->Domains();
|
->innerJoin('Group',
|
||||||
if ($domains) foreach($domains as $domain) {
|
"\"Group\".\"ID\" = \"Group_Subsites\".\"GroupID\" OR \"Group\".\"AccessAllSubsites\" = 1")
|
||||||
$domainStr = $domain->Domain;
|
->innerJoin('Group_Members',
|
||||||
if(!self::$strict_subdomain_matching) $domainStr = preg_replace('/^www\./', '', $domainStr);
|
"\"Group_Members\".\"GroupID\"=\"Group\".\"ID\" AND \"Group_Members\".\"MemberID\" = $member->ID")
|
||||||
$hostmap[$domainStr] = $subsite->domain();
|
->innerJoin('Group_Roles', "\"Group_Roles\".\"GroupID\"=\"Group\".\"ID\"")
|
||||||
}
|
->innerJoin('PermissionRole', "\"Group_Roles\".\"PermissionRoleID\"=\"PermissionRole\".\"ID\"")
|
||||||
if ($subsite->DefaultSite) $hostmap['default'] = $subsite->domain();
|
->innerJoin('PermissionRoleCode',
|
||||||
}
|
"\"PermissionRole\".\"ID\"=\"PermissionRoleCode\".\"RoleID\" AND \"PermissionRoleCode\".\"Code\" IN ($SQL_codes, 'CMS_ACCESS_LeftAndMain', 'ADMIN')");
|
||||||
|
|
||||||
$data = "<?php \n";
|
if (!$subsites && $rolesSubsites) {
|
||||||
$data .= "// Generated by Subsite::writeHostMap() on " . date('d/M/y') . "\n";
|
return $rolesSubsites;
|
||||||
$data .= '$subsiteHostmap = ' . var_export($hostmap, true) . ';';
|
}
|
||||||
|
|
||||||
if (is_writable(dirname($file)) || is_writable($file)) {
|
$subsites = new ArrayList($subsites->toArray());
|
||||||
file_put_contents($file, $data);
|
|
||||||
}
|
if ($rolesSubsites) {
|
||||||
}
|
foreach ($rolesSubsites as $subsite) {
|
||||||
|
if (!$subsites->find('ID', $subsite->ID)) {
|
||||||
/**
|
$subsites->push($subsite);
|
||||||
* Checks if a member can be granted certain permissions, regardless of the subsite context.
|
}
|
||||||
* Similar logic to {@link Permission::checkMember()}, but only returns TRUE
|
}
|
||||||
* if the member is part of a group with the "AccessAllSubsites" flag set.
|
}
|
||||||
* If more than one permission is passed to the method, at least one of them must
|
|
||||||
* be granted for if to return TRUE.
|
if ($includeMainSite) {
|
||||||
*
|
if (!is_array($permCode)) {
|
||||||
* @todo Allow permission inheritance through group hierarchy.
|
$permCode = [$permCode];
|
||||||
*
|
}
|
||||||
* @param Member Member to check against. Defaults to currently logged in member
|
if (self::hasMainSitePermission($member, $permCode)) {
|
||||||
* @param Array Permission code strings. Defaults to "ADMIN".
|
$subsites = $subsites->toArray();
|
||||||
* @return boolean
|
|
||||||
*/
|
$mainSite = new Subsite();
|
||||||
public static function hasMainSitePermission($member = null, $permissionCodes = array('ADMIN')) {
|
$mainSite->Title = $mainSiteTitle;
|
||||||
if(!is_array($permissionCodes))
|
array_unshift($subsites, $mainSite);
|
||||||
user_error('Permissions must be passed to Subsite::hasMainSitePermission as an array', E_USER_ERROR);
|
$subsites = ArrayList::create($subsites);
|
||||||
|
}
|
||||||
if(!$member && $member !== FALSE) $member = Member::currentUser();
|
}
|
||||||
|
|
||||||
if(!$member) return false;
|
self::$_cache_accessible_sites[$cacheKey] = $subsites;
|
||||||
|
|
||||||
if(!in_array("ADMIN", $permissionCodes)) $permissionCodes[] = "ADMIN";
|
return $subsites;
|
||||||
|
}
|
||||||
$SQLa_perm = Convert::raw2sql($permissionCodes);
|
|
||||||
$SQL_perms = join("','", $SQLa_perm);
|
/**
|
||||||
$memberID = (int)$member->ID;
|
* Write a host->domain map to subsites/host-map.php
|
||||||
|
*
|
||||||
// Count this user's groups which can access the main site
|
* This is used primarily when using subsites in conjunction with StaticPublisher
|
||||||
$groupCount = DB::query("
|
*
|
||||||
|
* @param string $file - filepath of the host map to be written
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public static function writeHostMap($file = null)
|
||||||
|
{
|
||||||
|
if (!self::$write_hostmap) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$file) {
|
||||||
|
$file = Director::baseFolder() . '/subsites/host-map.php';
|
||||||
|
}
|
||||||
|
$hostmap = [];
|
||||||
|
|
||||||
|
$subsites = DataObject::get(Subsite::class);
|
||||||
|
|
||||||
|
if ($subsites) {
|
||||||
|
foreach ($subsites as $subsite) {
|
||||||
|
$domains = $subsite->Domains();
|
||||||
|
if ($domains) {
|
||||||
|
foreach ($domains as $domain) {
|
||||||
|
$domainStr = $domain->Domain;
|
||||||
|
if (!self::$strict_subdomain_matching) {
|
||||||
|
$domainStr = preg_replace('/^www\./', '', $domainStr);
|
||||||
|
}
|
||||||
|
$hostmap[$domainStr] = $subsite->domain();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($subsite->DefaultSite) {
|
||||||
|
$hostmap['default'] = $subsite->domain();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = "<?php \n";
|
||||||
|
$data .= "// Generated by Subsite::writeHostMap() on " . date('d/M/y') . "\n";
|
||||||
|
$data .= '$subsiteHostmap = ' . var_export($hostmap, true) . ';';
|
||||||
|
|
||||||
|
if (is_writable(dirname($file)) || is_writable($file)) {
|
||||||
|
file_put_contents($file, $data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a member can be granted certain permissions, regardless of the subsite context.
|
||||||
|
* Similar logic to {@link Permission::checkMember()}, but only returns TRUE
|
||||||
|
* if the member is part of a group with the "AccessAllSubsites" flag set.
|
||||||
|
* If more than one permission is passed to the method, at least one of them must
|
||||||
|
* be granted for if to return TRUE.
|
||||||
|
*
|
||||||
|
* @todo Allow permission inheritance through group hierarchy.
|
||||||
|
*
|
||||||
|
* @param Member Member to check against. Defaults to currently logged in member
|
||||||
|
* @param Array Permission code strings. Defaults to "ADMIN".
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public static function hasMainSitePermission($member = null, $permissionCodes = ['ADMIN'])
|
||||||
|
{
|
||||||
|
if (!is_array($permissionCodes)) {
|
||||||
|
user_error('Permissions must be passed to Subsite::hasMainSitePermission as an array', E_USER_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$member && $member !== FALSE) {
|
||||||
|
$member = Member::currentUser();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$member) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!in_array("ADMIN", $permissionCodes)) {
|
||||||
|
$permissionCodes[] = "ADMIN";
|
||||||
|
}
|
||||||
|
|
||||||
|
$SQLa_perm = Convert::raw2sql($permissionCodes);
|
||||||
|
$SQL_perms = join("','", $SQLa_perm);
|
||||||
|
$memberID = (int)$member->ID;
|
||||||
|
|
||||||
|
// Count this user's groups which can access the main site
|
||||||
|
$groupCount = DB::query("
|
||||||
SELECT COUNT(\"Permission\".\"ID\")
|
SELECT COUNT(\"Permission\".\"ID\")
|
||||||
FROM \"Permission\"
|
FROM \"Permission\"
|
||||||
INNER JOIN \"Group\" ON \"Group\".\"ID\" = \"Permission\".\"GroupID\" AND \"Group\".\"AccessAllSubsites\" = 1
|
INNER JOIN \"Group\" ON \"Group\".\"ID\" = \"Permission\".\"GroupID\" AND \"Group\".\"AccessAllSubsites\" = 1
|
||||||
@ -476,8 +554,8 @@ class Subsite extends DataObject {
|
|||||||
AND \"MemberID\" = {$memberID}
|
AND \"MemberID\" = {$memberID}
|
||||||
")->value();
|
")->value();
|
||||||
|
|
||||||
// Count this user's groups which have a role that can access the main site
|
// Count this user's groups which have a role that can access the main site
|
||||||
$roleCount = DB::query("
|
$roleCount = DB::query("
|
||||||
SELECT COUNT(\"PermissionRoleCode\".\"ID\")
|
SELECT COUNT(\"PermissionRoleCode\".\"ID\")
|
||||||
FROM \"Group\"
|
FROM \"Group\"
|
||||||
INNER JOIN \"Group_Members\" ON \"Group_Members\".\"GroupID\" = \"Group\".\"ID\"
|
INNER JOIN \"Group_Members\" ON \"Group_Members\".\"GroupID\" = \"Group\".\"ID\"
|
||||||
@ -489,369 +567,388 @@ class Subsite extends DataObject {
|
|||||||
AND \"MemberID\" = {$memberID}
|
AND \"MemberID\" = {$memberID}
|
||||||
")->value();
|
")->value();
|
||||||
|
|
||||||
// There has to be at least one that allows access.
|
// There has to be at least one that allows access.
|
||||||
return ($groupCount + $roleCount > 0);
|
return ($groupCount + $roleCount > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
private static $db = array(
|
private static $db = [
|
||||||
'Title' => 'Varchar(255)',
|
'Title' => 'Varchar(255)',
|
||||||
'RedirectURL' => 'Varchar(255)',
|
'RedirectURL' => 'Varchar(255)',
|
||||||
'DefaultSite' => 'Boolean',
|
'DefaultSite' => 'Boolean',
|
||||||
'Theme' => 'Varchar',
|
'Theme' => 'Varchar',
|
||||||
'Language' => 'Varchar(6)',
|
'Language' => 'Varchar(6)',
|
||||||
|
|
||||||
// Used to hide unfinished/private subsites from public view.
|
// Used to hide unfinished/private subsites from public view.
|
||||||
// If unset, will default to true
|
// If unset, will default to true
|
||||||
'IsPublic' => 'Boolean',
|
'IsPublic' => 'Boolean',
|
||||||
|
|
||||||
// Comma-separated list of disallowed page types
|
// Comma-separated list of disallowed page types
|
||||||
'PageTypeBlacklist' => 'Text',
|
'PageTypeBlacklist' => 'Text',
|
||||||
);
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
private static $has_many = array(
|
private static $has_many = [
|
||||||
'Domains' => SubsiteDomain::class,
|
'Domains' => SubsiteDomain::class,
|
||||||
);
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
private static $belongs_many_many = array(
|
private static $belongs_many_many = [
|
||||||
"Groups" => "SilverStripe\\Security\\Group",
|
"Groups" => "SilverStripe\\Security\\Group",
|
||||||
);
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
private static $defaults = array(
|
private static $defaults = [
|
||||||
'IsPublic' => 1
|
'IsPublic' => 1
|
||||||
);
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
private static $searchable_fields = array(
|
private static $searchable_fields = [
|
||||||
'Title',
|
'Title',
|
||||||
'Domains.Domain',
|
'Domains.Domain',
|
||||||
'IsPublic',
|
'IsPublic',
|
||||||
);
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
private static $default_sort = "\"Title\" ASC";
|
private static $default_sort = "\"Title\" ASC";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @todo Possible security issue, don't grant edit permissions to everybody.
|
* @todo Possible security issue, don't grant edit permissions to everybody.
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
public function canEdit($member = false) {
|
public function canEdit($member = false)
|
||||||
return true;
|
{
|
||||||
}
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show the configuration fields for each subsite
|
* Show the configuration fields for each subsite
|
||||||
*
|
*
|
||||||
* @return FieldList
|
* @return FieldList
|
||||||
*/
|
*/
|
||||||
public function getCMSFields() {
|
public function getCMSFields()
|
||||||
if($this->ID!=0) {
|
{
|
||||||
$domainTable = new GridField(
|
if ($this->ID != 0) {
|
||||||
"Domains",
|
$domainTable = new GridField(
|
||||||
_t('Subsite.DomainsListTitle',"Domains"),
|
"Domains",
|
||||||
$this->Domains(),
|
_t('Subsite.DomainsListTitle', "Domains"),
|
||||||
GridFieldConfig_RecordEditor::create(10)
|
$this->Domains(),
|
||||||
);
|
GridFieldConfig_RecordEditor::create(10)
|
||||||
}else {
|
);
|
||||||
$domainTable = new LiteralField(
|
} else {
|
||||||
'Domains',
|
$domainTable = new LiteralField(
|
||||||
'<p>'._t('Subsite.DOMAINSAVEFIRST', 'You can only add domains after saving for the first time').'</p>'
|
'Domains',
|
||||||
);
|
'<p>' . _t('Subsite.DOMAINSAVEFIRST',
|
||||||
}
|
'You can only add domains after saving for the first time') . '</p>'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
$languageSelector = new DropdownField(
|
$languageSelector = new DropdownField(
|
||||||
'Language',
|
'Language',
|
||||||
$this->fieldLabel('Language'),
|
$this->fieldLabel('Language'),
|
||||||
(new IntlLocales)->getLocales()
|
(new IntlLocales)->getLocales()
|
||||||
);
|
);
|
||||||
|
|
||||||
$pageTypeMap = array();
|
$pageTypeMap = [];
|
||||||
$pageTypes = SiteTree::page_type_classes();
|
$pageTypes = SiteTree::page_type_classes();
|
||||||
foreach($pageTypes as $pageType) {
|
foreach ($pageTypes as $pageType) {
|
||||||
$pageTypeMap[$pageType] = singleton($pageType)->i18n_singular_name();
|
$pageTypeMap[$pageType] = singleton($pageType)->i18n_singular_name();
|
||||||
}
|
}
|
||||||
asort($pageTypeMap);
|
asort($pageTypeMap);
|
||||||
|
|
||||||
$fields = new FieldList(
|
$fields = new FieldList(
|
||||||
$subsiteTabs = new TabSet('Root',
|
$subsiteTabs = new TabSet('Root',
|
||||||
new Tab(
|
new Tab(
|
||||||
'Configuration',
|
'Configuration',
|
||||||
_t('Subsite.TabTitleConfig', 'Configuration'),
|
_t('Subsite.TabTitleConfig', 'Configuration'),
|
||||||
new HeaderField('ConfigurationHeader', $this->getClassName() . ' configuration', 2),
|
new HeaderField('ConfigurationHeader', $this->getClassName() . ' configuration', 2),
|
||||||
new TextField('Title', $this->fieldLabel('Title'), $this->Title),
|
new TextField('Title', $this->fieldLabel('Title'), $this->Title),
|
||||||
|
|
||||||
new HeaderField(
|
new HeaderField(
|
||||||
'DomainsHeader',
|
'DomainsHeader',
|
||||||
_t('Subsite.DomainsHeadline', "Domains for this subsite")
|
_t('Subsite.DomainsHeadline', "Domains for this subsite")
|
||||||
),
|
),
|
||||||
$domainTable,
|
$domainTable,
|
||||||
$languageSelector,
|
$languageSelector,
|
||||||
// new TextField('RedirectURL', 'Redirect to URL', $this->RedirectURL),
|
// new TextField('RedirectURL', 'Redirect to URL', $this->RedirectURL),
|
||||||
new CheckboxField('DefaultSite', $this->fieldLabel('DefaultSite'), $this->DefaultSite),
|
new CheckboxField('DefaultSite', $this->fieldLabel('DefaultSite'), $this->DefaultSite),
|
||||||
new CheckboxField('IsPublic', $this->fieldLabel('IsPublic'), $this->IsPublic),
|
new CheckboxField('IsPublic', $this->fieldLabel('IsPublic'), $this->IsPublic),
|
||||||
|
|
||||||
new DropdownField('Theme',$this->fieldLabel('Theme'), $this->allowedThemes(), $this->Theme),
|
new DropdownField('Theme', $this->fieldLabel('Theme'), $this->allowedThemes(), $this->Theme),
|
||||||
|
|
||||||
|
|
||||||
new LiteralField(
|
new LiteralField(
|
||||||
'PageTypeBlacklistToggle',
|
'PageTypeBlacklistToggle',
|
||||||
sprintf(
|
sprintf(
|
||||||
'<div class="field"><a href="#" id="PageTypeBlacklistToggle">%s</a></div>',
|
'<div class="field"><a href="#" id="PageTypeBlacklistToggle">%s</a></div>',
|
||||||
_t('Subsite.PageTypeBlacklistField', 'Disallow page types?')
|
_t('Subsite.PageTypeBlacklistField', 'Disallow page types?')
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
new CheckboxSetField(
|
new CheckboxSetField(
|
||||||
'PageTypeBlacklist',
|
'PageTypeBlacklist',
|
||||||
false,
|
false,
|
||||||
$pageTypeMap
|
$pageTypeMap
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
new HiddenField('ID', '', $this->ID),
|
new HiddenField('ID', '', $this->ID),
|
||||||
new HiddenField('IsSubsite', '', 1)
|
new HiddenField('IsSubsite', '', 1)
|
||||||
);
|
);
|
||||||
|
|
||||||
$subsiteTabs->addExtraClass('subsite-model');
|
$subsiteTabs->addExtraClass('subsite-model');
|
||||||
|
|
||||||
$this->extend('updateCMSFields', $fields);
|
$this->extend('updateCMSFields', $fields);
|
||||||
return $fields;
|
return $fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param boolean $includerelations
|
* @param boolean $includerelations
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function fieldLabels($includerelations = true) {
|
public function fieldLabels($includerelations = true)
|
||||||
$labels = parent::fieldLabels($includerelations);
|
{
|
||||||
$labels['Title'] = _t('Subsites.TitleFieldLabel', 'Subsite Name');
|
$labels = parent::fieldLabels($includerelations);
|
||||||
$labels['RedirectURL'] = _t('Subsites.RedirectURLFieldLabel', 'Redirect URL');
|
$labels['Title'] = _t('Subsites.TitleFieldLabel', 'Subsite Name');
|
||||||
$labels['DefaultSite'] = _t('Subsites.DefaultSiteFieldLabel', 'Default site');
|
$labels['RedirectURL'] = _t('Subsites.RedirectURLFieldLabel', 'Redirect URL');
|
||||||
$labels['Theme'] = _t('Subsites.ThemeFieldLabel', 'Theme');
|
$labels['DefaultSite'] = _t('Subsites.DefaultSiteFieldLabel', 'Default site');
|
||||||
$labels['Language'] = _t('Subsites.LanguageFieldLabel', 'Language');
|
$labels['Theme'] = _t('Subsites.ThemeFieldLabel', 'Theme');
|
||||||
$labels['IsPublic'] = _t('Subsites.IsPublicFieldLabel', 'Enable public access');
|
$labels['Language'] = _t('Subsites.LanguageFieldLabel', 'Language');
|
||||||
$labels['PageTypeBlacklist'] = _t('Subsites.PageTypeBlacklistFieldLabel', 'Page Type Blacklist');
|
$labels['IsPublic'] = _t('Subsites.IsPublicFieldLabel', 'Enable public access');
|
||||||
$labels['Domains.Domain'] = _t('Subsites.DomainFieldLabel', 'Domain');
|
$labels['PageTypeBlacklist'] = _t('Subsites.PageTypeBlacklistFieldLabel', 'Page Type Blacklist');
|
||||||
$labels['PrimaryDomain'] = _t('Subsites.PrimaryDomainFieldLabel', 'Primary Domain');
|
$labels['Domains.Domain'] = _t('Subsites.DomainFieldLabel', 'Domain');
|
||||||
|
$labels['PrimaryDomain'] = _t('Subsites.PrimaryDomainFieldLabel', 'Primary Domain');
|
||||||
|
|
||||||
return $labels;
|
return $labels;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the themes that can be used with this subsite, as an array of themecode => description
|
* Return the themes that can be used with this subsite, as an array of themecode => description
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function allowedThemes() {
|
public function allowedThemes()
|
||||||
if($themes = $this->stat('allowed_themes')) {
|
{
|
||||||
return ArrayLib::valuekey($themes);
|
if ($themes = $this->stat('allowed_themes')) {
|
||||||
} else {
|
return ArrayLib::valuekey($themes);
|
||||||
$themes = array();
|
} else {
|
||||||
if(is_dir('../themes/')) {
|
$themes = [];
|
||||||
foreach(scandir('../themes/') as $theme) {
|
if (is_dir('../themes/')) {
|
||||||
if($theme[0] == '.') continue;
|
foreach (scandir('../themes/') as $theme) {
|
||||||
$theme = strtok($theme,'_');
|
if ($theme[0] == '.') {
|
||||||
$themes[$theme] = $theme;
|
continue;
|
||||||
}
|
}
|
||||||
ksort($themes);
|
$theme = strtok($theme, '_');
|
||||||
}
|
$themes[$theme] = $theme;
|
||||||
return $themes;
|
}
|
||||||
}
|
ksort($themes);
|
||||||
}
|
}
|
||||||
|
return $themes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return string Current locale of the subsite
|
* @return string Current locale of the subsite
|
||||||
*/
|
*/
|
||||||
public function getLanguage() {
|
public function getLanguage()
|
||||||
if($this->getField('Language')) {
|
{
|
||||||
return $this->getField('Language');
|
if ($this->getField('Language')) {
|
||||||
} else {
|
return $this->getField('Language');
|
||||||
return i18n::get_locale();
|
} else {
|
||||||
}
|
return i18n::get_locale();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @return ValidationResult
|
* @return ValidationResult
|
||||||
*/
|
*/
|
||||||
public function validate() {
|
public function validate()
|
||||||
$result = parent::validate();
|
{
|
||||||
if(!$this->Title) {
|
$result = parent::validate();
|
||||||
$result->error(_t('Subsite.ValidateTitle', 'Please add a "Title"'));
|
if (!$this->Title) {
|
||||||
}
|
$result->error(_t('Subsite.ValidateTitle', 'Please add a "Title"'));
|
||||||
return $result;
|
}
|
||||||
}
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whenever a Subsite is written, rewrite the hostmap
|
* Whenever a Subsite is written, rewrite the hostmap
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function onAfterWrite() {
|
public function onAfterWrite()
|
||||||
Subsite::writeHostMap();
|
{
|
||||||
parent::onAfterWrite();
|
Subsite::writeHostMap();
|
||||||
}
|
parent::onAfterWrite();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the primary domain of this site. Tries to "normalize" the domain name,
|
* Return the primary domain of this site. Tries to "normalize" the domain name,
|
||||||
* by replacing potential wildcards.
|
* by replacing potential wildcards.
|
||||||
*
|
*
|
||||||
* @return string The full domain name of this subsite (without protocol prefix)
|
* @return string The full domain name of this subsite (without protocol prefix)
|
||||||
*/
|
*/
|
||||||
public function domain() {
|
public function domain()
|
||||||
if($this->ID) {
|
{
|
||||||
$domains = DataObject::get(SubsiteDomain::class, "\"SubsiteID\" = $this->ID", "\"IsPrimary\" DESC","", 1);
|
if ($this->ID) {
|
||||||
if($domains && $domains->Count()>0) {
|
$domains = DataObject::get(SubsiteDomain::class, "\"SubsiteID\" = $this->ID", "\"IsPrimary\" DESC", "", 1);
|
||||||
$domain = $domains->First()->Domain;
|
if ($domains && $domains->Count() > 0) {
|
||||||
// If there are wildcards in the primary domain (not recommended), make some
|
$domain = $domains->First()->Domain;
|
||||||
// educated guesses about what to replace them with:
|
// If there are wildcards in the primary domain (not recommended), make some
|
||||||
$domain = preg_replace('/\.\*$/',".$_SERVER[HTTP_HOST]", $domain);
|
// educated guesses about what to replace them with:
|
||||||
// Default to "subsite." prefix for first wildcard
|
$domain = preg_replace('/\.\*$/', ".$_SERVER[HTTP_HOST]", $domain);
|
||||||
// TODO Whats the significance of "subsite" in this context?!
|
// Default to "subsite." prefix for first wildcard
|
||||||
$domain = preg_replace('/^\*\./',"subsite.", $domain);
|
// TODO Whats the significance of "subsite" in this context?!
|
||||||
// *Only* removes "intermediate" subdomains, so 'subdomain.www.domain.com' becomes 'subdomain.domain.com'
|
$domain = preg_replace('/^\*\./', "subsite.", $domain);
|
||||||
$domain = str_replace('.www.','.', $domain);
|
// *Only* removes "intermediate" subdomains, so 'subdomain.www.domain.com' becomes 'subdomain.domain.com'
|
||||||
|
$domain = str_replace('.www.', '.', $domain);
|
||||||
|
|
||||||
return $domain;
|
return $domain;
|
||||||
}
|
}
|
||||||
|
|
||||||
// SubsiteID = 0 is often used to refer to the main site, just return $_SERVER['HTTP_HOST']
|
// SubsiteID = 0 is often used to refer to the main site, just return $_SERVER['HTTP_HOST']
|
||||||
} else {
|
} else {
|
||||||
return $_SERVER['HTTP_HOST'];
|
return $_SERVER['HTTP_HOST'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @return string - The full domain name of this subsite (without protocol prefix)
|
* @return string - The full domain name of this subsite (without protocol prefix)
|
||||||
*/
|
*/
|
||||||
public function getPrimaryDomain() {
|
public function getPrimaryDomain()
|
||||||
return $this->domain();
|
{
|
||||||
}
|
return $this->domain();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function absoluteBaseURL() {
|
public function absoluteBaseURL()
|
||||||
return "http://" . $this->domain() . Director::baseURL();
|
{
|
||||||
}
|
return "http://" . $this->domain() . Director::baseURL();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @todo getClassName is redundant, already stored as a database field?
|
* @todo getClassName is redundant, already stored as a database field?
|
||||||
*/
|
*/
|
||||||
public function getClassName() {
|
public function getClassName()
|
||||||
return $this->class;
|
{
|
||||||
}
|
return $this->class;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Javascript admin action to duplicate this subsite
|
* Javascript admin action to duplicate this subsite
|
||||||
*
|
*
|
||||||
* @return string - javascript
|
* @return string - javascript
|
||||||
*/
|
*/
|
||||||
public function adminDuplicate() {
|
public function adminDuplicate()
|
||||||
$newItem = $this->duplicate();
|
{
|
||||||
$message = _t(
|
$newItem = $this->duplicate();
|
||||||
'Subsite.CopyMessage',
|
$message = _t(
|
||||||
'Created a copy of {title}',
|
'Subsite.CopyMessage',
|
||||||
array('title' => Convert::raw2js($this->Title))
|
'Created a copy of {title}',
|
||||||
);
|
['title' => Convert::raw2js($this->Title)]
|
||||||
|
);
|
||||||
|
|
||||||
return <<<JS
|
return <<<JS
|
||||||
statusMessage($message, 'good');
|
statusMessage($message, 'good');
|
||||||
$('Form_EditForm').loadURLFromServer('admin/subsites/show/$newItem->ID');
|
$('Form_EditForm').loadURLFromServer('admin/subsites/show/$newItem->ID');
|
||||||
JS;
|
JS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make this subsite the current one
|
* Make this subsite the current one
|
||||||
*/
|
*/
|
||||||
public function activate() {
|
public function activate()
|
||||||
Subsite::changeSubsite($this);
|
{
|
||||||
}
|
Subsite::changeSubsite($this);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param array $permissionCodes
|
* @param array $permissionCodes
|
||||||
* @return DataList
|
* @return DataList
|
||||||
*/
|
*/
|
||||||
public function getMembersByPermission($permissionCodes = array('ADMIN')){
|
public function getMembersByPermission($permissionCodes = ['ADMIN'])
|
||||||
if(!is_array($permissionCodes))
|
{
|
||||||
user_error('Permissions must be passed to Subsite::getMembersByPermission as an array', E_USER_ERROR);
|
if (!is_array($permissionCodes)) {
|
||||||
$SQL_permissionCodes = Convert::raw2sql($permissionCodes);
|
user_error('Permissions must be passed to Subsite::getMembersByPermission as an array', E_USER_ERROR);
|
||||||
|
}
|
||||||
|
$SQL_permissionCodes = Convert::raw2sql($permissionCodes);
|
||||||
|
|
||||||
$SQL_permissionCodes = join("','", $SQL_permissionCodes);
|
$SQL_permissionCodes = join("','", $SQL_permissionCodes);
|
||||||
|
|
||||||
return DataObject::get(
|
return DataObject::get(
|
||||||
'SilverStripe\\Security\\Member',
|
'SilverStripe\\Security\\Member',
|
||||||
"\"Group\".\"SubsiteID\" = $this->ID AND \"Permission\".\"Code\" IN ('$SQL_permissionCodes')",
|
"\"Group\".\"SubsiteID\" = $this->ID AND \"Permission\".\"Code\" IN ('$SQL_permissionCodes')",
|
||||||
'',
|
'',
|
||||||
"LEFT JOIN \"Group_Members\" ON \"Member\".\"ID\" = \"Group_Members\".\"MemberID\"
|
"LEFT JOIN \"Group_Members\" ON \"Member\".\"ID\" = \"Group_Members\".\"MemberID\"
|
||||||
LEFT JOIN \"Group\" ON \"Group\".\"ID\" = \"Group_Members\".\"GroupID\"
|
LEFT JOIN \"Group\" ON \"Group\".\"ID\" = \"Group_Members\".\"GroupID\"
|
||||||
LEFT JOIN \"Permission\" ON \"Permission\".\"GroupID\" = \"Group\".\"ID\""
|
LEFT JOIN \"Permission\" ON \"Permission\".\"GroupID\" = \"Group\".\"ID\""
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Duplicate this subsite
|
* Duplicate this subsite
|
||||||
*/
|
*/
|
||||||
public function duplicate($doWrite = true) {
|
public function duplicate($doWrite = true)
|
||||||
$duplicate = parent::duplicate($doWrite);
|
{
|
||||||
|
$duplicate = parent::duplicate($doWrite);
|
||||||
|
|
||||||
$oldSubsiteID = Session::get('SubsiteID');
|
$oldSubsiteID = Session::get('SubsiteID');
|
||||||
self::changeSubsite($this->ID);
|
self::changeSubsite($this->ID);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copy data from this object to the given subsite. Does this using an iterative depth-first search.
|
* Copy data from this object to the given subsite. Does this using an iterative depth-first search.
|
||||||
* This will make sure that the new parents on the new subsite are correct, and there are no funny
|
* This will make sure that the new parents on the new subsite are correct, and there are no funny
|
||||||
* issues with having to check whether or not the new parents have been added to the site tree
|
* issues with having to check whether or not the new parents have been added to the site tree
|
||||||
* when a page, etc, is duplicated
|
* when a page, etc, is duplicated
|
||||||
*/
|
*/
|
||||||
$stack = array(array(0,0));
|
$stack = [[0, 0]];
|
||||||
while(count($stack) > 0) {
|
while (count($stack) > 0) {
|
||||||
list($sourceParentID, $destParentID) = array_pop($stack);
|
list($sourceParentID, $destParentID) = array_pop($stack);
|
||||||
$children = Versioned::get_by_stage('Page', 'Live', "\"ParentID\" = $sourceParentID", '');
|
$children = Versioned::get_by_stage('Page', 'Live', "\"ParentID\" = $sourceParentID", '');
|
||||||
|
|
||||||
if($children) {
|
if ($children) {
|
||||||
foreach($children as $child) {
|
foreach ($children as $child) {
|
||||||
self::changeSubsite($duplicate->ID); //Change to destination subsite
|
self::changeSubsite($duplicate->ID); //Change to destination subsite
|
||||||
|
|
||||||
$childClone = $child->duplicateToSubsite($duplicate, false);
|
$childClone = $child->duplicateToSubsite($duplicate, false);
|
||||||
$childClone->ParentID = $destParentID;
|
$childClone->ParentID = $destParentID;
|
||||||
$childClone->writeToStage('Stage');
|
$childClone->writeToStage('Stage');
|
||||||
$childClone->publish('Stage', 'Live');
|
$childClone->publish('Stage', 'Live');
|
||||||
|
|
||||||
self::changeSubsite($this->ID); //Change Back to this subsite
|
self::changeSubsite($this->ID); //Change Back to this subsite
|
||||||
|
|
||||||
array_push($stack, array($child->ID, $childClone->ID));
|
array_push($stack, [$child->ID, $childClone->ID]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self::changeSubsite($oldSubsiteID);
|
self::changeSubsite($oldSubsiteID);
|
||||||
|
|
||||||
return $duplicate;
|
return $duplicate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,98 +3,102 @@
|
|||||||
namespace SilverStripe\Subsites\Model;
|
namespace SilverStripe\Subsites\Model;
|
||||||
|
|
||||||
|
|
||||||
use SilverStripe\Forms\TextField;
|
use SilverStripe\Core\Convert;
|
||||||
use SilverStripe\Forms\CheckboxField;
|
use SilverStripe\Forms\CheckboxField;
|
||||||
use SilverStripe\Forms\FieldList;
|
use SilverStripe\Forms\FieldList;
|
||||||
use SilverStripe\Core\Convert;
|
use SilverStripe\Forms\TextField;
|
||||||
use SilverStripe\ORM\DataObject;
|
use SilverStripe\ORM\DataObject;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @property text Domain domain name of this subsite. Do not include the URL scheme here
|
* @property text Domain domain name of this subsite. Do not include the URL scheme here
|
||||||
* @property bool IsPrimary Is this the primary subdomain?
|
* @property bool IsPrimary Is this the primary subdomain?
|
||||||
*/
|
*/
|
||||||
class SubsiteDomain extends DataObject {
|
class SubsiteDomain extends DataObject
|
||||||
|
{
|
||||||
|
|
||||||
private static $table_name = 'SubsiteDomain';
|
private static $table_name = 'SubsiteDomain';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
private static $default_sort = "\"IsPrimary\" DESC";
|
private static $default_sort = "\"IsPrimary\" DESC";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
private static $db = array(
|
private static $db = [
|
||||||
"Domain" => "Varchar(255)",
|
"Domain" => "Varchar(255)",
|
||||||
"IsPrimary" => "Boolean",
|
"IsPrimary" => "Boolean",
|
||||||
);
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
private static $has_one = array(
|
private static $has_one = [
|
||||||
"Subsite" => Subsite::class,
|
"Subsite" => Subsite::class,
|
||||||
);
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
private static $summary_fields=array(
|
private static $summary_fields = [
|
||||||
'Domain',
|
'Domain',
|
||||||
'IsPrimary',
|
'IsPrimary',
|
||||||
);
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whenever a Subsite Domain is written, rewrite the hostmap
|
* Whenever a Subsite Domain is written, rewrite the hostmap
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function onAfterWrite() {
|
public function onAfterWrite()
|
||||||
Subsite::writeHostMap();
|
{
|
||||||
}
|
Subsite::writeHostMap();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @return \FieldList
|
* @return \FieldList
|
||||||
*/
|
*/
|
||||||
public function getCMSFields() {
|
public function getCMSFields()
|
||||||
$fields = new FieldList(
|
{
|
||||||
new TextField('Domain', $this->fieldLabel('Domain'), null, 255),
|
$fields = new FieldList(
|
||||||
new CheckboxField('IsPrimary', $this->fieldLabel('IsPrimary'))
|
new TextField('Domain', $this->fieldLabel('Domain'), null, 255),
|
||||||
);
|
new CheckboxField('IsPrimary', $this->fieldLabel('IsPrimary'))
|
||||||
|
);
|
||||||
|
|
||||||
$this->extend('updateCMSFields', $fields);
|
$this->extend('updateCMSFields', $fields);
|
||||||
return $fields;
|
return $fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param bool $includerelations
|
* @param bool $includerelations
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function fieldLabels($includerelations = true) {
|
public function fieldLabels($includerelations = true)
|
||||||
$labels = parent::fieldLabels($includerelations);
|
{
|
||||||
$labels['Domain'] = _t('SubsiteDomain.DOMAIN', 'Domain');
|
$labels = parent::fieldLabels($includerelations);
|
||||||
$labels['IsPrimary'] = _t('SubsiteDomain.IS_PRIMARY', 'Is Primary Domain');
|
$labels['Domain'] = _t('SubsiteDomain.DOMAIN', 'Domain');
|
||||||
|
$labels['IsPrimary'] = _t('SubsiteDomain.IS_PRIMARY', 'Is Primary Domain');
|
||||||
|
|
||||||
return $labels;
|
return $labels;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Before writing the Subsite Domain, strip out any HTML the user has entered.
|
* Before writing the Subsite Domain, strip out any HTML the user has entered.
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function onBeforeWrite() {
|
public function onBeforeWrite()
|
||||||
parent::onBeforeWrite();
|
{
|
||||||
|
parent::onBeforeWrite();
|
||||||
|
|
||||||
//strip out any HTML to avoid XSS attacks
|
//strip out any HTML to avoid XSS attacks
|
||||||
$this->Domain = Convert::html2raw($this->Domain);
|
$this->Domain = Convert::html2raw($this->Domain);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,213 +3,234 @@
|
|||||||
namespace SilverStripe\Subsites\Pages;
|
namespace SilverStripe\Subsites\Pages;
|
||||||
|
|
||||||
|
|
||||||
use SilverStripe\ORM\DataObject;
|
use SilverStripe\CMS\Model\VirtualPage;
|
||||||
use SilverStripe\ORM\ArrayList;
|
|
||||||
use SilverStripe\View\ArrayData;
|
|
||||||
use SilverStripe\Forms\DropdownField;
|
|
||||||
use SilverStripe\Control\Controller;
|
use SilverStripe\Control\Controller;
|
||||||
use SilverStripe\Forms\LabelField;
|
|
||||||
use SilverStripe\Forms\TextField;
|
|
||||||
use SilverStripe\Forms\TextareaField;
|
|
||||||
use SilverStripe\Control\Session;
|
use SilverStripe\Control\Session;
|
||||||
use SilverStripe\Core\Config\Config;
|
use SilverStripe\Core\Config\Config;
|
||||||
use SilverStripe\CMS\Model\VirtualPage;
|
use SilverStripe\Forms\DropdownField;
|
||||||
use SilverStripe\Subsites\Model\Subsite;
|
use SilverStripe\Forms\LabelField;
|
||||||
|
use SilverStripe\Forms\TextareaField;
|
||||||
|
use SilverStripe\Forms\TextField;
|
||||||
|
use SilverStripe\ORM\ArrayList;
|
||||||
|
use SilverStripe\ORM\DataObject;
|
||||||
use SilverStripe\Subsites\Forms\SubsitesTreeDropdownField;
|
use SilverStripe\Subsites\Forms\SubsitesTreeDropdownField;
|
||||||
|
use SilverStripe\Subsites\Model\Subsite;
|
||||||
|
use SilverStripe\View\ArrayData;
|
||||||
|
|
||||||
|
|
||||||
class SubsitesVirtualPage extends VirtualPage {
|
class SubsitesVirtualPage extends VirtualPage
|
||||||
|
{
|
||||||
|
|
||||||
private static $table_name = 'SubsitesVirtualPage';
|
private static $table_name = 'SubsitesVirtualPage';
|
||||||
|
|
||||||
private static $description = 'Displays the content of a page on another subsite';
|
private static $description = 'Displays the content of a page on another subsite';
|
||||||
|
|
||||||
private static $db = array(
|
private static $db = [
|
||||||
'CustomMetaTitle' => 'Varchar(255)',
|
'CustomMetaTitle' => 'Varchar(255)',
|
||||||
'CustomMetaKeywords' => 'Varchar(255)',
|
'CustomMetaKeywords' => 'Varchar(255)',
|
||||||
'CustomMetaDescription' => 'Text',
|
'CustomMetaDescription' => 'Text',
|
||||||
'CustomExtraMeta' => 'HTMLText'
|
'CustomExtraMeta' => 'HTMLText'
|
||||||
);
|
];
|
||||||
|
|
||||||
public function getCMSFields() {
|
public function getCMSFields()
|
||||||
$fields = parent::getCMSFields();
|
{
|
||||||
|
$fields = parent::getCMSFields();
|
||||||
|
|
||||||
$subsites = DataObject::get(Subsite::class);
|
$subsites = DataObject::get(Subsite::class);
|
||||||
if(!$subsites) {
|
if (!$subsites) {
|
||||||
$subsites = new ArrayList();
|
$subsites = new ArrayList();
|
||||||
}else {
|
} else {
|
||||||
$subsites=ArrayList::create($subsites->toArray());
|
$subsites = ArrayList::create($subsites->toArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
$subsites->push(new ArrayData(array('Title' => 'Main site', 'ID' => 0)));
|
$subsites->push(new ArrayData(['Title' => 'Main site', 'ID' => 0]));
|
||||||
|
|
||||||
$fields->addFieldToTab(
|
$fields->addFieldToTab(
|
||||||
'Root.Main',
|
'Root.Main',
|
||||||
DropdownField::create(
|
DropdownField::create(
|
||||||
"CopyContentFromID_SubsiteID",
|
"CopyContentFromID_SubsiteID",
|
||||||
_t('SubsitesVirtualPage.SubsiteField',Subsite::class),
|
_t('SubsitesVirtualPage.SubsiteField', Subsite::class),
|
||||||
$subsites->map('ID', 'Title')
|
$subsites->map('ID', 'Title')
|
||||||
)->addExtraClass('subsitestreedropdownfield-chooser no-change-track'),
|
)->addExtraClass('subsitestreedropdownfield-chooser no-change-track'),
|
||||||
'CopyContentFromID'
|
'CopyContentFromID'
|
||||||
);
|
);
|
||||||
|
|
||||||
// Setup the linking to the original page.
|
// Setup the linking to the original page.
|
||||||
$pageSelectionField = new SubsitesTreeDropdownField(
|
$pageSelectionField = new SubsitesTreeDropdownField(
|
||||||
"CopyContentFromID",
|
"CopyContentFromID",
|
||||||
_t('VirtualPage.CHOOSE', "Choose a page to link to"),
|
_t('VirtualPage.CHOOSE', "Choose a page to link to"),
|
||||||
"SilverStripe\\CMS\\Model\\SiteTree",
|
"SilverStripe\\CMS\\Model\\SiteTree",
|
||||||
"ID",
|
"ID",
|
||||||
"MenuTitle"
|
"MenuTitle"
|
||||||
);
|
);
|
||||||
|
|
||||||
if(Controller::has_curr() && Controller::curr()->getRequest()) {
|
if (Controller::has_curr() && Controller::curr()->getRequest()) {
|
||||||
$subsiteID = Controller::curr()->getRequest()->requestVar('CopyContentFromID_SubsiteID');
|
$subsiteID = Controller::curr()->getRequest()->requestVar('CopyContentFromID_SubsiteID');
|
||||||
$pageSelectionField->setSubsiteID($subsiteID);
|
$pageSelectionField->setSubsiteID($subsiteID);
|
||||||
}
|
}
|
||||||
$fields->replaceField('CopyContentFromID', $pageSelectionField);
|
$fields->replaceField('CopyContentFromID', $pageSelectionField);
|
||||||
|
|
||||||
// Create links back to the original object in the CMS
|
// Create links back to the original object in the CMS
|
||||||
if($this->CopyContentFromID) {
|
if ($this->CopyContentFromID) {
|
||||||
$editLink = "admin/pages/edit/show/$this->CopyContentFromID/?SubsiteID=" . $this->CopyContentFrom()->SubsiteID;
|
$editLink = "admin/pages/edit/show/$this->CopyContentFromID/?SubsiteID=" . $this->CopyContentFrom()->SubsiteID;
|
||||||
$linkToContent = "
|
$linkToContent = "
|
||||||
<a class=\"cmsEditlink\" href=\"$editLink\">" .
|
<a class=\"cmsEditlink\" href=\"$editLink\">" .
|
||||||
_t('VirtualPage.EDITCONTENT', 'Click here to edit the content') .
|
_t('VirtualPage.EDITCONTENT', 'Click here to edit the content') .
|
||||||
"</a>";
|
"</a>";
|
||||||
$fields->removeByName("VirtualPageContentLinkLabel");
|
$fields->removeByName("VirtualPageContentLinkLabel");
|
||||||
$fields->addFieldToTab(
|
$fields->addFieldToTab(
|
||||||
"Root.Main",
|
"Root.Main",
|
||||||
$linkToContentLabelField = new LabelField('VirtualPageContentLinkLabel', $linkToContent),
|
$linkToContentLabelField = new LabelField('VirtualPageContentLinkLabel', $linkToContent),
|
||||||
'Title'
|
'Title'
|
||||||
);
|
);
|
||||||
$linkToContentLabelField->setAllowHTML(true);
|
$linkToContentLabelField->setAllowHTML(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
$fields->addFieldToTab(
|
$fields->addFieldToTab(
|
||||||
'Root.Main',
|
'Root.Main',
|
||||||
TextField::create(
|
TextField::create(
|
||||||
'CustomMetaTitle',
|
'CustomMetaTitle',
|
||||||
$this->fieldLabel('CustomMetaTitle')
|
$this->fieldLabel('CustomMetaTitle')
|
||||||
)->setDescription(_t('SubsitesVirtualPage.OverrideNote', 'Overrides inherited value from the source')),
|
)->setDescription(_t('SubsitesVirtualPage.OverrideNote', 'Overrides inherited value from the source')),
|
||||||
'MetaTitle'
|
'MetaTitle'
|
||||||
);
|
);
|
||||||
$fields->addFieldToTab(
|
$fields->addFieldToTab(
|
||||||
'Root.Main',
|
'Root.Main',
|
||||||
TextareaField::create(
|
TextareaField::create(
|
||||||
'CustomMetaKeywords',
|
'CustomMetaKeywords',
|
||||||
$this->fieldLabel('CustomMetaTitle')
|
$this->fieldLabel('CustomMetaTitle')
|
||||||
)->setDescription(_t('SubsitesVirtualPage.OverrideNote')),
|
)->setDescription(_t('SubsitesVirtualPage.OverrideNote')),
|
||||||
'MetaKeywords'
|
'MetaKeywords'
|
||||||
);
|
);
|
||||||
$fields->addFieldToTab(
|
$fields->addFieldToTab(
|
||||||
'Root.Main',
|
'Root.Main',
|
||||||
TextareaField::create(
|
TextareaField::create(
|
||||||
'CustomMetaDescription',
|
'CustomMetaDescription',
|
||||||
$this->fieldLabel('CustomMetaTitle')
|
$this->fieldLabel('CustomMetaTitle')
|
||||||
)->setDescription(_t('SubsitesVirtualPage.OverrideNote')),
|
)->setDescription(_t('SubsitesVirtualPage.OverrideNote')),
|
||||||
'MetaDescription'
|
'MetaDescription'
|
||||||
);
|
);
|
||||||
$fields->addFieldToTab(
|
$fields->addFieldToTab(
|
||||||
'Root.Main',
|
'Root.Main',
|
||||||
TextField::create(
|
TextField::create(
|
||||||
'CustomExtraMeta',
|
'CustomExtraMeta',
|
||||||
$this->fieldLabel('CustomMetaTitle')
|
$this->fieldLabel('CustomMetaTitle')
|
||||||
)->setDescription(_t('SubsitesVirtualPage.OverrideNote')),
|
)->setDescription(_t('SubsitesVirtualPage.OverrideNote')),
|
||||||
'ExtraMeta'
|
'ExtraMeta'
|
||||||
);
|
);
|
||||||
|
|
||||||
return $fields;
|
return $fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function fieldLabels($includerelations = true) {
|
public function fieldLabels($includerelations = true)
|
||||||
$labels = parent::fieldLabels($includerelations);
|
{
|
||||||
$labels['CustomMetaTitle'] = _t('Subsite.CustomMetaTitle','Title');
|
$labels = parent::fieldLabels($includerelations);
|
||||||
$labels['CustomMetaKeywords'] = _t('Subsite.CustomMetaKeywords','Keywords');
|
$labels['CustomMetaTitle'] = _t('Subsite.CustomMetaTitle', 'Title');
|
||||||
$labels['CustomMetaDescription'] = _t('Subsite.CustomMetaDescription','Description');
|
$labels['CustomMetaKeywords'] = _t('Subsite.CustomMetaKeywords', 'Keywords');
|
||||||
$labels['CustomExtraMeta'] = _t('Subsite.CustomExtraMeta','Custom Meta Tags');
|
$labels['CustomMetaDescription'] = _t('Subsite.CustomMetaDescription', 'Description');
|
||||||
|
$labels['CustomExtraMeta'] = _t('Subsite.CustomExtraMeta', 'Custom Meta Tags');
|
||||||
|
|
||||||
return $labels;
|
return $labels;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getCopyContentFromID_SubsiteID() {
|
public function getCopyContentFromID_SubsiteID()
|
||||||
return ($this->CopyContentFromID) ? (int)$this->CopyContentFrom()->SubsiteID : (int)Session::get('SubsiteID');
|
{
|
||||||
}
|
return ($this->CopyContentFromID) ? (int)$this->CopyContentFrom()->SubsiteID : (int)Session::get('SubsiteID');
|
||||||
|
}
|
||||||
|
|
||||||
public function getVirtualFields() {
|
public function getVirtualFields()
|
||||||
$fields = parent::getVirtualFields();
|
{
|
||||||
foreach($fields as $k => $v) {
|
$fields = parent::getVirtualFields();
|
||||||
if($v == 'SubsiteID') unset($fields[$k]);
|
foreach ($fields as $k => $v) {
|
||||||
}
|
if ($v == 'SubsiteID') {
|
||||||
|
unset($fields[$k]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
foreach(self::$db as $field => $type) if (in_array($field, $fields)) unset($fields[array_search($field, $fields)]);
|
foreach (self::$db as $field => $type) {
|
||||||
|
if (in_array($field, $fields)) {
|
||||||
|
unset($fields[array_search($field, $fields)]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return $fields;
|
return $fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function syncLinkTracking() {
|
public function syncLinkTracking()
|
||||||
$oldState = Subsite::$disable_subsite_filter;
|
{
|
||||||
Subsite::$disable_subsite_filter = true;
|
$oldState = Subsite::$disable_subsite_filter;
|
||||||
if ($this->CopyContentFromID) $this->HasBrokenLink = DataObject::get_by_id('SilverStripe\\CMS\\Model\\SiteTree', $this->CopyContentFromID) ? false : true;
|
Subsite::$disable_subsite_filter = true;
|
||||||
Subsite::$disable_subsite_filter = $oldState;
|
if ($this->CopyContentFromID) {
|
||||||
}
|
$this->HasBrokenLink = DataObject::get_by_id('SilverStripe\\CMS\\Model\\SiteTree',
|
||||||
|
$this->CopyContentFromID) ? false : true;
|
||||||
|
}
|
||||||
|
Subsite::$disable_subsite_filter = $oldState;
|
||||||
|
}
|
||||||
|
|
||||||
public function onBeforeWrite() {
|
public function onBeforeWrite()
|
||||||
parent::onBeforeWrite();
|
{
|
||||||
|
parent::onBeforeWrite();
|
||||||
|
|
||||||
if($this->CustomMetaTitle) $this->MetaTitle = $this->CustomMetaTitle;
|
if ($this->CustomMetaTitle) {
|
||||||
else {
|
$this->MetaTitle = $this->CustomMetaTitle;
|
||||||
$this->MetaTitle = $this->ContentSource()->MetaTitle ? $this->ContentSource()->MetaTitle : $this->MetaTitle;
|
} else {
|
||||||
}
|
$this->MetaTitle = $this->ContentSource()->MetaTitle ? $this->ContentSource()->MetaTitle : $this->MetaTitle;
|
||||||
if($this->CustomMetaKeywords) $this->MetaKeywords = $this->CustomMetaKeywords;
|
}
|
||||||
else {
|
if ($this->CustomMetaKeywords) {
|
||||||
$this->MetaKeywords = $this->ContentSource()->MetaKeywords ? $this->ContentSource()->MetaKeywords : $this->MetaKeywords;
|
$this->MetaKeywords = $this->CustomMetaKeywords;
|
||||||
}
|
} else {
|
||||||
if($this->CustomMetaDescription) $this->MetaDescription = $this->CustomMetaDescription;
|
$this->MetaKeywords = $this->ContentSource()->MetaKeywords ? $this->ContentSource()->MetaKeywords : $this->MetaKeywords;
|
||||||
else {
|
}
|
||||||
$this->MetaDescription = $this->ContentSource()->MetaDescription ? $this->ContentSource()->MetaDescription : $this->MetaDescription;
|
if ($this->CustomMetaDescription) {
|
||||||
}
|
$this->MetaDescription = $this->CustomMetaDescription;
|
||||||
if($this->CustomExtraMeta) $this->ExtraMeta = $this->CustomExtraMeta;
|
} else {
|
||||||
else {
|
$this->MetaDescription = $this->ContentSource()->MetaDescription ? $this->ContentSource()->MetaDescription : $this->MetaDescription;
|
||||||
$this->ExtraMeta = $this->ContentSource()->ExtraMeta ? $this->ContentSource()->ExtraMeta : $this->ExtraMeta;
|
}
|
||||||
}
|
if ($this->CustomExtraMeta) {
|
||||||
}
|
$this->ExtraMeta = $this->CustomExtraMeta;
|
||||||
|
} else {
|
||||||
|
$this->ExtraMeta = $this->ContentSource()->ExtraMeta ? $this->ContentSource()->ExtraMeta : $this->ExtraMeta;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function validURLSegment() {
|
public function validURLSegment()
|
||||||
$isValid = parent::validURLSegment();
|
{
|
||||||
|
$isValid = parent::validURLSegment();
|
||||||
|
|
||||||
// Veto the validation rules if its false. In this case, some logic
|
// Veto the validation rules if its false. In this case, some logic
|
||||||
// needs to be duplicated from parent to find out the exact reason the validation failed.
|
// needs to be duplicated from parent to find out the exact reason the validation failed.
|
||||||
if(!$isValid) {
|
if (!$isValid) {
|
||||||
$IDFilter = ($this->ID) ? "AND \"SiteTree\".\"ID\" <> $this->ID" : null;
|
$IDFilter = ($this->ID) ? "AND \"SiteTree\".\"ID\" <> $this->ID" : null;
|
||||||
$parentFilter = null;
|
$parentFilter = null;
|
||||||
|
|
||||||
if(Config::inst()->get('SilverStripe\\CMS\\Model\\SiteTree', 'nested_urls')) {
|
if (Config::inst()->get('SilverStripe\\CMS\\Model\\SiteTree', 'nested_urls')) {
|
||||||
if($this->ParentID) {
|
if ($this->ParentID) {
|
||||||
$parentFilter = " AND \"SiteTree\".\"ParentID\" = $this->ParentID";
|
$parentFilter = " AND \"SiteTree\".\"ParentID\" = $this->ParentID";
|
||||||
} else {
|
} else {
|
||||||
$parentFilter = ' AND "SiteTree"."ParentID" = 0';
|
$parentFilter = ' AND "SiteTree"."ParentID" = 0';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$origDisableSubsiteFilter = Subsite::$disable_subsite_filter;
|
$origDisableSubsiteFilter = Subsite::$disable_subsite_filter;
|
||||||
Subsite::$disable_subsite_filter = true;
|
Subsite::$disable_subsite_filter = true;
|
||||||
$existingPage = DataObject::get_one(
|
$existingPage = DataObject::get_one(
|
||||||
'SilverStripe\\CMS\\Model\\SiteTree',
|
'SilverStripe\\CMS\\Model\\SiteTree',
|
||||||
"\"URLSegment\" = '$this->URLSegment' $IDFilter $parentFilter",
|
"\"URLSegment\" = '$this->URLSegment' $IDFilter $parentFilter",
|
||||||
false // disable cache, it doesn't include subsite status in the key
|
false // disable cache, it doesn't include subsite status in the key
|
||||||
);
|
);
|
||||||
Subsite::$disable_subsite_filter = $origDisableSubsiteFilter;
|
Subsite::$disable_subsite_filter = $origDisableSubsiteFilter;
|
||||||
$existingPageInSubsite = DataObject::get_one(
|
$existingPageInSubsite = DataObject::get_one(
|
||||||
'SilverStripe\\CMS\\Model\\SiteTree',
|
'SilverStripe\\CMS\\Model\\SiteTree',
|
||||||
"\"URLSegment\" = '$this->URLSegment' $IDFilter $parentFilter",
|
"\"URLSegment\" = '$this->URLSegment' $IDFilter $parentFilter",
|
||||||
false // disable cache, it doesn't include subsite status in the key
|
false // disable cache, it doesn't include subsite status in the key
|
||||||
);
|
);
|
||||||
|
|
||||||
// If URL has been vetoed because of an existing page,
|
// If URL has been vetoed because of an existing page,
|
||||||
// be more specific and allow same URLSegments in different subsites
|
// be more specific and allow same URLSegments in different subsites
|
||||||
$isValid = !($existingPage && $existingPageInSubsite);
|
$isValid = !($existingPage && $existingPageInSubsite);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $isValid;
|
return $isValid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,73 +3,78 @@
|
|||||||
namespace SilverStripe\Subsites\Reports;
|
namespace SilverStripe\Subsites\Reports;
|
||||||
|
|
||||||
|
|
||||||
use SilverStripe\Forms\TreeMultiselectField;
|
|
||||||
use SilverStripe\Forms\FieldList;
|
use SilverStripe\Forms\FieldList;
|
||||||
|
use SilverStripe\Forms\TreeMultiselectField;
|
||||||
use SilverStripe\Reports\ReportWrapper;
|
use SilverStripe\Reports\ReportWrapper;
|
||||||
use SilverStripe\Subsites\Model\Subsite;
|
use SilverStripe\Subsites\Model\Subsite;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a subsite-aware version of another report.
|
* Creates a subsite-aware version of another report.
|
||||||
* Pass another report (or its classname) into the constructor.
|
* Pass another report (or its classname) into the constructor.
|
||||||
*/
|
*/
|
||||||
class SubsiteReportWrapper extends ReportWrapper {
|
class SubsiteReportWrapper extends ReportWrapper
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
{
|
||||||
// Filtering
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Filtering
|
||||||
|
|
||||||
function parameterFields() {
|
function parameterFields()
|
||||||
$subsites = Subsite::accessible_sites('CMS_ACCESS_CMSMain', true);
|
{
|
||||||
$options = $subsites->toDropdownMap('ID', 'Title');
|
$subsites = Subsite::accessible_sites('CMS_ACCESS_CMSMain', true);
|
||||||
|
$options = $subsites->toDropdownMap('ID', 'Title');
|
||||||
|
|
||||||
$subsiteField = new TreeMultiselectField(
|
$subsiteField = new TreeMultiselectField(
|
||||||
'Subsites',
|
'Subsites',
|
||||||
_t('SubsiteReportWrapper.ReportDropdown', 'Sites'),
|
_t('SubsiteReportWrapper.ReportDropdown', 'Sites'),
|
||||||
$options
|
$options
|
||||||
);
|
);
|
||||||
$subsiteField->setValue(array_keys($options));
|
$subsiteField->setValue(array_keys($options));
|
||||||
|
|
||||||
// We don't need to make the field editable if only one subsite is available
|
// We don't need to make the field editable if only one subsite is available
|
||||||
if(sizeof($options) <= 1) {
|
if (sizeof($options) <= 1) {
|
||||||
$subsiteField = $subsiteField->performReadonlyTransformation();
|
$subsiteField = $subsiteField->performReadonlyTransformation();
|
||||||
}
|
}
|
||||||
|
|
||||||
$fields = parent::parameterFields();
|
$fields = parent::parameterFields();
|
||||||
if($fields) {
|
if ($fields) {
|
||||||
$fields->insertBefore($subsiteField, $fields->First()->Name());
|
$fields->insertBefore($subsiteField, $fields->First()->Name());
|
||||||
} else {
|
} else {
|
||||||
$fields = new FieldList($subsiteField);
|
$fields = new FieldList($subsiteField);
|
||||||
}
|
}
|
||||||
return $fields;
|
return $fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Columns
|
// Columns
|
||||||
|
|
||||||
function columns() {
|
function columns()
|
||||||
$columns = parent::columns();
|
{
|
||||||
$columns['Subsite.Title'] = Subsite::class;
|
$columns = parent::columns();
|
||||||
return $columns;
|
$columns['Subsite.Title'] = Subsite::class;
|
||||||
}
|
return $columns;
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Querying
|
// Querying
|
||||||
|
|
||||||
function beforeQuery($params) {
|
function beforeQuery($params)
|
||||||
// The user has select a few specific sites
|
{
|
||||||
if(!empty($params['Subsites'])) {
|
// The user has select a few specific sites
|
||||||
Subsite::$force_subsite = $params['Subsites'];
|
if (!empty($params['Subsites'])) {
|
||||||
|
Subsite::$force_subsite = $params['Subsites'];
|
||||||
|
|
||||||
// Default: restrict to all accessible sites
|
// Default: restrict to all accessible sites
|
||||||
} else {
|
} else {
|
||||||
$subsites = Subsite::accessible_sites('CMS_ACCESS_CMSMain');
|
$subsites = Subsite::accessible_sites('CMS_ACCESS_CMSMain');
|
||||||
$options = $subsites->toDropdownMap('ID', 'Title');
|
$options = $subsites->toDropdownMap('ID', 'Title');
|
||||||
Subsite::$force_subsite = join(',', array_keys($options));
|
Subsite::$force_subsite = join(',', array_keys($options));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function afterQuery() {
|
|
||||||
// Manually manage the subsite filtering
|
function afterQuery()
|
||||||
Subsite::$force_subsite = null;
|
{
|
||||||
}
|
// Manually manage the subsite filtering
|
||||||
|
Subsite::$force_subsite = null;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -3,12 +3,12 @@
|
|||||||
namespace SilverStripe\Subsites\Tasks;
|
namespace SilverStripe\Subsites\Tasks;
|
||||||
|
|
||||||
|
|
||||||
use SilverStripe\ORM\DataObject;
|
|
||||||
use SilverStripe\Dev\BuildTask;
|
|
||||||
use InvalidArgumentException;
|
use InvalidArgumentException;
|
||||||
|
use SilverStripe\Dev\BuildTask;
|
||||||
|
use SilverStripe\ORM\DataObject;
|
||||||
use SilverStripe\Subsites\Model\Subsite;
|
use SilverStripe\Subsites\Model\Subsite;
|
||||||
use SilverStripe\Versioned\Versioned;
|
|
||||||
use SilverStripe\Subsites\Pages\SubsitesVirtualPage;
|
use SilverStripe\Subsites\Pages\SubsitesVirtualPage;
|
||||||
|
use SilverStripe\Versioned\Versioned;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -18,62 +18,74 @@ use SilverStripe\Subsites\Pages\SubsitesVirtualPage;
|
|||||||
*
|
*
|
||||||
* Example: sake dev/tasks/SubsiteCopyPagesTask from=<subsite-source> to=<subsite-target>
|
* Example: sake dev/tasks/SubsiteCopyPagesTask from=<subsite-source> to=<subsite-target>
|
||||||
*/
|
*/
|
||||||
class SubsiteCopyPagesTask extends BuildTask {
|
class SubsiteCopyPagesTask extends BuildTask
|
||||||
|
{
|
||||||
|
|
||||||
protected $title = 'Copy pages to different subsite';
|
protected $title = 'Copy pages to different subsite';
|
||||||
|
|
||||||
protected $description = '';
|
protected $description = '';
|
||||||
|
|
||||||
function run($request) {
|
function run($request)
|
||||||
$subsiteFromId = $request->getVar('from');
|
{
|
||||||
if(!is_numeric($subsiteFromId)) throw new InvalidArgumentException('Missing "from" parameter');
|
$subsiteFromId = $request->getVar('from');
|
||||||
$subsiteFrom = DataObject::get_by_id(Subsite::class, $subsiteFromId);
|
if (!is_numeric($subsiteFromId)) {
|
||||||
if(!$subsiteFrom) throw new InvalidArgumentException('Subsite not found');
|
throw new InvalidArgumentException('Missing "from" parameter');
|
||||||
|
}
|
||||||
|
$subsiteFrom = DataObject::get_by_id(Subsite::class, $subsiteFromId);
|
||||||
|
if (!$subsiteFrom) {
|
||||||
|
throw new InvalidArgumentException('Subsite not found');
|
||||||
|
}
|
||||||
|
|
||||||
$subsiteToId = $request->getVar('to');
|
$subsiteToId = $request->getVar('to');
|
||||||
if(!is_numeric($subsiteToId)) throw new InvalidArgumentException('Missing "to" parameter');
|
if (!is_numeric($subsiteToId)) {
|
||||||
$subsiteTo = DataObject::get_by_id(Subsite::class, $subsiteToId);
|
throw new InvalidArgumentException('Missing "to" parameter');
|
||||||
if(!$subsiteTo) throw new InvalidArgumentException('Subsite not found');
|
}
|
||||||
|
$subsiteTo = DataObject::get_by_id(Subsite::class, $subsiteToId);
|
||||||
|
if (!$subsiteTo) {
|
||||||
|
throw new InvalidArgumentException('Subsite not found');
|
||||||
|
}
|
||||||
|
|
||||||
$useVirtualPages = (bool)$request->getVar('virtual');
|
$useVirtualPages = (bool)$request->getVar('virtual');
|
||||||
|
|
||||||
Subsite::changeSubsite($subsiteFrom);
|
Subsite::changeSubsite($subsiteFrom);
|
||||||
|
|
||||||
// Copy data from this template to the given subsite. Does this using an iterative depth-first search.
|
// Copy data from this template to the given subsite. Does this using an iterative depth-first search.
|
||||||
// This will make sure that the new parents on the new subsite are correct, and there are no funny
|
// This will make sure that the new parents on the new subsite are correct, and there are no funny
|
||||||
// issues with having to check whether or not the new parents have been added to the site tree
|
// issues with having to check whether or not the new parents have been added to the site tree
|
||||||
// when a page, etc, is duplicated
|
// when a page, etc, is duplicated
|
||||||
$stack = array(array(0,0));
|
$stack = [[0, 0]];
|
||||||
while(count($stack) > 0) {
|
while (count($stack) > 0) {
|
||||||
list($sourceParentID, $destParentID) = array_pop($stack);
|
list($sourceParentID, $destParentID) = array_pop($stack);
|
||||||
|
|
||||||
$children = Versioned::get_by_stage('SilverStripe\\CMS\\Model\\SiteTree', 'Live', "\"ParentID\" = $sourceParentID", '');
|
$children = Versioned::get_by_stage('SilverStripe\\CMS\\Model\\SiteTree', 'Live',
|
||||||
|
"\"ParentID\" = $sourceParentID", '');
|
||||||
|
|
||||||
if($children) {
|
if ($children) {
|
||||||
foreach($children as $child) {
|
foreach ($children as $child) {
|
||||||
if($useVirtualPages) {
|
if ($useVirtualPages) {
|
||||||
$childClone = new SubsitesVirtualPage();
|
$childClone = new SubsitesVirtualPage();
|
||||||
$childClone->writeToStage('Stage');
|
$childClone->writeToStage('Stage');
|
||||||
$childClone->CopyContentFromID = $child->ID;
|
$childClone->CopyContentFromID = $child->ID;
|
||||||
$childClone->SubsiteID = $subsiteTo->ID;
|
$childClone->SubsiteID = $subsiteTo->ID;
|
||||||
} else {
|
} else {
|
||||||
$childClone = $child->duplicateToSubsite($subsiteTo->ID, true);
|
$childClone = $child->duplicateToSubsite($subsiteTo->ID, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
$childClone->ParentID = $destParentID;
|
$childClone->ParentID = $destParentID;
|
||||||
$childClone->writeToStage('Stage');
|
$childClone->writeToStage('Stage');
|
||||||
$childClone->publish('Stage', 'Live');
|
$childClone->publish('Stage', 'Live');
|
||||||
array_push($stack, array($child->ID, $childClone->ID));
|
array_push($stack, [$child->ID, $childClone->ID]);
|
||||||
|
|
||||||
$this->log(sprintf('Copied "%s" (#%d, %s)', $child->Title, $child->ID, $child->Link()));
|
$this->log(sprintf('Copied "%s" (#%d, %s)', $child->Title, $child->ID, $child->Link()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unset($children);
|
unset($children);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function log($msg) {
|
function log($msg)
|
||||||
echo $msg . "\n";
|
{
|
||||||
}
|
echo $msg . "\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,30 +3,34 @@
|
|||||||
use SilverStripe\Dev\SapphireTest;
|
use SilverStripe\Dev\SapphireTest;
|
||||||
use SilverStripe\Subsites\Model\Subsite;
|
use SilverStripe\Subsites\Model\Subsite;
|
||||||
|
|
||||||
class BaseSubsiteTest extends SapphireTest {
|
class BaseSubsiteTest extends SapphireTest
|
||||||
|
{
|
||||||
|
|
||||||
function setUp() {
|
function setUp()
|
||||||
parent::setUp();
|
{
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
Subsite::$use_session_subsiteid = true;
|
Subsite::$use_session_subsiteid = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Avoid subsites filtering on fixture fetching.
|
* Avoid subsites filtering on fixture fetching.
|
||||||
*/
|
*/
|
||||||
function objFromFixture($class, $id) {
|
function objFromFixture($class, $id)
|
||||||
Subsite::disable_subsite_filter(true);
|
{
|
||||||
$obj = parent::objFromFixture($class, $id);
|
Subsite::disable_subsite_filter(true);
|
||||||
Subsite::disable_subsite_filter(false);
|
$obj = parent::objFromFixture($class, $id);
|
||||||
|
Subsite::disable_subsite_filter(false);
|
||||||
|
|
||||||
return $obj;
|
return $obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests the initial state of disable_subsite_filter
|
* Tests the initial state of disable_subsite_filter
|
||||||
*/
|
*/
|
||||||
function testDisableSubsiteFilter() {
|
function testDisableSubsiteFilter()
|
||||||
$this->assertFalse(Subsite::$disable_subsite_filter);
|
{
|
||||||
}
|
$this->assertFalse(Subsite::$disable_subsite_filter);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,83 +1,87 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use SilverStripe\Assets\File;
|
use SilverStripe\Assets\File;
|
||||||
use SilverStripe\Forms\FieldList;
|
|
||||||
use SilverStripe\Assets\Folder;
|
use SilverStripe\Assets\Folder;
|
||||||
|
use SilverStripe\Forms\FieldList;
|
||||||
use SilverStripe\Subsites\Extensions\FileSubsites;
|
use SilverStripe\Subsites\Extensions\FileSubsites;
|
||||||
use SilverStripe\Subsites\Model\Subsite;
|
use SilverStripe\Subsites\Model\Subsite;
|
||||||
|
|
||||||
|
|
||||||
class FileSubsitesTest extends BaseSubsiteTest {
|
class FileSubsitesTest extends BaseSubsiteTest
|
||||||
static $fixture_file = 'subsites/tests/SubsiteTest.yml';
|
{
|
||||||
|
static $fixture_file = 'subsites/tests/SubsiteTest.yml';
|
||||||
|
|
||||||
function testTrivialFeatures() {
|
function testTrivialFeatures()
|
||||||
$this->assertTrue(is_array(singleton(FileSubsites::class)->extraStatics()));
|
{
|
||||||
$file = new File();
|
$this->assertTrue(is_array(singleton(FileSubsites::class)->extraStatics()));
|
||||||
$file->Name = 'FileTitle';
|
$file = new File();
|
||||||
$file->Title = 'FileTitle';
|
$file->Name = 'FileTitle';
|
||||||
$this->assertEquals(' * FileTitle', $file->alternateTreeTitle());
|
$file->Title = 'FileTitle';
|
||||||
$file->SubsiteID = $this->objFromFixture(Subsite::class, 'domaintest1')->ID;
|
$this->assertEquals(' * FileTitle', $file->alternateTreeTitle());
|
||||||
$this->assertEquals('FileTitle', $file->getTreeTitle());
|
$file->SubsiteID = $this->objFromFixture(Subsite::class, 'domaintest1')->ID;
|
||||||
$this->assertTrue(singleton('SilverStripe\\Assets\\Folder')->getCMSFields() instanceof FieldList);
|
$this->assertEquals('FileTitle', $file->getTreeTitle());
|
||||||
Subsite::changeSubsite(1);
|
$this->assertTrue(singleton('SilverStripe\\Assets\\Folder')->getCMSFields() instanceof FieldList);
|
||||||
$this->assertEquals($file->cacheKeyComponent(), 'subsite-1');
|
Subsite::changeSubsite(1);
|
||||||
}
|
$this->assertEquals($file->cacheKeyComponent(), 'subsite-1');
|
||||||
|
}
|
||||||
|
|
||||||
function testWritingSubsiteID() {
|
function testWritingSubsiteID()
|
||||||
$this->objFromFixture('SilverStripe\\Security\\Member', 'admin')->logIn();
|
{
|
||||||
|
$this->objFromFixture('SilverStripe\\Security\\Member', 'admin')->logIn();
|
||||||
|
|
||||||
$subsite = $this->objFromFixture(Subsite::class, 'domaintest1');
|
$subsite = $this->objFromFixture(Subsite::class, 'domaintest1');
|
||||||
FileSubsites::$default_root_folders_global = true;
|
FileSubsites::$default_root_folders_global = true;
|
||||||
|
|
||||||
Subsite::changeSubsite(0);
|
Subsite::changeSubsite(0);
|
||||||
$file = new File();
|
$file = new File();
|
||||||
$file->write();
|
$file->write();
|
||||||
$file->onAfterUpload();
|
$file->onAfterUpload();
|
||||||
$this->assertEquals((int)$file->SubsiteID, 0);
|
$this->assertEquals((int)$file->SubsiteID, 0);
|
||||||
|
|
||||||
Subsite::changeSubsite($subsite->ID);
|
Subsite::changeSubsite($subsite->ID);
|
||||||
$this->assertTrue($file->canEdit());
|
$this->assertTrue($file->canEdit());
|
||||||
|
|
||||||
$file = new File();
|
$file = new File();
|
||||||
$file->write();
|
$file->write();
|
||||||
$this->assertEquals((int)$file->SubsiteID, 0);
|
$this->assertEquals((int)$file->SubsiteID, 0);
|
||||||
$this->assertTrue($file->canEdit());
|
$this->assertTrue($file->canEdit());
|
||||||
|
|
||||||
FileSubsites::$default_root_folders_global = false;
|
FileSubsites::$default_root_folders_global = false;
|
||||||
|
|
||||||
Subsite::changeSubsite($subsite->ID);
|
Subsite::changeSubsite($subsite->ID);
|
||||||
$file = new File();
|
$file = new File();
|
||||||
$file->write();
|
$file->write();
|
||||||
$this->assertEquals($file->SubsiteID, $subsite->ID);
|
$this->assertEquals($file->SubsiteID, $subsite->ID);
|
||||||
|
|
||||||
// Test inheriting from parent folder
|
// Test inheriting from parent folder
|
||||||
$folder = new Folder();
|
$folder = new Folder();
|
||||||
$folder->write();
|
$folder->write();
|
||||||
$this->assertEquals($folder->SubsiteID, $subsite->ID);
|
$this->assertEquals($folder->SubsiteID, $subsite->ID);
|
||||||
FileSubsites::$default_root_folders_global = true;
|
FileSubsites::$default_root_folders_global = true;
|
||||||
$file = new File();
|
$file = new File();
|
||||||
$file->ParentID = $folder->ID;
|
$file->ParentID = $folder->ID;
|
||||||
$file->onAfterUpload();
|
$file->onAfterUpload();
|
||||||
$this->assertEquals($folder->SubsiteID, $file->SubsiteID);
|
$this->assertEquals($folder->SubsiteID, $file->SubsiteID);
|
||||||
}
|
}
|
||||||
|
|
||||||
function testSubsitesFolderDropdown() {
|
function testSubsitesFolderDropdown()
|
||||||
$this->objFromFixture('SilverStripe\\Security\\Member', 'admin')->logIn();
|
{
|
||||||
|
$this->objFromFixture('SilverStripe\\Security\\Member', 'admin')->logIn();
|
||||||
|
|
||||||
$file = new Folder();
|
$file = new Folder();
|
||||||
|
|
||||||
$source = array_values($file->getCMSFields()->dataFieldByName('SubsiteID')->getSource());
|
$source = array_values($file->getCMSFields()->dataFieldByName('SubsiteID')->getSource());
|
||||||
asort($source);
|
asort($source);
|
||||||
|
|
||||||
$this->assertEquals(array(
|
$this->assertEquals([
|
||||||
'Main site',
|
'Main site',
|
||||||
'Template',
|
'Template',
|
||||||
'Subsite1 Template',
|
'Subsite1 Template',
|
||||||
'Subsite2 Template',
|
'Subsite2 Template',
|
||||||
'Test 1',
|
'Test 1',
|
||||||
'Test 2',
|
'Test 2',
|
||||||
'Test 3'
|
'Test 3'
|
||||||
), $source);
|
], $source);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -6,26 +6,29 @@ use SilverStripe\Subsites\Extensions\GroupSubsites;
|
|||||||
use SilverStripe\Subsites\Model\Subsite;
|
use SilverStripe\Subsites\Model\Subsite;
|
||||||
|
|
||||||
|
|
||||||
class GroupSubsitesTest extends BaseSubsiteTest {
|
class GroupSubsitesTest extends BaseSubsiteTest
|
||||||
static $fixture_file = 'subsites/tests/SubsiteTest.yml';
|
{
|
||||||
|
static $fixture_file = 'subsites/tests/SubsiteTest.yml';
|
||||||
|
|
||||||
protected $requireDefaultRecordsFrom = array(GroupSubsites::class);
|
protected $requireDefaultRecordsFrom = [GroupSubsites::class];
|
||||||
|
|
||||||
function testTrivialFeatures() {
|
function testTrivialFeatures()
|
||||||
$this->assertTrue(is_array(singleton(GroupSubsites::class)->extraStatics()));
|
{
|
||||||
$this->assertTrue(is_array(singleton(GroupSubsites::class)->providePermissions()));
|
$this->assertTrue(is_array(singleton(GroupSubsites::class)->extraStatics()));
|
||||||
$this->assertTrue(singleton('SilverStripe\\Security\\Group')->getCMSFields() instanceof FieldList);
|
$this->assertTrue(is_array(singleton(GroupSubsites::class)->providePermissions()));
|
||||||
}
|
$this->assertTrue(singleton('SilverStripe\\Security\\Group')->getCMSFields() instanceof FieldList);
|
||||||
|
}
|
||||||
|
|
||||||
function testAlternateTreeTitle() {
|
function testAlternateTreeTitle()
|
||||||
$group = new Group();
|
{
|
||||||
$group->Title = 'The A Team';
|
$group = new Group();
|
||||||
$group->AccessAllSubsites = true;
|
$group->Title = 'The A Team';
|
||||||
$this->assertEquals($group->getTreeTitle(), 'The A Team <i>(global group)</i>');
|
$group->AccessAllSubsites = true;
|
||||||
$group->AccessAllSubsites = false;
|
$this->assertEquals($group->getTreeTitle(), 'The A Team <i>(global group)</i>');
|
||||||
$group->write();
|
$group->AccessAllSubsites = false;
|
||||||
$group->Subsites()->add($this->objFromFixture(Subsite::class, 'domaintest1'));
|
$group->write();
|
||||||
$group->Subsites()->add($this->objFromFixture(Subsite::class, 'domaintest2'));
|
$group->Subsites()->add($this->objFromFixture(Subsite::class, 'domaintest1'));
|
||||||
$this->assertEquals($group->getTreeTitle(), 'The A Team <i>(Test 1, Test 2)</i>');
|
$group->Subsites()->add($this->objFromFixture(Subsite::class, 'domaintest2'));
|
||||||
}
|
$this->assertEquals($group->getTreeTitle(), 'The A Team <i>(Test 1, Test 2)</i>');
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,95 +1,102 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use SilverStripe\Admin\LeftAndMain;
|
use SilverStripe\Admin\LeftAndMain;
|
||||||
|
use SilverStripe\AssetAdmin\Controller\AssetAdmin;
|
||||||
use SilverStripe\Core\Config\Config;
|
use SilverStripe\Core\Config\Config;
|
||||||
use SilverStripe\Dev\FunctionalTest;
|
use SilverStripe\Dev\FunctionalTest;
|
||||||
use SilverStripe\Subsites\Model\Subsite;
|
use SilverStripe\Subsites\Model\Subsite;
|
||||||
use SilverStripe\AssetAdmin\Controller\AssetAdmin;
|
|
||||||
|
|
||||||
|
|
||||||
class LeftAndMainSubsitesTest extends FunctionalTest {
|
class LeftAndMainSubsitesTest extends FunctionalTest
|
||||||
|
{
|
||||||
|
|
||||||
static $fixture_file = 'subsites/tests/SubsiteTest.yml';
|
static $fixture_file = 'subsites/tests/SubsiteTest.yml';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Avoid subsites filtering on fixture fetching.
|
* Avoid subsites filtering on fixture fetching.
|
||||||
*/
|
*/
|
||||||
function objFromFixture($class, $id) {
|
function objFromFixture($class, $id)
|
||||||
Subsite::disable_subsite_filter(true);
|
{
|
||||||
$obj = parent::objFromFixture($class, $id);
|
Subsite::disable_subsite_filter(true);
|
||||||
Subsite::disable_subsite_filter(false);
|
$obj = parent::objFromFixture($class, $id);
|
||||||
|
Subsite::disable_subsite_filter(false);
|
||||||
|
|
||||||
return $obj;
|
return $obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
function testSectionSites() {
|
function testSectionSites()
|
||||||
$member = $this->objFromFixture('SilverStripe\\Security\\Member', 'subsite1member');
|
{
|
||||||
|
$member = $this->objFromFixture('SilverStripe\\Security\\Member', 'subsite1member');
|
||||||
|
|
||||||
$cmsmain = singleton('SilverStripe\\CMS\\Controllers\\CMSMain');
|
$cmsmain = singleton('SilverStripe\\CMS\\Controllers\\CMSMain');
|
||||||
$subsites = $cmsmain->sectionSites(true, "Main site", $member);
|
$subsites = $cmsmain->sectionSites(true, "Main site", $member);
|
||||||
$this->assertDOSEquals(array(
|
$this->assertDOSEquals([
|
||||||
array('Title' =>'Subsite1 Template')
|
['Title' => 'Subsite1 Template']
|
||||||
), $subsites, 'Lists member-accessible sites for the accessible controller.');
|
], $subsites, 'Lists member-accessible sites for the accessible controller.');
|
||||||
|
|
||||||
$assetadmin = singleton(AssetAdmin::class);
|
$assetadmin = singleton(AssetAdmin::class);
|
||||||
$subsites = $assetadmin->sectionSites(true, "Main site", $member);
|
$subsites = $assetadmin->sectionSites(true, "Main site", $member);
|
||||||
$this->assertDOSEquals(array(), $subsites, 'Does not list any sites for forbidden controller.');
|
$this->assertDOSEquals([], $subsites, 'Does not list any sites for forbidden controller.');
|
||||||
|
|
||||||
$member = $this->objFromFixture('SilverStripe\\Security\\Member', 'editor');
|
$member = $this->objFromFixture('SilverStripe\\Security\\Member', 'editor');
|
||||||
|
|
||||||
$cmsmain = singleton('SilverStripe\\CMS\\Controllers\\CMSMain');
|
$cmsmain = singleton('SilverStripe\\CMS\\Controllers\\CMSMain');
|
||||||
$subsites = $cmsmain->sectionSites(true, "Main site", $member);
|
$subsites = $cmsmain->sectionSites(true, "Main site", $member);
|
||||||
$this->assertDOSContains(array(
|
$this->assertDOSContains([
|
||||||
array('Title' =>'Main site')
|
['Title' => 'Main site']
|
||||||
), $subsites, 'Includes the main site for members who can access all sites.');
|
], $subsites, 'Includes the main site for members who can access all sites.');
|
||||||
}
|
}
|
||||||
|
|
||||||
function testAccessChecksDontChangeCurrentSubsite() {
|
function testAccessChecksDontChangeCurrentSubsite()
|
||||||
$admin = $this->objFromFixture("SilverStripe\\Security\\Member","admin");
|
{
|
||||||
$this->loginAs($admin);
|
$admin = $this->objFromFixture("SilverStripe\\Security\\Member", "admin");
|
||||||
$ids = array();
|
$this->loginAs($admin);
|
||||||
|
$ids = [];
|
||||||
|
|
||||||
$subsite1 = $this->objFromFixture(Subsite::class, 'domaintest1');
|
$subsite1 = $this->objFromFixture(Subsite::class, 'domaintest1');
|
||||||
$subsite2 = $this->objFromFixture(Subsite::class, 'domaintest2');
|
$subsite2 = $this->objFromFixture(Subsite::class, 'domaintest2');
|
||||||
$subsite3 = $this->objFromFixture(Subsite::class, 'domaintest3');
|
$subsite3 = $this->objFromFixture(Subsite::class, 'domaintest3');
|
||||||
|
|
||||||
$ids[] = $subsite1->ID;
|
$ids[] = $subsite1->ID;
|
||||||
$ids[] = $subsite2->ID;
|
$ids[] = $subsite2->ID;
|
||||||
$ids[] = $subsite3->ID;
|
$ids[] = $subsite3->ID;
|
||||||
$ids[] = 0;
|
$ids[] = 0;
|
||||||
|
|
||||||
// Enable session-based subsite tracking.
|
// Enable session-based subsite tracking.
|
||||||
Subsite::$use_session_subsiteid = true;
|
Subsite::$use_session_subsiteid = true;
|
||||||
|
|
||||||
foreach($ids as $id) {
|
foreach ($ids as $id) {
|
||||||
Subsite::changeSubsite($id);
|
Subsite::changeSubsite($id);
|
||||||
$this->assertEquals($id, Subsite::currentSubsiteID());
|
$this->assertEquals($id, Subsite::currentSubsiteID());
|
||||||
|
|
||||||
$left = new LeftAndMain();
|
$left = new LeftAndMain();
|
||||||
$this->assertTrue($left->canView(), "Admin user can view subsites LeftAndMain with id = '$id'");
|
$this->assertTrue($left->canView(), "Admin user can view subsites LeftAndMain with id = '$id'");
|
||||||
$this->assertEquals($id, Subsite::currentSubsiteID(),
|
$this->assertEquals($id, Subsite::currentSubsiteID(),
|
||||||
"The current subsite has not been changed in the process of checking permissions for admin user.");
|
"The current subsite has not been changed in the process of checking permissions for admin user.");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function testShouldChangeSubsite() {
|
function testShouldChangeSubsite()
|
||||||
$l = new LeftAndMain();
|
{
|
||||||
Config::inst()->nest();
|
$l = new LeftAndMain();
|
||||||
|
Config::inst()->nest();
|
||||||
|
|
||||||
Config::modify()->set('SilverStripe\\CMS\\Controllers\\CMSPageEditController', 'treats_subsite_0_as_global', false);
|
Config::modify()->set('SilverStripe\\CMS\\Controllers\\CMSPageEditController', 'treats_subsite_0_as_global',
|
||||||
$this->assertTrue($l->shouldChangeSubsite('SilverStripe\\CMS\\Controllers\\CMSPageEditController', 0, 5));
|
false);
|
||||||
$this->assertFalse($l->shouldChangeSubsite('SilverStripe\\CMS\\Controllers\\CMSPageEditController', 0, 0));
|
$this->assertTrue($l->shouldChangeSubsite('SilverStripe\\CMS\\Controllers\\CMSPageEditController', 0, 5));
|
||||||
$this->assertTrue($l->shouldChangeSubsite('SilverStripe\\CMS\\Controllers\\CMSPageEditController', 1, 5));
|
$this->assertFalse($l->shouldChangeSubsite('SilverStripe\\CMS\\Controllers\\CMSPageEditController', 0, 0));
|
||||||
$this->assertFalse($l->shouldChangeSubsite('SilverStripe\\CMS\\Controllers\\CMSPageEditController', 1, 1));
|
$this->assertTrue($l->shouldChangeSubsite('SilverStripe\\CMS\\Controllers\\CMSPageEditController', 1, 5));
|
||||||
|
$this->assertFalse($l->shouldChangeSubsite('SilverStripe\\CMS\\Controllers\\CMSPageEditController', 1, 1));
|
||||||
|
|
||||||
Config::modify()->set('SilverStripe\\CMS\\Controllers\\CMSPageEditController', 'treats_subsite_0_as_global', true);
|
Config::modify()->set('SilverStripe\\CMS\\Controllers\\CMSPageEditController', 'treats_subsite_0_as_global',
|
||||||
$this->assertFalse($l->shouldChangeSubsite('SilverStripe\\CMS\\Controllers\\CMSPageEditController', 0, 5));
|
true);
|
||||||
$this->assertFalse($l->shouldChangeSubsite('SilverStripe\\CMS\\Controllers\\CMSPageEditController', 0, 0));
|
$this->assertFalse($l->shouldChangeSubsite('SilverStripe\\CMS\\Controllers\\CMSPageEditController', 0, 5));
|
||||||
$this->assertTrue($l->shouldChangeSubsite('SilverStripe\\CMS\\Controllers\\CMSPageEditController', 1, 5));
|
$this->assertFalse($l->shouldChangeSubsite('SilverStripe\\CMS\\Controllers\\CMSPageEditController', 0, 0));
|
||||||
$this->assertFalse($l->shouldChangeSubsite('SilverStripe\\CMS\\Controllers\\CMSPageEditController', 1, 1));
|
$this->assertTrue($l->shouldChangeSubsite('SilverStripe\\CMS\\Controllers\\CMSPageEditController', 1, 5));
|
||||||
|
$this->assertFalse($l->shouldChangeSubsite('SilverStripe\\CMS\\Controllers\\CMSPageEditController', 1, 1));
|
||||||
|
|
||||||
Config::inst()->unnest();
|
Config::inst()->unnest();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,43 +1,45 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use SilverStripe\SiteConfig\SiteConfig;
|
use SilverStripe\SiteConfig\SiteConfig;
|
||||||
use SilverStripe\Subsites\Model\Subsite;
|
|
||||||
use SilverStripe\Subsites\Extensions\SiteConfigSubsites;
|
use SilverStripe\Subsites\Extensions\SiteConfigSubsites;
|
||||||
|
use SilverStripe\Subsites\Model\Subsite;
|
||||||
|
|
||||||
|
|
||||||
class SiteConfigSubsitesTest extends BaseSubsiteTest {
|
class SiteConfigSubsitesTest extends BaseSubsiteTest
|
||||||
static $fixture_file = 'subsites/tests/SubsiteTest.yml';
|
{
|
||||||
|
static $fixture_file = 'subsites/tests/SubsiteTest.yml';
|
||||||
|
|
||||||
function testEachSubsiteHasAUniqueSiteConfig() {
|
function testEachSubsiteHasAUniqueSiteConfig()
|
||||||
$subsite1 = $this->objFromFixture(Subsite::class, 'domaintest1');
|
{
|
||||||
$subsite2 = $this->objFromFixture(Subsite::class, 'domaintest2');
|
$subsite1 = $this->objFromFixture(Subsite::class, 'domaintest1');
|
||||||
|
$subsite2 = $this->objFromFixture(Subsite::class, 'domaintest2');
|
||||||
|
|
||||||
$this->assertTrue(is_array(singleton(SiteConfigSubsites::class)->extraStatics()));
|
$this->assertTrue(is_array(singleton(SiteConfigSubsites::class)->extraStatics()));
|
||||||
|
|
||||||
Subsite::changeSubsite(0);
|
Subsite::changeSubsite(0);
|
||||||
$sc = SiteConfig::current_site_config();
|
$sc = SiteConfig::current_site_config();
|
||||||
$sc->Title = 'RootSite';
|
$sc->Title = 'RootSite';
|
||||||
$sc->write();
|
$sc->write();
|
||||||
|
|
||||||
Subsite::changeSubsite($subsite1->ID);
|
Subsite::changeSubsite($subsite1->ID);
|
||||||
$sc = SiteConfig::current_site_config();
|
$sc = SiteConfig::current_site_config();
|
||||||
$sc->Title = 'Subsite1';
|
$sc->Title = 'Subsite1';
|
||||||
$sc->write();
|
$sc->write();
|
||||||
|
|
||||||
Subsite::changeSubsite($subsite2->ID);
|
Subsite::changeSubsite($subsite2->ID);
|
||||||
$sc = SiteConfig::current_site_config();
|
$sc = SiteConfig::current_site_config();
|
||||||
$sc->Title = 'Subsite2';
|
$sc->Title = 'Subsite2';
|
||||||
$sc->write();
|
$sc->write();
|
||||||
|
|
||||||
Subsite::changeSubsite(0);
|
Subsite::changeSubsite(0);
|
||||||
$this->assertEquals(SiteConfig::current_site_config()->Title, 'RootSite');
|
$this->assertEquals(SiteConfig::current_site_config()->Title, 'RootSite');
|
||||||
Subsite::changeSubsite($subsite1->ID);
|
Subsite::changeSubsite($subsite1->ID);
|
||||||
$this->assertEquals(SiteConfig::current_site_config()->Title, 'Subsite1');
|
$this->assertEquals(SiteConfig::current_site_config()->Title, 'Subsite1');
|
||||||
Subsite::changeSubsite($subsite2->ID);
|
Subsite::changeSubsite($subsite2->ID);
|
||||||
$this->assertEquals(SiteConfig::current_site_config()->Title, 'Subsite2');
|
$this->assertEquals(SiteConfig::current_site_config()->Title, 'Subsite2');
|
||||||
|
|
||||||
$keys = SiteConfig::current_site_config()->extend('cacheKeyComponent');
|
$keys = SiteConfig::current_site_config()->extend('cacheKeyComponent');
|
||||||
$this->assertContains('subsite-' . $subsite2->ID, $keys);
|
$this->assertContains('subsite-' . $subsite2->ID, $keys);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,229 +1,243 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use SilverStripe\CMS\Model\SiteTree;
|
|
||||||
use SilverStripe\SiteConfig\SiteConfig;
|
|
||||||
use SilverStripe\Forms\FieldList;
|
|
||||||
use SilverStripe\Control\Session;
|
|
||||||
use SilverStripe\CMS\Controllers\CMSMain;
|
use SilverStripe\CMS\Controllers\CMSMain;
|
||||||
|
use SilverStripe\CMS\Model\ErrorPage;
|
||||||
|
use SilverStripe\CMS\Model\SiteTree;
|
||||||
|
use SilverStripe\Control\Session;
|
||||||
use SilverStripe\Core\Convert;
|
use SilverStripe\Core\Convert;
|
||||||
use SilverStripe\Dev\TestOnly;
|
use SilverStripe\Dev\TestOnly;
|
||||||
use SilverStripe\CMS\Model\ErrorPage;
|
use SilverStripe\Forms\FieldList;
|
||||||
|
use SilverStripe\SiteConfig\SiteConfig;
|
||||||
|
use SilverStripe\Subsites\Extensions\SiteTreeSubsites;
|
||||||
use SilverStripe\Subsites\Model\Subsite;
|
use SilverStripe\Subsites\Model\Subsite;
|
||||||
use SilverStripe\Subsites\Pages\SubsitesVirtualPage;
|
use SilverStripe\Subsites\Pages\SubsitesVirtualPage;
|
||||||
use SilverStripe\Subsites\Extensions\SiteTreeSubsites;
|
|
||||||
|
|
||||||
|
|
||||||
class SiteTreeSubsitesTest extends BaseSubsiteTest {
|
class SiteTreeSubsitesTest extends BaseSubsiteTest
|
||||||
|
{
|
||||||
|
|
||||||
static $fixture_file = 'subsites/tests/SubsiteTest.yml';
|
static $fixture_file = 'subsites/tests/SubsiteTest.yml';
|
||||||
|
|
||||||
protected $extraDataObjects = array(
|
protected $extraDataObjects = [
|
||||||
'SiteTreeSubsitesTest_ClassA',
|
'SiteTreeSubsitesTest_ClassA',
|
||||||
'SiteTreeSubsitesTest_ClassB',
|
'SiteTreeSubsitesTest_ClassB',
|
||||||
'SiteTreeSubsitesTest_ErrorPage'
|
'SiteTreeSubsitesTest_ErrorPage'
|
||||||
);
|
];
|
||||||
|
|
||||||
protected $illegalExtensions = array(
|
protected $illegalExtensions = [
|
||||||
'SilverStripe\CMS\Model\SiteTree' => array('Translatable')
|
'SilverStripe\CMS\Model\SiteTree' => ['Translatable']
|
||||||
);
|
];
|
||||||
|
|
||||||
function testPagesInDifferentSubsitesCanShareURLSegment() {
|
function testPagesInDifferentSubsitesCanShareURLSegment()
|
||||||
$subsiteMain = $this->objFromFixture(Subsite::class, 'main');
|
{
|
||||||
$subsite1 = $this->objFromFixture(Subsite::class, 'subsite1');
|
$subsiteMain = $this->objFromFixture(Subsite::class, 'main');
|
||||||
|
$subsite1 = $this->objFromFixture(Subsite::class, 'subsite1');
|
||||||
|
|
||||||
$pageMain = new SiteTree();
|
$pageMain = new SiteTree();
|
||||||
$pageMain->URLSegment = 'testpage';
|
$pageMain->URLSegment = 'testpage';
|
||||||
$pageMain->write();
|
$pageMain->write();
|
||||||
$pageMain->publish('Stage', 'Live');
|
$pageMain->publish('Stage', 'Live');
|
||||||
|
|
||||||
$pageMainOther = new SiteTree();
|
$pageMainOther = new SiteTree();
|
||||||
$pageMainOther->URLSegment = 'testpage';
|
$pageMainOther->URLSegment = 'testpage';
|
||||||
$pageMainOther->write();
|
$pageMainOther->write();
|
||||||
$pageMainOther->publish('Stage', 'Live');
|
$pageMainOther->publish('Stage', 'Live');
|
||||||
|
|
||||||
$this->assertNotEquals($pageMain->URLSegment, $pageMainOther->URLSegment,
|
$this->assertNotEquals($pageMain->URLSegment, $pageMainOther->URLSegment,
|
||||||
'Pages in same subsite cant share the same URL'
|
'Pages in same subsite cant share the same URL'
|
||||||
);
|
);
|
||||||
|
|
||||||
Subsite::changeSubsite($subsite1->ID);
|
Subsite::changeSubsite($subsite1->ID);
|
||||||
|
|
||||||
$pageSubsite1 = new SiteTree();
|
$pageSubsite1 = new SiteTree();
|
||||||
$pageSubsite1->URLSegment = 'testpage';
|
$pageSubsite1->URLSegment = 'testpage';
|
||||||
$pageSubsite1->write();
|
$pageSubsite1->write();
|
||||||
$pageSubsite1->publish('Stage', 'Live');
|
$pageSubsite1->publish('Stage', 'Live');
|
||||||
|
|
||||||
$this->assertEquals($pageMain->URLSegment, $pageSubsite1->URLSegment,
|
$this->assertEquals($pageMain->URLSegment, $pageSubsite1->URLSegment,
|
||||||
'Pages in different subsites can share the same URL'
|
'Pages in different subsites can share the same URL'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function testBasicSanity() {
|
function testBasicSanity()
|
||||||
$this->assertTrue(singleton('SilverStripe\\CMS\\Model\\SiteTree')->getSiteConfig() instanceof SiteConfig);
|
{
|
||||||
// The following assert is breaking in Translatable.
|
$this->assertTrue(singleton('SilverStripe\\CMS\\Model\\SiteTree')->getSiteConfig() instanceof SiteConfig);
|
||||||
$this->assertTrue(singleton('SilverStripe\\CMS\\Model\\SiteTree')->getCMSFields() instanceof FieldList);
|
// The following assert is breaking in Translatable.
|
||||||
$this->assertTrue(singleton(SubsitesVirtualPage::class)->getCMSFields() instanceof FieldList);
|
$this->assertTrue(singleton('SilverStripe\\CMS\\Model\\SiteTree')->getCMSFields() instanceof FieldList);
|
||||||
$this->assertTrue(is_array(singleton(SiteTreeSubsites::class)->extraStatics()));
|
$this->assertTrue(singleton(SubsitesVirtualPage::class)->getCMSFields() instanceof FieldList);
|
||||||
}
|
$this->assertTrue(is_array(singleton(SiteTreeSubsites::class)->extraStatics()));
|
||||||
|
}
|
||||||
|
|
||||||
function testErrorPageLocations() {
|
function testErrorPageLocations()
|
||||||
$subsite1 = $this->objFromFixture(Subsite::class, 'domaintest1');
|
{
|
||||||
|
$subsite1 = $this->objFromFixture(Subsite::class, 'domaintest1');
|
||||||
|
|
||||||
Subsite::changeSubsite($subsite1->ID);
|
Subsite::changeSubsite($subsite1->ID);
|
||||||
$path = SiteTreeSubsitesTest_ErrorPage::get_error_filename_spy(500);
|
$path = SiteTreeSubsitesTest_ErrorPage::get_error_filename_spy(500);
|
||||||
|
|
||||||
$expected_path = 'error-500-'.$subsite1->domain().'.html';
|
$expected_path = 'error-500-' . $subsite1->domain() . '.html';
|
||||||
$this->assertEquals($expected_path, $path);
|
$this->assertEquals($expected_path, $path);
|
||||||
}
|
}
|
||||||
|
|
||||||
function testCanEditSiteTree() {
|
function testCanEditSiteTree()
|
||||||
$admin = $this->objFromFixture('SilverStripe\\Security\\Member', 'admin');
|
{
|
||||||
$subsite1member = $this->objFromFixture('SilverStripe\\Security\\Member', 'subsite1member');
|
$admin = $this->objFromFixture('SilverStripe\\Security\\Member', 'admin');
|
||||||
$subsite2member = $this->objFromFixture('SilverStripe\\Security\\Member', 'subsite2member');
|
$subsite1member = $this->objFromFixture('SilverStripe\\Security\\Member', 'subsite1member');
|
||||||
$mainpage = $this->objFromFixture('Page', 'home');
|
$subsite2member = $this->objFromFixture('SilverStripe\\Security\\Member', 'subsite2member');
|
||||||
$subsite1page = $this->objFromFixture('Page', 'subsite1_home');
|
$mainpage = $this->objFromFixture('Page', 'home');
|
||||||
$subsite2page = $this->objFromFixture('Page', 'subsite2_home');
|
$subsite1page = $this->objFromFixture('Page', 'subsite1_home');
|
||||||
$subsite1 = $this->objFromFixture(Subsite::class, 'subsite1');
|
$subsite2page = $this->objFromFixture('Page', 'subsite2_home');
|
||||||
$subsite2 = $this->objFromFixture(Subsite::class, 'subsite2');
|
$subsite1 = $this->objFromFixture(Subsite::class, 'subsite1');
|
||||||
|
$subsite2 = $this->objFromFixture(Subsite::class, 'subsite2');
|
||||||
|
|
||||||
// Cant pass member as arguments to canEdit() because of GroupSubsites
|
// Cant pass member as arguments to canEdit() because of GroupSubsites
|
||||||
Session::set("loggedInAs", $admin->ID);
|
Session::set("loggedInAs", $admin->ID);
|
||||||
$this->assertTrue(
|
$this->assertTrue(
|
||||||
(bool)$subsite1page->canEdit(),
|
(bool)$subsite1page->canEdit(),
|
||||||
'Administrators can edit all subsites'
|
'Administrators can edit all subsites'
|
||||||
);
|
);
|
||||||
|
|
||||||
// @todo: Workaround because GroupSubsites->augmentSQL() is relying on session state
|
// @todo: Workaround because GroupSubsites->augmentSQL() is relying on session state
|
||||||
Subsite::changeSubsite($subsite1);
|
Subsite::changeSubsite($subsite1);
|
||||||
|
|
||||||
Session::set("loggedInAs", $subsite1member->ID);
|
Session::set("loggedInAs", $subsite1member->ID);
|
||||||
$this->assertTrue(
|
$this->assertTrue(
|
||||||
(bool)$subsite1page->canEdit(),
|
(bool)$subsite1page->canEdit(),
|
||||||
'Members can edit pages on a subsite if they are in a group belonging to this subsite'
|
'Members can edit pages on a subsite if they are in a group belonging to this subsite'
|
||||||
);
|
);
|
||||||
|
|
||||||
Session::set("loggedInAs", $subsite2member->ID);
|
Session::set("loggedInAs", $subsite2member->ID);
|
||||||
$this->assertFalse(
|
$this->assertFalse(
|
||||||
(bool)$subsite1page->canEdit(),
|
(bool)$subsite1page->canEdit(),
|
||||||
'Members cant edit pages on a subsite if they are not in a group belonging to this subsite'
|
'Members cant edit pages on a subsite if they are not in a group belonging to this subsite'
|
||||||
);
|
);
|
||||||
|
|
||||||
// @todo: Workaround because GroupSubsites->augmentSQL() is relying on session state
|
// @todo: Workaround because GroupSubsites->augmentSQL() is relying on session state
|
||||||
Subsite::changeSubsite(0);
|
Subsite::changeSubsite(0);
|
||||||
$this->assertFalse(
|
$this->assertFalse(
|
||||||
$mainpage->canEdit(),
|
$mainpage->canEdit(),
|
||||||
'Members cant edit pages on the main site if they are not in a group allowing this'
|
'Members cant edit pages on the main site if they are not in a group allowing this'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Similar to {@link SubsitesVirtualPageTest->testSubsiteVirtualPageCanHaveSameUrlsegmentAsOtherSubsite()}.
|
* Similar to {@link SubsitesVirtualPageTest->testSubsiteVirtualPageCanHaveSameUrlsegmentAsOtherSubsite()}.
|
||||||
*/
|
*/
|
||||||
function testTwoPagesWithSameURLOnDifferentSubsites() {
|
function testTwoPagesWithSameURLOnDifferentSubsites()
|
||||||
// Set up a couple of pages with the same URL on different subsites
|
{
|
||||||
$s1 = $this->objFromFixture(Subsite::class,'domaintest1');
|
// Set up a couple of pages with the same URL on different subsites
|
||||||
$s2 = $this->objFromFixture(Subsite::class,'domaintest2');
|
$s1 = $this->objFromFixture(Subsite::class, 'domaintest1');
|
||||||
|
$s2 = $this->objFromFixture(Subsite::class, 'domaintest2');
|
||||||
|
|
||||||
$p1 = new SiteTree();
|
$p1 = new SiteTree();
|
||||||
$p1->Title = $p1->URLSegment = "test-page";
|
$p1->Title = $p1->URLSegment = "test-page";
|
||||||
$p1->SubsiteID = $s1->ID;
|
$p1->SubsiteID = $s1->ID;
|
||||||
$p1->write();
|
$p1->write();
|
||||||
|
|
||||||
$p2 = new SiteTree();
|
$p2 = new SiteTree();
|
||||||
$p2->Title = $p1->URLSegment = "test-page";
|
$p2->Title = $p1->URLSegment = "test-page";
|
||||||
$p2->SubsiteID = $s2->ID;
|
$p2->SubsiteID = $s2->ID;
|
||||||
$p2->write();
|
$p2->write();
|
||||||
|
|
||||||
// Check that the URLs weren't modified in our set-up
|
// Check that the URLs weren't modified in our set-up
|
||||||
$this->assertEquals($p1->URLSegment, 'test-page');
|
$this->assertEquals($p1->URLSegment, 'test-page');
|
||||||
$this->assertEquals($p2->URLSegment, 'test-page');
|
$this->assertEquals($p2->URLSegment, 'test-page');
|
||||||
|
|
||||||
// Check that if we switch between the different subsites, we receive the correct pages
|
// Check that if we switch between the different subsites, we receive the correct pages
|
||||||
Subsite::changeSubsite($s1);
|
Subsite::changeSubsite($s1);
|
||||||
$this->assertEquals($p1->ID, SiteTree::get_by_link('test-page')->ID);
|
$this->assertEquals($p1->ID, SiteTree::get_by_link('test-page')->ID);
|
||||||
|
|
||||||
Subsite::changeSubsite($s2);
|
Subsite::changeSubsite($s2);
|
||||||
$this->assertEquals($p2->ID, SiteTree::get_by_link('test-page')->ID);
|
$this->assertEquals($p2->ID, SiteTree::get_by_link('test-page')->ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
function testPageTypesBlacklistInClassDropdown() {
|
function testPageTypesBlacklistInClassDropdown()
|
||||||
$editor = $this->objFromFixture('SilverStripe\\Security\\Member', 'editor');
|
{
|
||||||
Session::set("loggedInAs", $editor->ID);
|
$editor = $this->objFromFixture('SilverStripe\\Security\\Member', 'editor');
|
||||||
|
Session::set("loggedInAs", $editor->ID);
|
||||||
|
|
||||||
$s1 = $this->objFromFixture(Subsite::class,'domaintest1');
|
$s1 = $this->objFromFixture(Subsite::class, 'domaintest1');
|
||||||
$s2 = $this->objFromFixture(Subsite::class,'domaintest2');
|
$s2 = $this->objFromFixture(Subsite::class, 'domaintest2');
|
||||||
$page = singleton('SilverStripe\\CMS\\Model\\SiteTree');
|
$page = singleton('SilverStripe\\CMS\\Model\\SiteTree');
|
||||||
|
|
||||||
$s1->PageTypeBlacklist = 'SiteTreeSubsitesTest_ClassA,ErrorPage';
|
$s1->PageTypeBlacklist = 'SiteTreeSubsitesTest_ClassA,ErrorPage';
|
||||||
$s1->write();
|
$s1->write();
|
||||||
|
|
||||||
Subsite::changeSubsite($s1);
|
Subsite::changeSubsite($s1);
|
||||||
$settingsFields = $page->getSettingsFields()->dataFieldByName('ClassName')->getSource();
|
$settingsFields = $page->getSettingsFields()->dataFieldByName('ClassName')->getSource();
|
||||||
|
|
||||||
$this->assertArrayNotHasKey('SilverStripe\\CMS\\Model\\ErrorPage',
|
$this->assertArrayNotHasKey('SilverStripe\\CMS\\Model\\ErrorPage',
|
||||||
$settingsFields
|
$settingsFields
|
||||||
);
|
);
|
||||||
$this->assertArrayNotHasKey('SiteTreeSubsitesTest_ClassA',
|
$this->assertArrayNotHasKey('SiteTreeSubsitesTest_ClassA',
|
||||||
$settingsFields
|
$settingsFields
|
||||||
);
|
);
|
||||||
$this->assertArrayHasKey('SiteTreeSubsitesTest_ClassB',
|
$this->assertArrayHasKey('SiteTreeSubsitesTest_ClassB',
|
||||||
$settingsFields
|
$settingsFields
|
||||||
);
|
);
|
||||||
|
|
||||||
Subsite::changeSubsite($s2);
|
Subsite::changeSubsite($s2);
|
||||||
$settingsFields = $page->getSettingsFields()->dataFieldByName('ClassName')->getSource();
|
$settingsFields = $page->getSettingsFields()->dataFieldByName('ClassName')->getSource();
|
||||||
$this->assertArrayHasKey('SilverStripe\\CMS\\Model\\ErrorPage',
|
$this->assertArrayHasKey('SilverStripe\\CMS\\Model\\ErrorPage',
|
||||||
$settingsFields
|
$settingsFields
|
||||||
);
|
);
|
||||||
$this->assertArrayHasKey('SiteTreeSubsitesTest_ClassA',
|
$this->assertArrayHasKey('SiteTreeSubsitesTest_ClassA',
|
||||||
$settingsFields
|
$settingsFields
|
||||||
);
|
);
|
||||||
$this->assertArrayHasKey('SiteTreeSubsitesTest_ClassB',
|
$this->assertArrayHasKey('SiteTreeSubsitesTest_ClassB',
|
||||||
$settingsFields
|
$settingsFields
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function testPageTypesBlacklistInCMSMain() {
|
function testPageTypesBlacklistInCMSMain()
|
||||||
$editor = $this->objFromFixture('SilverStripe\\Security\\Member', 'editor');
|
{
|
||||||
Session::set("loggedInAs", $editor->ID);
|
$editor = $this->objFromFixture('SilverStripe\\Security\\Member', 'editor');
|
||||||
|
Session::set("loggedInAs", $editor->ID);
|
||||||
|
|
||||||
$cmsmain = new CMSMain();
|
$cmsmain = new CMSMain();
|
||||||
|
|
||||||
$s1 = $this->objFromFixture(Subsite::class,'domaintest1');
|
$s1 = $this->objFromFixture(Subsite::class, 'domaintest1');
|
||||||
$s2 = $this->objFromFixture(Subsite::class,'domaintest2');
|
$s2 = $this->objFromFixture(Subsite::class, 'domaintest2');
|
||||||
|
|
||||||
$s1->PageTypeBlacklist = 'SiteTreeSubsitesTest_ClassA,ErrorPage';
|
$s1->PageTypeBlacklist = 'SiteTreeSubsitesTest_ClassA,ErrorPage';
|
||||||
$s1->write();
|
$s1->write();
|
||||||
|
|
||||||
Subsite::changeSubsite($s1);
|
Subsite::changeSubsite($s1);
|
||||||
$hints = Convert::json2array($cmsmain->SiteTreeHints());
|
$hints = Convert::json2array($cmsmain->SiteTreeHints());
|
||||||
$classes = $hints['Root']['disallowedChildren'];
|
$classes = $hints['Root']['disallowedChildren'];
|
||||||
$this->assertContains('SilverStripe\\CMS\\Model\\ErrorPage', $classes);
|
$this->assertContains('SilverStripe\\CMS\\Model\\ErrorPage', $classes);
|
||||||
$this->assertContains('SiteTreeSubsitesTest_ClassA', $classes);
|
$this->assertContains('SiteTreeSubsitesTest_ClassA', $classes);
|
||||||
$this->assertNotContains('SiteTreeSubsitesTest_ClassB', $classes);
|
$this->assertNotContains('SiteTreeSubsitesTest_ClassB', $classes);
|
||||||
|
|
||||||
Subsite::changeSubsite($s2);
|
Subsite::changeSubsite($s2);
|
||||||
$hints = Convert::json2array($cmsmain->SiteTreeHints());
|
$hints = Convert::json2array($cmsmain->SiteTreeHints());
|
||||||
$classes = $hints['Root']['disallowedChildren'];
|
$classes = $hints['Root']['disallowedChildren'];
|
||||||
$this->assertNotContains('SilverStripe\\CMS\\Model\\ErrorPage', $classes);
|
$this->assertNotContains('SilverStripe\\CMS\\Model\\ErrorPage', $classes);
|
||||||
$this->assertNotContains('SiteTreeSubsitesTest_ClassA', $classes);
|
$this->assertNotContains('SiteTreeSubsitesTest_ClassA', $classes);
|
||||||
$this->assertNotContains('SiteTreeSubsitesTest_ClassB', $classes);
|
$this->assertNotContains('SiteTreeSubsitesTest_ClassB', $classes);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class SiteTreeSubsitesTest_ClassA extends SiteTree implements TestOnly {}
|
class SiteTreeSubsitesTest_ClassA extends SiteTree implements TestOnly
|
||||||
|
{
|
||||||
class SiteTreeSubsitesTest_ClassB extends SiteTree implements TestOnly {}
|
}
|
||||||
|
|
||||||
class SiteTreeSubsitesTest_ErrorPage extends ErrorPage implements TestOnly {
|
class SiteTreeSubsitesTest_ClassB extends SiteTree implements TestOnly
|
||||||
|
{
|
||||||
/**
|
}
|
||||||
* Helper method to call protected members
|
|
||||||
*
|
class SiteTreeSubsitesTest_ErrorPage extends ErrorPage implements TestOnly
|
||||||
* @param int $statusCode
|
{
|
||||||
* @return string
|
|
||||||
*/
|
/**
|
||||||
public static function get_error_filename_spy($statusCode) {
|
* Helper method to call protected members
|
||||||
return self::get_error_filename($statusCode);
|
*
|
||||||
}
|
* @param int $statusCode
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function get_error_filename_spy($statusCode)
|
||||||
|
{
|
||||||
|
return self::get_error_filename($statusCode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,148 +3,160 @@
|
|||||||
use SilverStripe\Control\Session;
|
use SilverStripe\Control\Session;
|
||||||
use SilverStripe\Core\Config\Config;
|
use SilverStripe\Core\Config\Config;
|
||||||
use SilverStripe\Dev\FunctionalTest;
|
use SilverStripe\Dev\FunctionalTest;
|
||||||
use SilverStripe\Subsites\Model\Subsite;
|
|
||||||
use SilverStripe\Subsites\Controller\SubsiteXHRController;
|
use SilverStripe\Subsites\Controller\SubsiteXHRController;
|
||||||
|
use SilverStripe\Subsites\Model\Subsite;
|
||||||
|
|
||||||
|
|
||||||
class SubsiteAdminFunctionalTest extends FunctionalTest {
|
class SubsiteAdminFunctionalTest extends FunctionalTest
|
||||||
static $fixture_file = 'subsites/tests/SubsiteTest.yml';
|
{
|
||||||
static $use_draft_site = true;
|
static $fixture_file = 'subsites/tests/SubsiteTest.yml';
|
||||||
|
static $use_draft_site = true;
|
||||||
|
|
||||||
protected $autoFollowRedirection = false;
|
protected $autoFollowRedirection = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper: FunctionalTest is only able to follow redirection once, we want to go all the way.
|
* Helper: FunctionalTest is only able to follow redirection once, we want to go all the way.
|
||||||
*/
|
*/
|
||||||
function getAndFollowAll($url) {
|
function getAndFollowAll($url)
|
||||||
$response = $this->get($url);
|
{
|
||||||
while ($location = $response->getHeader('Location')) {
|
$response = $this->get($url);
|
||||||
$response = $this->mainSession->followRedirection();
|
while ($location = $response->getHeader('Location')) {
|
||||||
}
|
$response = $this->mainSession->followRedirection();
|
||||||
echo $response->getHeader('Location');
|
}
|
||||||
|
echo $response->getHeader('Location');
|
||||||
|
|
||||||
return $response;
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Anonymous user cannot access anything.
|
* Anonymous user cannot access anything.
|
||||||
*/
|
*/
|
||||||
function testAnonymousIsForbiddenAdminAccess() {
|
function testAnonymousIsForbiddenAdminAccess()
|
||||||
$response = $this->getAndFollowAll('admin/pages/?SubsiteID=0');
|
{
|
||||||
$this->assertRegExp('#^Security/login.*#', $this->mainSession->lastUrl(), 'Admin is disallowed');
|
$response = $this->getAndFollowAll('admin/pages/?SubsiteID=0');
|
||||||
|
$this->assertRegExp('#^Security/login.*#', $this->mainSession->lastUrl(), 'Admin is disallowed');
|
||||||
|
|
||||||
$subsite1 = $this->objFromFixture(Subsite::class, 'subsite1');
|
$subsite1 = $this->objFromFixture(Subsite::class, 'subsite1');
|
||||||
$response = $this->getAndFollowAll("admin/pages/?SubsiteID={$subsite1->ID}");
|
$response = $this->getAndFollowAll("admin/pages/?SubsiteID={$subsite1->ID}");
|
||||||
$this->assertRegExp('#^Security/login.*#', $this->mainSession->lastUrl(), 'Admin is disallowed');
|
$this->assertRegExp('#^Security/login.*#', $this->mainSession->lastUrl(), 'Admin is disallowed');
|
||||||
|
|
||||||
$response = $this->getAndFollowAll(SubsiteXHRController::class);
|
$response = $this->getAndFollowAll(SubsiteXHRController::class);
|
||||||
$this->assertRegExp('#^Security/login.*#', $this->mainSession->lastUrl(),
|
$this->assertRegExp('#^Security/login.*#', $this->mainSession->lastUrl(),
|
||||||
'SubsiteXHRController is disallowed');
|
'SubsiteXHRController is disallowed');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Admin should be able to access all subsites and the main site
|
* Admin should be able to access all subsites and the main site
|
||||||
*/
|
*/
|
||||||
function testAdminCanAccessAllSubsites() {
|
function testAdminCanAccessAllSubsites()
|
||||||
$member = $this->objFromFixture('SilverStripe\\Security\\Member', 'admin');
|
{
|
||||||
Session::set("loggedInAs", $member->ID);
|
$member = $this->objFromFixture('SilverStripe\\Security\\Member', 'admin');
|
||||||
|
Session::set("loggedInAs", $member->ID);
|
||||||
|
|
||||||
$this->getAndFollowAll('admin/pages/?SubsiteID=0');
|
$this->getAndFollowAll('admin/pages/?SubsiteID=0');
|
||||||
$this->assertEquals(Subsite::currentSubsiteID(), '0', 'Can access main site.');
|
$this->assertEquals(Subsite::currentSubsiteID(), '0', 'Can access main site.');
|
||||||
$this->assertRegExp('#^admin/pages.*#', $this->mainSession->lastUrl(), 'Lands on the correct section');
|
$this->assertRegExp('#^admin/pages.*#', $this->mainSession->lastUrl(), 'Lands on the correct section');
|
||||||
|
|
||||||
$subsite1 = $this->objFromFixture(Subsite::class, 'subsite1');
|
$subsite1 = $this->objFromFixture(Subsite::class, 'subsite1');
|
||||||
$this->getAndFollowAll("admin/pages/?SubsiteID={$subsite1->ID}");
|
$this->getAndFollowAll("admin/pages/?SubsiteID={$subsite1->ID}");
|
||||||
$this->assertEquals(Subsite::currentSubsiteID(), $subsite1->ID, 'Can access other subsite.');
|
$this->assertEquals(Subsite::currentSubsiteID(), $subsite1->ID, 'Can access other subsite.');
|
||||||
$this->assertRegExp('#^admin/pages.*#', $this->mainSession->lastUrl(), 'Lands on the correct section');
|
$this->assertRegExp('#^admin/pages.*#', $this->mainSession->lastUrl(), 'Lands on the correct section');
|
||||||
|
|
||||||
$response = $this->getAndFollowAll(SubsiteXHRController::class);
|
$response = $this->getAndFollowAll(SubsiteXHRController::class);
|
||||||
$this->assertNotRegExp('#^Security/login.*#', $this->mainSession->lastUrl(),
|
$this->assertNotRegExp('#^Security/login.*#', $this->mainSession->lastUrl(),
|
||||||
'SubsiteXHRController is reachable');
|
'SubsiteXHRController is reachable');
|
||||||
}
|
}
|
||||||
|
|
||||||
function testAdminIsRedirectedToObjectsSubsite() {
|
function testAdminIsRedirectedToObjectsSubsite()
|
||||||
$member = $this->objFromFixture('SilverStripe\\Security\\Member', 'admin');
|
{
|
||||||
Session::set("loggedInAs", $member->ID);
|
$member = $this->objFromFixture('SilverStripe\\Security\\Member', 'admin');
|
||||||
|
Session::set("loggedInAs", $member->ID);
|
||||||
|
|
||||||
$mainSubsitePage = $this->objFromFixture('Page', 'mainSubsitePage');
|
$mainSubsitePage = $this->objFromFixture('Page', 'mainSubsitePage');
|
||||||
$subsite1Home = $this->objFromFixture('Page', 'subsite1_home');
|
$subsite1Home = $this->objFromFixture('Page', 'subsite1_home');
|
||||||
|
|
||||||
Config::inst()->nest();
|
Config::inst()->nest();
|
||||||
|
|
||||||
Config::modify()->set('SilverStripe\\CMS\\Controllers\\CMSPageEditController', 'treats_subsite_0_as_global', false);
|
Config::modify()->set('SilverStripe\\CMS\\Controllers\\CMSPageEditController', 'treats_subsite_0_as_global',
|
||||||
Subsite::changeSubsite(0);
|
false);
|
||||||
$this->getAndFollowAll("admin/pages/edit/show/$subsite1Home->ID");
|
Subsite::changeSubsite(0);
|
||||||
$this->assertEquals(Subsite::currentSubsiteID(), $subsite1Home->SubsiteID, 'Loading an object switches the subsite');
|
$this->getAndFollowAll("admin/pages/edit/show/$subsite1Home->ID");
|
||||||
$this->assertRegExp("#^admin/pages.*#", $this->mainSession->lastUrl(), 'Lands on the correct section');
|
$this->assertEquals(Subsite::currentSubsiteID(), $subsite1Home->SubsiteID,
|
||||||
|
'Loading an object switches the subsite');
|
||||||
|
$this->assertRegExp("#^admin/pages.*#", $this->mainSession->lastUrl(), 'Lands on the correct section');
|
||||||
|
|
||||||
Config::modify()->set('SilverStripe\\CMS\\Controllers\\CMSPageEditController', 'treats_subsite_0_as_global', true);
|
Config::modify()->set('SilverStripe\\CMS\\Controllers\\CMSPageEditController', 'treats_subsite_0_as_global',
|
||||||
Subsite::changeSubsite(0);
|
true);
|
||||||
$this->getAndFollowAll("admin/pages/edit/show/$subsite1Home->ID");
|
Subsite::changeSubsite(0);
|
||||||
$this->assertEquals(Subsite::currentSubsiteID(), $subsite1Home->SubsiteID, 'Loading a non-main-site object still switches the subsite if configured with treats_subsite_0_as_global');
|
$this->getAndFollowAll("admin/pages/edit/show/$subsite1Home->ID");
|
||||||
$this->assertRegExp("#^admin/pages.*#", $this->mainSession->lastUrl(), 'Lands on the correct section');
|
$this->assertEquals(Subsite::currentSubsiteID(), $subsite1Home->SubsiteID,
|
||||||
|
'Loading a non-main-site object still switches the subsite if configured with treats_subsite_0_as_global');
|
||||||
|
$this->assertRegExp("#^admin/pages.*#", $this->mainSession->lastUrl(), 'Lands on the correct section');
|
||||||
|
|
||||||
$this->getAndFollowAll("admin/pages/edit/show/$mainSubsitePage->ID");
|
$this->getAndFollowAll("admin/pages/edit/show/$mainSubsitePage->ID");
|
||||||
$this->assertNotEquals(Subsite::currentSubsiteID(), $mainSubsitePage->SubsiteID, 'Loading a main-site object does not change the subsite if configured with treats_subsite_0_as_global');
|
$this->assertNotEquals(Subsite::currentSubsiteID(), $mainSubsitePage->SubsiteID,
|
||||||
$this->assertRegExp("#^admin/pages.*#", $this->mainSession->lastUrl(), 'Lands on the correct section');
|
'Loading a main-site object does not change the subsite if configured with treats_subsite_0_as_global');
|
||||||
|
$this->assertRegExp("#^admin/pages.*#", $this->mainSession->lastUrl(), 'Lands on the correct section');
|
||||||
|
|
||||||
Config::inst()->unnest();
|
Config::inst()->unnest();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User which has AccessAllSubsites set to 1 should be able to access all subsites and main site,
|
* User which has AccessAllSubsites set to 1 should be able to access all subsites and main site,
|
||||||
* even though he does not have the ADMIN permission.
|
* even though he does not have the ADMIN permission.
|
||||||
*/
|
*/
|
||||||
function testEditorCanAccessAllSubsites() {
|
function testEditorCanAccessAllSubsites()
|
||||||
$member = $this->objFromFixture('SilverStripe\\Security\\Member', 'editor');
|
{
|
||||||
Session::set("loggedInAs", $member->ID);
|
$member = $this->objFromFixture('SilverStripe\\Security\\Member', 'editor');
|
||||||
|
Session::set("loggedInAs", $member->ID);
|
||||||
|
|
||||||
$this->getAndFollowAll('admin/pages/?SubsiteID=0');
|
$this->getAndFollowAll('admin/pages/?SubsiteID=0');
|
||||||
$this->assertEquals(Subsite::currentSubsiteID(), '0', 'Can access main site.');
|
$this->assertEquals(Subsite::currentSubsiteID(), '0', 'Can access main site.');
|
||||||
$this->assertRegExp('#^admin/pages.*#', $this->mainSession->lastUrl(), 'Lands on the correct section');
|
$this->assertRegExp('#^admin/pages.*#', $this->mainSession->lastUrl(), 'Lands on the correct section');
|
||||||
|
|
||||||
$subsite1 = $this->objFromFixture(Subsite::class, 'subsite1');
|
$subsite1 = $this->objFromFixture(Subsite::class, 'subsite1');
|
||||||
$this->getAndFollowAll("admin/pages/?SubsiteID={$subsite1->ID}");
|
$this->getAndFollowAll("admin/pages/?SubsiteID={$subsite1->ID}");
|
||||||
$this->assertEquals(Subsite::currentSubsiteID(), $subsite1->ID, 'Can access other subsite.');
|
$this->assertEquals(Subsite::currentSubsiteID(), $subsite1->ID, 'Can access other subsite.');
|
||||||
$this->assertRegExp('#^admin/pages.*#', $this->mainSession->lastUrl(), 'Lands on the correct section');
|
$this->assertRegExp('#^admin/pages.*#', $this->mainSession->lastUrl(), 'Lands on the correct section');
|
||||||
|
|
||||||
$response = $this->getAndFollowAll(SubsiteXHRController::class);
|
$response = $this->getAndFollowAll(SubsiteXHRController::class);
|
||||||
$this->assertNotRegExp('#^Security/login.*#', $this->mainSession->lastUrl(),
|
$this->assertNotRegExp('#^Security/login.*#', $this->mainSession->lastUrl(),
|
||||||
'SubsiteXHRController is reachable');
|
'SubsiteXHRController is reachable');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test a member who only has access to one subsite (subsite1) and only some sections (pages and security).
|
* Test a member who only has access to one subsite (subsite1) and only some sections (pages and security).
|
||||||
*/
|
*/
|
||||||
function testSubsiteAdmin() {
|
function testSubsiteAdmin()
|
||||||
$member = $this->objFromFixture('SilverStripe\\Security\\Member', 'subsite1member');
|
{
|
||||||
Session::set("loggedInAs", $member->ID);
|
$member = $this->objFromFixture('SilverStripe\\Security\\Member', 'subsite1member');
|
||||||
|
Session::set("loggedInAs", $member->ID);
|
||||||
|
|
||||||
$subsite1 = $this->objFromFixture(Subsite::class, 'subsite1');
|
$subsite1 = $this->objFromFixture(Subsite::class, 'subsite1');
|
||||||
|
|
||||||
// Check allowed URL.
|
// Check allowed URL.
|
||||||
$this->getAndFollowAll("admin/pages/?SubsiteID={$subsite1->ID}");
|
$this->getAndFollowAll("admin/pages/?SubsiteID={$subsite1->ID}");
|
||||||
$this->assertEquals(Subsite::currentSubsiteID(), $subsite1->ID, 'Can access own subsite.');
|
$this->assertEquals(Subsite::currentSubsiteID(), $subsite1->ID, 'Can access own subsite.');
|
||||||
$this->assertRegExp('#^admin/pages.*#', $this->mainSession->lastUrl(), 'Can access permitted section.');
|
$this->assertRegExp('#^admin/pages.*#', $this->mainSession->lastUrl(), 'Can access permitted section.');
|
||||||
|
|
||||||
// Check forbidden section in allowed subsite.
|
// Check forbidden section in allowed subsite.
|
||||||
$this->getAndFollowAll("admin/assets/?SubsiteID={$subsite1->ID}");
|
$this->getAndFollowAll("admin/assets/?SubsiteID={$subsite1->ID}");
|
||||||
$this->assertEquals(Subsite::currentSubsiteID(), $subsite1->ID, 'Is redirected within subsite.');
|
$this->assertEquals(Subsite::currentSubsiteID(), $subsite1->ID, 'Is redirected within subsite.');
|
||||||
$this->assertNotRegExp('#^admin/assets/.*#', $this->mainSession->lastUrl(),
|
$this->assertNotRegExp('#^admin/assets/.*#', $this->mainSession->lastUrl(),
|
||||||
'Is redirected away from forbidden section');
|
'Is redirected away from forbidden section');
|
||||||
|
|
||||||
// Check forbidden site, on a section that's allowed on another subsite
|
// Check forbidden site, on a section that's allowed on another subsite
|
||||||
$this->getAndFollowAll("admin/pages/?SubsiteID=0");
|
$this->getAndFollowAll("admin/pages/?SubsiteID=0");
|
||||||
$this->assertEquals(Subsite::currentSubsiteID(), $subsite1->ID, 'Is redirected to permitted subsite.');
|
$this->assertEquals(Subsite::currentSubsiteID(), $subsite1->ID, 'Is redirected to permitted subsite.');
|
||||||
|
|
||||||
// Check forbidden site, on a section that's not allowed on any other subsite
|
// Check forbidden site, on a section that's not allowed on any other subsite
|
||||||
$this->getAndFollowAll("admin/assets/?SubsiteID=0");
|
$this->getAndFollowAll("admin/assets/?SubsiteID=0");
|
||||||
$this->assertEquals(Subsite::currentSubsiteID(), $subsite1->ID, 'Is redirected to first permitted subsite.');
|
$this->assertEquals(Subsite::currentSubsiteID(), $subsite1->ID, 'Is redirected to first permitted subsite.');
|
||||||
$this->assertNotRegExp('#^Security/login.*#', $this->mainSession->lastUrl(), 'Is not denied access');
|
$this->assertNotRegExp('#^Security/login.*#', $this->mainSession->lastUrl(), 'Is not denied access');
|
||||||
|
|
||||||
// Check the standalone XHR controller.
|
// Check the standalone XHR controller.
|
||||||
$response = $this->getAndFollowAll(SubsiteXHRController::class);
|
$response = $this->getAndFollowAll(SubsiteXHRController::class);
|
||||||
$this->assertNotRegExp('#^Security/login.*#', $this->mainSession->lastUrl(),
|
$this->assertNotRegExp('#^Security/login.*#', $this->mainSession->lastUrl(),
|
||||||
'SubsiteXHRController is reachable');
|
'SubsiteXHRController is reachable');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,55 +1,63 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use SilverStripe\Control\Session;
|
|
||||||
use SilverStripe\Control\Director;
|
|
||||||
use SilverStripe\CMS\Controllers\CMSMain;
|
use SilverStripe\CMS\Controllers\CMSMain;
|
||||||
|
use SilverStripe\Control\Director;
|
||||||
|
use SilverStripe\Control\Session;
|
||||||
use SilverStripe\Subsites\Model\Subsite;
|
use SilverStripe\Subsites\Model\Subsite;
|
||||||
|
|
||||||
|
|
||||||
class SubsiteAdminTest extends BaseSubsiteTest {
|
class SubsiteAdminTest extends BaseSubsiteTest
|
||||||
static $fixture_file = 'subsites/tests/SubsiteTest.yml';
|
{
|
||||||
|
static $fixture_file = 'subsites/tests/SubsiteTest.yml';
|
||||||
|
|
||||||
function adminLoggedInSession() {
|
function adminLoggedInSession()
|
||||||
return new Session(array(
|
{
|
||||||
|
return new Session([
|
||||||
'loggedInAs' => $this->idFromFixture('SilverStripe\\Security\\Member', 'admin')
|
'loggedInAs' => $this->idFromFixture('SilverStripe\\Security\\Member', 'admin')
|
||||||
));
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test generation of the view
|
* Test generation of the view
|
||||||
*/
|
*/
|
||||||
function testBasicView() {
|
function testBasicView()
|
||||||
Subsite::$write_hostmap = false;
|
{
|
||||||
$subsite1ID = $this->objFromFixture(Subsite::class,'domaintest1')->ID;
|
Subsite::$write_hostmap = false;
|
||||||
|
$subsite1ID = $this->objFromFixture(Subsite::class, 'domaintest1')->ID;
|
||||||
|
|
||||||
// Open the admin area logged in as admin
|
// Open the admin area logged in as admin
|
||||||
$response1 = Director::test('admin/subsites/', null, $this->adminLoggedInSession());
|
$response1 = Director::test('admin/subsites/', null, $this->adminLoggedInSession());
|
||||||
|
|
||||||
// Confirm that this URL gets you the entire page, with the edit form loaded
|
// Confirm that this URL gets you the entire page, with the edit form loaded
|
||||||
$response2 = Director::test("admin/subsites/Subsite/EditForm/field/Subsite/item/$subsite1ID/edit", null, $this->adminLoggedInSession());
|
$response2 = Director::test("admin/subsites/Subsite/EditForm/field/Subsite/item/$subsite1ID/edit", null,
|
||||||
$this->assertTrue(strpos($response2->getBody(), 'id="Form_ItemEditForm_ID"') !== false, "Testing Form_ItemEditForm_ID exists");
|
$this->adminLoggedInSession());
|
||||||
|
$this->assertTrue(strpos($response2->getBody(), 'id="Form_ItemEditForm_ID"') !== false,
|
||||||
|
"Testing Form_ItemEditForm_ID exists");
|
||||||
$this->assertTrue(strpos($response2->getBody(), '<head') !== false, "Testing <head> exists");
|
$this->assertTrue(strpos($response2->getBody(), '<head') !== false, "Testing <head> exists");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test that the main-site user with ADMIN permissions can access all subsites, regardless
|
* Test that the main-site user with ADMIN permissions can access all subsites, regardless
|
||||||
* of whether he is in a subsite-specific group or not.
|
* of whether he is in a subsite-specific group or not.
|
||||||
*/
|
*/
|
||||||
function testMainsiteAdminCanAccessAllSubsites() {
|
function testMainsiteAdminCanAccessAllSubsites()
|
||||||
$member = $this->objFromFixture('SilverStripe\\Security\\Member', 'admin');
|
{
|
||||||
Session::set("loggedInAs", $member->ID);
|
$member = $this->objFromFixture('SilverStripe\\Security\\Member', 'admin');
|
||||||
|
Session::set("loggedInAs", $member->ID);
|
||||||
|
|
||||||
$cmsMain = new CMSMain();
|
$cmsMain = new CMSMain();
|
||||||
foreach($cmsMain->Subsites() as $subsite) {
|
foreach ($cmsMain->Subsites() as $subsite) {
|
||||||
$ids[$subsite->ID] = true;
|
$ids[$subsite->ID] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->assertArrayHasKey(0, $ids, "Main site accessible");
|
$this->assertArrayHasKey(0, $ids, "Main site accessible");
|
||||||
$this->assertArrayHasKey($this->idFromFixture(Subsite::class,'main'), $ids, "Site with no groups inaccesible");
|
$this->assertArrayHasKey($this->idFromFixture(Subsite::class, 'main'), $ids, "Site with no groups inaccesible");
|
||||||
$this->assertArrayHasKey($this->idFromFixture(Subsite::class,'subsite1'), $ids, "Subsite1 Template inaccessible");
|
$this->assertArrayHasKey($this->idFromFixture(Subsite::class, 'subsite1'), $ids,
|
||||||
$this->assertArrayHasKey($this->idFromFixture(Subsite::class,'subsite2'), $ids, "Subsite2 Template inaccessible");
|
"Subsite1 Template inaccessible");
|
||||||
}
|
$this->assertArrayHasKey($this->idFromFixture(Subsite::class, 'subsite2'), $ids,
|
||||||
|
"Subsite2 Template inaccessible");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,368 +1,390 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use SilverStripe\ORM\DataObject;
|
|
||||||
use SilverStripe\Control\Director;
|
use SilverStripe\Control\Director;
|
||||||
|
use SilverStripe\ORM\DataObject;
|
||||||
use SilverStripe\Subsites\Model\Subsite;
|
use SilverStripe\Subsites\Model\Subsite;
|
||||||
use SilverStripe\Subsites\Model\SubsiteDomain;
|
use SilverStripe\Subsites\Model\SubsiteDomain;
|
||||||
|
|
||||||
|
|
||||||
class SubsiteTest extends BaseSubsiteTest {
|
class SubsiteTest extends BaseSubsiteTest
|
||||||
|
{
|
||||||
|
|
||||||
static $fixture_file = 'subsites/tests/SubsiteTest.yml';
|
static $fixture_file = 'subsites/tests/SubsiteTest.yml';
|
||||||
|
|
||||||
function setUp() {
|
function setUp()
|
||||||
parent::setUp();
|
{
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
$this->origStrictSubdomainMatching = Subsite::$strict_subdomain_matching;
|
$this->origStrictSubdomainMatching = Subsite::$strict_subdomain_matching;
|
||||||
Subsite::$strict_subdomain_matching = false;
|
Subsite::$strict_subdomain_matching = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function tearDown() {
|
function tearDown()
|
||||||
parent::tearDown();
|
{
|
||||||
|
parent::tearDown();
|
||||||
|
|
||||||
Subsite::$strict_subdomain_matching = $this->origStrictSubdomainMatching;
|
Subsite::$strict_subdomain_matching = $this->origStrictSubdomainMatching;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new subsite from the template and verify that all the template's pages are copied
|
* Create a new subsite from the template and verify that all the template's pages are copied
|
||||||
*/
|
*/
|
||||||
function testSubsiteCreation() {
|
function testSubsiteCreation()
|
||||||
Subsite::$write_hostmap = false;
|
{
|
||||||
|
Subsite::$write_hostmap = false;
|
||||||
|
|
||||||
// Create the instance
|
// Create the instance
|
||||||
$template = $this->objFromFixture(Subsite::class, 'main');
|
$template = $this->objFromFixture(Subsite::class, 'main');
|
||||||
|
|
||||||
// Test that changeSubsite is working
|
// Test that changeSubsite is working
|
||||||
Subsite::changeSubsite($template->ID);
|
Subsite::changeSubsite($template->ID);
|
||||||
$tmplStaff = $this->objFromFixture('Page','staff');
|
$tmplStaff = $this->objFromFixture('Page', 'staff');
|
||||||
$tmplHome = DataObject::get_one('Page', "\"URLSegment\" = 'home'");
|
$tmplHome = DataObject::get_one('Page', "\"URLSegment\" = 'home'");
|
||||||
|
|
||||||
// Publish all the pages in the template, testing that DataObject::get only returns pages from the chosen subsite
|
// Publish all the pages in the template, testing that DataObject::get only returns pages from the chosen subsite
|
||||||
$pages = DataObject::get("SilverStripe\\CMS\\Model\\SiteTree");
|
$pages = DataObject::get("SilverStripe\\CMS\\Model\\SiteTree");
|
||||||
$totalPages = $pages->Count();
|
$totalPages = $pages->Count();
|
||||||
foreach($pages as $page) {
|
foreach ($pages as $page) {
|
||||||
$this->assertEquals($template->ID, $page->SubsiteID);
|
$this->assertEquals($template->ID, $page->SubsiteID);
|
||||||
$page->publish('Stage', 'Live');
|
$page->publish('Stage', 'Live');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new site
|
// Create a new site
|
||||||
$subsite = $template->duplicate();
|
$subsite = $template->duplicate();
|
||||||
|
|
||||||
// Check title
|
// Check title
|
||||||
$this->assertEquals($subsite->Title, $template->Title);
|
$this->assertEquals($subsite->Title, $template->Title);
|
||||||
|
|
||||||
// Another test that changeSubsite is working
|
// Another test that changeSubsite is working
|
||||||
$subsite->activate();
|
$subsite->activate();
|
||||||
|
|
||||||
$siteHome = DataObject::get_one('Page', "\"URLSegment\" = 'home'");
|
$siteHome = DataObject::get_one('Page', "\"URLSegment\" = 'home'");
|
||||||
$this->assertNotEquals($siteHome, false, 'Home Page for subsite not found');
|
$this->assertNotEquals($siteHome, false, 'Home Page for subsite not found');
|
||||||
$this->assertEquals($subsite->ID, $siteHome->SubsiteID,
|
$this->assertEquals($subsite->ID, $siteHome->SubsiteID,
|
||||||
'createInstance() copies existing pages retaining the same URLSegment'
|
'createInstance() copies existing pages retaining the same URLSegment'
|
||||||
);
|
);
|
||||||
|
|
||||||
Subsite::changeSubsite(0);
|
Subsite::changeSubsite(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Confirm that domain lookup is working
|
* Confirm that domain lookup is working
|
||||||
*/
|
*/
|
||||||
function testDomainLookup() {
|
function testDomainLookup()
|
||||||
// Clear existing fixtures
|
{
|
||||||
foreach(DataObject::get(Subsite::class) as $subsite) $subsite->delete();
|
// Clear existing fixtures
|
||||||
foreach(DataObject::get(SubsiteDomain::class) as $domain) $domain->delete();
|
foreach (DataObject::get(Subsite::class) as $subsite) {
|
||||||
|
$subsite->delete();
|
||||||
|
}
|
||||||
|
foreach (DataObject::get(SubsiteDomain::class) as $domain) {
|
||||||
|
$domain->delete();
|
||||||
|
}
|
||||||
|
|
||||||
// Much more expressive than YML in this case
|
// Much more expressive than YML in this case
|
||||||
$subsite1 = $this->createSubsiteWithDomains(array(
|
$subsite1 = $this->createSubsiteWithDomains([
|
||||||
'one.example.org' => true,
|
'one.example.org' => true,
|
||||||
'one.*' => false,
|
'one.*' => false,
|
||||||
));
|
]);
|
||||||
$subsite2 = $this->createSubsiteWithDomains(array(
|
$subsite2 = $this->createSubsiteWithDomains([
|
||||||
'two.mysite.com' => true,
|
'two.mysite.com' => true,
|
||||||
'*.mysite.com' => false,
|
'*.mysite.com' => false,
|
||||||
'subdomain.onmultiplesubsites.com' => false,
|
'subdomain.onmultiplesubsites.com' => false,
|
||||||
));
|
]);
|
||||||
$subsite3 = $this->createSubsiteWithDomains(array(
|
$subsite3 = $this->createSubsiteWithDomains([
|
||||||
'three.*' => true, // wildcards in primary domain are not recommended
|
'three.*' => true, // wildcards in primary domain are not recommended
|
||||||
'subdomain.unique.com' => false,
|
'subdomain.unique.com' => false,
|
||||||
'*.onmultiplesubsites.com' => false,
|
'*.onmultiplesubsites.com' => false,
|
||||||
));
|
]);
|
||||||
|
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
$subsite3->ID,
|
$subsite3->ID,
|
||||||
Subsite::getSubsiteIDForDomain('subdomain.unique.com'),
|
Subsite::getSubsiteIDForDomain('subdomain.unique.com'),
|
||||||
'Full unique match'
|
'Full unique match'
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
$subsite1->ID,
|
$subsite1->ID,
|
||||||
Subsite::getSubsiteIDForDomain('one.example.org'),
|
Subsite::getSubsiteIDForDomain('one.example.org'),
|
||||||
'Full match, doesn\'t complain about multiple matches within a single subsite'
|
'Full match, doesn\'t complain about multiple matches within a single subsite'
|
||||||
);
|
);
|
||||||
|
|
||||||
$failed = false;
|
$failed = false;
|
||||||
try {
|
try {
|
||||||
Subsite::getSubsiteIDForDomain('subdomain.onmultiplesubsites.com');
|
Subsite::getSubsiteIDForDomain('subdomain.onmultiplesubsites.com');
|
||||||
} catch(UnexpectedValueException $e) {
|
} catch (UnexpectedValueException $e) {
|
||||||
$failed = true;
|
$failed = true;
|
||||||
}
|
}
|
||||||
$this->assertTrue(
|
$this->assertTrue(
|
||||||
$failed,
|
$failed,
|
||||||
'Fails on multiple matches with wildcard vs. www across multiple subsites'
|
'Fails on multiple matches with wildcard vs. www across multiple subsites'
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
$subsite1->ID,
|
$subsite1->ID,
|
||||||
Subsite::getSubsiteIDForDomain('one.unique.com'),
|
Subsite::getSubsiteIDForDomain('one.unique.com'),
|
||||||
'Fuzzy match suffixed with wildcard (rule "one.*")'
|
'Fuzzy match suffixed with wildcard (rule "one.*")'
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
$subsite2->ID,
|
$subsite2->ID,
|
||||||
Subsite::getSubsiteIDForDomain('two.mysite.com'),
|
Subsite::getSubsiteIDForDomain('two.mysite.com'),
|
||||||
'Matches correct subsite for rule'
|
'Matches correct subsite for rule'
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
$subsite2->ID,
|
$subsite2->ID,
|
||||||
Subsite::getSubsiteIDForDomain('other.mysite.com'),
|
Subsite::getSubsiteIDForDomain('other.mysite.com'),
|
||||||
'Fuzzy match prefixed with wildcard (rule "*.mysite.com")'
|
'Fuzzy match prefixed with wildcard (rule "*.mysite.com")'
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
0,
|
0,
|
||||||
Subsite::getSubsiteIDForDomain('unknown.madeup.com'),
|
Subsite::getSubsiteIDForDomain('unknown.madeup.com'),
|
||||||
"Doesn't match unknown subsite"
|
"Doesn't match unknown subsite"
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function testStrictSubdomainMatching() {
|
function testStrictSubdomainMatching()
|
||||||
// Clear existing fixtures
|
{
|
||||||
foreach(DataObject::get(Subsite::class) as $subsite) $subsite->delete();
|
// Clear existing fixtures
|
||||||
foreach(DataObject::get(SubsiteDomain::class) as $domain) $domain->delete();
|
foreach (DataObject::get(Subsite::class) as $subsite) {
|
||||||
|
$subsite->delete();
|
||||||
|
}
|
||||||
|
foreach (DataObject::get(SubsiteDomain::class) as $domain) {
|
||||||
|
$domain->delete();
|
||||||
|
}
|
||||||
|
|
||||||
// Much more expressive than YML in this case
|
// Much more expressive than YML in this case
|
||||||
$subsite1 = $this->createSubsiteWithDomains(array(
|
$subsite1 = $this->createSubsiteWithDomains([
|
||||||
'example.org' => true,
|
'example.org' => true,
|
||||||
'example.com' => false,
|
'example.com' => false,
|
||||||
'*.wildcard.com' => false,
|
'*.wildcard.com' => false,
|
||||||
));
|
]);
|
||||||
$subsite2 = $this->createSubsiteWithDomains(array(
|
$subsite2 = $this->createSubsiteWithDomains([
|
||||||
'www.example.org' => true,
|
'www.example.org' => true,
|
||||||
'www.wildcard.com' => false,
|
'www.wildcard.com' => false,
|
||||||
));
|
]);
|
||||||
|
|
||||||
Subsite::$strict_subdomain_matching = false;
|
Subsite::$strict_subdomain_matching = false;
|
||||||
|
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
$subsite1->ID,
|
$subsite1->ID,
|
||||||
Subsite::getSubsiteIDForDomain('example.org'),
|
Subsite::getSubsiteIDForDomain('example.org'),
|
||||||
'Exact matches without strict checking when not using www prefix'
|
'Exact matches without strict checking when not using www prefix'
|
||||||
);
|
);
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
$subsite1->ID,
|
$subsite1->ID,
|
||||||
Subsite::getSubsiteIDForDomain('www.example.org'),
|
Subsite::getSubsiteIDForDomain('www.example.org'),
|
||||||
'Matches without strict checking when using www prefix, still matching first domain regardless of www prefix (falling back to subsite primary key ordering)'
|
'Matches without strict checking when using www prefix, still matching first domain regardless of www prefix (falling back to subsite primary key ordering)'
|
||||||
);
|
);
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
$subsite1->ID,
|
$subsite1->ID,
|
||||||
Subsite::getSubsiteIDForDomain('www.example.com'),
|
Subsite::getSubsiteIDForDomain('www.example.com'),
|
||||||
'Fuzzy matches without strict checking with www prefix'
|
'Fuzzy matches without strict checking with www prefix'
|
||||||
);
|
);
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
0,
|
0,
|
||||||
Subsite::getSubsiteIDForDomain('www.wildcard.com'),
|
Subsite::getSubsiteIDForDomain('www.wildcard.com'),
|
||||||
'Doesn\'t match www prefix without strict check, even if a wildcard subdomain is in place'
|
'Doesn\'t match www prefix without strict check, even if a wildcard subdomain is in place'
|
||||||
);
|
);
|
||||||
|
|
||||||
Subsite::$strict_subdomain_matching = true;
|
Subsite::$strict_subdomain_matching = true;
|
||||||
|
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
$subsite1->ID,
|
$subsite1->ID,
|
||||||
Subsite::getSubsiteIDForDomain('example.org'),
|
Subsite::getSubsiteIDForDomain('example.org'),
|
||||||
'Matches with strict checking when not using www prefix'
|
'Matches with strict checking when not using www prefix'
|
||||||
);
|
);
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
$subsite2->ID, // not 1
|
$subsite2->ID, // not 1
|
||||||
Subsite::getSubsiteIDForDomain('www.example.org'),
|
Subsite::getSubsiteIDForDomain('www.example.org'),
|
||||||
'Matches with strict checking when using www prefix'
|
'Matches with strict checking when using www prefix'
|
||||||
);
|
);
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
0,
|
0,
|
||||||
Subsite::getSubsiteIDForDomain('www.example.com'),
|
Subsite::getSubsiteIDForDomain('www.example.com'),
|
||||||
'Doesn\'t fuzzy match with strict checking when using www prefix'
|
'Doesn\'t fuzzy match with strict checking when using www prefix'
|
||||||
);
|
);
|
||||||
$failed = false;
|
$failed = false;
|
||||||
try {
|
try {
|
||||||
Subsite::getSubsiteIDForDomain('www.wildcard.com');
|
Subsite::getSubsiteIDForDomain('www.wildcard.com');
|
||||||
} catch(UnexpectedValueException $e) {
|
} catch (UnexpectedValueException $e) {
|
||||||
$failed = true;
|
$failed = true;
|
||||||
}
|
}
|
||||||
$this->assertTrue(
|
$this->assertTrue(
|
||||||
$failed,
|
$failed,
|
||||||
'Fails on multiple matches with strict checking and wildcard vs. www'
|
'Fails on multiple matches with strict checking and wildcard vs. www'
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function createSubsiteWithDomains($domains) {
|
protected function createSubsiteWithDomains($domains)
|
||||||
$subsite = new Subsite(array(
|
{
|
||||||
'Title' => 'My Subsite'
|
$subsite = new Subsite([
|
||||||
));
|
'Title' => 'My Subsite'
|
||||||
$subsite->write();
|
]);
|
||||||
foreach($domains as $domainStr => $isPrimary) {
|
$subsite->write();
|
||||||
$domain = new SubsiteDomain(array(
|
foreach ($domains as $domainStr => $isPrimary) {
|
||||||
'Domain' => $domainStr,
|
$domain = new SubsiteDomain([
|
||||||
'IsPrimary' => $isPrimary,
|
'Domain' => $domainStr,
|
||||||
'SubsiteID' => $subsite->ID
|
'IsPrimary' => $isPrimary,
|
||||||
));
|
'SubsiteID' => $subsite->ID
|
||||||
$domain->write();
|
]);
|
||||||
}
|
$domain->write();
|
||||||
|
}
|
||||||
|
|
||||||
return $subsite;
|
return $subsite;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test the Subsite->domain() method
|
* Test the Subsite->domain() method
|
||||||
*/
|
*/
|
||||||
function testDefaultDomain() {
|
function testDefaultDomain()
|
||||||
$this->assertEquals('one.example.org',
|
{
|
||||||
$this->objFromFixture(Subsite::class,'domaintest1')->domain());
|
$this->assertEquals('one.example.org',
|
||||||
|
$this->objFromFixture(Subsite::class, 'domaintest1')->domain());
|
||||||
|
|
||||||
$this->assertEquals('two.mysite.com',
|
$this->assertEquals('two.mysite.com',
|
||||||
$this->objFromFixture(Subsite::class,'domaintest2')->domain());
|
$this->objFromFixture(Subsite::class, 'domaintest2')->domain());
|
||||||
|
|
||||||
$originalHTTPHost = $_SERVER['HTTP_HOST'];
|
$originalHTTPHost = $_SERVER['HTTP_HOST'];
|
||||||
|
|
||||||
$_SERVER['HTTP_HOST'] = "www.example.org";
|
$_SERVER['HTTP_HOST'] = "www.example.org";
|
||||||
$this->assertEquals('three.example.org',
|
$this->assertEquals('three.example.org',
|
||||||
$this->objFromFixture(Subsite::class,'domaintest3')->domain());
|
$this->objFromFixture(Subsite::class, 'domaintest3')->domain());
|
||||||
|
|
||||||
$_SERVER['HTTP_HOST'] = "mysite.example.org";
|
$_SERVER['HTTP_HOST'] = "mysite.example.org";
|
||||||
$this->assertEquals('three.mysite.example.org',
|
$this->assertEquals('three.mysite.example.org',
|
||||||
$this->objFromFixture(Subsite::class,'domaintest3')->domain());
|
$this->objFromFixture(Subsite::class, 'domaintest3')->domain());
|
||||||
|
|
||||||
$this->assertEquals($_SERVER['HTTP_HOST'], singleton(Subsite::class)->PrimaryDomain);
|
$this->assertEquals($_SERVER['HTTP_HOST'], singleton(Subsite::class)->PrimaryDomain);
|
||||||
$this->assertEquals('http://'.$_SERVER['HTTP_HOST'].Director::baseURL(), singleton(Subsite::class)->absoluteBaseURL());
|
$this->assertEquals('http://' . $_SERVER['HTTP_HOST'] . Director::baseURL(),
|
||||||
|
singleton(Subsite::class)->absoluteBaseURL());
|
||||||
|
|
||||||
$_SERVER['HTTP_HOST'] = $originalHTTPHost;
|
$_SERVER['HTTP_HOST'] = $originalHTTPHost;
|
||||||
}
|
}
|
||||||
|
|
||||||
function testAllSites() {
|
function testAllSites()
|
||||||
$subsites = Subsite::all_sites();
|
{
|
||||||
$this->assertDOSEquals(array(
|
$subsites = Subsite::all_sites();
|
||||||
array('Title' =>'Main site'),
|
$this->assertDOSEquals([
|
||||||
array('Title' =>'Template'),
|
['Title' => 'Main site'],
|
||||||
array('Title' =>'Subsite1 Template'),
|
['Title' => 'Template'],
|
||||||
array('Title' =>'Subsite2 Template'),
|
['Title' => 'Subsite1 Template'],
|
||||||
array('Title' =>'Test 1'),
|
['Title' => 'Subsite2 Template'],
|
||||||
array('Title' =>'Test 2'),
|
['Title' => 'Test 1'],
|
||||||
array('Title' =>'Test 3')
|
['Title' => 'Test 2'],
|
||||||
), $subsites, 'Lists all subsites');
|
['Title' => 'Test 3']
|
||||||
}
|
], $subsites, 'Lists all subsites');
|
||||||
|
}
|
||||||
|
|
||||||
function testAllAccessibleSites() {
|
function testAllAccessibleSites()
|
||||||
$member = $this->objFromFixture('SilverStripe\\Security\\Member', 'subsite1member');
|
{
|
||||||
|
$member = $this->objFromFixture('SilverStripe\\Security\\Member', 'subsite1member');
|
||||||
|
|
||||||
$subsites = Subsite::all_accessible_sites(true, 'Main site', $member);
|
$subsites = Subsite::all_accessible_sites(true, 'Main site', $member);
|
||||||
$this->assertDOSEquals(array(
|
$this->assertDOSEquals([
|
||||||
array('Title' =>'Subsite1 Template')
|
['Title' => 'Subsite1 Template']
|
||||||
), $subsites, 'Lists member-accessible sites.');
|
], $subsites, 'Lists member-accessible sites.');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test Subsite::accessible_sites()
|
* Test Subsite::accessible_sites()
|
||||||
*/
|
*/
|
||||||
function testAccessibleSites() {
|
function testAccessibleSites()
|
||||||
$member1Sites = Subsite::accessible_sites("CMS_ACCESS_CMSMain", false, null,
|
{
|
||||||
$this->objFromFixture('SilverStripe\\Security\\Member', 'subsite1member'));
|
$member1Sites = Subsite::accessible_sites("CMS_ACCESS_CMSMain", false, null,
|
||||||
$member1SiteTitles = $member1Sites->column("Title");
|
$this->objFromFixture('SilverStripe\\Security\\Member', 'subsite1member'));
|
||||||
sort($member1SiteTitles);
|
$member1SiteTitles = $member1Sites->column("Title");
|
||||||
$this->assertEquals('Subsite1 Template', $member1SiteTitles[0], 'Member can get to a subsite via a group');
|
sort($member1SiteTitles);
|
||||||
|
$this->assertEquals('Subsite1 Template', $member1SiteTitles[0], 'Member can get to a subsite via a group');
|
||||||
|
|
||||||
$adminSites = Subsite::accessible_sites("CMS_ACCESS_CMSMain", false, null,
|
$adminSites = Subsite::accessible_sites("CMS_ACCESS_CMSMain", false, null,
|
||||||
$this->objFromFixture('SilverStripe\\Security\\Member', 'admin'));
|
$this->objFromFixture('SilverStripe\\Security\\Member', 'admin'));
|
||||||
$adminSiteTitles = $adminSites->column("Title");
|
$adminSiteTitles = $adminSites->column("Title");
|
||||||
sort($adminSiteTitles);
|
sort($adminSiteTitles);
|
||||||
$this->assertEquals(array(
|
$this->assertEquals([
|
||||||
'Subsite1 Template',
|
'Subsite1 Template',
|
||||||
'Subsite2 Template',
|
'Subsite2 Template',
|
||||||
'Template',
|
'Template',
|
||||||
'Test 1',
|
'Test 1',
|
||||||
'Test 2',
|
'Test 2',
|
||||||
'Test 3',
|
'Test 3',
|
||||||
), $adminSiteTitles);
|
], $adminSiteTitles);
|
||||||
|
|
||||||
$member2Sites = Subsite::accessible_sites("CMS_ACCESS_CMSMain", false, null,
|
$member2Sites = Subsite::accessible_sites("CMS_ACCESS_CMSMain", false, null,
|
||||||
$this->objFromFixture('SilverStripe\\Security\\Member', 'subsite1member2'));
|
$this->objFromFixture('SilverStripe\\Security\\Member', 'subsite1member2'));
|
||||||
$member2SiteTitles = $member2Sites->column("Title");
|
$member2SiteTitles = $member2Sites->column("Title");
|
||||||
sort($member2SiteTitles);
|
sort($member2SiteTitles);
|
||||||
$this->assertEquals('Subsite1 Template', $member2SiteTitles[0], 'Member can get to subsite via a group role');
|
$this->assertEquals('Subsite1 Template', $member2SiteTitles[0], 'Member can get to subsite via a group role');
|
||||||
}
|
}
|
||||||
|
|
||||||
function testhasMainSitePermission() {
|
function testhasMainSitePermission()
|
||||||
$admin = $this->objFromFixture('SilverStripe\\Security\\Member', 'admin');
|
{
|
||||||
$subsite1member = $this->objFromFixture('SilverStripe\\Security\\Member', 'subsite1member');
|
$admin = $this->objFromFixture('SilverStripe\\Security\\Member', 'admin');
|
||||||
$subsite1admin = $this->objFromFixture('SilverStripe\\Security\\Member', 'subsite1admin');
|
$subsite1member = $this->objFromFixture('SilverStripe\\Security\\Member', 'subsite1member');
|
||||||
$allsubsitesauthor = $this->objFromFixture('SilverStripe\\Security\\Member', 'allsubsitesauthor');
|
$subsite1admin = $this->objFromFixture('SilverStripe\\Security\\Member', 'subsite1admin');
|
||||||
|
$allsubsitesauthor = $this->objFromFixture('SilverStripe\\Security\\Member', 'allsubsitesauthor');
|
||||||
|
|
||||||
$this->assertTrue(
|
$this->assertTrue(
|
||||||
Subsite::hasMainSitePermission($admin),
|
Subsite::hasMainSitePermission($admin),
|
||||||
'Default permissions granted for super-admin'
|
'Default permissions granted for super-admin'
|
||||||
);
|
);
|
||||||
$this->assertTrue(
|
$this->assertTrue(
|
||||||
Subsite::hasMainSitePermission($admin, array("ADMIN")),
|
Subsite::hasMainSitePermission($admin, ["ADMIN"]),
|
||||||
'ADMIN permissions granted for super-admin'
|
'ADMIN permissions granted for super-admin'
|
||||||
);
|
);
|
||||||
$this->assertFalse(
|
$this->assertFalse(
|
||||||
Subsite::hasMainSitePermission($subsite1admin, array("ADMIN")),
|
Subsite::hasMainSitePermission($subsite1admin, ["ADMIN"]),
|
||||||
'ADMIN permissions (on main site) denied for subsite1 admin'
|
'ADMIN permissions (on main site) denied for subsite1 admin'
|
||||||
);
|
);
|
||||||
$this->assertFalse(
|
$this->assertFalse(
|
||||||
Subsite::hasMainSitePermission($subsite1admin, array("CMS_ACCESS_CMSMain")),
|
Subsite::hasMainSitePermission($subsite1admin, ["CMS_ACCESS_CMSMain"]),
|
||||||
'CMS_ACCESS_CMSMain (on main site) denied for subsite1 admin'
|
'CMS_ACCESS_CMSMain (on main site) denied for subsite1 admin'
|
||||||
);
|
);
|
||||||
$this->assertFalse(
|
$this->assertFalse(
|
||||||
Subsite::hasMainSitePermission($allsubsitesauthor, array("ADMIN")),
|
Subsite::hasMainSitePermission($allsubsitesauthor, ["ADMIN"]),
|
||||||
'ADMIN permissions (on main site) denied for CMS author with edit rights on all subsites'
|
'ADMIN permissions (on main site) denied for CMS author with edit rights on all subsites'
|
||||||
);
|
);
|
||||||
$this->assertTrue(
|
$this->assertTrue(
|
||||||
Subsite::hasMainSitePermission($allsubsitesauthor, array("CMS_ACCESS_CMSMain")),
|
Subsite::hasMainSitePermission($allsubsitesauthor, ["CMS_ACCESS_CMSMain"]),
|
||||||
'CMS_ACCESS_CMSMain (on main site) granted for CMS author with edit rights on all subsites'
|
'CMS_ACCESS_CMSMain (on main site) granted for CMS author with edit rights on all subsites'
|
||||||
);
|
);
|
||||||
$this->assertFalse(
|
$this->assertFalse(
|
||||||
Subsite::hasMainSitePermission($subsite1member, array("ADMIN")),
|
Subsite::hasMainSitePermission($subsite1member, ["ADMIN"]),
|
||||||
'ADMIN (on main site) denied for subsite1 subsite1 cms author'
|
'ADMIN (on main site) denied for subsite1 subsite1 cms author'
|
||||||
);
|
);
|
||||||
$this->assertFalse(
|
$this->assertFalse(
|
||||||
Subsite::hasMainSitePermission($subsite1member, array("CMS_ACCESS_CMSMain")),
|
Subsite::hasMainSitePermission($subsite1member, ["CMS_ACCESS_CMSMain"]),
|
||||||
'CMS_ACCESS_CMSMain (on main site) denied for subsite1 cms author'
|
'CMS_ACCESS_CMSMain (on main site) denied for subsite1 cms author'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function testDuplicateSubsite() {
|
function testDuplicateSubsite()
|
||||||
// get subsite1 & create page
|
{
|
||||||
$subsite1 = $this->objFromFixture(Subsite::class,'domaintest1');
|
// get subsite1 & create page
|
||||||
$subsite1->activate();
|
$subsite1 = $this->objFromFixture(Subsite::class, 'domaintest1');
|
||||||
$page1 = new Page();
|
$subsite1->activate();
|
||||||
$page1->Title = 'MyAwesomePage';
|
$page1 = new Page();
|
||||||
$page1->write();
|
$page1->Title = 'MyAwesomePage';
|
||||||
$page1->doPublish();
|
$page1->write();
|
||||||
$this->assertEquals($page1->SubsiteID, $subsite1->ID);
|
$page1->doPublish();
|
||||||
|
$this->assertEquals($page1->SubsiteID, $subsite1->ID);
|
||||||
|
|
||||||
// duplicate
|
// duplicate
|
||||||
$subsite2 = $subsite1->duplicate();
|
$subsite2 = $subsite1->duplicate();
|
||||||
$subsite2->activate();
|
$subsite2->activate();
|
||||||
// change content on dupe
|
// change content on dupe
|
||||||
$page2 = DataObject::get_one('Page', "\"Title\" = 'MyAwesomePage'");
|
$page2 = DataObject::get_one('Page', "\"Title\" = 'MyAwesomePage'");
|
||||||
$page2->Title = 'MyNewAwesomePage';
|
$page2->Title = 'MyNewAwesomePage';
|
||||||
$page2->write();
|
$page2->write();
|
||||||
$page2->doPublish();
|
$page2->doPublish();
|
||||||
|
|
||||||
// check change & check change has not affected subiste1
|
// check change & check change has not affected subiste1
|
||||||
$subsite1->activate();
|
$subsite1->activate();
|
||||||
$this->assertEquals('MyAwesomePage', DataObject::get_by_id('Page', $page1->ID)->Title);
|
$this->assertEquals('MyAwesomePage', DataObject::get_by_id('Page', $page1->ID)->Title);
|
||||||
$subsite2->activate();
|
$subsite2->activate();
|
||||||
$this->assertEquals('MyNewAwesomePage', DataObject::get_by_id('Page', $page2->ID)->Title);
|
$this->assertEquals('MyNewAwesomePage', DataObject::get_by_id('Page', $page2->ID)->Title);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,279 +1,289 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use SilverStripe\Assets\Filesystem;
|
use SilverStripe\Assets\Filesystem;
|
||||||
use SilverStripe\ORM\DB;
|
|
||||||
use SilverStripe\Core\Config\Config;
|
|
||||||
|
|
||||||
use SilverStripe\Assets\Tests\Storage\AssetStoreTest\TestAssetStore;
|
use SilverStripe\Assets\Tests\Storage\AssetStoreTest\TestAssetStore;
|
||||||
|
use SilverStripe\Core\Config\Config;
|
||||||
|
use SilverStripe\ORM\DB;
|
||||||
use SilverStripe\Subsites\Model\Subsite;
|
use SilverStripe\Subsites\Model\Subsite;
|
||||||
use SilverStripe\Subsites\Pages\SubsitesVirtualPage;
|
use SilverStripe\Subsites\Pages\SubsitesVirtualPage;
|
||||||
use SilverStripe\Versioned\Versioned;
|
use SilverStripe\Versioned\Versioned;
|
||||||
|
|
||||||
|
|
||||||
class SubsitesVirtualPageTest extends BaseSubsiteTest {
|
class SubsitesVirtualPageTest extends BaseSubsiteTest
|
||||||
static $fixture_file = array(
|
{
|
||||||
'subsites/tests/SubsiteTest.yml',
|
static $fixture_file = [
|
||||||
'subsites/tests/SubsitesVirtualPageTest.yml',
|
'subsites/tests/SubsiteTest.yml',
|
||||||
);
|
'subsites/tests/SubsitesVirtualPageTest.yml',
|
||||||
|
];
|
||||||
|
|
||||||
public function setUp() {
|
public function setUp()
|
||||||
parent::setUp();
|
{
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
// Set backend root to /DataDifferencerTest
|
// Set backend root to /DataDifferencerTest
|
||||||
TestAssetStore::activate('SubsitesVirtualPageTest');
|
TestAssetStore::activate('SubsitesVirtualPageTest');
|
||||||
|
|
||||||
// Create a test files for each of the fixture references
|
// Create a test files for each of the fixture references
|
||||||
$file = $this->objFromFixture('SilverStripe\\Assets\\File', 'file1');
|
$file = $this->objFromFixture('SilverStripe\\Assets\\File', 'file1');
|
||||||
$page = $this->objFromFixture('SilverStripe\\CMS\\Model\\SiteTree', 'page1');
|
$page = $this->objFromFixture('SilverStripe\\CMS\\Model\\SiteTree', 'page1');
|
||||||
$fromPath = __DIR__ . '/testscript-test-file.pdf';
|
$fromPath = __DIR__ . '/testscript-test-file.pdf';
|
||||||
$destPath = TestAssetStore::getLocalPath($file);
|
$destPath = TestAssetStore::getLocalPath($file);
|
||||||
Filesystem::makeFolder(dirname($destPath));
|
Filesystem::makeFolder(dirname($destPath));
|
||||||
copy($fromPath, $destPath);
|
copy($fromPath, $destPath);
|
||||||
|
|
||||||
// Hack in site link tracking after the fact
|
// Hack in site link tracking after the fact
|
||||||
$page->Content = '<p><img src="'. $file->getURL(). '" data-fileid="' . $file->ID . '" /></p>';
|
$page->Content = '<p><img src="' . $file->getURL() . '" data-fileid="' . $file->ID . '" /></p>';
|
||||||
$page->write();
|
$page->write();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function tearDown() {
|
public function tearDown()
|
||||||
TestAssetStore::reset();
|
{
|
||||||
parent::tearDown();
|
TestAssetStore::reset();
|
||||||
}
|
parent::tearDown();
|
||||||
|
}
|
||||||
|
|
||||||
// Attempt to bring main:linky to subsite2:linky
|
// Attempt to bring main:linky to subsite2:linky
|
||||||
function testVirtualPageFromAnotherSubsite() {
|
function testVirtualPageFromAnotherSubsite()
|
||||||
Subsite::$write_hostmap = false;
|
{
|
||||||
|
Subsite::$write_hostmap = false;
|
||||||
|
|
||||||
$subsite = $this->objFromFixture(Subsite::class, 'subsite2');
|
$subsite = $this->objFromFixture(Subsite::class, 'subsite2');
|
||||||
|
|
||||||
Subsite::changeSubsite($subsite->ID);
|
Subsite::changeSubsite($subsite->ID);
|
||||||
Subsite::$disable_subsite_filter = false;
|
Subsite::$disable_subsite_filter = false;
|
||||||
|
|
||||||
$linky = $this->objFromFixture('Page', 'linky');
|
$linky = $this->objFromFixture('Page', 'linky');
|
||||||
|
|
||||||
$svp = new SubsitesVirtualPage();
|
$svp = new SubsitesVirtualPage();
|
||||||
$svp->CopyContentFromID = $linky->ID;
|
$svp->CopyContentFromID = $linky->ID;
|
||||||
$svp->SubsiteID = $subsite->ID;
|
$svp->SubsiteID = $subsite->ID;
|
||||||
$svp->URLSegment = 'linky';
|
$svp->URLSegment = 'linky';
|
||||||
|
|
||||||
$svp->write();
|
$svp->write();
|
||||||
|
|
||||||
$this->assertEquals($svp->SubsiteID, $subsite->ID);
|
$this->assertEquals($svp->SubsiteID, $subsite->ID);
|
||||||
$this->assertEquals($svp->Title, $linky->Title);
|
$this->assertEquals($svp->Title, $linky->Title);
|
||||||
}
|
}
|
||||||
|
|
||||||
function testFileLinkRewritingOnVirtualPages() {
|
function testFileLinkRewritingOnVirtualPages()
|
||||||
// File setup
|
{
|
||||||
$this->logInWithPermission('ADMIN');
|
// File setup
|
||||||
|
$this->logInWithPermission('ADMIN');
|
||||||
|
|
||||||
// Publish the source page
|
// Publish the source page
|
||||||
$page = $this->objFromFixture('SilverStripe\\CMS\\Model\\SiteTree', 'page1');
|
$page = $this->objFromFixture('SilverStripe\\CMS\\Model\\SiteTree', 'page1');
|
||||||
$this->assertTrue($page->doPublish());
|
$this->assertTrue($page->doPublish());
|
||||||
|
|
||||||
// Create a virtual page from it, and publish that
|
// Create a virtual page from it, and publish that
|
||||||
$svp = new SubsitesVirtualPage();
|
$svp = new SubsitesVirtualPage();
|
||||||
$svp->CopyContentFromID = $page->ID;
|
$svp->CopyContentFromID = $page->ID;
|
||||||
$svp->write();
|
$svp->write();
|
||||||
$svp->doPublish();
|
$svp->doPublish();
|
||||||
|
|
||||||
// Rename the file
|
// Rename the file
|
||||||
$file = $this->objFromFixture('SilverStripe\\Assets\\File', 'file1');
|
$file = $this->objFromFixture('SilverStripe\\Assets\\File', 'file1');
|
||||||
$file->Name = 'renamed-test-file.pdf';
|
$file->Name = 'renamed-test-file.pdf';
|
||||||
$file->write();
|
$file->write();
|
||||||
|
|
||||||
// Verify that the draft and publish virtual pages both have the corrected link
|
// Verify that the draft and publish virtual pages both have the corrected link
|
||||||
$this->assertContains('<img src="/assets/SubsitesVirtualPageTest/464dedb70a/renamed-test-file.pdf"',
|
$this->assertContains('<img src="/assets/SubsitesVirtualPageTest/464dedb70a/renamed-test-file.pdf"',
|
||||||
DB::query("SELECT \"Content\" FROM \"SiteTree\" WHERE \"ID\" = $svp->ID")->value());
|
DB::query("SELECT \"Content\" FROM \"SiteTree\" WHERE \"ID\" = $svp->ID")->value());
|
||||||
$this->assertContains('<img src="/assets/SubsitesVirtualPageTest/464dedb70a/renamed-test-file.pdf"',
|
$this->assertContains('<img src="/assets/SubsitesVirtualPageTest/464dedb70a/renamed-test-file.pdf"',
|
||||||
DB::query("SELECT \"Content\" FROM \"SiteTree_Live\" WHERE \"ID\" = $svp->ID")->value());
|
DB::query("SELECT \"Content\" FROM \"SiteTree_Live\" WHERE \"ID\" = $svp->ID")->value());
|
||||||
}
|
}
|
||||||
|
|
||||||
function testSubsiteVirtualPagesArentInappropriatelyPublished() {
|
function testSubsiteVirtualPagesArentInappropriatelyPublished()
|
||||||
// Fixture
|
{
|
||||||
$p = new Page();
|
// Fixture
|
||||||
$p->Content = "test content";
|
$p = new Page();
|
||||||
$p->write();
|
$p->Content = "test content";
|
||||||
$vp = new SubsitesVirtualPage();
|
$p->write();
|
||||||
$vp->CopyContentFromID = $p->ID;
|
$vp = new SubsitesVirtualPage();
|
||||||
$vp->write();
|
$vp->CopyContentFromID = $p->ID;
|
||||||
|
$vp->write();
|
||||||
|
|
||||||
// VP is oragne
|
// VP is oragne
|
||||||
$this->assertTrue($vp->IsAddedToStage);
|
$this->assertTrue($vp->IsAddedToStage);
|
||||||
|
|
||||||
// VP is still orange after we publish
|
// VP is still orange after we publish
|
||||||
$p->doPublish();
|
$p->doPublish();
|
||||||
$this->fixVersionNumberCache($vp);
|
$this->fixVersionNumberCache($vp);
|
||||||
$this->assertTrue($vp->IsAddedToStage);
|
$this->assertTrue($vp->IsAddedToStage);
|
||||||
|
|
||||||
// A new VP created after P's initial construction
|
// A new VP created after P's initial construction
|
||||||
$vp2 = new SubsitesVirtualPage();
|
$vp2 = new SubsitesVirtualPage();
|
||||||
$vp2->CopyContentFromID = $p->ID;
|
$vp2->CopyContentFromID = $p->ID;
|
||||||
$vp2->write();
|
$vp2->write();
|
||||||
$this->assertTrue($vp2->IsAddedToStage);
|
$this->assertTrue($vp2->IsAddedToStage);
|
||||||
|
|
||||||
// Also remains orange after a republish
|
// Also remains orange after a republish
|
||||||
$p->Content = "new content";
|
$p->Content = "new content";
|
||||||
$p->write();
|
$p->write();
|
||||||
$p->doPublish();
|
$p->doPublish();
|
||||||
$this->fixVersionNumberCache($vp2);
|
$this->fixVersionNumberCache($vp2);
|
||||||
$this->assertTrue($vp2->IsAddedToStage);
|
$this->assertTrue($vp2->IsAddedToStage);
|
||||||
|
|
||||||
// VP is now published
|
// VP is now published
|
||||||
$vp->doPublish();
|
$vp->doPublish();
|
||||||
|
|
||||||
$this->fixVersionNumberCache($vp);
|
$this->fixVersionNumberCache($vp);
|
||||||
$this->assertTrue($vp->ExistsOnLive);
|
$this->assertTrue($vp->ExistsOnLive);
|
||||||
$this->assertFalse($vp->IsModifiedOnStage);
|
$this->assertFalse($vp->IsModifiedOnStage);
|
||||||
|
|
||||||
// P edited, VP and P both go green
|
// P edited, VP and P both go green
|
||||||
$p->Content = "third content";
|
$p->Content = "third content";
|
||||||
$p->write();
|
$p->write();
|
||||||
|
|
||||||
$this->fixVersionNumberCache($vp, $p);
|
$this->fixVersionNumberCache($vp, $p);
|
||||||
$this->assertTrue($p->IsModifiedOnStage);
|
$this->assertTrue($p->IsModifiedOnStage);
|
||||||
$this->assertTrue($vp->IsModifiedOnStage);
|
$this->assertTrue($vp->IsModifiedOnStage);
|
||||||
|
|
||||||
// Publish, VP goes black
|
// Publish, VP goes black
|
||||||
$p->doPublish();
|
$p->doPublish();
|
||||||
$this->fixVersionNumberCache($vp);
|
$this->fixVersionNumberCache($vp);
|
||||||
$this->assertTrue($vp->ExistsOnLive);
|
$this->assertTrue($vp->ExistsOnLive);
|
||||||
$this->assertFalse($vp->IsModifiedOnStage);
|
$this->assertFalse($vp->IsModifiedOnStage);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This test ensures published Subsites Virtual Pages immediately reflect updates
|
* This test ensures published Subsites Virtual Pages immediately reflect updates
|
||||||
* to their published target pages. Note - this has to happen when the virtual page
|
* to their published target pages. Note - this has to happen when the virtual page
|
||||||
* is in a different subsite to the page you are editing and republishing,
|
* is in a different subsite to the page you are editing and republishing,
|
||||||
* otherwise the test will pass falsely due to current subsite ID being the same.
|
* otherwise the test will pass falsely due to current subsite ID being the same.
|
||||||
*/
|
*/
|
||||||
function testPublishedSubsiteVirtualPagesUpdateIfTargetPageUpdates()
|
function testPublishedSubsiteVirtualPagesUpdateIfTargetPageUpdates()
|
||||||
{
|
{
|
||||||
// create page
|
// create page
|
||||||
$p = new Page();
|
$p = new Page();
|
||||||
$p->Content = 'Content';
|
$p->Content = 'Content';
|
||||||
$p->Title = 'Title';
|
$p->Title = 'Title';
|
||||||
$p->writeToStage('Stage');
|
$p->writeToStage('Stage');
|
||||||
$p->publish('Stage', 'Live');
|
$p->publish('Stage', 'Live');
|
||||||
$this->assertTrue($p->ExistsOnLive);
|
$this->assertTrue($p->ExistsOnLive);
|
||||||
|
|
||||||
// change to subsite
|
// change to subsite
|
||||||
$subsite = $this->objFromFixture(Subsite::class, 'subsite2');
|
$subsite = $this->objFromFixture(Subsite::class, 'subsite2');
|
||||||
Subsite::changeSubsite($subsite->ID);
|
Subsite::changeSubsite($subsite->ID);
|
||||||
Subsite::$disable_subsite_filter = false;
|
Subsite::$disable_subsite_filter = false;
|
||||||
|
|
||||||
// create svp in subsite
|
// create svp in subsite
|
||||||
$svp = new SubsitesVirtualPage();
|
$svp = new SubsitesVirtualPage();
|
||||||
$svp->CopyContentFromID = $p->ID;
|
$svp->CopyContentFromID = $p->ID;
|
||||||
$svp->write();
|
$svp->write();
|
||||||
$svp->writeToStage('Stage');
|
$svp->writeToStage('Stage');
|
||||||
$svp->publish('Stage', 'Live');
|
$svp->publish('Stage', 'Live');
|
||||||
$this->assertEquals($svp->SubsiteID, $subsite->ID);
|
$this->assertEquals($svp->SubsiteID, $subsite->ID);
|
||||||
$this->assertTrue($svp->ExistsOnLive);
|
$this->assertTrue($svp->ExistsOnLive);
|
||||||
|
|
||||||
// change back to original subsite ("Main site")
|
// change back to original subsite ("Main site")
|
||||||
Subsite::changeSubsite(0);
|
Subsite::changeSubsite(0);
|
||||||
|
|
||||||
// update original page
|
// update original page
|
||||||
$p->Title = 'New Title';
|
$p->Title = 'New Title';
|
||||||
// "save & publish"
|
// "save & publish"
|
||||||
$p->writeToStage('Stage');
|
$p->writeToStage('Stage');
|
||||||
$p->publish('Stage', 'Live');
|
$p->publish('Stage', 'Live');
|
||||||
$this->assertNotEquals($p->SubsiteID, $subsite->ID);
|
$this->assertNotEquals($p->SubsiteID, $subsite->ID);
|
||||||
|
|
||||||
// reload SVP from database
|
// reload SVP from database
|
||||||
// can't use DO::get by id because caches.
|
// can't use DO::get by id because caches.
|
||||||
$svpdb = $svp->get()->byID($svp->ID);
|
$svpdb = $svp->get()->byID($svp->ID);
|
||||||
|
|
||||||
// ensure title changed
|
// ensure title changed
|
||||||
$this->assertEquals($svpdb->Title, $p->Title);
|
$this->assertEquals($svpdb->Title, $p->Title);
|
||||||
}
|
}
|
||||||
|
|
||||||
function testUnpublishingParentPageUnpublishesSubsiteVirtualPages() {
|
function testUnpublishingParentPageUnpublishesSubsiteVirtualPages()
|
||||||
Config::modify()->set('StaticPublisher', 'disable_realtime', true);
|
{
|
||||||
|
Config::modify()->set('StaticPublisher', 'disable_realtime', true);
|
||||||
|
|
||||||
// Go to main site, get parent page
|
// Go to main site, get parent page
|
||||||
$subsite = $this->objFromFixture(Subsite::class, 'main');
|
$subsite = $this->objFromFixture(Subsite::class, 'main');
|
||||||
Subsite::changeSubsite($subsite->ID);
|
Subsite::changeSubsite($subsite->ID);
|
||||||
$page = $this->objFromFixture('Page', 'importantpage');
|
$page = $this->objFromFixture('Page', 'importantpage');
|
||||||
|
|
||||||
// Create two SVPs on other subsites
|
// Create two SVPs on other subsites
|
||||||
$subsite = $this->objFromFixture(Subsite::class, 'subsite1');
|
$subsite = $this->objFromFixture(Subsite::class, 'subsite1');
|
||||||
Subsite::changeSubsite($subsite->ID);
|
Subsite::changeSubsite($subsite->ID);
|
||||||
$vp1 = new SubsitesVirtualPage();
|
$vp1 = new SubsitesVirtualPage();
|
||||||
$vp1->CopyContentFromID = $page->ID;
|
$vp1->CopyContentFromID = $page->ID;
|
||||||
$vp1->write();
|
$vp1->write();
|
||||||
$vp1->doPublish();
|
$vp1->doPublish();
|
||||||
|
|
||||||
$subsite = $this->objFromFixture(Subsite::class, 'subsite2');
|
$subsite = $this->objFromFixture(Subsite::class, 'subsite2');
|
||||||
Subsite::changeSubsite($subsite->ID);
|
Subsite::changeSubsite($subsite->ID);
|
||||||
$vp2 = new SubsitesVirtualPage();
|
$vp2 = new SubsitesVirtualPage();
|
||||||
$vp2->CopyContentFromID = $page->ID;
|
$vp2->CopyContentFromID = $page->ID;
|
||||||
$vp2->write();
|
$vp2->write();
|
||||||
$vp2->doPublish();
|
$vp2->doPublish();
|
||||||
|
|
||||||
// Switch back to main site, unpublish source
|
// Switch back to main site, unpublish source
|
||||||
$subsite = $this->objFromFixture(Subsite::class, 'main');
|
$subsite = $this->objFromFixture(Subsite::class, 'main');
|
||||||
Subsite::changeSubsite($subsite->ID);
|
Subsite::changeSubsite($subsite->ID);
|
||||||
$page = $this->objFromFixture('Page', 'importantpage');
|
$page = $this->objFromFixture('Page', 'importantpage');
|
||||||
$page->doUnpublish();
|
$page->doUnpublish();
|
||||||
|
|
||||||
Subsite::changeSubsite($vp1->SubsiteID);
|
Subsite::changeSubsite($vp1->SubsiteID);
|
||||||
$onLive = Versioned::get_one_by_stage(SubsitesVirtualPage::class, 'Live', "\"SiteTree_Live\".\"ID\" = ".$vp1->ID);
|
$onLive = Versioned::get_one_by_stage(SubsitesVirtualPage::class, 'Live',
|
||||||
$this->assertNull($onLive, 'SVP has been removed from live');
|
"\"SiteTree_Live\".\"ID\" = " . $vp1->ID);
|
||||||
|
$this->assertNull($onLive, 'SVP has been removed from live');
|
||||||
|
|
||||||
$subsite = $this->objFromFixture(Subsite::class, 'subsite2');
|
$subsite = $this->objFromFixture(Subsite::class, 'subsite2');
|
||||||
Subsite::changeSubsite($vp2->SubsiteID);
|
Subsite::changeSubsite($vp2->SubsiteID);
|
||||||
$onLive = Versioned::get_one_by_stage(SubsitesVirtualPage::class, 'Live', "\"SiteTree_Live\".\"ID\" = ".$vp2->ID);
|
$onLive = Versioned::get_one_by_stage(SubsitesVirtualPage::class, 'Live',
|
||||||
$this->assertNull($onLive, 'SVP has been removed from live');
|
"\"SiteTree_Live\".\"ID\" = " . $vp2->ID);
|
||||||
}
|
$this->assertNull($onLive, 'SVP has been removed from live');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Similar to {@link SiteTreeSubsitesTest->testTwoPagesWithSameURLOnDifferentSubsites()}
|
* Similar to {@link SiteTreeSubsitesTest->testTwoPagesWithSameURLOnDifferentSubsites()}
|
||||||
* and {@link SiteTreeSubsitesTest->testPagesInDifferentSubsitesCanShareURLSegment()}.
|
* and {@link SiteTreeSubsitesTest->testPagesInDifferentSubsitesCanShareURLSegment()}.
|
||||||
*/
|
*/
|
||||||
function testSubsiteVirtualPageCanHaveSameUrlsegmentAsOtherSubsite() {
|
function testSubsiteVirtualPageCanHaveSameUrlsegmentAsOtherSubsite()
|
||||||
Subsite::$write_hostmap = false;
|
{
|
||||||
$subsite1 = $this->objFromFixture(Subsite::class, 'subsite1');
|
Subsite::$write_hostmap = false;
|
||||||
$subsite2 = $this->objFromFixture(Subsite::class, 'subsite2');
|
$subsite1 = $this->objFromFixture(Subsite::class, 'subsite1');
|
||||||
Subsite::changeSubsite($subsite1->ID);
|
$subsite2 = $this->objFromFixture(Subsite::class, 'subsite2');
|
||||||
|
Subsite::changeSubsite($subsite1->ID);
|
||||||
|
|
||||||
$subsite1Page = $this->objFromFixture('Page', 'subsite1_staff');
|
$subsite1Page = $this->objFromFixture('Page', 'subsite1_staff');
|
||||||
$subsite1Page->URLSegment = 'staff';
|
$subsite1Page->URLSegment = 'staff';
|
||||||
$subsite1Page->write();
|
$subsite1Page->write();
|
||||||
|
|
||||||
// saving on subsite1, and linking to subsite1
|
// saving on subsite1, and linking to subsite1
|
||||||
$subsite1Vp = new SubsitesVirtualPage();
|
$subsite1Vp = new SubsitesVirtualPage();
|
||||||
$subsite1Vp->CopyContentFromID = $subsite1Page->ID;
|
$subsite1Vp->CopyContentFromID = $subsite1Page->ID;
|
||||||
$subsite1Vp->SubsiteID = $subsite1->ID;
|
$subsite1Vp->SubsiteID = $subsite1->ID;
|
||||||
$subsite1Vp->write();
|
$subsite1Vp->write();
|
||||||
$this->assertNotEquals(
|
$this->assertNotEquals(
|
||||||
$subsite1Vp->URLSegment,
|
$subsite1Vp->URLSegment,
|
||||||
$subsite1Page->URLSegment,
|
$subsite1Page->URLSegment,
|
||||||
"Doesn't allow explicit URLSegment overrides when already existing in same subsite"
|
"Doesn't allow explicit URLSegment overrides when already existing in same subsite"
|
||||||
);
|
);
|
||||||
|
|
||||||
//Change to subsite 2
|
//Change to subsite 2
|
||||||
Subsite::changeSubsite($subsite2->ID);
|
Subsite::changeSubsite($subsite2->ID);
|
||||||
|
|
||||||
// saving in subsite2 (which already has a page with URLSegment 'contact-us'),
|
// saving in subsite2 (which already has a page with URLSegment 'contact-us'),
|
||||||
// but linking to a page in subsite1
|
// but linking to a page in subsite1
|
||||||
$subsite2Vp = new SubsitesVirtualPage();
|
$subsite2Vp = new SubsitesVirtualPage();
|
||||||
$subsite2Vp->CopyContentFromID = $subsite1Page->ID;
|
$subsite2Vp->CopyContentFromID = $subsite1Page->ID;
|
||||||
$subsite2Vp->SubsiteID = $subsite2->ID;
|
$subsite2Vp->SubsiteID = $subsite2->ID;
|
||||||
$subsite2Vp->write();
|
$subsite2Vp->write();
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
$subsite2Vp->URLSegment,
|
$subsite2Vp->URLSegment,
|
||||||
$subsite1Page->URLSegment,
|
$subsite1Page->URLSegment,
|
||||||
"Does allow explicit URLSegment overrides when only existing in a different subsite"
|
"Does allow explicit URLSegment overrides when only existing in a different subsite"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function fixVersionNumberCache($page) {
|
function fixVersionNumberCache($page)
|
||||||
$pages = func_get_args();
|
{
|
||||||
foreach($pages as $p) {
|
$pages = func_get_args();
|
||||||
Versioned::prepopulate_versionnumber_cache('SilverStripe\\CMS\\Model\\SiteTree', 'Stage', array($p->ID));
|
foreach ($pages as $p) {
|
||||||
Versioned::prepopulate_versionnumber_cache('SilverStripe\\CMS\\Model\\SiteTree', 'Live', array($p->ID));
|
Versioned::prepopulate_versionnumber_cache('SilverStripe\\CMS\\Model\\SiteTree', 'Stage', [$p->ID]);
|
||||||
}
|
Versioned::prepopulate_versionnumber_cache('SilverStripe\\CMS\\Model\\SiteTree', 'Live', [$p->ID]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2,17 +2,18 @@
|
|||||||
|
|
||||||
namespace Subsites\Test\Behaviour;
|
namespace Subsites\Test\Behaviour;
|
||||||
|
|
||||||
if(!class_exists('SilverStripe\BehatExtension\Context\SilverStripeContext')) return;
|
if (!class_exists('SilverStripe\BehatExtension\Context\SilverStripeContext')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
use SilverStripe\BehatExtension\Context\SilverStripeContext,
|
use SilverStripe\BehatExtension\Context\BasicContext;
|
||||||
SilverStripe\BehatExtension\Context\BasicContext,
|
use SilverStripe\BehatExtension\Context\FixtureContext;
|
||||||
SilverStripe\BehatExtension\Context\LoginContext,
|
use SilverStripe\BehatExtension\Context\LoginContext;
|
||||||
SilverStripe\BehatExtension\Context\FixtureContext,
|
use SilverStripe\BehatExtension\Context\SilverStripeContext;
|
||||||
SilverStripe\Framework\Test\Behaviour\CmsFormsContext,
|
|
||||||
SilverStripe\Framework\Test\Behaviour\CmsUiContext,
|
|
||||||
SilverStripe\Cms\Test\Behaviour;
|
|
||||||
use SilverStripe\Core\Injector\Injector;
|
|
||||||
use SilverStripe\Core\ClassInfo;
|
use SilverStripe\Core\ClassInfo;
|
||||||
|
use SilverStripe\Core\Injector\Injector;
|
||||||
|
use SilverStripe\Framework\Test\Behaviour\CmsFormsContext;
|
||||||
|
use SilverStripe\Framework\Test\Behaviour\CmsUiContext;
|
||||||
|
|
||||||
|
|
||||||
// PHPUnit
|
// PHPUnit
|
||||||
@ -25,7 +26,8 @@ require_once 'PHPUnit/Framework/Assert/Functions.php';
|
|||||||
* Context automatically loaded by Behat.
|
* Context automatically loaded by Behat.
|
||||||
* Uses subcontexts to extend functionality.
|
* Uses subcontexts to extend functionality.
|
||||||
*/
|
*/
|
||||||
class FeatureContext extends SilverStripeContext {
|
class FeatureContext extends SilverStripeContext
|
||||||
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var FixtureFactory
|
* @var FixtureFactory
|
||||||
@ -38,7 +40,8 @@ class FeatureContext extends SilverStripeContext {
|
|||||||
*
|
*
|
||||||
* @param array $parameters context parameters (set them up through behat.yml)
|
* @param array $parameters context parameters (set them up through behat.yml)
|
||||||
*/
|
*/
|
||||||
public function __construct(array $parameters) {
|
public function __construct(array $parameters)
|
||||||
|
{
|
||||||
parent::__construct($parameters);
|
parent::__construct($parameters);
|
||||||
|
|
||||||
$this->useContext('BasicContext', new BasicContext($parameters));
|
$this->useContext('BasicContext', new BasicContext($parameters));
|
||||||
@ -53,25 +56,28 @@ class FeatureContext extends SilverStripeContext {
|
|||||||
// Use blueprints to set user name from identifier
|
// Use blueprints to set user name from identifier
|
||||||
$factory = $fixtureContext->getFixtureFactory();
|
$factory = $fixtureContext->getFixtureFactory();
|
||||||
$blueprint = Injector::inst()->create('SilverStripe\\Dev\\FixtureBlueprint', 'SilverStripe\\Security\\Member');
|
$blueprint = Injector::inst()->create('SilverStripe\\Dev\\FixtureBlueprint', 'SilverStripe\\Security\\Member');
|
||||||
$blueprint->addCallback('beforeCreate', function($identifier, &$data, &$fixtures) {
|
$blueprint->addCallback('beforeCreate', function ($identifier, &$data, &$fixtures) {
|
||||||
if(!isset($data['FirstName'])) $data['FirstName'] = $identifier;
|
if (!isset($data['FirstName'])) {
|
||||||
|
$data['FirstName'] = $identifier;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
$factory->define('SilverStripe\\Security\\Member', $blueprint);
|
$factory->define('SilverStripe\\Security\\Member', $blueprint);
|
||||||
|
|
||||||
// Auto-publish pages
|
// Auto-publish pages
|
||||||
foreach(ClassInfo::subclassesFor('SilverStripe\\CMS\\Model\\SiteTree') as $id => $class) {
|
foreach (ClassInfo::subclassesFor('SilverStripe\\CMS\\Model\\SiteTree') as $id => $class) {
|
||||||
$blueprint = Injector::inst()->create('SilverStripe\\Dev\\FixtureBlueprint', $class);
|
$blueprint = Injector::inst()->create('SilverStripe\\Dev\\FixtureBlueprint', $class);
|
||||||
$blueprint->addCallback('afterCreate', function($obj, $identifier, &$data, &$fixtures) {
|
$blueprint->addCallback('afterCreate', function ($obj, $identifier, &$data, &$fixtures) {
|
||||||
$obj->publish('Stage', 'Live');
|
$obj->publish('Stage', 'Live');
|
||||||
});
|
});
|
||||||
$factory->define($class, $blueprint);
|
$factory->define($class, $blueprint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setMinkParameters(array $parameters) {
|
public function setMinkParameters(array $parameters)
|
||||||
|
{
|
||||||
parent::setMinkParameters($parameters);
|
parent::setMinkParameters($parameters);
|
||||||
|
|
||||||
if(isset($parameters['files_path'])) {
|
if (isset($parameters['files_path'])) {
|
||||||
$this->getSubcontext('FixtureContext')->setFilesPath($parameters['files_path']);
|
$this->getSubcontext('FixtureContext')->setFilesPath($parameters['files_path']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -79,15 +85,17 @@ class FeatureContext extends SilverStripeContext {
|
|||||||
/**
|
/**
|
||||||
* @return FixtureFactory
|
* @return FixtureFactory
|
||||||
*/
|
*/
|
||||||
public function getFixtureFactory() {
|
public function getFixtureFactory()
|
||||||
if(!$this->fixtureFactory) {
|
{
|
||||||
|
if (!$this->fixtureFactory) {
|
||||||
$this->fixtureFactory = Injector::inst()->create('SilverStripe\\Dev\\BehatFixtureFactory');
|
$this->fixtureFactory = Injector::inst()->create('SilverStripe\\Dev\\BehatFixtureFactory');
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->fixtureFactory;
|
return $this->fixtureFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setFixtureFactory(FixtureFactory $factory) {
|
public function setFixtureFactory(FixtureFactory $factory)
|
||||||
|
{
|
||||||
$this->fixtureFactory = $factory;
|
$this->fixtureFactory = $factory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,26 +1,26 @@
|
|||||||
Feature: Preview navigation
|
Feature: Preview navigation
|
||||||
As a CMS user
|
As a CMS user
|
||||||
I can navigate a subsite in the preview pane
|
I can navigate a subsite in the preview pane
|
||||||
In order to preview my content
|
In order to preview my content
|
||||||
|
|
||||||
Background:
|
Background:
|
||||||
Given a "subsite" "My subsite"
|
Given a "subsite" "My subsite"
|
||||||
And a "page" "My page" with "URLSegment"="my-page", "Content"="My page content <a name='aname'>aname</a><a href='other-page'>ahref</a>" and "Subsite"="=>Subsite.My subsite"
|
And a "page" "My page" with "URLSegment"="my-page", "Content"="My page content <a name='aname'>aname</a><a href='other-page'>ahref</a>" and "Subsite"="=>Subsite.My subsite"
|
||||||
And a "page" "Other page" with "URLSegment"="other-page", "Content"="Other page content <form action='my-page'><input type='submit' value='Submit my form'></form>" and "Subsite"="=>Subsite.My subsite"
|
And a "page" "Other page" with "URLSegment"="other-page", "Content"="Other page content <form action='my-page'><input type='submit' value='Submit my form'></form>" and "Subsite"="=>Subsite.My subsite"
|
||||||
Given a "member" "Joe" belonging to "Admin Group" with "Email"="joe@test.com" and "Password"="Password1"
|
Given a "member" "Joe" belonging to "Admin Group" with "Email"="joe@test.com" and "Password"="Password1"
|
||||||
And the "group" "Admin Group" has permissions "Full administrative rights"
|
And the "group" "Admin Group" has permissions "Full administrative rights"
|
||||||
And I log in with "joe@test.com" and "Password1"
|
And I log in with "joe@test.com" and "Password1"
|
||||||
|
|
||||||
Scenario: I can navigate the subsite preview
|
Scenario: I can navigate the subsite preview
|
||||||
When I go to "admin"
|
When I go to "admin"
|
||||||
And I select "My subsite" from "SubsitesSelect"
|
And I select "My subsite" from "SubsitesSelect"
|
||||||
And I go to "admin/pages"
|
And I go to "admin/pages"
|
||||||
And I click on "My page" in the tree
|
And I click on "My page" in the tree
|
||||||
And I wait for 3 seconds
|
And I wait for 3 seconds
|
||||||
And I set the CMS mode to "Preview mode"
|
And I set the CMS mode to "Preview mode"
|
||||||
And I follow "ahref" in preview
|
And I follow "ahref" in preview
|
||||||
Then the preview contains "Other page content"
|
Then the preview contains "Other page content"
|
||||||
# We are already on the second page, submit the form to return to first one.
|
# We are already on the second page, submit the form to return to first one.
|
||||||
When I wait for 3 seconds
|
When I wait for 3 seconds
|
||||||
And I press "Submit my form" in preview
|
And I press "Submit my form" in preview
|
||||||
Then the preview contains "My page content"
|
Then the preview contains "My page content"
|
||||||
|
Loading…
Reference in New Issue
Block a user