Subquery on symfony form field - php

I'm trying to generate a subquery to populate and form select in symfony but I get this error message
[Semantical Error] line 0, col 167 near 'd2 WHERE d2.distributor': Error: 'd2' is already defined.
this is my code
-`>add('doctor', EntityType::class, [
'class' => Doctor::class,
'query_builder' => function (EntityRepository $er) use ($options) {
$subquery = $er->createQueryBuilder('d2')
->select('')
->from('AppBundle\Entity\Distributor', 'd2')
->andWhere('d2.distributor = :distributor_subquery')
->setParameter('distributor_subquery', $options['user']);
$query = $er->createQueryBuilder('d');
$query->select('d')
->where('d.distributor = :distributor')
->setParameter('distributor', $options['user'])
->orWhere($query->expr()->in('d.distributor', $subquery->getDQL()))
->orderBy('d.name', 'ASC')
->addOrderBy('d.surname', 'ASC');
return $query;
},`
d2 alias is defined two times
$er->createQueryBuilder('d2')
and
->from('AppBundle\Entity\Distributor', 'd2')
but in both functions the parameter is mandatory
I tried with
$subquery = $er->createQueryBuilder() ->select('') ->from('AppBundle\Entity\Distributor', 'd2') ->andWhere('d2.distributor = :distributor_subquery')
but it doesn't work

Please see the implementation of EntityRepository::createQueryBuilder() method: it already contains the select and from parts, it gets this information from it's entity class. So you can omit calling these methods, just add a where clause and bind params:
$subquery = $er->createQueryBuilder('d2')
->andWhere('d2.distributor = :distributor_subquery')
->setParameter('distributor_subquery', $options['user']);

Related

A Database Error Occurred Error Number: 1054 Unknown column 'Array' in 'where clause'

i cannot get value $list_izin from array, how can i get value from array and set the value for where clause condition
$list_izin = ['7','11','14','16','19','202','139','157'];
$where = array(
'tmuser_userauth.userauth_id' => $userauth_id,
'tmpegawai.bidangid' => $bidangid,
'trperizinan_user.trperizinan_id' => $list_izin
);
}
return $this->db
->select('
tmpegawai.pegawaiid,
tmpegawai.n_pegawai,
tmpegawai.telp,
tmuser.photo,
tmuser.last_login,
trperizinan_user.trperizinan_id
')
->from($this->table)
->join('tmuser', 'tmuser.tmpegawai_id = tmpegawai.pegawaiid')
->join('tmuser_userauth','tmuser_userauth.tmuser_id = tmuser.id')
->join('trperizinan_user','trperizinan_user.user_id = tmuser.id')
->where($where)
->get();
}
You're seeing the "unknown column 'Array'" error because the array of IDs is being converted to a string when that value of the associative array is processed by where(). ("Array" is the string representation of any array in PHP.)
To fix it, first remove that last column from the $where array.
$where = array(
'tmuser_userauth.userauth_id' => $userauth_id,
'tmpegawai.bidangid' => $bidangid,
);
Then in your select query add the list of IDs in a where_in() condition.
return $this->db
->select('
tmpegawai.pegawaiid,
tmpegawai.n_pegawai,
tmpegawai.telp,
tmuser.photo,
tmuser.last_login,
trperizinan_user.trperizinan_id
')
->from($this->table)
->join('tmuser', 'tmuser.tmpegawai_id = tmpegawai.pegawaiid')
->join('tmuser_userauth','tmuser_userauth.tmuser_id = tmuser.id')
->join('trperizinan_user','trperizinan_user.user_id = tmuser.id')
->where($where)
->where_in('trperizinan_user.trperizinan_id', $list_izin)
->get();
The where_in() will be added to the existing criteria defined in the where(), it won't replace it.

Symfony2: How do I use in a form (query builder) left join and isnull?

I have a problem with a filter function for which I am using two tables.
The first ‚eventcheckin-table‘ is used for checking in the guests via booking-ID for a certain event. Therfore it should also verify if the ID is already checked in. The ID´s which aren´t yet checked in shall be available as an option in the ‚Entity‘ field. This problem I tried to solve in the following way:
SELECT booking.booking_id FROM booking LEFT JOIN event_checkin ON `event_checkin.booking_booking_id = booking.booking_id WHERE` event_checkin.booking_booking_id IS NULL
It works fine.
My solution for the Symfony2 Form Builder is
->add('bookingBooking', EntityType::class, array (
'class' => 'AppBundle:Booking',
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('b')
->leftjoin('AppBundle:EventCheckin', 'e', 'with', 'e.bookingBooking = b.Id')
->expr()->isNull('e.bookingbooking');
},
'label' => 'Booking-ID: * ',
))
Symfony displays this message
Expected argument of type "Doctrine\ORM\QueryBuilder", "string" given
How can I solve this problem?
Thanks for your help. ;)
As i think, you can use andWhere statement like :
$er->createQueryBuilder('b')
->leftjoin('AppBundle:EventCheckin', 'e', 'with', 'e.bookingBooking = b.Id')
->andWhere('e.bookingbooking is null');
Or
$qb = $er->createQueryBuilder('b');
$qb->leftjoin('AppBundle:EventCheckin', 'e', 'with', 'e.bookingBooking = b.Id')
->add('where', $qb->expr()->isNull('e.bookingBooking'));
return $qb;
Inspired on this.

Cakephp3 ElasticSearch Query Q

How do I make a query like
http://localhost:9200/index/businesses/_search?q=services
in Cakephp3 ElasticSearch
I have tried
$this->Businesses->find('all')->where(['*'=>'services']);
However I get no results.
The more accurate answer is to use a builder
$q = 'services';
$businesses = $this->Businesses->find('all')->where(function ($builder) use($q) {
return $builder->query(new \Elastica\Query\SimpleQueryString($q));
});
The _all key might solve the problem
$this->Businesses->find('all')->where(['_all'=>'services']);
Not sure what you're asking, but the asterisk in where(['*'=>'services']) should be a column name in your table schema/database.
Another common issue is that the result of find() is not the result of the query by design. See my answer to Cake PHP 3 needs limit option for find all method and also CakePHP 3 Cookbook: ElasticSearch — Searching Indexed Documents:
$query = $this->Articles->find()
->where([
'title' => 'special',
'or' => [
'tags in' => ['cake', 'php'],
'tags not in' => ['c#', 'java']
]
]);
// The query returns multiple rows which you can loop through
// or alternatively you can call $query->all(); to get the object
// $query->toArray(); to get the array
foreach ($query as $article) {
echo $article->title;
}

Query_builder Symfony form builder error

I have an entity field in my form that shows all forms in the database in a list. These forms have revision numbers. What I want to do is to show only the last revision of a form as an option in the list.
To clarify, the form table looks like this
Id || Name || Revision_number
1 || Form1 || 1
2 || Form1 || 2
The select list should only show revision 2.
So far, I have tried this
->add('form', 'entity', array(
'class' => 'AppBundle\Entity\Form',
'label' => 'label.ship.form',
'query_builder' => function(EntityRepository $er){
return $er->createQueryBuilder('f')
->select('f, MAX(f.revisionNumber) AS max_revision');
}
))
But I get this error
Warning: spl_object_hash() expects parameter 1 to be object, string given
I've faced this problem too.
'query_builder' option should return Doctrine\ORM\QueryBuilder or a Closure and in your case (someone correct me if I am wrong) the "select" method is supposed to return a Doctrine\ORM\QueryBuilder object too. Weird, right...
What I did was create a method in the entity repository that returns the query builder itself:
public function generateStaffRolesQB() {
$qb = $this->getEntityManager()->createQueryBuilder();
$qb->select('r')
->from('DatabaseModelsBundle:Role', 'r')
->where('r.id IN (1, 2)');
return $qb;
}
And in the form I use it like this:
'query_builder' => function(EntityRepository $er) {
return $er->generateStaffRolesQB();
},
Hope it helps.

CGridView filtering with aggregate (grouping) functions - eg MAX()

I have a CGridView that uses a MAX() mysql column to provide data for one of the columns. I have that working with sorting, but I can't figure out filtering. I assumed that I could just use CDbCriteria::compare() call to set it, but it's not working. Ideas?
My search function:
$criteria = new CDbCriteria;
$criteria->condition = 't.is_deleted = 0 and is_admin = 0';
// get last note date
$criteria->select = array('t.*', 'MAX(n.visit_date) AS last_note');
$criteria->join = 'LEFT JOIN notes n ON t.id = n.distributor_id';
$criteria->group = 't.id';
$criteria->order = 't.status';
$criteria->compare('t.type', $this->type);
$criteria->compare('t.name', $this->name, true);
$criteria->compare('t.city', $this->city, true);
$criteria->compare('t.state', $this->state);
$criteria->compare('last_note', $this->last_note);
return new CActiveDataProvider('Distributor', array(
'criteria' => $criteria,
'pagination' => array(
'pageSize' => 20
),
'sort' => array(
'defaultOrder' => 'name',
'attributes' => array(
'last_note' => array(
'asc' => 'last_note',
'desc' => 'last_note DESC'
),
)
),
));
In my view, I just have the name and value values set.
The error I get is CDbCommand failed to execute the SQL statement: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'last_note' in 'where clause'
Edit: The only way I found to do this is (because you can't have aggregate functions in where clauses) is to check the $_GET array for the last_note value, and add a having clause. Note, this isn't parameterized or anything yet, I just wanted to rough it out to see if it would work:
if(isset($_GET['Distributor']['last_note']) && $_GET['Distributor']['last_note'] != '') {
$criteria->having = 'MAX(n.visit_date)=\'' . $this->last_note . "'";
}
I hate using the request variables in the model like this, but there isn't much else I could do.
You're on the right track. You filter aggregate functions like MAX() and SUM() using having. In a query like this, you should probably add a group, otherwise you'll end up with a lot of duplicated data in your result when a Distributor has multiple notes on the same day (assuming t.id is a primary key). Second, you should use named params instead of putting variables directly into SQL. So, instead of compare('last_note'... you'd end up with something like this:
$criteria->group = 't.id';
$criteria->having = 'MAX(n.visit_date) = :last_note';
$criteria->params = array(':last_note' => $this->last_note);
In order for filtering to work, you should have a class attribute to store the data:
public $last_note;
otherwise $this->last_note wont return anything and your $criteria->compare('last_note', $this->last_note); wont do anything either

Categories