Codeigniter Injecting WHERE clause into existing query pulled from Model - codeigniter

Here's my dilemma: I need to use the values of $this->request->uri->getSegments() as WHERE clauses in my website's queries. I understand $this->request->uri->getSegments() can only be accessed in the Controller, so if I am calling my query in the Controller from the Model ie.
Controller:
$brand = $this->request->uri->getSegment(1);
$model = new ShopModel();
data ['shop'] = $model->products()
Model:
public function products()
{
$query = $this ->table('shop')
->select('brand_name, brand_name_slug, count(*) as brand_name_total')
->join('(SELECT sku, MIN(sale_price) as sale_price FROM shop GROUP BY sku) as min', 'shop.sku = min.sku and shop.sale_price = min.sale_price')
->where('availability', 'in stock')
->where('shop.sku !=', '')
->groupBy('brand_name')
->orderBy('brand_name')
->findAll();
return $query;
}
Is there a way for me to inject ->where('brand', $brand) clause into $model->products() in the Controller?
Note: I've already trialled the idea of building all my queries IN the Controller (line by line) and adding the WHERE statement in order, however I kept getting bugs and this would be a 'tidier' solution.

You could just pass the variable as a parameter in the function when calling it like any other function. (Reference)
Controller
$brand = $this->request->uri->getSegment(1);
$model = new ShopModel();
data ['shop'] = $model->products($brand); // pass the variable
Model
public function products($brand){ // get the variable value
$query = $this ->table('shop')
->select('brand_name, brand_name_slug, count(*) as brand_name_total')
->join('(SELECT sku, MIN(sale_price) as sale_price FROM shop GROUP BY sku) as min', 'shop.sku = min.sku and shop.sale_price = min.sale_price')
->where('availability', 'in stock')
->where('shop.sku !=', '')
->where('brand', $brand) // use it in where clause
->groupBy('brand_name')
->orderBy('brand_name')
->findAll();
return $query;
}
Edit
If you want to send multiple parameters, you can either send them one by one or in an array, then in your model, you can check if the variable is defined or not, like so
By multiple parameters -
Controller
$brand = $this->request->uri->getSegment(1);
$xyz = 'value'; // make sure to use key same as table column
$abc = 'some-value';
$pqr = 'some-other-value';
$model = new ShopModel();
data ['shop'] = $model->products($brand, $xyz, $abc, $pqr); // pass multiple variables
Model
public function products($brand = false, $xyz = false, $abc = false, $pqr = false){ // get variables value and give false default value
$builder = $db->table('shop');
$builder->select('brand_name, brand_name_slug, count(*) as brand_name_total');
$builder->join('(SELECT sku, MIN(sale_price) as sale_price FROM shop GROUP BY sku) as min', 'shop.sku = min.sku and shop.sale_price = min.sale_price');
$builder->where('availability', 'in stock');
$builder->where('shop.sku !=', '');
if($brand){ // if value is not false
$builder->where('brand', $brand); // use it in where clause
}
if($xyz){
$builder->where('xyz', $xyz);
}
if($abc){
$builder->where('abc', $abc);
}
if($pqr){
$builder->where('pqr', $pqr);
}
$builder->groupBy('brand_name')
$builder->orderBy('brand_name')
$query = $builder->findAll();
return $query;
}
or as an array
Controller
$arr['brand'] = $this->request->uri->getSegment(1);
$arr['xyz'] = 'value'; // make sure to use key same as table column
$arr['abc'] = 'some-value';
$arr['pqr'] = 'some-other-value';
$model = new ShopModel();
$data['shop'] = $model->products($arr); // pass the $arr array as parameter
Model
public function products($arr){ // get values in array
$builder = $db->table('shop');
$builder->select('brand_name, brand_name_slug, count(*) as brand_name_total');
$builder->join('(SELECT sku, MIN(sale_price) as sale_price FROM shop GROUP BY sku) as min', 'shop.sku = min.sku and shop.sale_price = min.sale_price');
$builder->where('availability', 'in stock');
$builder->where('shop.sku !=', '');
if(!empty($arr['brand']){ // if value is not false
$builder->where('brand', $arr['brand']); // use it in where clause
}
if(!empty($arr['xyz']){
$builder->where('xyz', $arr['xyz']);
}
if(!empty($arr['abc']){
$builder->where('abc', $arr['abc']);
}
if(!empty($arr['pqr']){
$builder->where('pqr', $arr['pqr']);
}
$builder->groupBy('brand_name')
$builder->orderBy('brand_name')
$query = $builder->findAll();
return $query;
}
You can also use foreach in your model to prevent repetition of your code -
Model
public function products($arr){ // get values in array
$builder = $db->table('shop');
$builder->select('brand_name, brand_name_slug, count(*) as brand_name_total');
$builder->join('(SELECT sku, MIN(sale_price) as sale_price FROM shop GROUP BY sku) as min', 'shop.sku = min.sku and shop.sale_price = min.sale_price');
$builder->where('availability', 'in stock');
$builder->where('shop.sku !=', '');
foreach($arr as $key => $val){
if(!empty($val)){ // or if($val != "") -- if value is not false
$builder->where($key, $val); // use it in where clause
}
}
$builder->groupBy('brand_name')
$builder->orderBy('brand_name')
$query = $builder->findAll();
return $query;
}
See if this helps you.

Related

Codeigniter 4 Pagination 404 File Not Found error

I'm really struggling to overcome a 404 File Not Found error in CI4 since adding pagination to the Model function. I'm assuming it's to do with routing alone as it's also throwing up the same error on my subbrand_name page, which doesn't include any pagination in its Model code and was working fine until I added pagination to the brand_name page.
My Routes file:
$routes->get('shop/brands/(:segment)', 'Shop::brand_name/$1');
$routes->get('shop/brands/(:segment)/(:segment)', 'Shop::subbrand_name/$1/$2');
My Controller:
public function brand_name($brand_name_slug)
{
$model = new ShopModel();
$data = [
'category_menu' => $model->category_menu(),
'brand_menu' => $model->brand_menu(),
'nav' => $model->nav(),
'subnav' => $model->subnav(),
'shop' => $model->brand_name($brand_name_slug),
'pager' => $model->pager
];
if (empty($data['shop']))
{
throw new \CodeIgniter\Exceptions\PageNotFoundException('Cannot find the news item: '. $slug);
}
echo view('templates/header', $data);
echo view('shop/view', $data);
echo view('templates/footer', $data);
}
My Model:
public function brand_name($brand_name_slug)
{
return $this
->table('shop a')
->select()
->join('(SELECT sku, MIN(sale_price) AS sale_price FROM shop GROUP BY sku) AS b', 'a.sku = b.sku AND a.sale_price = b.sale_price')
->where('availability', 'in stock')
->where('a.sku !=', '')
->where('brand_name_slug', $brand_name_slug)
->groupBy('a.sku')
->orderBy('brand_name, subbrand_name, product, size, unit')
->paginate(15);
}
Turns out, it was nothing to do with routing... just simply, my JOIN was buggy.
Managed to sort it by replacing shop a and a.sku in the JOIN part of the argument with shop and shop.sku. Worked perfectly... FINALLY!
public function brand_name($brand_name_slug)
{
return $this
->table('shop')
->select('*')
->join('(SELECT sku, MIN(sale_price) AS sale_price FROM shop GROUP BY sku) AS b', 'shop.sku = b.sku AND shop.sale_price = b.sale_price')
->where('availability', 'in stock')
->where('shop.sku !=', '')
->where('brand_name_slug', $brand_name_slug)
->groupBy('shop.sku')
->orderBy('brand_name, subbrand_name, product, size, unit')
->paginate(15);
}

codeigniter get array data in controller

I have sql query in controller, this query produces number of rows.
$q1 = $this->db->query("SELECT product_code,product_quantity FROM tbl_order_details WHERE order_id='$order_no' AND location='$location'")->row();
foreach($q1 as $v_barcode){
$result = $this->settings_model->update_cancel_stock($v_barcode->product_code,$v_barcode->product_quantity);
}
then i pass this data to my model,
public function update_cancel_stock($code,$qty)
{
$this->db->set('product_quantity', $qty , FALSE);
$this->db->where('product_id', $order );
$this->db->update("tbl_inventory6");
}
but no any update. please check above code. thanx
Try this
$cond = array("order_id" => $order_no, "location" => $location);
$q1 = $this->db->select("product_code,product_quantity")->from("tbl_order_details")->where($cond)->row();
$result = $this->settings_model->update_cancel_stock($q1->product_code,$q1->product_quantity);
and then model ($code was not used)
public function update_cancel_stock($code,$qty){
$this->db->set('product_quantity', $qty , FALSE);
$this->db->where('product_id', $code);
$this->db->update('tbl_inventory6');
}
You are using row() function of Active Record. It already return only one row. So there is no requirement of foreach. Try this:
$q1 = $this->db->query("SELECT product_code,product_quantity FROM tbl_order_details WHERE order_id='$order_no' AND location='$location'")->row();
$result = $this->settings_model->update_cancel_stock($q1->product_code,$q1->product_quantity);
If you are getting multiple records and you are using foreach, you should use result().
$q1 = $this->db->query("SELECT product_code,product_quantity FROM tbl_order_details WHERE order_id='$order_no' AND location='$location'")->result();
foreach($q1 as $v_barcode){
$result = $this->settings_model->update_cancel_stock($v_barcode->product_code,$v_barcode->product_quantity);
}

Codeigniter activerecord query for multiple values with exact results

I have a query for filtering products that are related to categories and subcategories and tags/attributes (color, lengths, connection etc) and i'm having problems getting exact results using $this->db->where_in("field",$array_of_tags); is there another whey to this i haven't figured out ?
This is my function
`public function get_public_products($limit_start = false, $limit_end = false, $categoria = false, $subcategoria = false , $tags = false){
if(!$subcategoria){
$this->db->select('*');
}
$this->db->from('products');
if($categoria && !$subcategoria){
$this->db->join('products_categories', 'products.familia = products_categories.codigo');
$this->db->where('products_categories.slug',$categoria);
}
if($subcategoria && !$tags){
$this->db->select('products.familia AS familia, products.subfamilia AS subfamilia, products.slug AS pslug, products_categories.slug AS cslug , products.nombre AS nombre, products_categories.name AS cname, products.codigo_producto AS codigo_producto');
$this->db->join('products_categories', 'products.subfamilia = products_categories.codigo');
$this->db->where('products_categories.slug',$subcategoria);
}
if($tags){
$this->db->select('products.familia AS familia, products.subfamilia AS subfamilia, products.slug AS pslug, products_categories.slug AS cslug , products.nombre AS nombre, products_categories.name AS cname, products.codigo_producto AS codigo_producto , products_tags_values.value AS tvalue, products_tags_values.slug AS tslug');
$this->db->join('products_categories', 'products.subfamilia = products_categories.codigo');
$this->db->where('products_categories.slug',$subcategoria);
$this->db->join('products_tags_values', 'products_tags_values.pid = products.codigo_producto');
$tags_array = explode(",", $tags);
$this->db->where_in('products_tags_values.slug',$tags_array);
}
if($limit_start){
$this->db->limit($limit_start, $limit_end);
}
$query = $this->db->get();
return $query->result_array();
}`
This works fine when i use $this->db->where('products_tags_values.slug',"blue"); but not if i chane them like this for multiple tags.
$this->db->where('products_tags_values.slug',"blue");
$this->db->where('products_tags_values.slug',"20-m");

Magento Changing Default Payment Method

I have a function that runs raw SQL queries to our database in Magento. What the function does is changes the customer's default credit card to a value passed to the function. My question is how would I rewrite the function utilizing Magento models. The current function works, but we'd rather have it not be directly interfacing with SQL.
Here is the function:
public function setDefaultPayment($value)
{
$customerId = $this->_getSession()->getCustomer()->getId();
$write = Mage::getSingleton('core/resource')->getConnection('core_write');
$read = $write->query("SELECT entity_type_id FROM eav_entity_type WHERE entity_type_code='customer'");
$row = $read->fetch();
$entity_type_id = $row['entity_type_id'];
$read = $write->query("SELECT attribute_id FROM eav_attribute WHERE attribute_code='default_payment' AND entity_type_id = $entity_type_id");
$row = $read->fetch();
$attribute_id = $row['attribute_id'];
$read = $write->query("SELECT * FROM customer_entity_int WHERE entity_type_id='$entity_type_id' AND attribute_id='$attribute_id' AND entity_id='$customerId'");
if ($row = $read->fetch()) {
$write->update(
'customer_entity_int',
array('value' => $value),
"entity_type_id='$entity_type_id' AND attribute_id='$attribute_id' AND entity_id='$customerId'"
);
} else {
$write->insert(
'customer_entity_int',
array(
'entity_type_id' => $entity_type_id,
'attribute_id' => $attribute_id,
'entity_id' => $customerId,
'value' => $value
)
);
}
}
If I read you code right, you want to update the customer attribute default_payment with a value given.
For that you need to:
Load the customer by id
Set the new value for the customer attribute default_payment
Save the customer
public function setDefaultPayment($value)
{
$customerId = $this->_getSession()->getCustomer()->getId();
$write = Mage::getSingleton('core/resource')->getConnection('core_write');
$customer = Mage::getModel('customer/customer')->load($customerId);
$oldValue = $customer->getDefaultPayment(); // optional, just for checking
$customer->setDefaultPayment($value);
$customer->save();
}

How can I use CodeIgniter form dropdown function?

codeIgniter form_dropdown() function can receive only associative array but I have multi dimension array by using result_array() function. How can I fetch my data on form_dropdown() function?
Let's say you want a dropdown of items, using result_array():
$query = $this->db->query("SELECT id, item_name FROM items");
$options = array();
foreach ($query->result_array() as $row){
$options[$row['id']] = $row['item_name'];
}
echo form_dropdown('my_items_dropdown', $options, '1');
I have extended the class DB_result.php in system/database with this new function
public function dropdown_array($id_field = FALSE, $list_field = FALSE)
{
$result = array();
if ($id_field === FALSE || $list_field === FALSE) return $result;
$array = $this->result_array();
foreach ($array as $value) {
$result[$value[$id_field]] = $value[$list_field];
}
return $result;
}
Now you can simply call from every Model class your new function to generate a dropdown-compliant array like this:
$customers = $this->db->get('customers');
$result = $customers->dropdown_array('id', 'name');
return $result;

Resources