Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Change SiteTreeHints to check for canEdit #1035

Open
wants to merge 3 commits into from

5 participants

@RuthAdele

Allowing ability to have
public function canCreate($member = null) {
return MyPage::get()->count() < 1;
}
and still be able to re-order this page in the sitetree.

I have tested moving pages in site tree, with and without the canCreate and canEdit rules, can_be_root and allowed_children statics.

This Fixes #657

@RuthAdele RuthAdele Change SiteTreeHints to check for canEdit
Allowing ability to have
public function canCreate($member = null) {
    return MyPage::get()->count() < 1;
}
and still be able to re-order this page in the sitetree.
a513b47
code/controllers/CMSMain.php
@@ -386,12 +386,12 @@ public function SiteTreeHints() {
$json = '';
$classes = SiteTree::page_type_classes();
- $cacheCanCreate = array();
- foreach($classes as $class) $cacheCanCreate[$class] = singleton($class)->canCreate();
+ $cacheCanEdit = array();
+ foreach($classes as $class) $cacheCanEdit[$class] = singleton($class)->canEdit();
@wilr Collaborator
wilr added a note

I think this behaviour is incorrect. canEdit() I assume requires a record rather than being intialized as a singleton (i.e since canEdit would normally check the page access rights). canCreate doesn't normally rely on instance state.

Can you give me a resource to look at in order to get this correct? I'm happy to do the work, and I think it's an important issue to fix.

@tractorcow Collaborator

Hm, I see the fix you've added, but I'm not sure that using the permissions of the ->first matching instance is a good idea. Pages can have permissions applied to them on a one by one basis. E.g. if you restrict editing to the home page to certain users (type = 'ContentPage') then all other ContentPage types in your tree are unsortable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@oddnoc oddnoc referenced this pull request from a commit in oddnoc/silverstripe-cms
@RuthAdele RuthAdele Change SiteTreeHints to check for canEdit
Allowing ability to have
public function canCreate($member = null) {
    return MyPage::get()->count() < 1;
}
and still be able to re-order this page in the sitetree.

Cleaned-up version of [this pull request][1].

[1]: silverstripe#1035
388acf2
@tractorcow tractorcow added the 3.1 label
@tractorcow
Collaborator

(as commented above, since it probably isn't visible)

Hm, I see the fix you've added, but I'm not sure that using the permissions of the ->first matching instance is a good idea. Pages can have permissions applied to them on a one by one basis. E.g. if you restrict editing to the home page to certain users (type = 'ContentPage') then all other ContentPage types in your tree are unsortable.

@RuthAdele

Yeah, I know, I guess that's the problem with using canEdit to check for sorting ability. A similar problem already exists with using canCreate (can't move pages that are restricted to one only, i.e. homepage, cartpage, checkoutpage etc)

I suppose we could change the reference array to a page by page basis, instead of class. But I imagine the overhead on this would make thing slower? (can someone confirm?)

Other options could be:

  • remove all permissions on moving pages?
  • make it a permission based on current member rather than page class.
@tractorcow
Collaborator

Could it be cached by page ID rather than class?

@RuthAdele

Yes, I thought the same thing. @wilr - can you confirm this won't cause any other issues? And does this sound like a solution to you?

@tractorcow
Collaborator

You will just have to test it. :)

@RuthAdele RuthAdele Change SiteTreeHints to a page by page basis.
Also checking canEdit permissions rather than canCreate.
f91ed94
@RuthAdele

This one is going to fail too - can anyone show me how to run the tests without needing to commit here? Or is that the only way to do it?

@stevie-mayhew

@RuthAdele, you need to install PHPUnit and run them locally.

There is a guide at http://doc.silverstripe.org/framework/en/howto/phpunit-configuration

@RuthAdele

Thankyou muchly!

@oddnoc oddnoc referenced this pull request from a commit in oddnoc/silverstripe-cms
@RuthAdele RuthAdele Change SiteTreeHints to check for canEdit
Allowing ability to have
public function canCreate($member = null) {
    return MyPage::get()->count() < 1;
}
and still be able to re-order this page in the sitetree.

Cleaned-up version of [this pull request][1].

[1]: silverstripe#1035
823f9fe
@nfauchelle

@RuthAdele @tractorcow
What about instead of checking for canCreate or canEdit here, we don't worry about it.

When the user goes to drag an item which is canEdit = false then little notification pops up saying "Forbidden" and the item moves back to where it was in the list anyway.

I don't think it's worth the extra code just to get a red X, and instead we could remove 3 lines of code, modify 1 line (might even run a little faster without the loop over the classes) and we get the desired result.

Any reason we can't solve it with that?

@nfauchelle

I've created a pull request with my suggestion.
It passes the phpunit tests locally.
#1125

@oddnoc oddnoc referenced this pull request from a commit in oddnoc/silverstripe-cms
@RuthAdele RuthAdele Change SiteTreeHints to check for canEdit
Allowing ability to have
public function canCreate($member = null) {
    return MyPage::get()->count() < 1;
}
and still be able to re-order this page in the sitetree.

Cleaned-up version of [this pull request][1].

[1]: silverstripe#1035
a86026f
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jun 18, 2014
  1. @RuthAdele

    Change SiteTreeHints to check for canEdit

    RuthAdele authored
    Allowing ability to have
    public function canCreate($member = null) {
        return MyPage::get()->count() < 1;
    }
    and still be able to re-order this page in the sitetree.
Commits on Jul 10, 2014
  1. @RuthAdele
Commits on Aug 20, 2014
  1. @RuthAdele

    Change SiteTreeHints to a page by page basis.

    RuthAdele authored
    Also checking canEdit permissions rather than canCreate.
This page is out of date. Refresh to see the latest.
Showing with 23 additions and 22 deletions.
  1. +23 −22 code/controllers/CMSMain.php
View
45 code/controllers/CMSMain.php
@@ -384,77 +384,78 @@ public function Breadcrumbs($unlinked = false) {
*/
public function SiteTreeHints() {
$json = '';
- $classes = SiteTree::page_type_classes();
+
+ $pages = Page::get();
+ $pageIDs = array();
+ foreach($pages as $page) $pageIDs[] = $page->ID;
- $cacheCanCreate = array();
- foreach($classes as $class) $cacheCanCreate[$class] = singleton($class)->canCreate();
+ $cacheCanEdit = array();
+ foreach($pages as $page) $cacheCanEdit[$page->ID] = $page->canEdit();
// Generate basic cache key. Too complex to encompass all variations
$cache = SS_Cache::factory('CMSMain_SiteTreeHints');
- $cacheKey = md5(implode('_', array(Member::currentUserID(), implode(',', $cacheCanCreate), implode(',', $classes))));
+ $cacheKey = md5(implode('_', array(Member::currentUserID(), implode(',', $cacheCanEdit), implode(',', $pageIDs))));
if($this->request->getVar('flush')) $cache->clean(Zend_Cache::CLEANING_MODE_ALL);
$json = $cache->load($cacheKey);
if(!$json) {
$def['Root'] = array();
$def['Root']['disallowedChildren'] = array();
- // Contains all possible classes to support UI controls listing them all,
+ // Contains all possible ids to support UI controls listing them all,
// such as the "add page here" context menu.
$def['All'] = array();
// Identify disallows and set globals
$globalDisallowed = array();
- foreach($classes as $class) {
- $obj = singleton($class);
+ foreach($pages as $obj) {
$needsPerm = $obj->stat('need_permission');
if(!($obj instanceof HiddenClass)) {
- $def['All'][$class] = array(
- 'title' => $obj->i18n_singular_name()
+ $def['All'][$obj->ID] = array(
+ 'title' => $obj->i18n_singular_name() //NOT SURE IF THIS LINE NEED EDITING.
);
}
if(!$obj->stat('can_be_root')) {
- $def['Root']['disallowedChildren'][] = $class;
+ $def['Root']['disallowedChildren'][] = $obj->ID;
}
if(
($obj instanceof HiddenClass)
- || (!array_key_exists($class, $cacheCanCreate) || !$cacheCanCreate[$class])
+ || (!array_key_exists($obj->ID, $cacheCanEdit) || !$cacheCanEdit[$obj->ID])
|| ($needsPerm && !$this->can($needsPerm))
) {
- $globalDisallowed[] = $class;
- $def['Root']['disallowedChildren'][] = $class;
+ $globalDisallowed[] = $obj->ID;
+ $def['Root']['disallowedChildren'][] = $obj->ID;
}
}
- // Set disallows by class
- foreach($classes as $class) {
- $obj = singleton($class);
+ // Set disallows by id
+ foreach($pages as $obj) {
if($obj instanceof HiddenClass) continue;
- $def[$class] = array();
+ $def[$obj->ID] = array();
$allowed = $obj->allowedChildren();
if($pos = array_search('SiteTree', $allowed)) unset($allowed[$pos]);
- // Start by disallowing all classes which aren't specifically allowed,
+ // Start by disallowing all ids which aren't specifically allowed,
// then add the ones which are globally disallowed.
- $disallowed = array_diff($classes, (array)$allowed);
+ $disallowed = array_diff($pageIDs, (array)$allowed);
$disallowed = array_unique(array_merge($disallowed, $globalDisallowed));
// Re-index the array for JSON non sequential key issue
- if($disallowed) $def[$class]['disallowedChildren'] = array_values($disallowed);
+ if($disallowed) $def[$obj->ID]['disallowedChildren'] = array_values($disallowed);
$defaultChild = $obj->defaultChild();
if($defaultChild != 'Page' && $defaultChild != null) {
- $def[$class]['defaultChild'] = $defaultChild;
+ $def[$obj->ID]['defaultChild'] = $defaultChild;
}
$defaultParent = $obj->defaultParent();
$parent = SiteTree::get_by_link($defaultParent);
$id = $parent ? $parent->id : null;
if ($defaultParent != 1 && $defaultParent != null) {
- $def[$class]['defaultParent'] = $defaultParent;
+ $def[$obj->ID]['defaultParent'] = $defaultParent;
}
}
Something went wrong with that request. Please try again.