get looping data from one data - php

I am using codeigniter.
I have two function in the model.
In the first function, I get all specific rows from one table. This is where I want to get all product details.
function getProduct()
{
$shoes = 'SELECT pd.name,
pd.id,
pd.price
FROM product_detail pd
LEFT JOIN product_sub_category psc
ON pd.sub_category_id = psc.id
WHERE psc.name = "Shoes"';
$categoried = $this->db->query($shoes);
return $categoried->result();
}
While in the second function, I get all specific rows based on one row from the first function. This is where I want to get all images for each products.
function getImage()
{
$shoes = 'SELECT pim.file_name
FROM product_img pim
LEFT JOIN product_detail pd
ON pim.product_detail_id = pd.id
WHERE pim.product_detail_id = "'.$row->id.'"';
$categoried = $this->db->query($shoes);
return $categoried->result();
}
But it gives me some errors.
Can someone please help me? Thanks for the help.
[UPDATE]
This is my Controller
In the controller, I identify records to get the product, and recorded to get the image.
function index()
{
$this->load->model('site_model');
$data = array();
$query = $this->site_model->getProduct();
$data['records'] = $query;
foreach ($query as $row)
{
$id = $row->id; // get ID
$name = $row->name; // get ID
$product_image = $this->site_model->getImage($id); // invoke the second method feeding that ID
$data['recorded'] = $product_image;
}
$this->load->view('mothershop', $data);
}
This is my Model
function getProduct()
{
$shoes = 'SELECT pd.name,
pd.id,
pd.price
FROM product_detail pd
LEFT JOIN product_sub_category psc
ON pd.sub_category_id = psc.id
WHERE psc.name = "Shoes"';
$categoried = $this->db->query($shoes);
return $categoried->result();
}
function getImage($id)
{
$shoes = 'SELECT pim.file_name
FROM product_img pim
LEFT JOIN product_detail pd
ON pim.product_detail_id = pd.id
WHERE pim.product_detail_id = "'.$id.'"';
$categoried = $this->db->query($shoes);
return $categoried->result();
}
This is my View of mothershop.php
In this section, I call the records and recorded
foreach ($records as $row)
{
echo "<div>".$row->name."</br>";
foreach ($recorded as $rowed)
{
echo "<img src='".base_url()."upload/thumbs/".$rowed->file_name."'/>";
}
echo "</div>";
}
However, I don't know why, it only get the same image for each products.
But if i print the $product_image in the controller, it gives me different images for each products.
What is wrong here?
Thanks in advance for #Ghost

Since that $row->id is solely depending on the first fetching method, currently, its out of scope. In order to use that ID from the first method, just add an argument on the second method and use that to the second query. More like this:
function getImage($id)
Then you can use it on the second method.
Since you haven't shown any code on how you are using your methods. Consider this example:
First method usage (Controller):
$this->load->model('Super_model');
$products = $this->Super_model->getProduct();
foreach($products as &$row) {
$id = $row->id; // get ID
$product_image = $this->Super_model->getImage($id); // invoke the second method feeding that ID
if(!empty($product_image)) { // if it exists
$row->file_name = $product_image->file_name; // add another property which is file_name on that first fetched data
}
}
Model method:
function getImage($id)
{
$shoes = "SELECT pim.file_name
FROM product_img pim
LEFT JOIN product_detail pd
ON pim.product_detail_id = pd.id
WHERE pim.product_detail_id = '$id' ";
$categoried = $this->db->query($shoes);
return ($categoried->num_rows() > 0) ? $categoried->row() : null;
}
That's the basic idea of it, we don't know what goes on and how you glue everything else on the controller, adjust it to fit into your codebase.

Related

Selecting a single column from model to controller in codeigniter3.0.0

I am new in codeigniter.
I need only the available column from the model than what code I write in the controller to get a single column
My model code is:
public function check_reservation($restaurant_id,$date,$people,$start_time,$end_time){
$sql="SELECT
r.restaurant_id,r.restaurant_name,r.capacity,rs.start_time,rs.end_time,rs.people,rs.date,r.capacity - SUM(IFNULL(rs.people,0)) AS available FROM restaurant r
LEFT JOIN reservation rs ON r.restaurant_id = rs.restaurant_id
AND ".$date." = rs.`date`
AND ".$people." = rs.`people`
AND '".$start_time."' = rs.`start_time`
AND '".$end_time."' = rs.`end_time`
WHERE r.restaurant_id = ".$restaurant_id."
GROUP BY r.`restaurant_id`";
$query=$this->db->query($sql);
return $query->result();
}
Thank you
It's not clear what you need. If you want to get only one column in the Controller, when you iterate with foreach (or for), you ask for your column name.
foreach ( $records as $record ) {
echo $record['restaurant_name'];
echo "<br/>";
}

Getting null array PHP

i have a database named "products" which has a column "categories". This table contain four category of products namely electronic,Decoration,clothes and vehicle. My target to show these category with their count ie:if there are four products belongs to category electronic, then output should be like this :electronic=4 and so on
My code
public function category()
{
$arrayCategorys = ['electronic','Decoration','clothes','vehicle'];
$data = [];
foreach($arrayCategorys as $arrayCategory)
{
$sql = "SELECT count(id) FROM products WHERE categories='$arrayCategory'";
$records = \DB::select($sql);
$data = array_merge_recursive($data, [
"{$arrayCategory}" =>isset($records[0]->count),
]);
$data=array_filter($data);
dd($data);
}
}
I want show output like this
'electronic'=>'4',
'Decoration'=>'2',
'clothes'=>'2',
'vehicle'=>'1' according to data in database
but iam getting nothing ,[]
You can GROUP BY your categories like this way when you COUNT
SELECT categories,COUNT(*)
FROM products
GROUP BY categories;
For Idea: http://www.w3resource.com/mysql/aggregate-functions-and-grouping/aggregate-functions-and-grouping-count-with-group-by.php
EDIT: Though i am not familiar with laravel5 syntax but this may work for you
$result = DB::table('products')
->select('products.categories',
DB::raw('count(products.id) as category_count')
)
->orderBy('products.id', 'asc')
->groupBy('products.categories')
->get();
You used isset($records[0]->count) but the column name for the count will be count(id). Name the count as count like this "SELECT count(id) AS count FROM products WHERE categories='$arrayCategory'". And you wont be able to get the count just by checking if it is set. Remove the isset and just use $records[0]->count. The code should look like:
public function category()
{
$arrayCategorys = ['electronic','Decoration','clothes','vehicle'];
$data = [];
foreach($arrayCategorys as $arrayCategory)
{
$sql = "SELECT count(id) AS count FROM products WHERE categories='$arrayCategory'";
$records = \DB::select($sql);
$data = array_merge_recursive($data, [
"{$arrayCategory}" =>$records[0]->count,
]);
$data=array_filter($data);
dd($data);
}
}

Getting data from 2 tables in magento

I created 2 textension in magento along with 2 different tables. First extension store data in table-1 while second second extension store data in table-2. Now i want to display data in first extension by LeftJoin. It show data without leftjoin from first table but not showing data with leftjoin from both the tables.
This code in block.php
public function methodblock()
{
$collection = Mage::getModel('test/test')->getCollection();
$returnCollection = $collection->getSelect()
->joinLeft('magento_answer', 'id_pfay_test=question_id',
array('*'), null , 'left');
return $returnCollection;
}
On Layout side. dislplaydata.phtml
<?php
$collection = $this->testmethodblock();
foreach($collection as $rows {
echo $rows ->getData('name');
}
I Got the answer. I use the custom query which works for me.
$resource = Mage::getSingleton('core/resource');
$readConnection = $resource->getConnection('core_read');
$qTable = $resource->getTableName('pfay_test');
$aTable = $resource->getTableName('answer/answer');
$query = 'SELECT * FROM '.$qTable.' q left join '.$aTable.' a ON a.question_id=q.id_pfay_test';
$results = $readConnection->fetchAll($query);
return $results;

Select posts based on selected categories

I have following scenario:
user selects couple categories
user should see posts which belongs to these categories
post belong to one or more categories
I setup the database like this:
users -> category_user <- categories
posts -> categoriy_post <- categories
I managed to accomplish this, but I had to find all ids from these tables to find relevant posts. I need to make it simpler because this approach is blocking some other actions I need to do. This is my code:
$categoryIds = Auth::user()->categories;
$ids = array();
$t = array_filter((array)$categoryIds);
if(!empty($t)){
foreach ($categoryIds as $key => $value) {
$ids[] = $value->id;
}
}else{
return View::make("main")
->with("posts", null)
->with("message", trans("front.noposts"))->with("option", "Latest");
}
$t = array_filter((array)$ids);
if(!empty($t)){
$p = DB::table("category_post")->whereIn("category_id", $ids)->get();
}else{
return View::make("main")
->with("posts", null)
->with("message", trans("front.noposts"))->with("option", "Latest");
}
$postsIds = array();
foreach ($p as $key => $value) {
$postsIds[] = $value->post_id;
}
$t = array_filter((array)$postsIds);
if(!empty($t)){
$postIds = array_unique($postsIds);
$posts = Post::whereIn("id", $postsIds)
->where("published", "=", "1")
->where("approved", "=", "1")
->where("user_id", "!=", Auth::user()->id)
->orderBy("created_at", "desc")
->take(Config::get("settings.num_posts_per_page"))
->get();
return View::make("main")
->with("posts", $posts)->with("option", "Latest");
}else{
return View::make("main")
->with("posts", null)
->with("message", trans("front.noposts"))->with("option", "Latest");
}
How to do this properly without this bunch code?
Yes, there is Eloquent way:
$userCategories = Auth::user()->categories()
->select('categories.id as id') // required to use lists on belongsToMany
->lists('id');
if (empty($userCategories)) // no categories, do what you need
$posts = Post::whereHas('categories', function ($q) use ($userCategories) {
$q->whereIn('categories.id', $userCategories);
})->
... // your constraints here
->get();
if (empty($posts)) {} // no posts
return View::make() ... // with posts
Or even better with this clever trick:
$posts = null;
Auth::user()->load(['categories.posts' => function ($q) use (&$posts) {
$posts = $q->get();
}]);
if (empty($posts)) // no posts
return View... // with posts
Obviously, you can write joins, or even raw sql ;)
You can take those categories directly from the database from user records:
SELECT ...
FROM posts AS p
INNER JOIN category_post AS cp ON cp.id_post = p.id
INNER JOIN categories AS c on c.id = cp.id_category
INNER JOIN category_user AS cu ON cu.id_category = c.id
WHERE cu.id_user = 123 AND p.published = 1 AND ...
Joins in Laravel can be achieved, see the documentation: laravel.com/docs/queries#joins Maybe there is also an Eloquent way, I don't know, try searching :-)

Second counting query for pagination

I have a couple of pretty complex queries, and for each of them I have to write a second query counting results. So for example, in the model:
$dql = "SELECT u FROM AcmeBundle:Users u LEFT JOIN AcmeBundle:Products p WITH u.id = p.id";
I would have to create a duplicate query like this:
$countingQuery = "SELECT COUNT(u.id) FROM AcmeBundle:Users u LEFT JOIN AcmeBundle:Products p WITH u.id = p.id";
The main problem with that is that with every change in the first query, I would have to change the second either.
So I came up with another idea:
$countingSelect = "SELECT COUNT(u.id)";
$noncountingSelect = "SELECT u";
$dql = " FROM AcmeBundle:Users u LEFT JOIN AcmeBundle:Products p WITH u.id = p.id";
return $this->getEntityManager()->createQuery($noncountingSelect . $dql)
->setHint('knp_paginator.count', $this->getEntityManager()->createQuery($countingSelect . $dql)->getSingleScalarResult());
It works of course, but the solution seems quite ugly with larger selects.
How can I solve this problem?
I believe the Doctrine\ORM\Tools\Pagination\Paginator will do what you're looking for, without the additional complexity.
$paginator = new Paginator($dql);
$paginator
->getQuery()
->setFirstResult($pageSize * ($currentPage - 1)) // set the offset
->setMaxResults($pageSize); // set the limit
$totalItems = count($paginator);
$pagesCount = ceil($totalItems / $paginator->getMaxResults());
Code yanked from: http://showmethecode.es/php/doctrine2/doctrine2-paginator/
You can create a customer repository as explained in the docs and add your query to that with a minor edit like..
use Doctrine\ORM\EntityRepository;
class ProductRepository extends EntityRepository
{
public function findProducts()
{
return $this->findProductsOrCountProducts();
}
public function findCountProducts()
{
return $this->findProductsOrCountProducts(true);
}
private function findProductsOrCountProducts($count = false)
{
$queryBuilder = $this->createQueryBuilder('u');
if ($count) {
$queryBuilder->select('COUNT(u.id)');
}
$query = $queryBuilder
->leftJoin('AcmeBundle:Products', 'p', 'WITH', 'u.id = p.id')
->getQuery()
;
if ($count) {
return $query->getSingleScalarResult();
} else {
return $query->getResult();
}
}
}
Then you can call your method using...
$repository = $this->getDoctrine()
->getRepository('AcmeBundle:Users');
// for products
$products = $repository->findProducts();
// for count
$countProducts = $repository->findCountProducts();
Note:
I know it's not best practice to just say look at the docs for the customer repository bit s here' the YAML mapping...
# src/Acme/StoreBundle/Resources/config/doctrine/Product.orm.yml
Acme\StoreBundle\Entity\Product:
type: entity
repositoryClass: Acme\StoreBundle\Entity\ProductRepository
# ...

Categories