Categories
JavaScript jQuery Php SilverStripe Tutorial

Silverstripe 3 – Per user page access permissions

Most of the times group access in SilverStripe is sufficient for controlling user access, but for this project I had a specific situation where every user needs to have a dedicated page. In order to avoid unnecessary editing and creating groups for each individual user, I decided to extend SiteTree and create a page with per user access control.

So, I’ve created a new page type, since I only needed it for a single page type, but you can extend/decorate SiteTree any way you like.

Let’s get to the code. This goes to mysite/code/FilePage.php

So, let’s break it down a bit:

I’ve created a new variable – CanViewTypeExtended to replace SiteTree’s CanViewType, since I couldn’t find the way to add an option (If you know a way, feel free to drop a line). It replicates SiteTree’s CanViewType with OnlyTheseMembers option added, which is our per user access type.

Then, we have has one ViewerMember, which holds actual user ID for single user (I’ve limited it to one user, since using any more would be a group).

The rest is pretty basic, mostly copied from SiteTree with a bit of additions, getSettingsFields  is a standard function for updating the Settings tab in CMS. There we have first included the JavaScript file, which will be shown later, and is only for decoration – showing and hiding fields based on selection.

Then we have created Member selection field, to pick a member to which the access will be granted, and replicated creating CanViewType field from SiteTree.php with addition of our new OnlyTheseMembers option.

After this is saved, all that is left is to check user permissions in canView() method. Since we don’t use CanViewType any more, but have replaced it with CanViewTypeExtended, the entire function is copied from SiteTree.php, except for the last part which grants the access if current member is our selected member:

if($this->CanViewTypeExtended == ‘OnlyTheseMembers’ && $member && $member->ID == $this->ViewerMemberID)
return true;

So, here’s the remaining js file, which goes to mysite/javascript/CMSMain.EditFormMember.js

 

Categories
JavaScript

Integrate CKFinder with TinyMCE

I know TinyMCE isn’t very popular lately, since it’s not free any more, but I was asked by a client to fix the file uploading with TinyMCE in their CMS. It uses the last free version of TinyMCE – 1.41, and used to have TinyBrowser integrated for file browsing. As the TinyBrowser stopped working and support is equal to nothing, I decided to integrate CKFinder instead.

It wasn’t an easy task, but bit by bit i somehow managed it. What’s even worse, their CMS didn’t use any frameworks, so I decided to keep it that way, and wrote pure javascript. The script isn’t very nice, but it works.

OK, let’s get to the coding part. After importing the needed .js files first thing that needed to be done is defining the custom function in TinyMCE initialization that will be called when the Browse button is pressed.

 

Here it’s named myFileBrowser (file_browser_callback : ‘myFileBrowser’). Nothing much to say about that, so let’s skip to myFileBrowser function, which launches the CKBrowser itself.

 

I left the comments from the example I found for using CKBrowser with a textfield. So, basicaly we just init the finder and set what function will be called when the file is selected. SetFileField is the function that is left to be created, and file_name will be contained in the data array passed to the function. Let’s get onto it:

 

This part was a bit tricky, since TinyMCE opens iFrames in modal dialogs I couldn’t just access the text field by it’s id, but had to access it via iFrames id. To do that, as the frames id is generated again with each modal opening, I had to find the current assigned id. I used a bit of trick there, by accessing the overlay div by class, as it is always static (clearlooks2), and then getting element by tag name “iframe”. Once I had that prepared, I was able to get the field by id and populate it’s contents. In my case, as there was no framework support, I used Robert’s Ultimate getElementsByClassName to get the element by class.

I don’t know if this will be useful to someone, as TinyMCE is disappearing from the scene, but if anyone get’s in a similar situation, I’m sure this will help.