Is there a way to set Expression Engine entries to be viewable by Super Admins but prevent everyone else from seeing it?
Thanks
It depends on how you have things set up.
You can set templates to only be viewable by super admins, so you could handle this at that level.
Or in the channel entries tag itself, you could set the status parameter depending on whether someone is a super admin and then use a certain status for the restricted entries (which could be closed if you like, or a custom status). Or you could do the same thing with categories instead if you prefer.
The following conditional is true for super admins (more info at http://expressionengine.com/user_guide/templates/globals/conditionals.html#cond_group_id)
{if group_id == '1'}
Using conditions within a channel entries tag can be a bit iffy - it depends on parse order - something like this could work:
{exp:channel:entries status='open{if group_id == "1"}|restricted{/if}' ....}
You can also just output certain stuff within a channel entries loop if the viewer is a super admin, but you need to use {if member_group == '1'} inside the loop instead.
This doesn't work for me, I've found that I can use the dynamic parameters feature of the channel:entries tag pair though to achieve the desired result:
http://expressionengine.com/user_guide/modules/channel/dynamic_parameters.html
:)
Related
We currently have a number of workflows in our organization that require users to add an item to a list via a form, but then not be able to edit that item unless given special permission to do so.
For example a user submits a leave of absence request and it is routed to their manager. The 1st level manager might approve this request and the workflow continues. While the request is in the managers hands it cannot be modified by the original submitter, however if the manager rejects it or requires revision the original submitter should then be able to edit.
Is this possible? The best strategy we could come up with for this is multiple Lists to handle the different levels of security required for this. Are there better ways of doing this?
SharePoint seems to have a very open concept of security within an SP site and maybe were just trying to fit a square peg in a round hole.
Thanks!
How about Remove permission for that user/for all user using workflow itself?
http://spcycle.blogspot.jp/2012/01/how-to-create-workflow-to-change-item.html
http://shareapointkiran.blogspot.jp/2012/06/addremove-permissions-using-sharepoint.html
And then give it back when manager approves/rejects
I had a similar problem and solved it with a quick and dirty solution.
In our case this quick and dirty solution might be even easier.
You could add a hidden field that has an default value of for example 0.
Then you add a (formating) rule to one of the fields that should be deactived.
The rule should deactivate the field if the value of the hidden field is not 0.
This rule can be copied to every field that should be deactivated too.
Now add a set field action to your workflow that set the value of the hidden field to something else than 0, for example 1.
To make a hidden field you can define formating rule with a condition that is always true.
Now if someone creates a form the workflow will set the value of your hidden field to 1. The rule of the fields that should be deactived will now deactivate the fields.
Hide the field
Deactivate the field rule
I've been asked if the internal sales site i built can support multiple event calendars. What they would like is a calendar for each group and a global. So the global calendar will shows global and events from each group. The Group Calendars would only show their relevant events.
So i added folders to my Event node, and added some test pages. They show in the global event since it's path is ./%. Great.
For a group (Compliance), it's path is /events/compliance/%. This works, and the Compliance calendar only shows events in within the specified folder.
But.
Each event node's url is based on the global path so /event/compliance/event-1.aspx. This takes the user out of the group section and breaks the user flow. I'd like the group specific events to still apear with their URL stucture. So like this, /Our-Company/Compliance/Calendar-of-Events/event-1.aspx.
I could have the group specific events with their node, but then i loose all the vents on the global calendar. So is there a way for a single calendar to pull events from multiple locations within the tree?
You have a couple options:
Use linked pages. This would allow you to have a global location and simply have a "copy" in a different location (for navigation purposes really). Nice part is if update one of those linked pages, it updates them all so no worries about outdated content.
Categorize your events. Little more effort involved with this one but will work the same.
Set the WHERE statement to filter on the NodeAliasPath. You'd do something like this
Path = /%
Where = "NodeAliasPath LIKE '/GlobalEvents/%' OR NodeAliasPath LIKE '/Groups/Compliance/Events/%'"
3 is probably your best bet and if you want to make it more dynamic you can use macros in your where condition.
I agree with Brenden especially #2. #2 is going to give you the most flexibility and control over querying global items into multiple areas, but also gives you a single management location. We use that method on almost all of our projects and is both easy to manage but also easy to teach your content contributors how to use it the best.
The only other recommendation I would give is also include some kind of flag field where you can prioritize those items on a calendar list view. We often have a requirement that things do not only show up by date order, but also that certain calendar events take priority in sorting. Where you might not use that upfront, having that available down the road is some good forward thinking.
Edit: See my answer below.
For my needs, I decided to use both ACL and voters for my app (maybe it is not the best way, please, tell me if I'm wrong with this).
My entities represent a factory where there are :
Lines owning Workshops owning Equipments owning Spare Parts.
I want to give either a manager or a viewer access to a line level. For this purpose, I use an ACL on the line.
Because there are more than 5000 spare parts per line, I don't want to write 5000 ace to tell symfony that this user, which is allowed to manage this line, can manage the spare parts of the line.
To solve this problem, I decided to add a voter before the acl check.
I do a isGranted('edit',$sparepart) which is handled by a voter, and inside my own voter, I want to perform a isGranted('OPERATOR',$line).
Actually, I have many more things to check (is the user plant manager ? for example) and I like to combine the voter and the ACL.
Unfortunately, I'm a bit lost and I don't manage to call the right "isGranted" from my voter, I get an infinite loop error.
Voter isGranted
$authChecker = $this->get('security.authorization_checker');
$authChecker->isGranted('', $post);
ACL isGranted
$securityContext = $this->get('security.context');
$securityContext->isGranted('EDIT', $comment);
I understand this might be a bit confusing, and maybe I'm not doing it the right way :s
Thanks for your help !
So I finally did this in another way.
I use one voter and I created new entities to manage my access.
I have a LineAccess entity with:
ManyToOne: Line
ManyToOne: User
Sp_access: smallint
Cart_access: smallint
Line_access: smallint
So I check everything by myself and I also manage the links with my LineAccess entity and CustomerAccess entity.
Finally, it is the best way I think. Good luck
Here is the full problem for the curious :
For each user, I want to be able to select his permissions with this table.
If, for example, I check Boeing (the customer) manage. I will create an ACL/ACE with OPERATOR for this $customer.
That's it. Later, I want to check if this user is able to manage a line by first looking at a 'OPERATOR' on $line but if it doesn't exist, I will check 'OPERATOR' on $plant, and then 'OPERATOR' on $customer.
If I select Manage Dreamliner plant, I get this :
You can see that I'm still able to chose the kind of access to spare parts and cart. I can set this user, which is a plant manager, another permission : Spare parts manage. For that kind of permission, I can use the mask builder feature which allows me to store with a single integer "SP_MANAGER, CART_VALIDATE, LINE MANAGE', for example.
You can see that it gets a little complex here and this is why I think that ACL are my best friends, but I wanted to add a level of control in which I can manually select which isGranted() method, and on which entity.
I tried to be precise but it is not that easy :s
Thanks a lot for your help !
Voters and ACL are both standalone architecture approach to authorization. I'd recommend using Voters only, since they're easier to understand, use and extend.
For more details on this comparison, check these explanatory slides.
Where exactly you can't use Voters instead of ACL?
Also, why you need to nest Voters/ACL?
Thanks for your quick answer !
Actually, I thought I needed ACL because I have to put in the database my permissions. And here is the kind of permissions I want :
User A:
Manage line 1 (include workshops, equipments, sp) and can create shopping carts in this line.
View line 2 (can't manage the line but can see it's content) and can only validate the shopping carts.
So I thought it was good to use ACL because that way I can write in the database the permissions for each objects.
I also like the fact that I can use masks.
(There is the same logic on the Plant level)
Very simply I want to have multiple content regions on a single page. Note this is my first Modx site.
So far I have the home page and created child documents for the sub regions on the home page. All I want is to call them in the template.
For example there is a document with an id of 2, and I want the long title on the home page (id of 1).
Something like :
[[~2*longtitle]]
Unfortunately the above just returns the url to that sub document and not the longtitle of that document itself.
So far I've found no documentation on doing so. Does anyone know how to accomplish this?
You have 2 options, the hard way ~ the route you have chosen ;) and the easy way... which I will outline as well.
For what you are trying to do you are going to want to use either getResources http://rtfm.modx.com/display/ADDON/getResources which will allow you to loop over a collection of resources & extract the fields you need [in this case 'content'] or getresourceField http://rtfm.modx.com/display/ADDON/getResourceField which will allow you to specify a single resource & the field to extract, just call it multiple times in your template.
You might try:
[[getResources? &parents='[[*id]]' &tpl='myTpl' &includeContent='1']]
Should get all the child resources [up to default ~ 10] of the current resource, then you would create a template for get resources to loop over:
<h1>[[+longtitle]]</h1>
<p>[[+content]]</p>
notice the use of + instead of * for the resource fields
OR
the easy way, create template variables for your extra content areas, you can set them up as rich text areas as well. that way all your content for any given page is within the one resource ~ no need for you to create child resources to hold content for your header/footer/sidebar/etc
Either way will work, the TV method may use less overhead though.
you can use fastfield
[[#12.pagetitle]]
or in a call
[[#[[+id]].pagetitle]]
You can also grab all TVs of that resource, like
[[#12.myTv]]
see also: http://rtfm.modx.com/extras/revo/fastfield
Is it possible to limit the number of channel entries a member can create?
I would like to set a max number per member group.
Thanks
Yes, but it would require writing an extension. The logic would be something like this (assuming you're talking about limiting on the back-end ... from the front-end, if you're using a Safecracker entry form for example, you'd need to take a different approach):
use the sessions_end hook
check to make sure you're in the control panel ($this->EE->input->get('D') == 'cp')
check to make sure you're on the publish screen ($this->EE->input->get('C') ==
'content_publish')
query the database to see how many entries in exp_channel_titles with the channel_id of $this->EE->input->get('channel_id') belong to $this->EE->session->userdata('member_id')
if the result is greater than your allowed maximum, show them an error
That should get you started.