FIX Subsites VirtualPage link to edit main page and TreeDropdownField API implementations

This commit is contained in:
Robbie Averill 2018-01-30 16:21:45 +13:00
parent 6fb0af0f93
commit 34b3fbf04d
5 changed files with 95 additions and 37 deletions

View File

@ -4,14 +4,14 @@
* Choose a subsite from which to select pages.
* Needs to clear tree dropdowns in case selection is changed.
*/
$('.subsitestreedropdownfield-chooser').entwine({
$('select.subsitestreedropdownfield-chooser').entwine({
onchange: function() {
// TODO Data binding between two fields
// TODO create resetField method on API instead
var fields = $('.SubsitesTreeDropdownField');
fields.setValue(null);
fields.setTitle(null);
fields.find('.tree-holder').empty();
const name = this.attr('name').replace('_SubsiteID', '');
let field = $('#Form_EditForm_' + name).first();
field.setValue(0);
field.refresh();
field.trigger('change');
}
});
@ -20,12 +20,15 @@
* before asking for the tree.
*/
$('.TreeDropdownField.SubsitesTreeDropdownField').entwine({
getRequestParams: function() {
var name = this.find(':input[type=hidden]:first').attr('name') + '_SubsiteID',
source = $('[name=' + name + ']'), params = {};
params[name] = source.length ? source.val() : null;
return params;
}
getAttributes() {
const fieldName = this.attr('id').replace('Form_EditForm_', '');
const subsiteID = $('#Form_EditForm_' + fieldName + '_SubsiteID option:selected').val();
let attributes = this._super();
attributes.data.urlTree += "?" + fieldName + "_SubsiteID=" + subsiteID;
attributes.data.cacheKey = attributes.data.cacheKey.substring(0, 19) + "_" + subsiteID;
return attributes;
}
});
});
})(jQuery);

View File

@ -5,6 +5,7 @@ namespace SilverStripe\Subsites\Extensions;
use SilverStripe\Admin\AdminRootController;
use SilverStripe\Admin\CMSMenu;
use SilverStripe\Admin\LeftAndMainExtension;
use SilverStripe\CMS\Controllers\CMSPagesController;
use SilverStripe\CMS\Model\SiteTree;
use SilverStripe\CMS\Controllers\CMSPageEditController;
use SilverStripe\Control\Controller;
@ -270,13 +271,31 @@ class LeftAndMainSubsites extends LeftAndMainExtension
$session->clear($sessionNamespace . '.currentPage');
}
// Subsite ID has already been set to the state via InitStateMiddleware. If the user cannot view
// the current page, or we're in the context of editing a specific page, redirect to the admin landing
// section to prevent a loop of re-loading the original subsite for the current page.
if (!$this->owner->canView() || Controller::curr() instanceof CMSPageEditController) {
// Context: Subsite ID has already been set to the state via InitStateMiddleware
// If the user cannot view the current page, redirect to the admin landing section
if (!$this->owner->canView()) {
return $this->owner->redirect(AdminRootController::config()->get('url_base') . '/');
}
$currentController = Controller::curr();
if ($currentController instanceof CMSPageEditController) {
/** @var SiteTree $page */
$page = $currentController->currentPage();
// If the page exists but doesn't belong to the requested subsite, redirect to admin/pages which
// will show a list of the requested subsite's pages
$currentSubsiteId = $request->getVar('SubsiteID');
if ($page && (int) $page->SubsiteID !== (int) $currentSubsiteId) {
return $this->owner->redirect(CMSPagesController::singleton()->Link());
}
// Page does belong to the current subsite, so remove the query string parameter and refresh the page
// Remove the subsiteID parameter and redirect back to the current URL again
$request->offsetSet('SubsiteID', null);
return $this->owner->redirect($request->getURL(true));
}
// Redirect to clear the current page, retaining the current URL parameters
return $this->owner->redirect(
Controller::join_links($this->owner->Link(), ...array_values($this->owner->getURLParams()))
@ -299,10 +318,7 @@ class LeftAndMainSubsites extends LeftAndMainExtension
$canViewElsewhere = SubsiteState::singleton()->withState(function ($newState) use ($record) {
$newState->setSubsiteId($record->SubsiteID);
if ($this->owner->canView(Security::getCurrentUser())) {
return true;
}
return false;
return (bool) $this->owner->canView(Security::getCurrentUser());
});
if ($canViewElsewhere) {

View File

@ -118,15 +118,15 @@ class SiteTreeSubsites extends DataExtension
'SubsiteOperations',
_t(__CLASS__ . '.SubsiteOperations', 'Subsite Operations'),
[
new DropdownField('CopyToSubsiteID', _t(
DropdownField::create('CopyToSubsiteID', _t(
__CLASS__ . '.CopyToSubsite',
'Copy page to subsite'
), $subsitesMap),
new CheckboxField(
CheckboxField::create(
'CopyToSubsiteWithChildren',
_t(__CLASS__ . '.CopyToSubsiteWithChildren', 'Include children pages?')
),
$copyAction = new FormAction(
$copyAction = FormAction::create(
'copytosubsite',
_t(__CLASS__ . '.CopyAction', 'Copy')
)
@ -134,6 +134,8 @@ class SiteTreeSubsites extends DataExtension
)->setHeadingLevel(4)
);
$copyAction->addExtraClass('btn btn-primary font-icon-save ml-3');
// @todo check if this needs re-implementation
// $copyAction->includeDefaultJS(false);
}

View File

@ -5,6 +5,7 @@ namespace SilverStripe\Subsites\Forms;
use SilverStripe\Control\Controller;
use SilverStripe\Control\HTTPRequest;
use SilverStripe\Forms\TreeDropdownField;
use SilverStripe\Subsites\Model\Subsite;
use SilverStripe\View\Requirements;
use SilverStripe\Subsites\State\SubsiteState;
@ -20,7 +21,10 @@ class SubsitesTreeDropdownField extends TreeDropdownField
'tree'
];
protected $subsiteID = 0;
/**
* @var int
*/
protected $subsiteId = 0;
/**
* Extra HTML classes
@ -39,20 +43,42 @@ class SubsitesTreeDropdownField extends TreeDropdownField
return $html;
}
public function setSubsiteID($id)
/**
* Sets the subsite ID to use when generating the tree
*
* @param int $id
* @return $this
*/
public function setSubsiteId($id)
{
$this->subsiteID = $id;
$this->subsiteId = $id;
return $this;
}
public function getSubsiteID()
/**
* Get the subsite ID to use when generating the tree
*
* @return int
*/
public function getSubsiteId()
{
return $this->subsiteID;
return $this->subsiteId;
}
/**
* Get the CMS tree with the provided subsite ID applied to the state
*
* {@inheritDoc}
*/
public function tree(HTTPRequest $request)
{
$results = SubsiteState::singleton()->withState(function () use ($request) {
SubsiteState::singleton()->setSubsiteId($this->subsiteID);
// Detect subsite ID from the request
if ($request->getVar($this->getName() . '_SubsiteID')) {
$this->setSubsiteId($request->getVar($this->getName() . '_SubsiteID'));
}
$results = SubsiteState::singleton()->withState(function (SubsiteState $newState) use ($request) {
$newState->setSubsiteId($this->getSubsiteId());
return parent::tree($request);
});

View File

@ -2,14 +2,17 @@
namespace SilverStripe\Subsites\Pages;
use SilverStripe\CMS\Controllers\CMSPageEditController;
use SilverStripe\CMS\Model\SiteTree;
use SilverStripe\CMS\Model\VirtualPage;
use SilverStripe\Control\Controller;
use SilverStripe\Core\Config\Config;
use SilverStripe\Forms\DropdownField;
use SilverStripe\Forms\LabelField;
use SilverStripe\Forms\LiteralField;
use SilverStripe\Forms\TextareaField;
use SilverStripe\Forms\TextField;
use SilverStripe\Forms\TreeDropdownField;
use SilverStripe\ORM\ArrayList;
use SilverStripe\ORM\DataObject;
use SilverStripe\Subsites\Forms\SubsitesTreeDropdownField;
@ -59,23 +62,32 @@ class SubsitesVirtualPage extends VirtualPage
);
// Setup the linking to the original page.
$pageSelectionField = new SubsitesTreeDropdownField(
$pageSelectionField = SubsitesTreeDropdownField::create(
'CopyContentFromID',
_t('SilverStripe\\CMS\\Model\\VirtualPage.CHOOSE', 'Choose a page to link to'),
"SilverStripe\\CMS\\Model\\SiteTree",
_t('SilverStripe\\CMS\\Model\\VirtualPage.CHOOSE', 'Linked Page'),
SiteTree::class,
'ID',
'MenuTitle'
);
$fields->addFieldToTab(
'Root.Main',
TreeDropdownField::create('CopyContentFromID', 'Linked Page', SiteTree::class)
);
if (Controller::has_curr() && Controller::curr()->getRequest()) {
$subsiteID = Controller::curr()->getRequest()->requestVar('CopyContentFromID_SubsiteID');
$subsiteID = (int) Controller::curr()->getRequest()->requestVar('CopyContentFromID_SubsiteID');
$pageSelectionField->setSubsiteID($subsiteID);
}
$fields->replaceField('CopyContentFromID', $pageSelectionField);
// Create links back to the original object in the CMS
if ($this->CopyContentFromID) {
$editLink = "admin/pages/edit/show/$this->CopyContentFromID/?SubsiteID=" . $this->CopyContentFrom()->SubsiteID;
$editLink = Controller::join_links(
CMSPageEditController::singleton()->Link('show'),
$this->CopyContentFromID
);
$linkToContent = "
<a class=\"cmsEditlink\" href=\"$editLink\">" .
_t('SilverStripe\\CMS\\Model\\VirtualPage.EDITCONTENT', 'Click here to edit the content') .
@ -83,10 +95,9 @@ class SubsitesVirtualPage extends VirtualPage
$fields->removeByName('VirtualPageContentLinkLabel');
$fields->addFieldToTab(
'Root.Main',
$linkToContentLabelField = new LabelField('VirtualPageContentLinkLabel', $linkToContent),
$linkToContentLabelField = LiteralField::create('VirtualPageContentLinkLabel', $linkToContent),
'Title'
);
$linkToContentLabelField->setAllowHTML(true);
}