condition while making relation in YIi - yii

Agent:
agent_id (primary key)
User:
f_id (foreign key)
type
I have created relation in this way
public function relations() {
return array(
'user' => array(self::HAS_ONE, 'Users', 'f_id'),
);
}
But I want to add more conditions like join only if type=3 in User table.
thanks.

There is no error like 'Property "CHasOneRelation.0" is not defined' if you use this:
public function relations()
{
return array(
'user' => array(
self::HAS_ONE,
'Users',
'f_id',
'on' => 'user.ref_type = :type',
'params' => array(':type' => 3))
);
}
See this link: http://www.yiiframework.com/forum/index.php/topic/10185-using-relations-and-conditions/

add the condition on your relation
public function relations() {
return array(
'user' => array(self::HAS_ONE, 'Users', 'f_id', array(
'condition' => 'user.type = :type',
'params' => array(':type'=>3)
)),
);
}
http://www.yiiframework.com/doc/guide/1.1/en/database.arr#relational-query-options

You should create a function to get user rather use lazy-load which would use more query even you do not use this relation.
public function getUser(){
return Users::model()->find(array(
'condition'=>'type = :type',
'params' => array(':type'=>3)
));
}
By using this you could use cache function to cache query that relation does not support.
public function getUser(){
return Users::model()->cache(1000)->find(array(
'condition'=>'type = :type',
'params' => array(':type'=>3)
));
}

Related

How to access relationship data in groupgridview with extraRowColumns

The Database Tables:
project_master (id, project_name)
task_master (id, task_name, project_id)
Relationship in the TaskMaster Model:
TaskMaster.php
class TaskMaster extends CActiveRecord
{
/**
* #return array relational rules.
*/
public function relations()
{
// NOTE: you may need to adjust the relation name and the related
// class name for the relations automatically generated below.
return array(
'ProjectsRpl' => array(self::BELONGS_TO, 'Projects', 'project_id'),
);
}
}
Following GroupGridView view file:
Task.php
$this->widget('ext.groupgridview.GroupGridView', array(
'id' => 'Customer-grid',
'dataProvider' => $modelCustomer->searchCustomer(),
//'mergeColumns' => 'project_id',
'extraRowColumns' => array('ProjectsRpl.project_name'),
'extraRowPos' => 'above',
'afterAjaxUpdate' => 'function(){}',
'columns'=>$columns,
));
GroupGridView reference site.
Getting the following errors:
CException: Column or attribute "ProjectsRpl.project_name" not found!
Only one change in Task.php file.
$this->widget('ext.groupgridview.GroupGridView', array(
'id' => 'Customer-grid',
'dataProvider' => $model->search(),
//'mergeColumns' => 'project_id',
'extraRowColumns' => array('project_id'),
'extraRowPos' => 'above',
'extraRowExpression' => '"<b style=\"color: black\">".$data->ProjectsRpl->project_name."</b>"',
'afterAjaxUpdate' => 'function(){}',
'ajaxUrl' => Yii::app()->createUrl('customer/index'),
'ajaxUpdate' => true,
'enablePagination' => true,
"summaryText" => true,
'enableSorting' => FALSE,
'columns'=>$columns,
));

Laravel Auth::attempt() fails. I use SQLite btw

What i'm doing wrong?
<?php
public function login() {
$user_name = time();
User::create(array(
'name' => $user_name,
'email' => $user_name.'#test.com',
'password' => Hash::make('123123'),
));
$user = array(
'email' => $user_name.'#test.com',
'password' => '123123',
);
$m = User::where('email' , '=', $user_name.'#test.com')->first();
dd([
'Auth::attempt($user)',
Auth::attempt($user),
'Auth::check()',
Auth::check(),
'Hash::check($m->password, \'123123\')',
Hash::check($m->password, '123123')
]);
}
Result:
array(6) {
[0]=>
string(20) "Auth::attempt($user)"
[1]=>
bool(false)
[2]=>
string(13) "Auth::check()"
[3]=>
bool(false)
[4]=>
string(38) "Hash::check($user->password, '123123')"
[5]=>
bool(false)
}
Not sure what information should I add.
app/config/auth.php
'driver' => 'eloquent',
'model' => 'User',
'table' => 'users',
app/config/app.php
'key' => 'DMmiPAxSYz4O2jG44S92OcdPZN7ZsGGs',
'cipher' => MCRYPT_RIJNDAEL_256,
models/User.php
<?php
use Illuminate\Auth\UserTrait;
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableTrait;
use Illuminate\Auth\Reminders\RemindableInterface;
class User extends Eloquent implements UserInterface, RemindableInterface {
use UserTrait, RemindableTrait;
/**
* Validation rules
*/
public static $rules = array(
'name' => 'required',
'email' => 'email|required|unique',
'password' => 'min:6',
);
/**
* Validation rules
*/
public static $messages = array(
'name.required' => 'The name field is required',
'email.email' => 'The email field must contain properly formatted email.',
'email.required' => 'The email field is required',
'password.required' => 'The password field is required',
'password.min:6' => 'The password must be minimum 6 characters long',
);
protected $table = 'users';
protected $hidden = array('password', 'remember_token');
protected $guarded = array('id');
public function setPasswordAttribute($value) {
if ($value) {
$this->attributes['password'] = Hash::make($value);
}
}
}
Well here's some checks that you can do
Have you setup config/auth.php with driver, model and table?
Have you filled the fillable array of the User's model?
Have you change the key inside config/app.php ?
Also try to dd($m) in order to see what you got from that query.
I found what is wrong.
This part of code hash password for first time:
User::create(array(
'name' => $user_name,
'email' => $user_name.'#test.com',
'password' => Hash::make('123123'), // <---- first time
));
And this mutator in User model does hashing for second time before put password to database:
public function setPasswordAttribute($value) {
if ($value) {
$this->attributes['password'] = Hash::make($value); // <---- second time
}
}
So I just changed first block to this:
User::create(array(
'name' => $user_name,
'email' => $user_name.'#test.com',
'password' => '123123', // <---- no hashing here
));

How to apply one filter function to all fields in ORM?

I have a Model class:
class Model_Feedback extends ORM {
public function filters() {
return array(
'username' => array(
array('trim'),
),
'email' => array(
array('trim'),
),
'tel' => array(
array('trim'),
),
'text' => array(
array('trim'),
),
);
}
}
Is there a way to trim all fields at once and not to define separate trim filter to every field?
Yes, Kohana allows this via a wildcard as you can see in run_filter(), instead of setting a column as key, use TRUE
public function filters() {
return array(
TRUE => array(
array('trim'),
),
);
}

Saving a Doctrine 2 Entity that contains an ObjectSelect element using Zend Form

I was following along with the Doctrine Hydrator tutorial, but I am having issues saving when my fieldset contains an ObjectSelect. I'm using ORM mapping on my entities. Basically I have a Role entity with id and name. I also have a User entity with id, name and role (ManyToOne). I also have my getters and setters. My setRole() method passes the Role entity as a parameter.
/** #param Role $role */
public function setRole(\Application\Entity\Role $role) {
$this->role = $role;
}
I setup a UserFieldset with a Doctrine Hydrator.
$this->setHydrator(new DoctrineHydrator($objectManager, 'Application\Entity\User'))
->setObject(new User());
The object select for the Role
$this->add(array(
'type' => 'DoctrineModule\Form\Element\ObjectSelect',
'name' => 'role',
'options' => array(
'label' => 'Role',
'object_manager' => $objectManager,
'target_class' => 'Application\Entity\Role',
'property' => 'name'
)
));
I then setup a UserForm that sets the DoctrineHydrator and adds the UserFieldset.
My controller action
public function addUserAction() {
$objectManager = $this->getServiceLocator()->get('Doctrine\ORM\EntityManager');
$form = new UserForm($objectManager);
$user = new User();
$form->bind($user);
if ($this->request->isPost()) {
$form->setData($this->request->getPost());
if ($form->isValid()) {
$objectManager->persist($user);
$objectManager->flush();
}
}
return array('form' => $form);
}
What seems to be happening is that the ID of the role is passed to setRole rather than an object. As a workaround I've modified my action to:
if ($form->isValid()) {
$objectManager->persist($user);
$data = $this->request->getPost();
$role = $objectManager->find('Application\Entity\Role', $data->user['role']);
$user->setRole($role);
$objectManager->flush();
}
It seems as if this additional step should not be required, but I am not sure if I need to modify my setRole or if I also need to bind a Role entity to the form. This is obviously a simplified example, but my actual forms have many associations that will be tedious to have to code in the controller like this.
UPDATE:
Debug information about post and form.
var_dump($form->getData());
var_dump($this->request->getPost());
Output
object(Application\Entity\User)[395]
protected 'id' => int 6
protected 'name' => string 'Jane Doe' (length=8)
protected 'role' => null
object(Zend\Stdlib\Parameters)[146]
public 'user' =>
array (size=3)
'id' => string '' (length=0)
'name' => string 'Jane Doe' (length=8)
'role' => string '3' (length=1)
public 'submit' => string 'Add User' (length=8)
At long last I got it working. The issue was that I needed to add the role to my input filter on the fieldset
public function getInputFilterSpecification() {
return array(
'name' => array('required' => true),
'role' => array('required' => true)
)
}
... and my validation group on my form.
$this->setValidationGroup(array(
'User' => array(
'name',
'role'
)
));
Now to save the user in my action it is simply
if ($form->isValid()) {
$objectManager->persist($user);
$objectManager->flush();
}

Show company users depending on login of their tenent admin in php yii

I have three tables as roles, users and companies. and their relationships as
for Role.php
public function relations()
{
return array(
'userRoles' => array(self::HAS_MANY, 'UserRoles', 'id_roles'),
);
}
for User.php
public function relations()
{
return array(
'userRoles' => array(self::HAS_MANY, 'UserRole', 'id_users'),
'companies' => array(self::BELONGS_TO, 'Company', 'id_companies'),
);
}
For Company.php
public function relations()
{
return array(
'idCompnayType' => array(self::BELONGS_TO, 'CompanyType', 'id_company_type'),
'companies' => array(self::HAS_MANY, 'Company', 'id_companies'),
);
}
I have following functionality-
In roles table there are two three roles as SuperAdmin(Adds Company and their TenantAdmin for that company), TenantAdmin(Adds users to company) and Users.
I have done to functionality for adding all users and assign them roles.
But how can I display normal users as per their company when TenantAdmin for that company is logged in.
You can use the option of through on your relation.
For Company model:
public function relations()
{
return array(
'idCompnayType' => array(self::BELONGS_TO, 'CompanyType', 'id_company_type'),
'companies' => array(self::HAS_MANY, 'Company', 'id_companies'),
'users' => array(self::HAS_MANY, 'User', 'id_companies'),
'userRoles' => array(self::HAS_MANY,'UserRoles',array('id_users'=>'id_users'),'on'=>'userRoles.id_roles = 3','through'=>'users'),
);
}
For UserRole model make sure you have a relationship like so:
public function relations()
{
return array(
'user' => array(self::BELONGS_TO, 'User', 'id_users'),
);
}
A couple assumptions for this statement Primary Key in User is id_users, that the ID of the 'user' type is 3. This will give you an array of UserRole's that are the 'user' type. So you can easily list the users by using a foreach.
$user = User:model()->findByPk(Yii::app()->user->id);
$company = Company::model()->findByPk($user->id_companies);
foreach($company->userRoles as $userRole) {
$user = $userRole->user;
}