2

First site using Craft and impressed thus far.

I'm going to be allowing CP access for all users, and these users will have access to multiple channels. I want them to be able to relate their entries from different channels to each other, but only be able to select from their own entries within the relationship field.

I can't seem to find anywhere that allows this. I did a test with 2 separate users, and when I went to relate, I could see the other user's entries available for relationship in the entries relationship field. This won't be acceptable as each user should be in their own silo and only have the ability to relate their own entries.

Is there any way I can accomplish this that I'm missing? (edit: without custom field type)

2

Brad is correct – this isn't possible to do without writing a plugin. For your particular use case, this will be very simple, though.

What you'll have to do, is to write a custom FieldType that extends the stock EntriesFieldType class. The only thing your custom fieldtype needs to do, is to add an additional criteria to the query that pulls entries for input selection. Don't worry, this is going to be quite easy.

The quickest way to get started is to use the excellent Plugin Factory to scaffold your plugin. Call it whatever you like. Don't enable any of the plugin components.

Download and unzip your plugin, and put the folder in your craft/plugins directory. Add a sub folder called fieldtypes to your plugin's directory (i.e. {pluginhandle}/fieldtypes).

Create a new file in the fieldtypes directory called MyPlugin_RestrictedEntriesFieldType.php or the like (where MyPlugin should be replaced with the real name for your plugin).

Inside that file, paste the following code (remember to change the class name to whatever you called the file):

<?php
namespace Craft;

class MyPlugin_RestrictedEntriesFieldType extends EntriesFieldType
{

    public function getName()
    {
        // This can be whatever you want, but avoid "Entries"
        return Craft::t('Restricted Entries');
    }

    protected function getInputSelectionCriteria()
    {
        $user = craft()->userSession->getUser();
        return array(
            'authorId' => $user->id,
        );
    }

}

That's the whole thing; your custom fieldtype. Save the file and install your plugin. Convert whatever relevant Entries fields you may have to your new "Restricted Entries" fieldtype.

The code above should be fairly self explanatory – it extends EntriesFieldType which means it'll work exactly like the stock Entries field (and any fields can also be converted to and from the Entries fieldtype without losing data). The only difference is that your custom fieldtype includes the authorId criteria when Craft pulls entries for input selection, where the authorId needs to match the currently logged in user's ID.

If you need similar fields for other element types, you can just repeat the process – i.e. for a restricted Categories field, you'd create an additional file called myplugin/fieldtypes/MyPlugin_RestrictedCategoriesFieldType.php that extends CategoriesFieldType, and include the same getInputSelectionCriteria() method as above.

For a bit of flexibility, you can also limit the restrictive behaviour to non-admins – i.e., if an admin is editing a post, that user should able to select entries authored by all users:

protected function getInputSelectionCriteria()
{
    $user = craft()->userSession->getUser();
    if (!$user->admin) {
        return array(
            'authorId' => $user->id,
        );
    }
    return array();
}    

Finally, a different option is to set the authorId criteria to the current entry's (or category's) author's ID, instead of the currently logged in user's ID. This is more flexible and perhaps more future proof, in that any user that has permission to edit the entry will only be able to select entries that have the same author as the entry's original author.

Obviously, if the entry hasn't been saved yet it won't have an author, so this code should fall back to using the current user's ID for new entries, as above:

protected function getInputSelectionCriteria()
{
    if ($this->element) {
        return array(
            'authorId' => $this->element->authorId,
        );
    }
    $user = craft()->userSession->getUser();
    return array(
        'authorId' => $user->id,
    );
}
  • Fantastic answer and exactly what I needed. I knew I'd be able to do a custom field but this saved me having to research the best approach and implement. Much appreciated. – Dexterity Aug 4 '16 at 14:43
  • Awesome @Dexterity - happy it helped you out. – Mats Mikkel Rummelhoff Aug 4 '16 at 15:25
2

Craft's permission system doesn't go down to the field level, which is what you're looking for.

You'd either have to replicate the functionality you're looking for on the front-end of the site, or develop a custom field type that took into account custom permissions for your users.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.