I'm developing a application using sfDoctrineGuardPlugin and Symfony 1.4.20 then I've three users and three users groups and some permissions as follow:
user_name user_group permissions
u1 Group1 can_admin_full, can_admin
u2 Group2 can_admin
u3 Group3 no_admin
So u1 should be able to add users to the application but only can see Group2 and Group3 under Groups Options, u2 should be able to add users to the application to but only can see Group3 under Groups Options, so u1 and u2 shouldn't add users belonging to Group1, how I can get this using sfDoctrineGuard? It's possible?
NOTE: I use GroupN as a example but below in the code sample is the right names for groups and permissions!
EDIT: Improve question
So after take a closer look at this I'm trying to to the same but adapted to my code so in lib/form/doctrine/sfDoctrineGuardPlugin/sfGuardUserForm.class.php I change this:
class sfGuardUserForm extends PluginsfGuardUserForm {
public function configure() {
//groups_list
$this->getWidget('groups_list')->setOption('expanded', true);
$this->getWidget('groups_list')->setOption('table_method', 'getListForAdmin');
$this->getValidator('groups_list')->setOption('query', Doctrine::getTable('sfGuardGroup')->getListForAdmin());
}
}
Also I made this changes at lib/model/doctrine/sfDoctrineGuardPlugin/sfGuardGroupTable.class.php
class sfGuardGroupTable extends PluginsfGuardGroupTable {
/**
* Returns an instance of this class.
*
* #return object sfGuardGroupTable
*/
public static function getInstance() {
return Doctrine_Core::getTable('sfGuardGroup');
}
/**
* Builds list query based on credentials
*
*/
public function getListForAdmin() {
$user = sfContext::getInstance()->getUser();
$q = $this->createQuery('g');
if ($user->hasPermissions('can_admin_full')) {
$q->addWhere('g.name IN (?)', array('Administradores Monitor', 'Monitor'));
} else if ($user->hasPermissions('can_admin')) {
$q->addWhere('g.name IN (?)', array('Monitor'));
}
return $q;
}
}
But don't work because login using a user that belongs to group "Administrador de Servicios" and has permissions 'can_admin' and 'can_admin_full' and I can see all the groups in the widget and I'm looking just for see in that case 'Administradores Monitor' and 'Monitor'
EDIT 2
Also try this other code:
$this->widgetSchema['groups_list'] = new sfWidgetFormDoctrineChoice(array('multiple' => true, 'table_method' => 'getListForAdmin', 'query' => Doctrine::getTable('sfGuardGroup')->getListForAdmin()));
And still not working, I change 'table_method' => 'getListForAdmin' to 'table_method' => 'getListForAdmin1' and nothing happens so I suspect that the method is never called
EDIT 3
Now it's working but see this:
If I use this approach:
$this->getWidget('groups_list')->setOption('expanded', true);
$this->getWidget('groups_list')->setOption('table_method', 'getListForAdmin');
$this->getValidator('groups_list')->setOption('query', Doctrine::getTable('sfGuardGroup')->getListForAdmin());
Then I get this error:
SQLSTATE[HY093]: Invalid parameter number: number of bound variables
does not match number of tokens
If I use the other approach:
$this->widgetSchema['groups_list'] = new sfWidgetFormDoctrineChoice(array('multiple' => true, 'table_method' => 'getListForAdmin', 'query' => Doctrine::getTable('sfGuardGroup')->getListForAdmin()));
I get this other error:
sfWidgetFormDoctrineChoice requires the following options: 'model'.
Then I added the parameter model:
$this->widgetSchema['groups_list'] = new sfWidgetFormDoctrineChoice(array('multiple' => true, 'model' => 'sfGuardGroup', 'table_method' => 'getListForAdmin', 'query' => Doctrine::getTable('sfGuardGroup')->getListForAdmin()));
But get the same error as first approach, I suspect the problem is in getListForAdmin() function but really don't know where exactly
What's wrong at this point?
Try to change the conditional in getListForAdmin():
if ($user->hasPermissions('can_admin_full')) {
$q->whereIn('g.name', array('Administradores Monitor', 'Monitor'));
} else if ($user->hasPermissions('can_admin')) {
$q->whereIn('g.name', array('Monitor'));
}
Related
i have function in my controller that create a forecast :
public function updateOrCreate(Request $request, $subdomain, $uuid)
{
$fixture = Fixture::where('uuid',$uuid)->firstOrFail();
request()->validate([
'local_team_score' => 'integer|min:0',
'visitor_team_score' => 'integer|min:0',
'winner_team_id' => 'integer|nullable'
]);
if ($fixture->status !== "PENDING"){
return response()->json([
'message' => "You can not add or modify a forecast if the fixture is not pending"
], 403);
}
$winner_team = null;
// local team win
if ($request->local_team_score > $request->visitor_team_score) {
$winner_team = $fixture->localTeam;
}elseif ($request->local_team_score < $request->visitor_team_score){ //visitor win
$winner_team = $fixture->visitorTeam;
}else{ // draw
$winner_team = FixtureTeam::where('team_id',$request->winner_team_id)->first();
}
$user = auth('api')->user();
$platform = Platform::first();
$forecast = Forecast::updateOrCreate([
'user_id' => $user->id,
'fixture_id' => $fixture->id,
'platform_id' => $platform->id
],[
'local_team_score' => $request->local_team_score,
'visitor_team_score' => $request->visitor_team_score,
'winner_team_id' => is_null($winner_team) ? null : $winner_team->team_id
]);
$forecast->load('winnerTeam');
return new ForecastResource($forecast);
}
As you can see i use updateOrCreate methods to add or update a forecast.
The problem is when 2 requests from the same user run at the same time (and no forecast is already created) 2 row are inserted.
Do you have a solution ?
I See that the problem is not new but i could not find a solution https://github.com/laravel/framework/issues/19372
updateOrCreate does 2 steps:
tries to fetch the record
depending on the outcome does an update or a create.
This operation is not atomic, meaning that between step 1 and 2 another process could create the record and you would end up with duplicates (your situation).
To solve your problem you need following:
determine what columns would give the uniqueness of the record and add an unique index (probably compound between user_id, fixture_id, platform_id)
you need to let database handle the upsert (ON DUPLICATE KEY UPDATE in MySQL, ON CONFLICT (...) DO UPDATE SET in Postgres, etc). This can be achieved in Laravel by using the upsert(array $values, $uniqueBy, $update = null) instead of updateOrCreate.
I have some where condition in my model .
Its check is field active or no.
Now I need to write a join relation. But I need to remove where condition. Is it possible?
My model.
...
public static function find() {
return (new AssetgroupsQuery(get_called_class()))->active();
}
My relation
public function getAssetgroup(): \app\models\AssetgroupsQuery {
return $this->hasOne(Assetgroups::class, ['asg_id' => 'ass_group'])->andOnCondition(['asg_active' => '1'])
->viaTable('assets', ['ass_id' => 'log_ass_id',]);
}
I need to got all active assets and join, if asset is empty I need to got null fields, but
model where condition added to my current sql query and remove all fields which assets are null.
I try to add some where Condition to remove old where, but it don't work.
Can you help me?
You can reset existing conditions by using where(null).
On relation level:
public function getAssetgroup(): \app\models\AssetgroupsQuery {
return $this->hasOne(Assetgroups::class, ['asg_id' => 'ass_group'])
->andOnCondition(['asg_active' => '1'])
->where(null)
->viaTable('assets', ['ass_id' => 'log_ass_id',]);
}
Or directly on join:
$query = MyModel::find()
->joinWith([
'assetgroup' => function (ActiveQuery $query) {
$query->where(null);
},
])
I'm trying to use auth()->login() in laravel 5.1 but it returns an error. Please see my code below:
$user = User::where('username', $username)->where('activation_code', $activation_code);
$not_activated_user = $user->where('status', 0)->where('confirmed', 0);
if($not_activated_user->count() == 1){
$not_activated_user->update([
'status' => 1,
'confirmed' => 1
]);
auth()->login($user->where('status', 1)->where('confirmed', 1));
}
I've also import use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract; and implements AuthenticatableContract in my User model, but it still returns the same error. Why is that? I also tried to use ->get() in ->login(....->get()) to get the current user, but still same error.
Error:
Argument 1 passed to Illuminate\Auth\Guard::login() must implement interface Illuminate\Contracts\Auth\Authenticatable, instance of Illuminate\Database\Eloquent\Builder given
Try
$user = User::where('username', $username)->where('activation_code', $activation_code)->firstOrFail();
$user->update([
'status' => 1,
'confirmed' => 1
]);
auth()->login($user);
}
It's working now, I just called the User model again to select the current user :)
I'm trying to do a LEFT JOIN in CakePHP3.
But all I get is a "is not associated"-Error.
I've two tables BORROWERS and IDENTITIES.
In SQL this is what I want:
SELECT
identities.id
FROM
identities
LEFT JOIN borrowers ON borrowers.id = identities.id
WHERE
borrowers.id IS NULL;
I guess this is what I need:
$var = $identities->find()->select(['identities.id'])->leftJoinWith('Borrowers',
function ($q) {
return $q->where(['borrowers.id' => 'identities.id']);
});
But I'm getting "Identities is not associated with Borrowers".
I also added this to my Identities Table:
$this->belongsTo('Borrowers', [
'foreignKey' => 'id'
]);
What else do I need?
Thanx!
The foreign key cannot just be 'id', that's not a correct model association. You'd need to put a 'borrower_id' field in identities, and declare it like this in the Identities model:
class Identities extends AppModel {
var $name = 'Identities';
public $belongsTo = array(
'Borrower' => array (
'className' => 'Borrower',
'foreignKey' => 'borrower_id'
)
);
Note the capitalization and singular/plural general naming conventions which your example doesn't follow in the least - ignoring those will get you some really hard to debug errors..
Yup. It was an instance of \Cake\ORM\Table, due to my not well chosen table name (Identity/Identities). I guess it's always better not to choose those obstacles, for now I renamed it to Label/Labels.
This query now works perfectly:
$var = $identities
->find('list')
->select(['labels.id'])
->from('labels')
->leftJoinWith('Borrowers')
->where(function ($q) {
return $q->isNull('borrowers.id');
});
Hi I am using Yii to create an Application
I have modified the search() in model and I have come up with a problem.
Users can log in as admins, managers, clients
When a user is logged as a manager, he can view clients only from the store they both belong. So far so good, I've managed to accomplish that.
Now the problem is when I try to prevent managers from viewing other managers from the same store (and therefore edit each other's accounts) in CGridView.
The relations
/**
* #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(
'authitems' => array(self::MANY_MANY, 'Authassignment', 'authassignment(userid, itemname)'),
'additionalContacts' => array(self::HAS_MANY, 'AdditionalContact', 'Client_Id'),
'store' => array(self::BELONGS_TO, 'Store', 'Store_Id'),
'user' => array(self::BELONGS_TO, 'User', 'User_Id'),
'genericPoints' => array(self::HAS_MANY, 'GenericPoint', 'Client_Id'),
);
}
The Custom model search
public function searchCustom()
{
// Warning: Please modify the following code to remove attributes that
// should not be searched.
$criteria=new CDbCriteria;
$criteria->addCondition('t.id !='.$this->id);
$criteria->compare('t.Created',$this->Created,true);
$criteria->compare('t.Updated',$this->Updated,true);
$criteria->compare('t.Discount',$this->Discount,true);
$criteria->compare('t.Discount_Type',$this->Discount_Type,true);
$criteria->addCondition('t.Store_Id ='.$this->Store_Id);
//$criteria->addCondition('t.id !='.$this->id);
//GET FIELDS FROM USER IN SEARCH
$criteria->with=array('user');
$criteria->compare('user.id',$this->User_Id,true);
$criteria->compare('user.First_Name',$this->First_Name,true);
$criteria->compare('user.Last_Name',$this->Last_Name,true);
$criteria->compare('user.Username',$this->Username,true);
$criteria->compare('user.Email',$this->Email,true);
$criteria->addCondition('user.Status = 1');
$criteria->with=array('authitems');
$criteria->compare('authitems.userid',$this->id,false);
$criteria->compare('authitems.itemname','client',false);
$criteria->together = true;
$criteria->order = 't.Created DESC';
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
));
}
And this the error I am getting
CDbCommand failed to execute the SQL statement: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'user.Status' in 'where clause'. The SQL statement executed was: SELECT COUNT(DISTINCT `t`.`id`) FROM `client` `t` LEFT OUTER JOIN `authassignment` `authitems_authitems` ON (`t`.`id`=`authitems_authitems`.`userid`) LEFT OUTER JOIN `authassignment` `authitems` ON (`authitems`.`itemname`=`authitems_authitems`.`itemname`) WHERE (((((t.id !=2) AND (t.Store_Id =1)) AND (user.Status = 1)) AND (authitems.userid=:ycp0)) AND (authitems.itemname=:ycp1))
I know it has something to do with the relations the gii set up for me but I can't pinpoint it.
Perhaps authitems' MANY_MANY relation stops the user relation from loading?
Instead of making another assignement for $criteria->with (which will override the previous one), you should simply try :
$criteria->with=array('user', 'authitems');