Let say I have:
$user = $this->Users->newEntity();
So now how can I get the text 'Users' from the $user entity?
In the Entity class I see the _registryAlias, but it is protected and don't have any function to get that. (I dont want to modify the core also)
I need this for my global function that I want to pass only the $user (not to pass both $user and 'Users' to that function).
Thanks.
If you look closely there is a method that returns that properties value: EntityTrait::source()
See API > \Cake\Datasource\EntityTrait::source()
[...]
If called with no arguments, it returns the alias of the repository this entity came from if it is known.
[...]
Related
I installed dektrium\user and dektrium\rbac\ modules for manage user and access control.Related tables and files installed completely and i can see several tabs in /user/admin path ( Users, Roles, Permissions, Rules, Create ) for work with modules.I can manage users perfectly(create user, reset password, edit,..). buy I can not create a rule.
I created a class in app\rbac\rules folder named AuthorRule :
<?php
namespace app\rbac\rules;
use yii\rbac\Rule;
use app\models\News;
/**
* Checks if authorID matches user passed via params
*/
class AuthorRule extends Rule
{
public $name = 'isAuthor';
/**
* #param string|int $user the user ID.
* #param Item $item the role or permission that this rule is associated with
* #param array $params parameters passed to ManagerInterface::checkAccess().
* #return bool a value indicating whether the rule permits the role or permission it is associated with.
*/
public function execute($user, $item, $params)
{
return isset($params['news']) ? $params['news']->createdBy == $user : false;
}
}
(I created news class with model,controler,views)
but when I entered name and class rule in my modules. Neither the data is logged nor the error message. I can't add the rest of the sections until I get into the rule.
I certainly hope the OP has solved their problem by now, but other people might encounter it.
First a remark: as described, the Save fails silently. This is because the form is submitted with Ajax (XHR). The error can be seen in the browser console.
This is the relevant part of the error message:
preg_match(): Compilation failed: invalid range in character class at offset 8
Due to the architecture of Yii 2, the actual regexp is a little tricky to find. It is in the model for Rules in yii2-rbac vendor/dektrium/yii2-rbac/models/Rule.php, line 86.
The original regexp is /^[\w][\w-.:]+[\w]$/
PHP 7.3 uses the PCRE2 library instead of the original PCRE, and the pattern above is wrong. The dash (-) needs to be escaped.
The full line should now be:
['name', 'match', 'pattern' => '/^[\w][\w\-.:]+[\w]$/'],
As the yii2-rbac package is abandoned, you can just modify the file. A more robust solution would be to override the Class.
In the official docs I read:
Do bear in mind that virtual fields cannot be used in finds. If you want them to be part of JSON or array representations of your entities, see Exposing Virtual Fields.
It's not clear to me if the second sentence is in someway related to the first one - say as a workaround to overcome the limitation - or they are completely independent.
I mean: if I expose a Virtual Field then may I use it in a find statement?
Is there a way to include a virtual field in a query? Here a real example:
ItemOrdersTable.php:
$this->setTable('item_orders');
$this->setDisplayField('summary'); // virtual field
$this->setPrimaryKey('id');
Entity:
protected $_virtual = [
'summary'
];
protected function _getSummary()
{
return $this->name . ' ' . $this->description;
}
Usage in a Controller:
return TableRegistry::get('itemOrders')->find('list')->where(['order_id' => $id]);
Because I specified 'summary' as DisplayField, I'm expecting a key-value list of all records that meet the where clause, with the id as key and the summary virtual field as value. Because this doesn't happen (the returned object is null) I'm trying to understand if my code is wrong or I didn't read correctly the documentation as asked above.
Customize Key-Value Output:
https://book.cakephp.org/3.0/en/orm/retrieving-data-and-resultsets.html#customize-key-value-output
Update:
$results = TableRegistry::getTableLocator()->get('item_orders')
->find('list')
->where(['order_id' => $id]);
debug($results->toArray());
$this->set('orders', $results);
debug($orders); exit; <-- test results, and post in your question.
I'm creating a project on CakePHP 3.x where I'm quite new. I'm having trouble with the hasMany related tables to get the name of my entities instead of their ids.
I'm coming from CakePHP 2.x where I used an App::import('controller', array('Users') but in the view to retrieve all data to display instead of the ids, which is said to be a bad practice. And I wouldn't like to have any code violation in my new code. Can anybody help me? here is the code :
public function view($id = null)
{
$this->loadModel('Users');
$relatedUser = $this->Users->find()
->select(['Users.id', 'Users.email'])
->where(['Users.id'=>$id]);
$program = $this->Programs->get($id, [
'contain' => ['Users', 'ProgramSteps', 'Workshops']
]);
$this->set(compact('program', 'users'));
$this->set('_serialize', ['ast', 'relatedUser']);
}
I expect to get the user's email in the relatedUsers of the program table but the actual output is:
Notice (8): Trying to get property 'user_email' of non-object [APP/Template\Asts\view.ctp, line 601].
Really need help
Thank you in advance.
You've asked it to serialize the relatedUser variable, but that's for JSON and XML views. You haven't actually set the relatedUser variable for the view:
$this->set(compact('program', 'users', 'relatedUser'));
Also, you're setting the $users variable here, but it's never been initialized.
In addition to #Greg's answers, the variable $relateduser is still a query object, meaning that trying to access the email property will fail. The query still needs to be executed first.
You can change the query to:
$relatedUser = $this->Users->find()
->select(['Users.id', 'Users.email'])
->where(['Users.id' => $id])
->first();
Now the query is executed and the only the first entry is returned.
There is are a number of ways to get a query to execute, a lot of them are implicit is use. See:
Cookbook > Retrieving Data & Results Sets
Hi I followed a tutorial to implement a friend system. It all works find, but I need to post other columns to the row that just the id's. How would I expand that.
This is the method that is accessed when the add friend button is clicked
public function getAdd($id){
$user = User::where('id', $id)->first();
//After passing all checks. Add other account
Auth::user()->addFriend($user);
echo "Sent";
}
AddTenancy Method
public function addFriend(User $user){
$this->friendsOf()->attach($user->id);
}
I assume the relationship is many-to-many between users. And you need to add additional data to the pivot.
Here's how you'd do that:
public function addFriend(User $user){
$this->friendsOf()->attach($user->id, ['another_col' => 'some data']);
}
Replace 'another_col' and some data with your column and your data. You can also add more than 1 column into the array.
Yii2 build relation many to many
I have 2 tables users and friends
Code query
$friends = Friends::find()
->select(['friends.user_id', 'users.name'])
->leftJoin('users','users.id = friends.friend_user')
->with('users')
->all();
In result error
Invalid Parameter – yii\base\InvalidParamException. app\models\Friends has no relation named "users".
Friends has a column called user_id and thus only belongs to one user. If you auto-generated the Friends ActiveRecord it probably has a function getUser (singular because it is only one) that will look something like this:
public function getUser() {
return $this->hasOne(User::className(), ['id' => 'user_id']);
}
So you're getting the error because no getUsers function exists (that returns a valid ActiveQuery object). Because there can only be one user per friend I think you should use the singular version. And if that still gives the same error you should implement the function above and maybe change it a bit to match your classname.
When you use with(['relation']) to load relations Yii will convert the entry to getRelation and call that function on the model to get the query that is needed to load the relation.