So I finally got "ACL" to work, and now im trying to get the "alias" value from the "AROS" table.
I want to make a simple message like logged in as .... (admin, moderator or user).
After some tinkering i got the "alias" value from the code below but I can't shed the feeling ther's an easier way to do this. Any help or advice will be greatly appreciated.
Currently im using:
$logindata = $this->Acl->Aro->findByForeignKey($user['User']['id']);
$parent_id = $logindata['Aro']['parent_id'];
$rankdata = $this->Acl->Aro->find('first', array('recursive' => -1, 'conditions' => array('Aro.id' => $parent_id)));
$rank = $rankdata['Aro']['alias'];
There are two option for you which is simpler than yours..i tried that in my project.
1.Save your aros with the same alias as its parent.And then you can use it simply with one line code.
2.Or you can save its parent alias into users table and then you get this all again almost every part of your site with $auth .
Related
I want to archive somthing quite similar to the Bookmark Tutorial here: https://book.cakephp.org/3/en/tutorials-and-examples/bookmarks/intro.html#getting-bookmarks-with-a-specific-tag
To find Bookmarks with the Tags "funny", "cat", "gifs" This query is usable in the BookmarksController:
$tags = ['funny','cat','gifs'];
$bookmarks = $this->Bookmarks->find();
->innerJoinWith('Tags')
->where(['Tags.title IN ' => $tags]);
->group(['Bookmarks.id']);
$this->set('result',$tags);
This returns the Bookmarks tagged with funny OR cat OR gifs.
Im trying to change this to return only Bookmarks taged with funny AND cat AND gifs.
Does anyone has a hint how to archive this?
Thanks I got it working. This is how
$current_tags = ['funny','cat','gifs']
$query = $this->Bookmarks->find()->contain(['Tags'])
->matching('Tags', function($query) use ($current_tags){
return $query->where(['Tags.name IN' => $current_tags]);
});
$query->group('Bookmarks.id')->having([
$this->Bookmarks->query()->newExpr('COUNT(DISTINCT Tags.name) = '.count($current_tags))
]);
Thanks to this answer i solved a problem i had after follwoing the comented answer above. The Problem appears when using variables for the array to search in. in this case $current_tags.
matching([...]) is using an anonymous function.
anonymous functions have a new scope. This is why the variable has to be inherited using use().
I have an event form which contains information related to event like: start_time, finish_time etc.
Every event bolongs to a user. The requirements are that the same type of event can be saved for multiple users, so from the form I receive a list of users as well.
Now that makes it impossible to use model's native save function and for that reason I have the following code:
function saveNotRepeatedEvents($event, $users){
foreach($users as $user){
$event['Event']['user_id'] = $user;
$this->create();
$this->save($event);
}
return true;
}
First of all, it does not allow for transactions, and I have a feeling that it can be done better, like "cakePHP way", but just cannot find anything during the research.
So the main issue would be how to intruduce transactions in this case. But any help or guidance on how to make it more cakePHP way would be much appreciated.
What you're looking for is Model::saveAll($yourData), which at the end will make use of a transaction (as long as your database engine supports transactions).
The main idea is that you will prepare $yourData as an array with this form
$yourData = array(
array('Event' => array('user_id' => 1)),
array('Event' => array('user_id' => 2)),
);
Of course, you will do this in your for loop, I am just giving you the main idea.
I'm trying to implement PDF functionality to my application. So, I added some new actions in controllers (like 'viewpdf').
After this, I rebuild the ACL tree with the build_acl action (from Mark Story Tutorial Automated tool for creating ACOS ).
So, I can see with MySQL that a new node is created.
Until this, everything is fine. But now I try to test the viewpdf button, and I get a 'You are not authorized to access that location.' error (even being admin). I check the error.log file and I see a warning:
> Aco: controllers/Specializations/viewpdf in [/usr/share/php/cake/libs/controller/components/acl.php, line 273]
2011-02-24 11:40:34 Warning: Warning (512): DbAcl::check() - Failed ARO/ACO node lookup in permissions check. Node references:
Aro: Array
(
[User] => Array
(
[id] => 1
[email] => admin#gmail.com
[group_id] => 1
)
)
Aco: controllers/Specializations/viewpdf in [/usr/share/php/cake/libs/controller/components/acl.php, line 273]
Then I check the aros_acos table in the database and I see that there's no 'viewpdf' ACO related to any node, so there's an ARO, an ACO, but not an ARO_ACO, so I suppose that this is the reason why I'm getting this error.
¿Are my suppositions right? If they are, how could I create this aro_aco? I'm afraid that I could break anything if I do it manually...
Thanks in advance,
Alf.
alfizqu,
if you have an ARO and an ACO but no connection between these by means of entries in the ACO_ARO table, this means you have not set up the permissions your AROs have on the ACOs.
Proceed like this:
/*
* Copied from the tutorial, and modified, this function initializes the per-
* missions for accessing controller actions.
*/
function initDB() {
$group =& $this->User->Group;
// A D M I N S
$group->id = 3;
$this->Acl->allow($group, 'controllers');
// M A N A G E R S
$group->id = 2;
$this->Acl->deny($group, 'controllers');
$this->Acl->allow($group, 'controllers/Items','*'); ... ...
Once you have set up such an initDB function, you have to run it once by calling it from your browser.
If this does not suffice to help you back on the track, just go over the basic AUTH/ACL tutorial again.
Yours, Benjamin.
Edit 1:
One of the crucial points is to call the parent::beforeFilter() in the beforeFilter() methods of self-defined controllers and properly setting up the app_controller.
If these tips do not help, the most time-efficient way is to go over the ACL/AUTH tutorial very carefully, starting from a fresh cake environment. Once you can get it up and running there, you are confident to do it in your app.
Edit 2:
And don't be afraid to throw out everything ACL/AUTH related of your app. It just sounds daunting, but it can safe a lot of debugging headaches/time.
P.S.: Btw there should be some moderately usable ACL/AUTH plugins at the bakery and one at sourceforge.
Try to create an sample action in users controller like this
function install(){
$aco = new Aco();
$aco->create();
$aco->save(array(
'parent_id' => <Id of the Specializations in acos table>,
'alias' => 'viewpdf',
));
$this->Acl->allow('admin','controllers/Specializations/viewpdf','*');
}
If u run the action the a new Aco node will be created in acos table. and for the admin user u can give the whole permission.you can use any valid user (username should be in Aros table) instead admin.
hope it helps.
I've got the following relationship set-up between two models
Story belongsTo StoryType
StoryType hasMany Story
I've set-up a form to select the StoryType for each story using the following code:
echo $this->Form->input('Story.story_type_id', array('tabindex' => 2));
with this code in the controller to populate the list
$this->set('story_types', $this->Story->StoryType->find('list', array ('order' => 'title')));
But it's not populating the select box with anything. I know that the find() option is working because doing a debug within the controller produces this:
Array
(
[1] => First Person
[3] => Third Person
)
The weird thing is that it's exactly the same code, just querying other models, to populate select lists for things like users and genres, it's just the story types that isn't working.
Any ideas? Cheers.
You don't mention which version of CakePHP you're using, but try setting storyTypes rather than story_types:
$this->set( 'storyTypes', $this->Story->StoryType->find( 'list', array( 'order' => 'title' ) ) );
Older versions of CakePHP (pre-1.3) modified set variable names to headlessCamelCase and, even if you're using 1.3.x, there may be a little bit of that infrastructure lingering. It's a bit of a reach, but it's easy enough to test and it seems plausible that this could be the root of your problem.
I'll be curious to see what you find out.
This is a little hacky, but I think it will work:
echo $this->Form->input('Story.story_type_id', array('tabindex' => 2, 'options' => $story_types));
here's what you should really do .. (esp, for version 2.x) - in case if some people are facing the same problem.
[inside your constroller action]
$oneOfTheColumns = 'title'; //just for sake of making it clear - if you have to order the results
$storyTypes = $this->Story->StoryType('find', array('order'=>$oneOfTheColumns));
$this->set(compact('storyTypes'));
[inside your view]
echo $this->Form->input('StoryType');
In CakePHP, I have two tables, Countries & Networks. They have a HABTM relationship and are joined by countries_networks.
I'm trying to get all countries from the countries table where the 'name' field in Networks = 'o2'
I've realised I can't do this using a basic find(), so I've been experimenting with the containable behaviour. I have managed to restrict the returned data, but it looks as though 'containable' doesn't exactly work as I want. Heres my code:
$countries = $this->Country->find('all', array('contain' => array(
'Network' => array(
'conditions' => array('Network.name =' => "o2"),
)
)));
This query however returns ALL countries, and the Network.name if its 'o2'. What I really need to do is return ONLY the countries that have a Network.name of 'o2', and no others.
Can anyone help? Thanks.
"=' =>"
What is it? there is no needed to use "=" symbol after "Network.name"
Your query returns you exactly what your ask.
Try to select from Network.
$countries = $this->Country->Network->find('first', array(
'conditions' => array('Network.name' => "o2"),
'contain' => array('Country')
));
$countries = $countries['Country'];
You should be able to do something like this:
$this->Country->hasAndBelongsToMany['Network']['conditions'] = array('Network.name'=>'o2');
$myCountries = $this->Country->find('all');
I haven't tested this, but it should get you pretty close to where you need to be.
Also, bear in mind that changing the hasAndBelongsToMany array like this will affect all subsequent queries against that model during the current page load (but it will be reset the next time the model is instantiated).
I'm on my way out the door, so sorry for the brief explanation.
I think what you want is a HABTM relationship, but to be able to filter based on the associated model's data. To do this, check out the "Containable" behavior in Cake's manual. Pretty sure that's what you're after.