I have plugin
plugin: tree
-----controller: tree
-------------action : admin_index
DB Table aros_acos has updated _CRUD 1 1 1 1 for this aco.
I code $this->Acl->check(array('model'=>'User','foreign_key'=>2),'Tree/Tree/admin_index');
error:
DbAcl::check() - Failed ARO/ACO node lookup in permissions check. Node references:
Aro: Array
(
[model] => User
[foreign_key] => 2
)
Aco: Tree/Tree/admin_index [CORE\cake\libs\controller\components\acl.php, line 273]
All other action is permission valid but action of plugins, I cant find reason . Anyone help me.
I don't understand why you have Tree as a plugin - it's a core behaviour.
Please post the appropriate rows from the aros_acos table.
The array you pass into Acl->check doesn't look right to me. I pass in the output of $this->Auth->user() which looks like:
Array
(
[User] => Array
(
[id] => 12
[username] => somebody
[group_id] => 1
)
)
Have a look at Mark Story's tutorial - it really is excellent:
http://mark-story.com/posts/view/auth-and-acl-an-end-to-end-tutorial-pt-1
There was a change in Cakephp 1.3. Only the index route is supported for the controller that is named the same as plugin. So, you will need to handle that first if you use 1.3 version.
Check the ARO and ACO tree in the console: cake acl view aco, cake acl view aro. Try to check the permissions from console cake acl check YOURARO YOURACO all
Related
I need my nodes to have multiple aliases for example www.example.com/1/title-of-node. should be opened by www.example.com/2/title-of-node or www.example.com/3/title-of-node. Does there exist any functionality for this in drupal ? Pathauto doesn't provide this.
for this you have to create a custom module i am writting pesudo code bellow
step1 : create a custom trigger in module
step2 : write db_insert query in a function which will be call just after a node is saved in trigger
db_insert code is given is below
$nid = db_insert('url_alias')
->fields(array(
'alias' => 'another alise',
'source' => 'node/'.$node->id,
))
->execute();
in drupal url_alise table is reposible to keep alise with respect to node.
I've run into a bit of a problem saving data in cake php.
here are the models/relationships.
District hasMany Departments
Department hasMany Groups
I am in a view for creating new district, in which I've allowed the user to create multiple new departments. while creating each department, the user may create multiple groups for that dept. Now the trouble is I'm unsure of how to save the group data.
for each department that is created on the fly, im using the multiple index method for the inputs (i.e. "Department.0.name", Department.0.type) so this will be a cinch to save using the saveAll method. However, for each group that is created, i will need a department_id, and since none of the District's departments have yet been saved, they don't have an id. how can i save this new district's data, saving the new departments, and their associated new created groups? is there a way that i can address the name attribute of the group inputs that will create the proper association, something like "Department.0.Group.0.name", for instance?
Thanks in advance!!! if anything is unclear, please don't hesitate to say so, I'll be glad to rephrase.
What does your POST data array look like?
<?php
debug($this->data);
?>
If it is not in the correct format, the associated models won't get saved.. Cake knows to grab the "lastInsertId()" of the models which haven't been saved yet, so you don't have to worry about those... What i'm not sure about, and the docs don't really go into, is how deep the save goes. The example provided is as follows:
$this->data =
Array
(
[Article] => Array
(
[title] => My first article
)
[Comment] => Array
(
[0] => Array
(
[comment] => Comment 1
[user_id] => 1
)
[1] => Array
(
[comment] => Comment 2
[user_id] => 2
)
)
)
$this->Article->saveAll($this->data);
This is the correct structure (cakephp 1.3) for saving associated models of a 'hasMany' relationship, but i'm not sure if it goes any deeper than one child.
One thing that comes to my mind is to build the array according to the format above, but leave the parent model out. Then manually save the parent model data, grab the ::getLastInsertId(); then do a saveAll on departments and groups.
[UPDATE]
I just tested your theory and it will work the way you intend.
<?php
echo $this->Form->input('Department.0.Group.0.name');
?>
Will produce:
<input name="data[Department][0][Group][0][name]" type="text" id="Department0Group0name">
[UPDATE 2]
I did some exploring in lib/Cake/Model/Model.php and found this:
<?php
...
public function saveAssociated($data = null, $options = array()) {
...
... // code omitted.
...
if ($options['deep']) { // This will recurse infinitely through all associations
$saved = $this->{$association}->saveAssociated($values, array_merge($options, array('atomic' => false)));
}
...
...
... // code omitted.
...
?>
I am having trouble with my cakePHP and wondering if anyone else has experienced this. I am trying to setup a User object. I create the Model:
class User extends AppModel
{
}
I create the controller:
class UsersController extends AppController
{
function view($id = null) {
$this->User->id = $id;
$this->set('users', $this->User->read());
}
}
and I go to the view page. However, I am not getting what the cake documentation says I should be getting. I am getting:
Array
(
[0] => Array
(
[id] => 3
[FirstName] => 1
[LastName] => 1
)
)
when what I am expecting to see is
Array
(
[User] => Array
(
[id] => 3
[FirstName] => 1
[LastName] => 1
)
)
Also when I do a $this->User->find('all'); I get back an array like so:
Array
(
[0] => Array ([0] => Array (/*stuff here*/))
[1] => Array ([0] => Array (/*stuff here*/))
[2] => Array ([0] => Array (/*stuff here*/))
)
I have tried changing the name to Myuser (including the database table, controller, model, etc) and still have the same results, so I don't think it's related to a reserved keyword.
Has anyone run into this or, more importantly, does anyone have a clue how I might fix it? Thanks.
EDIT:
I am using cake version 2.0.6. I am using a MySQL 5.0.92 database. I just have tried setting the name variable and it did not change my results.
After an ENTIRE DAY of troubleshooting, I finally was able to solve it.
The cause is definitely an outdated pdo_mysql.so library. This is located in /usr/local/lib/php/extensions/(latest directory)/pdo_mysql.so
The table name being returned in getColumnMeta was only added in a certain version due to this function request:
https://bugs.php.net/41416/
Now, the problem is, in some web hosts, PHP needs to be compiled with Easy Apache. Mine had to go through that as well just in order to enable PDO (it was initially disabled). But the problem is, for some reason, Easy Apache is downloading some obsolete source code everytime it runs. Running yum or installing any RPMs don't help either.
So here is what I did:
- I downloaded the latest PHP sources from the PHP site, extracted the tarball
- I ran Easy Apache, did a recompilation, and very quickly went to the console to watch it redownload the outdated PHP sources
- When the PHP sources have reappeared, I very quickly replaced the entire ext/pdo_mysql directory with the latest sources
- Easy Apache will compile httpd first, so you have some time to do the above step
- After the build is done, reboot.
- To check if your version of pdo_mysql.so supports the table name, execute this command:
strings -f pdo_mysql.so | grep ': table'
- There should be an entry there. The old version doesn't.
- By the way, I noticed that there are more copied of the pdo_mysql.so in /usr/lib/php/modules and /usr/lib/php/extensions, but it seems that the one in /usr/local is the one that is active. Nevertheless, I update all copies manually
NOTE: if you just try to update the pdo_mysql.so file, it will not work. You will get a segmentation fault, and the pages will render nothing. You need to recompile PHP using the above steps.
I hope this will help other people who will come across this bug.
Be sure your table is named users and include the association explicitly
class User extends AppModel {
public $name = 'User';
public $useTable = 'users';
...
You need to set the $uses variable to associate the User model with the controller if you are using any additional models. Adding it explicitly even if there's just one will not hurt either...
for example
class UsersController extends AppController {
//Controller Name
public $name = 'Users';
//DB Config for desired connection
public $useDbConfig = 'test';
// Array of associated models
public $uses = array('Store','User');
//Array of Helpers used by Controller Views
public $helpers = array('Html', 'Form');
...
Also, check to be sure there are no edits in AppModel or AppController which may be accidentally contributing to the interactions here... You may also consider dumping the value of the $uses to see what's there.
Finally found out that the reason for it has to do with a function called PDOStatement::getColumnMeta. This gets called on the queries that cakePHP runs is used by the framework to get the column name, column type, and table name. However, for whatever reason, on the webhost I currently have, this function does not return the table name so cakePHP defaults to creating the array with a 0 index rather than a table name index.
$column = $results->getColumnMeta($index);
if (!empty($column['table']) && strpos($column['name'], $this->virtualFieldSeparator) === false) {
$this->map[$index++] = array($column['table'], $column['name'], $type);
} else {
$this->map[$index++] = array(0, $column['name'], $type);
}
still not sure how to fix it yet, but this is definitely why it is happening.
Yes, you are right. beastmaster
The reason why is that u using old version of PDO driver which has been been deprecated. the PDOStatement::getColumnMeta does not show [table]=name in old version
So solution here download new version of PHP which has build-in PDO. DO NOT INSTALL PDO VIA PECL coz u getting old version of PDO extension. and using
<?php phpinfo ?>
to check if it is installed properly. so u can use native PDO driver coming with PHP rather than use extension PDO driver.
By the way, Thank you for point out the problem.
I have just faced the problem. The cause was not an outdated pdo_mysql.so library.
If you use cakephp 2.3.x and make sure to use PHP 5.2.8 or greater, you should check whether the pdo_mysql extension is enabled or disabled.
You can echo phpinfo() to check it.
Note: the pdo_mysql extension is only enabled if you see "PDO Driver for MySQL enabled", otherwise it is disabled.
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 am using cakephp ACL component to make site secure but the problem is when i am trying to deny a particular action for eg.cake acl deny Group.3 Notes 'delete' , it denies all the action of the controller for that group.The aros_acos table is as follows----
id aro_id aco_id _create _read _update _delete
1 1 1 1 1 1 1
2 2 10 1 1 1 1
3 3 10 1 1 1 -1
In the above table, the third row aro_id points to Group 3 and aco_id points to Notes controller.
What might be the problem.
I don't have access to my implementations at the moment, so this is from memory:
The crud settings in the acos_aros table don't map onto or control access to methods/functions/actions as such. It is the actual row in the table that does that. There will be a row for every permutation of Aro -> Aco that you have defined - they do not necessarily exist by default.
Hence the entry (row) for Administrators:AdminUser_1 => Posts::delete will be a bunch of 1s, 0s or -1s. Set all four numbers to 1 for access or -1 for deny.
I made this easier by building a (huge) matrix of checkboxes for each group, controller & action.
To summarise this, to turn on delete for a user:
find the corresponding row in the acos_aros table
Set all four _create, _read, _update, _delete to 1
e.g.
(3087, 1, 1314, '1', '1', '1', '1'), // allow
(3086, 1, 1313, '-1', '-1', '-1', '-1') // deny
Perhaps your database is corrupted since last changes.
I would recommend you to fix the tables, remember, this are hasMany relations plus TreeBehaviour, if the action kept out from the controller node for any reason would explain that behaviour.
Luckily, there is someone that thought about this and developed the ACL Manager plugin that allows you to fix this using the console.
https://github.com/FMCorz/AclManager
Download the plugin to your plugins folder.
Load the plugin in your bootstrap if you are not loading all already.
Login to you server and use the console to execute any of the following command:
./Console/cake AclExtras.AclExtras aco_sync
You can get a complete guide for all available commands like this:
./Console/cake AclExtras.AclExtras -h
./Console/cake AclExtras.AclExtras aco_sync -h
Any time, if you can not access to the APP, add Controller to the authorize method in your AppController and then: $this->Auth->allow() so any one with valid auth is valid.
Example, just acl check:
$this->Auth->authorize = array(
'Actions' => array('actionPath' => 'controllers')
);
Example Controller and ACL check:
$this->Auth->authorize = array(
'Controller',
'Actions' => array('actionPath' => 'controllers')
);
Using the second option, you can anytime include $this->Auth->allow() in your controller's beforeFilter to allow access who you want.