i have a sql query and it working:
$sql = "
SELECT P.`name`, P.`price`, P.`year`, P.`slug`, P.`image`, C.`title`, C.`des`
FROM `tbl_category` C, `tbl_products` P
WHERE C.`group_cat` = 1 AND C.`slug` = '/category/".$category."/'
ORDER BY `P.updated_at` DESC
LIMIT 0,".Yii::app()->params['limitPageSizeView']
";
$dbCommand = Yii::app()->db->createCommand($sql);
$data = $dbCommand->queryAll();
now, i want converter this sql to syntax CDbCriteria:
$criteria = new CDbCriteria();
$criteria->select = '???';
$criteria->where= '???';
$criteria->condition = '???';
$criteria->order = '???';
$criteria->limit = '???';
$data = ProductsModel::model()->findAll($criteria);
somebody can help me?
$criteria = new CDbCriteria();
$criteria->select = 'name, price, year, slug, image';
$criteria->order = 'upadated_at';
$criteria->limit = Yii::app()->params['limitPageSizeView'];
$criteria->with = array(
'category' => array(
'together'=>true,
'select'=>array('title','des'),
'condition'=>"group_cat = 1 AND slug = '/category/".$category."/'"
)
);
$data = ProductsModel::model()->findAll($criteria);
this will do left join on, make sure you have relation defined on product for category, if you dont have relation you can add "ON" condition.
Related
I want to create a database query in a view helper, this works with the following code:
$uid = 11;
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_test_domain_model_author');
$query = $queryBuilder
->select('*')
->addSelectLiteral(
$queryBuilder->expr()->count('tx_test_domain_model_author.author', 'counter')
)
->from('tx_test_domain_model_author')
->join(
'tx_test_domain_model_author',
'tx_test_publication_author_mm',
'tx_test_publication_author_mm',
$queryBuilder->expr()->eq(
'tx_test_domain_model_author.uid',
$queryBuilder->quoteIdentifier('tx_test_publication_author_mm.uid_foreign')
)
)
->where(
$queryBuilder->expr()->eq(
'tx_test_publication_author_mm.uid_local',
$queryBuilder->createNamedParameter($uid, \PDO::PARAM_INT)
)
)
->orderBy('tx_test_domain_model_author.uid', 'ASC');
$result = $query->execute();
$res = [];
while ($row = $result->fetch()) {
$res[] = $row;
}
print_r($res);
However, I only get one record, although the counter tells me it would be 3.
What am I doing wrong?
If the counter says its three items, then try change this:
$result = $query->execute();
$res = [];
while ($row = $result->fetch()) {
$res[] = $row;
}
into this:
$result = $query->execute()->fetchAll();
That fetches all rows into an array that you walk throug with:
foreach($result as $row){
...
}
It seems the QueryBuilder works differently, this gives me one result namely the first entry in the table:
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_test_publication_author_mm');
$query = $queryBuilder
->select('*')
->from('tx_test_publication_author_mm');
$result = $query->execute()->fetchAll();
foreach($result as $row){
echo $row['field'];;
}
This gives me all results:
$db = mysqli_connect($dbHost, $dbUser, $dbPassword, $dbName) or die (mysql_error ());
$sql = "SELECT * FROM tx_test_publication_author_mm";
foreach ($db->query($sql) as $row) {
echo $row['field'];
}
How can I write this procedural query as codeigniter active record query (update_batch mode )
UPDATE products SET current_stock = current_stock + 1 where product_id = 1
You can use update_batch like this:
$products = $this->db->get('products'))->result();
for( $i = 0; $i < count($products); $i++){
$data[] = array(
'product_id' => $product[$i]->product_id,
'current_stock' => $product[$i]->current_stock + 1
);
}
$this->db->update_batch('products', $data, 'product_id');
You can use below query as explained on Codeigniter Query Builder Class:
$this->db->set('current_stock', 'current_stock+1', FALSE);
$this->db->where('product_id', 2);
$result = $this->db->update('products');
Relations of review below:
return array(
'product' => array(self::BELONGS_TO, 'Product', 'product_id'),
'profile' => array(self::BELONGS_TO, 'Profile', 'profile_id'),
'rating' => array(self::BELONGS_TO, 'Rating', 'rating_id'),
'reviewcomments' => array(self::HAS_MANY, 'Reviewcomment', 'review_id'),
'reviewhelpfuls' => array(self::HAS_MANY, 'Reviewhelpful', 'review_id'),
'commentCounts' => array(self::STAT, 'Reviewcomment', 'review_id'),
);
Controller code below:
$criteria = new CDbCriteria();
$criteria->addCondition("t.seoUrl = :seoUrl");
$criteria->addCondition("t.published = 1");
$criteria->params = array("seoUrl"=>$seoUrl);
$data['product'] = Product::model()->find($criteria);
if($data['product']){
$data['product']->hits = $data['product']->hits+1;
$data['product']->save();
} else{
throw new CHttpException(404, "Invalid Request for product");
}
$product_id = $data['product']->id;
$criteria = new CDbCriteria();
$criteria->addCondition("t.product_id = '$product_id'");
if(isset($_GET['rating']))
{
$rating_id = $_GET['rating'];
$criteria->addCondition("t.rating_id = '$rating_id'");
}
$criteria->addCondition('t.status = "approved"');
if(isset($_GET['sort']))
{
$sorting = $_GET['sort'];
if($sorting=='newest')
$criteria->order = "t.postDate DESC";
elseif($sorting=='oldest')
$criteria->order = "t.postDate ASC";
elseif($sorting=='rating_high')
$criteria->order = "t.rating_id DESC";
elseif($sorting=='rating_low')
$criteria->order = "t.rating_id ASC";
}
$data['reviews'] = new CActiveDataProvider('Review', array(
'criteria'=>$criteria,
'pagination'=>array('pagesize'=>4)
));
Now when I am running this code, I am getting CDbCommand failed to execute the SQL statement: SQLSTATE[42S22]: Column not found: 1054 Unknown column 't.rating_id' in 'where clause'
Thanks for your help
Intstead of using 't' as alias for your tables, start using getTableAlias(false, false)
In your case it would be:
$criteria->addCondition(Review::model()->getTableAlias(false, false).".rating_id = '$rating_id'");
More importantly this code screams SQL injection
$rating_id = $_GET['rating'];
$criteria->addCondition("t.rating_id = '$rating_id'");
Never use user input without processing it. Yii allows you to bind values which would be escaped for you - no threat of SQL injection(atleast as far as i know). You should be creating your criteria like so:
$criteria->addCondition(Review::model()->getTableAlias(false, false).".rating_id = :rating_id");
$criteria->params = array(
':rating_id' => $rating_id,
);
i have order table where in product_id is string Like 10,11,12,13. And have Product table with this id.
how to get dataProvider with each product_id
My code is
public function getProducts($id){
$idarray = explode(',', $id);
$dataProviderProduct = Array();
foreach($idarray as $i=>$id){
$dataProviderProduct[$i]=new CActiveDataProvider('Product',
array( 'criteria'=>array(
'condition'=>'id=:id',
'params'=>array(':id' => $id),
),
'pagination'=>array( 'pageSize'=>10),
)
);
}
return $dataProviderProduct;
}
But this is wrong code
Use addInCondition like this:
$idarray = explode(',', $id);
$criteria = new CDbCriteria();
$criteria->addInCondition('id', $idarray);
$data = ModelName::model()->findAll($criteria);
Is there a way to use a regular mysql select statement with Zend Framework without having to use Zend_Db::factory
Code below is in my Model classes which extends Zend_Db_Table_Abstract
I can currently do this (which works):
$db = Zend_Db::factory('Pdo_Mysql', array(
'host' => 'localhost',
'username' => 'dbuser',
'password' => 'dbuserpass',
'dbname' => "somedbname"
));
$select = "SELECT iv.*
FROM image_variations AS iv
LEFT JOIN images AS i ON (i.image_id = iv.image_id)
LEFT JOIN product_images AS pi ON (pi.image_id = iv.image_id)
WHERE pi.pid = '$pid'
&& iv.image_type_id = '$image_type_id' ";
$stmt = $db->query($select);
$rows = $stmt->fetchAll();
return $rows;
I would like to do this:
$select = "SELECT iv.*
FROM image_variations AS iv
LEFT JOIN images AS i ON (i.image_id = iv.image_id)
LEFT JOIN product_images AS pi ON (pi.image_id = iv.image_id)
WHERE pi.pid = '$pid'
&& iv.image_type_id = '$image_type_id' ";
$stmt = $this->query($select);
$rows = $stmt->fetchAll();
return $rows;
So I dont always have to define db variables in each method and have mysql passwords all over the place. Is there a way to use $this instead of having to instantiate a new $db Zend_DB Factory??
Ok figured it out. The solution is not very elegant buts works and is portable.
My setup consists of multiple DBs, so in Bootstrap.php I have:
protected function _initDatabase() {
$resource = $this->getPluginResource('multidb');
$resource->init();
Zend_Registry::set('db', $resource->getDb('db'));
Zend_Registry::set('shopdb', $resource->getDb('shopdb'));
}
In Application.ini
resources.multidb.db.adapter = PDO_MYSQL
resources.multidb.db.host = 127.0.0.1
resources.multidb.db.username = user
resources.multidb.db.password = userpassword
resources.multidb.db.dbname = dbone
resources.multidb.db.isDefaultTableAdapter = true
resources.multidb.db.default = true
resources.multidb.shopdb.adapter = PDO_MYSQL
resources.multidb.shopdb.host = 127.0.0.1
resources.multidb.shopdb.username = user
resources.multidb.shopdb.password = userpassword
resources.multidb.shopdb.dbname = dbtwo
resources.multidb.shopdb.isDefaultTableAdapter = false
in index.php
$config = new Zend_Config_Ini(APPLICATION_PATH . "/configs/application.ini");
Zend_Registry::set('settings', $config);
Then (the not very elegant bit) in Models add an init() method
protected $db;
public function init() {
$settings = Zend_Registry::get('settings');
$adapter = $settings->production->resources->multidb->shopdb->adapter;
$params = array(
'host' => $settings->production->resources->multidb->shopdb->host,
'username' => $settings->production->resources->multidb->shopdb->username,
'password' => $settings->production->resources->multidb->shopdb->password,
'dbname' => $settings->production->resources->multidb->shopdb->dbname,
);
$this->db = Zend_Db::factory("$adapter", $params);
}
And then you can use $this->db in other methods in the Model class, eg:
public function getProductImages($pid, $image_type_id) {
$select = "SELECT iv.*
FROM image_variations AS iv
LEFT JOIN images AS i ON (i.image_id = iv.image_id)
LEFT JOIN product_images AS pi ON (pi.image_id = iv.image_id)
WHERE pi.pid = '$pid'
&& iv.image_type_id = '$image_type_id' ";
$stmt = $this->db->query($select);
$rows = $stmt->fetchAll();
return $rows;
}
It works but it still seems like there should be an easier way...