I am using Entity Query to select nodes of two different types say article and page. The fetching seems to be working but now i have to apply sorting to it. Both the content types have different date field say field_date_1 and field_date_2. Now i know i could do this by adding expression$query->addExpression('COALESCE( field_date_1, field_date_2)', 'Date'); in SQL query and sort on $query->sort('Date', 'DESC');
But, addExpression() or adding COALESCE to sort() in Entity Query is throwing Error: Call to undefined method Drupal\Core\Entity\Query\Sql\Query::addExpression()
So, could anyone help me with how to apply sort on more than 2 date fields or how to add an Expression.
This has helped me:
Add tag to the query:
$query->addTag('my_module_tag');
And add expressions in the module file by implementing hook_query_TAG_alter() -
/**
* Implements hook_query_TAG_alter().
*/
function hook_query_my_module_tag_alter(Drupal\Core\Database\Query\AlterableInterface $query) {
$query->addExpression('COALESCE( field_date_1, field_date_2)', 'Date');
}
Related
I need to filter an "Entity Reference View" autocomplete widget by passing arguments from a "Reference Field" in my content type.
I researched on this and found that PHP Code type Contextual Filter is the most suggested way to achieving this but as PHP Code has now been removed from Drupal 8 Core, what are the alternatives to this common use case? (an earlier suggestion to use PHP Code: Drupal 7: how to filter view content (with entity reference field) based on current page content)
While editing the reference field, it seems that only hard-coded values be mentioned in "View arguments" field and there is no dynamical way of achieving this (e.g. from URL/query string etc).
It's hacky, but you can use a hook_form_alter. Here's an example passing the current NID as an argument:
/**
* Implements hook_form_alter().
*/
function MYMODULE_form_alter(&$form, FormStateInterface $form_state, $form_id)
{
if ($form_id == 'node_NODETYPE_edit_form') {
$node = $form_state->getFormObject()->getEntity();
$form['field_MY_REF_FIELD']['widget'][0]['target_id']['#selection_settings']['view']['arguments'][0] = $node->id();
}
}
For example.com/path?id=55
[current-page:query:id]
For example.com/path/55
[current-page:url:args:last]
For example.com/path/alias
[current-page:url:unaliased:args:last]
Ads entity is described by geographic information: Country> Region>County. The Ads entity is only linked with County. Consequently, retrieving Ads by countries will require us joining entities twice.
My goal is counting the number of Ads for a given country. For that, I tried this DQL query but without success:
public function getMotorsAdsCountByCountry($slug){
$qb = $this->_em->createQueryBuilder()
->select("m.id, COUNT(m.id) AS cnt")
->from("MinnAdsBundle:MotorsAds", "m")
->join("m.county","county")->addSelect("county")
->join("county.region","region")->addSelect("region")
->join("region.country","country")->addSelect("country")
->where("country.slug=:slug")
->setParameter(":slug", $slug);
return $qb->getQuery()->getSingleScalarResult();
}
The error I got is:
[Semantical Error] line 0, col -1 near 'SELECT m.id,': Error: Cannot
select entity through identification variables without choosing at
least one root entity alias.
I have even seen a post regarding the same error in this link but without success.
I found the solution:
$qb = $this->_em->createQueryBuilder()
->select("COUNT(m.id) AS cnt")
->from("MinnAdsBundle:MotorsAds", "m")
->join("m.county","county")
->join("county.region","region")
->join("region.country","country")
->where("country.slug=:slug")
->setParameter(":slug", $slug);
I have just remove the addSelect() in addition to the modification of the select().
try changing
->select("m.id, COUNT(m.id) AS cnt")
to
->select("m, COUNT(m.id) AS cnt")
or change hydration to array
this is known as Doctrine limitation you should first join with MotorAds Entity like this
from('MinnAdsBundle','mi')->leftJoin(MotorsAds::class,'m','WITH','mi.motorsAds = m');
then you can select form MotorsAds directly
refer to this answer
fellow programmers :)
I'm having a bad case of no idea what's going on.
This concerns two entities: Ware and File.
In my repository, I have a function that returns File objects along with wares to avoid lazy loading:
The relevant part of this function ( because the exception happens even if i trigger this bit only ) is this:
public function findByWithFilesTotal($params, $page = false, $per_page = false){
$res = $this->_em->createQuery('SELECT w, f FROM ShopBundle:Ware w JOIN w.files f');
// same result occurs with LEFT JOIN
return count($res->getResult());
}
Important stuff:
1) Ware and File classes are direct descendants of class Data. Discriminators are all right.
2) Ware has OneToMany relation with File - that means File table has ware_id column.
3) This is the most important part ( IMHO ). I use this filter to separate deleted items in all Data descendants.
class UndeletedFilter extends SQLFilter
{
public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAlias)
{
if(!$targetEntity->hasField('deleted'))
return "";
return "( $targetTableAlias.deleted = 0 OR $targetTableAlias.deleted IS NULL)";
}
}
It works for all the other entities, but causes a HydrationException with message 'The discriminator column "discr" is missing for "Acme\CoreBundle\Entity\File" using the DQL alias "f".' for this one query.
This, however, DOES NOT happen if I either remove JOIN w.files from DQL query, and leave it to lazy loading, or return an empty string from addFilterConstraint() method even if it does have the 'deleted' field.
So, if anyone knows: What exactly causes this, and how do solve it?
Thank you in advance :)
One reason for trigger this exception in when you are working inherent classes, then for example, if your discriminator column has null values the QueryBuilder will do not know how to convert this unknown type based in type.
Hi I like to add a custom function to doctrine.
I need to add a mysql Field function to be able to order by size like here:
mysql custom order by with mixed data types
So I use this as exemple: https://github.com/beberlei/DoctrineExtensions/blob/master/lib/DoctrineExtensions/Query/Mysql/Field.php
and try to add it to Symfony2 like that: http://symfony.com/fr/doc/current/cookbook/doctrine/custom_dql_functions.html
When I do:
$queryBuilder->addOrderBy("FIELD(size, 'XS', 'S', 'M', 'L', 'XL', 'XXL', 'XXXL'), size, length", 'ASC');
I always get the error:
Error: Expected end of string, got '('
Any idea how to implement it?
You cannot use DQL functions within ORDER BY clause. You must select the result of FIELD() function into hidden field and sort results using that field:
SELECT ..., FIELD(size, ...) AS HIDDEN sizeOrder
FROM ...
ORDER BY sizeOrder
sizeOrder field won't affect your results as it won't be even hydrated.
I have a basic Symfony2/Doctrine2 question. I have two entities the first called "Column" that has OneToMany issues, entity "Issue". And the Issue entity has a ManyToOne relationship with the entity Column. When I create a new Issue I wish to assign a default value for the column.
If I create a hidden field in IssueType.php and assigned a default value I cannot save the submitted form because I get an error about assigning a string to setColumn and not an instance of the Column entity as defined in my Issue entity (see below).
public function setColumn(\WebConfection\ServiceDeskBundle\Entity\Column $column)
{
$this->column = $column;
return $this;
}
Can anybody please advise on the best way to accomplish this? I have read a few articles but am a tad confused and not sure which way to jump. An idiot friendly answer would be greatly appreciated.
You don't really need a hidden field for this to work. Just set the right (default) Column on the Issue you want to add within your action,
// ...
$issue = new Issue();
$issue->setColumn($yourDefaultColumn);
$form = $this->createForm('your_issue_form', $issue);
// ...