Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 15 additions & 12 deletions javascript/SubsitesTreeDropdownField.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');
}
});

Expand All @@ -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);
32 changes: 24 additions & 8 deletions src/Extensions/LeftAndMainSubsites.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
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;
Expand Down Expand Up @@ -270,13 +271,31 @@ public function onBeforeInit()
$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()))
Expand All @@ -299,10 +318,7 @@ public function onBeforeInit()
$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) {
Expand Down
8 changes: 5 additions & 3 deletions src/Extensions/SiteTreeSubsites.php
Original file line number Diff line number Diff line change
Expand Up @@ -118,22 +118,24 @@ public function updateCMSFields(FieldList $fields)
'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')
)
]
)->setHeadingLevel(4)
);

$copyAction->addExtraClass('btn btn-primary font-icon-save ml-3');

// @todo check if this needs re-implementation
// $copyAction->includeDefaultJS(false);
}
Expand Down
40 changes: 33 additions & 7 deletions src/Forms/SubsitesTreeDropdownField.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
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;

Expand All @@ -20,7 +21,10 @@ class SubsitesTreeDropdownField extends TreeDropdownField
'tree'
];

protected $subsiteID = 0;
/**
* @var int
*/
protected $subsiteId = 0;

/**
* Extra HTML classes
Expand All @@ -39,20 +43,42 @@ public function Field($properties = [])
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);
});

Expand Down
25 changes: 18 additions & 7 deletions src/Pages/SubsitesVirtualPage.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -59,34 +62,42 @@ public function getCMSFields()
);

// 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') .
'</a>';
$fields->removeByName('VirtualPageContentLinkLabel');
$fields->addFieldToTab(
'Root.Main',
$linkToContentLabelField = new LabelField('VirtualPageContentLinkLabel', $linkToContent),
$linkToContentLabelField = LiteralField::create('VirtualPageContentLinkLabel', $linkToContent),
'Title'
);
$linkToContentLabelField->setAllowHTML(true);
}


Expand Down