Yii 1.x, query in query DB selection - php

I have such sql query
SELECT * FROM tbl_role WHERE
tbl_role.id NOT IN (
SELECT tbl_user_role.roleID FROM tbl_user_role
WHERE tbl_user_role.userID = 35
)
AND
tbl_role.id NOT IN (
SELECT tbl_user_role_request.roleID FROM tbl_user_role_request
WHERE tbl_user_role_request.userID = 35 AND tbl_user_role_request.dateEnd IS NULL)
What is the best solution to make it in Yii-like code. How can i do this query using Yii 1.x ?

Assumptions:
tbl_role has a model named Role
tbl_user_role has a model named UserRole
tbl_user_role_request has a model named UserRoleRequest
Note that this will do 3 seperate queries but I believe this is the closest you can get without creating a total mess.
<?php
$userId = 35;
$roles = UserRole::findAllByCondition(array('userId' => $userId));
$roleIds = array_values(CHtml::listData($roles, 'roleId', 'roleId');
$roleRequests = UserRoleRequest::findAllByCondition(array('userId'=>$userId, 'dateEnd'=>null));
$roleRequestIds = array_values(CHtml::listData($roleRequest, 'roleId', 'roleId'));
$criteria = new CDbCriteria();
$criteria->addNotInCondition('id', $roleIds);
$criteria->addNotInCondition('id', $roleRequestIds);
$roles = Role::findAll($criteria);

I would use CDbCommand: http://www.yiiframework.com/doc/api/1.1/CDbCommand#queryAll-detail
Use the following code to fetch the data
$data = Yii::app()->db->createCommand('sql query')->queryAll;
And then you can use this dataset to create the dropDownList
$list = CHtml::listData($data, 'value field', 'text field');
echo $form->dropDownList($model, 'attribute', $list);

Related

How to use update() functionality in Laravel?

Inside my store function i have to search a name of a particular person, thus:
$person = DB::select("select p.* from persons p where concat_ws(', ' ,p.family_name,concat_ws(' ',concat_ws(' ',p.first_name,p.middle_name),p.third_name)) like ?", [$request['person_name']]);
If this person exist i have to update the person and this one works:
Person::where('id', $person[0]->id)->update(['status' => 'Active']);
but not this one:
$person[0]->status = 'Active';
$pArray = json_decode(json_encode($person[0]), true);
$per = new Person($pArray);
$per->update();
Since you have already created a new model instance, you would need to call the save() method.
$per = new Person($pArray);
$per->save();
Or, you can use update() to pass data into an existing model. But first, you need to retrieve the model you want to update.
$per = Person::find($pArray['id']);
$per->update($pArray);
Use your search query instead of mine. I think this will help you.
$result = User::where('id', $userId)->first();
$result->name = 'xyz';
$result->update();
For update data in laravel using model you need to pass where condition in it.
Sample example
$flight = App\Flight::find(1);
$flight->name = 'New Flight Name';
$flight->save();
Hope this helps you!

Laravel, copy row to another table with eloquent relationship

I want to get the data form database table and create a new row in another table.
Which 1 PO have many PoProducts.
$_getPO = Order::find($id);
$_getPOProducts= OrderProducts::where('order_id', $id)->get();
$order_no = $_getPO->order_no;
$eta = $_getPO->eta;
$_Order = new DeliveryOrders();
$_Order->order_no = $order_no;
$_Order->eta = $eta;
$_Order->save();
$POProduct = array();
foreach($_getPOProducts as $i => $_getPOProduct)
{
$POProduct[] = new DeliveryOrderProducts();
$POProduct[] = $_getPOProduct->order_id;
$POProduct[] = $_getPOProduct->item_id;
$POProduct[] = $_getPOProduct->qty;
$POProduct->save();
}
But, this output an error.
Call to a member function save() on array
Please help me. Thanks.
If you wish to copy records from one table to another or just duplicate a record in the same table you could simply use the repliacate() method.
$user = User::findOrFail($id);
// replicate (duplicate) the data
$staff = $user->replicate();
// make into array for mass assign.
//make sure you activate $guarded in your Staff model
$staff = $staff->toArray();
Staff::firstOrCreate($staff);
Note: in case you're only duplicating on the same table replace Staff with User on this example.
You are trying to run the save method on the array but what you want is to use it on the array index instead.
Change your foreach to this and it should work (assuming columns are the same).
foreach($_getPOProducts as $i => $_getPOProduct)
{
$POProduct[$i] = new DeliveryOrderProducts();
$POProduct[$i]->order_id = $_getPOProduct->order_id;
$POProduct[$i]->item_id = $_getPOProduct->item_id;
$POProduct[$i]->qty = $_getPOProduct->qty;
$POProduct[$i]->save();
}
You can shorten this by using forceCreate.
foreach($_getPOProducts as $i => $_getPOProduct)
{
$POProduct[$i] = (new DeliveryOrderProducts())->forceCreate($_getPOProduct->only(['order_id', 'item_id', 'qty']));
}

Update table using custom queries in TYPO3 Extbase

I have a table named 'user'.I need to update the field 'email' .Is there any custom build queries for updating.I have only the uid of user.
I mean.. Is there any TYPO3 custom queries equivalent to
Update table 'user' set email = 'new#xyz.com' where uid = 1;
like
$query = $this->createQuery();
$query->matching(
$query->logicalAnd(
$query->equals('organization', $organization),
$query->contains('regions', $region)
)
)
return $query->execute();
if you use extbase , you can use :
$object = $this->yourRepository->yourQuery();
$object->setEmail('your#email.tld');
$this->yourRepository->update($object);
Why don't you use
use HDNET\ExtensionName\Utility;
Utility::exec_UPDATEquery (
$table,
$where,
$fields_values,
$no_quote_fields = false
);
Please refer exec_UPDATEquery From TYPO3

Yii : how to count records in a model?

I have following code to fetch data from a model.
$notifyModel = Notification::model()->findByAttributes(array(
'user_id'=> Yii::app()->user->uid
));
Now I want to count the number of rows fetched.
Neither $notifyModel->count() work nor count($notifyModel).
It is very simple but googling did not help.
$notifyModels = Notification::model()->findAllByAttributes(array(
'user_id'=> Yii::app()->user->uid
));
$count = count($notifyModels);
Or
$count = Notification::model()->countByAttributes(array(
'user_id'=> Yii::app()->user->uid
));
the right usage of count():
$userid = Yii::app()->user->uid;
$count = Notification::model()->count( 'user_id=:userid', array(':userid' => $userid));
Please see http://www.yiiframework.com/doc/api/1.1/CActiveRecord#count-detail
try this:
$userid = Yii::app()->user->uid;
$notifyModel = Notification::model()->count(
array('condition' => 'user_id=:userid',
'params'=>array(':userid' => $userid)
));
$count = Notification::model()->countByAttributes(array(
'user_id'=> Yii::app()->user->uid
));
Since the questions title is about calling the count function in a model I'll add some for those beginners reading this :)
A function inside a model could look like this:
/**
* Count the number of rows which match the user ID
* #param int $uid The user ID
* #return int The number of found rows
*/
public function getCountByUserID($uid)
{
$count = $this->count(array(
'condition'=>'user_id = :uid',
'params'=>array(
':uid'=>$uid,
),
));
return $count;
}
simple ways:
$model = News::model()->findAll(); //returns AR objects
$count = count($model);
I think it is much faster than others
$userTable=User::model()->tableName();
$userid = Yii::app()->user->uid;
$criteria=new CDbCriteria();
$criteria->select=count(id);
$criteria->compare('user_id',$userid);
$count=Yii::app()->db->commandBuilder->createFindCommand($userTable,$criteria)->queryScalar();
That method is wrong!
You trying to get by selecting all rows from database, you load the server, but that's wrong way!
All you need to do :
$sql = "SELECT COUNT(*) FROM {{...table_name...}}";
$count = intval(Yii::app()->db
->createCommand($sql)
->queryScalar());
Or you can create function in your model:
Class User extends CActiveRecord
{
private $_total;
public function getTotalItems()
{
if( empty( $this->_total )) {
$this->_total = intval(Yii::app()->db
->createCommand($sql)->queryScalar());
}
return $this->_total;
}
}
then you can use this functions like this:
$totalItems = User::model()->totalItems;
or :
$model = User::model()->findByPk( $uid );
$totalItems = $model->totalItems;
or :
$model = new User;
$totalItems = $model->totalItems;
This is the most simple way to do that:
$count = Table::Model()
->count("field=:field", array("field" => $fildID));
echo $count;
I strongly recommend you to find count with SQL query else it will degrade your system performance.
There are three way to find out count with the SQL query itself in Yii 1 CActiveRecord, those are:
1. count() method
Finds the number of rows satisfying the specified query condition.
Example :
$count = Notification::model()->count('user_id'=> Yii::app()->user->uid);
2. countByAttributes() method (available since v1.1.4)
Finds the number of rows that have the specified attribute values.
Example :
$count = Notification::model()->countByAttributes(array(
'user_id'=> Yii::app()->user->uid
));
3. countBySql() method
Finds the number of rows using the given SQL statement. This is equivalent to calling CDbCommand::queryScalar with the specified SQL statement and the parameters.
Example:
$count = Notification::model()
->countBySql("select *from notification where user_id=:userId",
array(':userId'=>Yii::app()->user->uid)
);
Don't use the following code, which will reduce system performance:
$notifyModels = Notification::model()->findAllByAttributes(array(
'user_id'=> Yii::app()->user->uid
));
$count = count($notifyModels);
Because, there are two function call to find the count
In my research, The easiest and Best Practice is like below.
$notifyModel = Notification::model()->count(array('user_id'=> Yii::app()->user->uid));

Yii AR join not working when using findAll

I have two tables menus and lang_menus. My Menus model is as follows :
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(
'menulanguages'=>array(self::HAS_MANY, 'MenuLangs', 'menuId'),
);
}
...
public function getMenus(){
$criteria = new CDbCriteria();
$criteria->condition = "t.clientId = ".Yii::app()->user->clientId." AND menulanguages.languageId = ".Yii::app()->user->userlanguage;
$count = Menus::model()->with('menulanguages')->count($criteria);
$pages=new CPagination($count);
//Results per page
$pages->pageSize=10;
$pages->applyLimit($criteria);
$menus = Menus::model()->with('menulanguages')->findAll($criteria);
return array('menus' => $menus, 'paging' => $pages);
}
This is throwing the error Unknown column 'menulanguages.languageId'.
The error is in the line $menus = Menus::model()->with('menulanguages')->findAll($criteria);.
Surprisingly I am getting the value of the variable $count correctly.
On looking at the log I can see that the SQL query that is running for the findAll query is :
SELECT `t`.`id` AS `t0_c0`, `t`.`clientId` AS `t0_c1`, `t`.`restaurantId` AS `t0_c2` FROM `posif_menus` `t` WHERE (t.clientId = 1 AND menulanguages.languageId = 2) LIMIT 10
which means the join has not taken place. Whereas proper join query is running for the count value. Am I doing something wrong ?
Please help.
Just use together() of CActiveRecord or together property of CDbCriteria:
$menus = Menus::model()->with('menulanguages')->together()->findAll($criteria);
or:
$criteria = new CDbCriteria();
$criteria->condition = "t.clientId = ".Yii::app()->user->clientId." AND menulanguages.languageId = ".Yii::app()->user->userlanguage;
$criteria->together=true;
Try this.. apply joining table in cdbcriteria..
public function getMenus(){
$criteria = new CDbCriteria();
$criteria->condition = "t.clientId = ".Yii::app()->user->clientId." AND menulanguages.languageId = ".Yii::app()->user->userlanguage;
$criteria->with = array('menulanguages');
$count = Menus::model()->count($criteria);
$pages=new CPagination($count);
//Results per page
$pages->pageSize=10;
$pages->applyLimit($criteria);
$menus = Menus::model()->findAll($criteria);
return array('menus' => $menus, 'paging' => $pages);
}

Categories