pogidude Posted June 17, 2013 Share Posted June 17, 2013 In my module, I have this: /** * Attach our hooks to Page::editable and Page::viewable * */ public function init() { $this->addHookAfter('Page::editable', $this, 'hookPageEditable'); then the callback function: /** * Check if this page, or any ancestor pages, are editable * * From Netcarver * */ public function onMyBranch($page) { $user = $this->user; //get the roles user has $user_roles = $user->roles; //set to false until proven otherwise $page_on_my_branch = false; foreach($user_roles as $role){ $editable_pages = $role->role_editable_pages; if(count($editable_pages)){ $page_on_my_branch = $role->role_editable_pages->has($page); //scan ancestors if applicable if($this->scan_ancestors && !$page_on_my_branch){ $parents = $page->parents; while(!$page_on_my_branch && count($parents)){ $p = $parents->pop(); $page_on_my_branch = $role->role_editable_pages->has($p); } } if($page_on_my_branch){ //page is editable, return! //return $page_on_my_branch; } } } //explicitly return false? return $page_on_my_branch; } /** * Page::editable hook * */ public function hookPageEditable($event) { if($event->return) return; if($this->user->hasPermission('page-edit')) { $event->return = $this->onMyBranch($event->object); } else { $event->return = false; } } Note the role_editable_pages field in the $role variable which is assigned to $editable_pages variable. It's used to store PageArrays. Now, when creating a new page, ProcessPageAdd does it's thing and in ProcessPageAdd::getAllowedTemplates() method, there is this line in line #102: $parentEditable = $this->parent->editable(); so the Page::editable() method is called and my hook runs and calls onMyBranch() method. which runs the foreach() loop. then the conditional check for $editable_pages. But this time, $editable_pages has no Page objects in it. what gives? If I edit a page, my hook still runs and $editable_pages has the Page objects that I've saved. Attached is the complete code. PageEditPerRole.module Link to comment Share on other sites More sharing options...
pogidude Posted June 18, 2013 Author Share Posted June 18, 2013 found something weird that I'm not sure why it's happening. So, I added the field "role_editable_pages" to the "role" template with type "InputfieldPageListSelectMultiple". then, I assigned four pages to the field => "about", "contact", "news", "staff". Now, I got my hook "hookPageEditable" which when editing a page (or showing edit links) checks if a role that a user is assigned to has the current page in the "role_editable_pages" field. For debugging, I list all the items in the role_editable_pages field... which should list 4 items as stated above. Here's what's interesting. When I'm editing a page like say the "about" page, all 4 items get listed. But, when I'm adding page under the "about" page and in the ProcessPageAdd::getAllowedTemplates() method this line is run: $parentEditable = $this->parent->editable(); //$this->parent in this case is the "about" page when I list the items in the role_editable_pages field, only 3 items get listed and the missing item is the "about" page. This is totally confusing to me since I'm not sure what the relationship between the field in the "role" template is and the about page. Link to comment Share on other sites More sharing options...
ryan Posted June 20, 2013 Share Posted June 20, 2013 I'm not sure that I follow everything here. But if you are getting 1 fewer pages in the role_editable_pages than you expect, that seems to imply that something has removed a page from it at runtime. Looking at the above code, the only place that I see where a page is removed is here: $p = $parents->pop(); You might try commenting out that line to see if that's the culprit. Or if commenting it out will result in some kind of infinite loop, you could just echo the contents of it like $this->message("pop: $p"); ...I'd be curious if it's popping the /about/ page. Link to comment Share on other sites More sharing options...
pogidude Posted June 20, 2013 Author Share Posted June 20, 2013 Hi Ryan, Thanks for chiming in. Yes I'm getting 1 fewer pages in role_editable_pages, but ONLY when I add a new page. which is when this line $parentEditable = $this->parent->editable(); runs in the ProcessPageAdd::getTemplates() method. Editing pages is no problem. But, I don't think it's the pop() thing because the first time I noticed this issue was when i only had 1 page assigned to the role_editable_pages field. Which means it wasn't going through this: $editable_pages = $role->role_editable_pages; if(count($editable_pages)){ ..... CODE BELOW ... because $editable_pages now had 0 pages in it (instead of 1 page). and oh, the pop() thing only runs when scan_ancestors is enabled - which I hadn't. What I did notice was if I access the role's "role_editable_pages" field before $this->parent->editable() is called with something like this: foreach($this->user->roles as $r){ $r->role_editable_pages; } things worked as expected. So, what I did was I hooked before ProcessPageAdd::execute() and just ran that foreach loop.. see workaround https://github.com/ryannmicua/PageEditPerRole/blob/master/PageEditPerRole.module#L244 Oh yeah, if you're going to test out the plugin, you'll have to make ProcessPageAdd::getTemplates() hookable. I've been mulling over how to do this for 3 days without hacking core but really saw no way. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now