I have a native query an want to fill a ResultSetMapping object with the results of my query.
Everything works as expected, but the field "distance". The field in the resulting array is always empty. When i run my query directly in MySQL there are results for "distance", so i guess my SQL is ok?
class PlaceRepository extends EntityRepository
{
public function getAllWithMainImage($lat, $lon)
{
try
{
$rsm = new ResultSetMapping;
$rsm->addScalarResult('slug', 'slug');
$rsm->addScalarResult('title', 'title');
$rsm->addScalarResult('rating', 'rating');
$rsm->addScalarResult('visited_at', 'visited_at');
$rsm->addScalarResult('img', 'img');
$rsm->addScalarResult('distance', 'distance');
return $this->getEntityManager()
->createNativeQuery('SELECT p.slug, p.title, p.rating, p.visited_at, pp.file AS img, ROUND(GLength(
LineString(
p.place_point,
GeomFromText("POINT(:lat :lon)")
)
) * 111.12, 1) AS distance
FROM place p
LEFT JOIN place_picture AS pp
ON p.id = pp.place_id
GROUP BY p.id
ORDER BY distance
LIMIT 20', $rsm)
->setParameter('lat', $lat)
->setParameter('lon', $lon)
->getResult();
}
catch(\Doctrine\ORM\NoResultException $e)
{
return false;
}
}
}
Repository function called from Crontroller:
class PlaceRestController extends Controller
{
public function getPlacesAction(ParamFetcher $paramFetcher)
{
$view = FOSView::create();
$view->setHeader('Access-Control-Allow-Origin', '*');
$em = $this->getDoctrine()->getManager();
$data = $em->getRepository('TouringPlaceBundle:Place')->getAllWithMainImage(48.39227479328352, 9.985520839691162); //hard-coded for debugging
print_r($data); //… [img] => xzz.jpg, [distance] =>
if($data)
{
$view->setStatusCode(200)->setData($data);
}
return $view;
}
}
Where is my mistake?
Can you add the part of your code where you are calling this method?
Where does the return value go? In an entity?
Evenf if I don't think so, the problem might come from the multiples quotes so :lat and :lon are not changed into the values you want them to be. Have you checked the profiler to be sure they are replaced?
Related
I am making some DB query via repository (ORM), I want to get a list of objects.
What's my problem?
I have two methods in the repository: getList() to get a list and getCount() to get the number of total records for information.
getList() gives me 5 records, and getCount() gives the number 9.
public function getList($criteria, $page, $limit, $orderBy, $joins = [])
{
$qb = $this->createQueryBuilder('a')->select('a');
if(!empty($joins)) {
$qb = $this->setCriteriaByJoins($qb, $joins);
}
$qb = $this->setCriteriaToQuery($qb, $criteria);
foreach($orderBy as $order) {
$qb->addOrderBy('a.' . $order[0], $order[1]);
}
if($page && $limit) {
$offset = ($page - 1) * $limit;
$qb->setFirstResult($offset)
->setMaxResults($limit);
}
$result = $qb->getQuery()->getResult();
return $result;
}
public function getCount($criteria = [], $joins = []) {
try {
$qb = $this->createQueryBuilder('a')->select('count(a.id)');
if(!empty($joins)) {
$qb = $this->setCriteriaByJoins($qb, $joins);
}
$qb = $this->setCriteriaToQuery($qb, $criteria);
$result = $qb->getQuery()->getSingleScalarResult();
} catch(\Exception $e) {
$result = 0;
}
return $result;
}
In debugging, I see that the getList() request was built like this:
SELECT r0 _. * FROM film r0_ LEFT JOIN person_film r1_ ON (r0_.id = r1_.film_id) WHERE r1_.person_id IN (45793) AND r0_.status = 1 ORDER BY r0_.`release` DESC, r0_.id DESC LIMIT 48
and getCount()
SELECT count (r0_.id) AS sclr_0 FROM film r0_ LEFT JOIN person_film r1_ ON (r0_.id = r1_.film_id) WHERE r1_.person_id IN (45793) AND r0_.status = 1
Requesting getList() from the repository gives me 5 records. However, if I directly ask the database with this query (without ORM), then I will get 9 records. Of these 9 records, 4 are duplicated due to the fact that the person_film table can contain more than one record with the same film_id and person_id (these records differ in other fields). I found that /vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php:hydrateRowData() removes duplicates.
How to do to make the ORM in the getList() request return all 9 records, even if they are duplicates?
And vice versa. How to do to the getCount() to return 5.
it seems like this is the answer to the second question
public function getCount($criteria = [], $joins = [], $distinct = false) {
try {
$sq = ($distinct) ? 'count(distinct(a.id))' : 'count(a.id)';
$qb = $this->createQueryBuilder('a')->select($sq);
if(!empty($joins)) {
$qb = $this->setCriteriaByJoins($qb, $joins);
}
$qb = $this->setCriteriaToQuery($qb, $criteria);
$result = $qb->getQuery()->getSingleScalarResult();
} catch(\Exception $e) {
$result = 0;
}
return $result;
}
I have to table article and table comment. In the home page I want to see how many comment for earch article.
Model
function show_latest_article($start,$display,$cate)
{
$query= $this->db->get_where('news_news', array('News_Cate_ID'=>$cate),$start,$display);
if($cate==0)
{
$query= $this->db->get_where('news_news',$start,$display);
}
return $query->result();
}
function count_comment($id)
{
$query = $this->db->get_where('comment',array('comment_article_id'=>$id) );
return $query->num_rows();
}
Controller
function index() {
$this->load->model('article');
$data=array('article'=>$this->article->show_latest_article(0,8,1),
'sidebar'=>$this->article->side_bar(9),
'count_comment'=> $this->article->count_comment($id),
);
$this->load->view('page/index',$data);
}
In the view I have this
foreach($article as $art)
{
echo $art->title."<br>";
$id= $art->id;
// I want to echo number of comment here.
// Or I want to call function count_comment($id)
}
$this->load->model('article');
$data['article'] = $this->article->show_latest_article(0, 8, 1);
$data['sidebar'] => $this->article->side_bar(9);
$data['count_comment'] => $this->article->count_comment($id);
$this->load->view('page/index', $data);
And it should work.
It's not so clear, where the $id variable come from, but I suggest to join the comments table to your article. It's not a best practice to make queries within loops.
In your model:
public function show_latest_article($ids = array())
{
return $this->db
->select('articles.*, COUNT(comments.id) as comment_count')
->where_in('articles.id', $ids) // You can skip this
->join('comments', 'comments.article_id = articles.id', 'left')
->group_by('articles.id')
->get('articles')
->result();
}
In your controller:
public function index()
{
$data['articles'] = $this->article->show_latest_article(array(0, 8, 1));
$this->load->view('page/index', $data);
}
Just change the field name according to database columns. Also you can skip the where_in condition. (I'm not sure what the three number stands for).
Then in your view, you can simply access the field:
$art->comment_count
EDIT: According to your comment:
$this->db
->select('a.*, (SELECT COUNT(*) FROM comment c WHERE c.comment_article_id = a.News_News_ID ) as counta')
->get('news_news')
->result();
I am writing this answer as you provided code. It could be more simpler if you give more database details. Try below code
function index() {
$this->load->model('article');
$articles = $this->article->show_latest_article(0,8,1);
foreach($articles as $article)
{
$article->comment_count = $this->article->count_comment($article->id);
$all_article[] = $article;
}
$data=array('article'=>$all_article,
'sidebar'=>$this->article->side_bar(9)
);
$this->load->view('page/index',$data);
}
On view
foreach($article as $art)
{
echo $art->title."<br>";
$id= $art->id;
echo $art->comment_count;
}
Controller :
function index() {
$this->load->model('article');
$articles = $this->article->show_latest_article(0,8,1);
$count_comments = Array();
for($i=0;$i<count($articles);$i++){
$count_comments[$i] = $this->article->count_comment($articles->$id);
}
$count_comments =
$data=array('article'=>$articles,
'sidebar'=>$this->article->side_bar(9),
'count_comment'=> $count_comments);
$this->load->view('page/index',$data);
}
In the View :
$i=0;
foreach($article as $art)
{
echo $art->title."<br>";
$id= $art->id;
echo $count_comment[$i];
$i++;
}
Data is passed from the controller to the view by way of an array or an object in the second parameter of the view loading function. Here is an example using an array:
$data = array(
'title' => 'My Title',
'heading' => 'My Heading',
'message' => 'My Message'
);
$this->load->view('blogview', $data);
Also below is the example for object
$data = new Someclass();
$this->load->view('blogview', $data);
PLEASE NOTE: Note: If you use an object, the class variables will be turned into array elements.
You can find out more from below ref URL
Ref: https://ellislab.com/codeigniter/user-guide/general/views.html
First of all in your controller you get count_comment only for specific article ID and not for all articles so you cant do foreach to display comment count of each article.
You need to setup you model better and in model function show_latest_article to use JOIN comments table and do count comment in query.
I will help you with query if you provide me more info about database table of article and comments.
SELECT
article.*,
COUNT(comment.id),0) AS numberOfCommments
FROM article
LEFT JOIN comment
ON comment.article_id = article.id
GROUP BY article.id
i have developed one model -view and controller in codeigniter but when i calling function of controller in url instead of executing that controller it redircts me to homepage
controller :
public function job_post_list()
{
$data['job_posts']=$this->recruiter_post_job_model->get_posts();
$this->load->view('recruiter/job_post_list',$data);
$this->load->view('template/footer');
}
Model :
public function get_posts()
{
$logged_in=$this->session->userdata('logged_in');
$query="SELECT RPJ.*, CM.country_name, SM.state_name, CTM.city_name
FROM recruiter_post_jobs AS RPJ
LEFT JOIN country_master AS CM ON ( CM.country_id = RPJ.country_id )
LEFT JOIN state_master AS SM ON ( SM.state_id = RPJ.state_id )
LEFT JOIN city_master AS CTM ON ( CTM.city_id = RPJ.city_id )
WHERE RPJ.recruiter_id = ".$logged_in['user_id']." AND RPJ.job_status = 1";
$data=$this->db->query($query);
if($data->num_rows() > 0)
{
$results=$data->result();
return $results;
}
else
{
$results=NULL;
return $results;
}
}
any body please answer me.
I am working on a project using symfony2. I already have my search function and it is already working. But what I want is to have pagination on the search results since there are times that there are a lots of data being retrieve. How can I possibly do it?
Here is my code :
public function searchAction (Request $request) {
$request = $this->getRequest();
$data = $request->get('search');
$em = $this->getDoctrine()->getManager();
$query = $em->createQuery (
'SELECT a,b,c FROM SampleBundle:transactDetail a
JOIN a.transact b
JOIN b.transactType c
WHERE b.pNumber LIKE :data
OR b.senderId LIKE :data'
)
->setParameter('data', "%$data%");
$result = $query->getResult();
if ($result == null ) {
return $this->render('SampleBundle:Sample:noresult.html.twig');
}
return $this->render('SampleBundle:Sample:search.html.twig', array('result' => $result));
}
Thanks in advance.
This is an example of your code with Paginator :
public function searchAction(Request $request, $firstResult = 0, $maxResults = 100)
{
$request = $this->getRequest();
$data = $request->get('search');
$em = $this->getDoctrine()->getManager();
$query = $em->createQuery(
'SELECT a,b,c FROM SampleBundle:transactDetail a
JOIN a.transact b
JOIN b.transactType c
WHERE b.pNumber LIKE :data
OR b.senderId LIKE :data'
)
->setParameter('data', "%$data%")
->setFirstResult($firstResult)
->setMaxResults($maxResults);
$result = new Paginator($query);
if ($result == null) {
return $this->render('SampleBundle:Sample:noresult.html.twig');
}
return $this->render('SampleBundle:Sample:search.html.twig', array('result' => $result));
}
And if you would like to count the total just count($result);.
Paginator has Countable et IteratorAggregate interfaces.
So you can loop on your result without problem.
this is the model function i am trying join the single database table it self the , parent::get method fetch the data from the table !
public function get_with_parents($id=NULL,$single=FALSE){
$this->db->select('pages.*','p.slug as parent_slug','p.title as parent_title');
$this->db->join('pages as p','pages.parent_id=p.id','left');
return parent::get($id,$single);
}
this is the controller!!
$this->data ['pages'] = $this->Page_model->get_with_parents();
Assuming your single tables is called pages, this should work -
$this->db->select('p1.title as ptitle','p.slug as parent_slug','p.title as parent_title');
$this->db->from('pages AS p1');
$this->db->join('pages AS p','p1.parent_id=p.id','left');
public function get_with_parent($id = NULL,$sengle = FALSE)
{
$this->db->select('pages.*,p.slug as parent_slug,p.title as parent_title')
->where("pages.language", $this->uri->segment(1))
->join('pages as p','pages.parent_id=p.id','left');
return parent::get($id,$sengle);
}
or
public function get_with_parent ()
{
$this->db->select('pages.*, p.slug as parent_slug, p.title as parent_title')
->where("pages.language", $this->uri->segment(1))
->join('pages as p', 'pages.parent_id=p.id', 'left');
$query = $this->db->get('pages');
return $query->result();
}