I've wrote the following Doctrine query:
$query3 = $this->entityManager
->createQueryBuilder()
->select('t.textDomain , t.translationKey , t.languageIso , t.translationDate')
->from(
'AMDatabase\Entity\TheVerse\TranslationsMasters',
't'
)
->groupBy('t.languageIso')
->orderBy(
't.translationDate',
'DESC'
);
// the values of $key2 array are:
// en-US
// es-MX
// es-PR
foreach( $translation AS $key2=>$value2 ) {
if ( $key2 == 'en-US' ) {
$query3
->orWhere(
$query3->expr()
->like(
't.languageIso',
':languageIso'
)
)
->setParameter(
'languageIso',
$key2
);
}
}
$result3 = $query3->getQuery()
->getArrayResult();
How do I have the query search for all 3 language ISO's at the same time?
With "if ( $key2 == 'en-US' ) {" the query executes and gives me the expected result.
But if I remove "if ( $key2 == 'en-US' ) {" there are no search results.
I thought by using "orWhere" it would keep adding conditions to the query (where en-US will still produce a match).
In haven't ever been able to get orWhere to function the way I think it should. It might be that you need a Where in your opening definition before you can add an orWhere later. You might have to use the nested orX statement like this instead:
$query3->andWhere($query3->expr()->orX(
$query3->expr()->like('t.languageIso', $query3->expr()->literal('en-US')),
$query3->expr()->like('t.languageIso', $query3->expr()->literal('es-MX')),
$query3->expr()->like('t.languageIso', $query3->expr()->literal('es-PR'))
));
You can't develop the statement through a loop. But, since you've only got three criteria, it's easy enough to write out.
Related
I have a tiny little plugin that does the job of hiding findings in html tags in wordpress search results.
Since one of the latest updates of WordPress (now 6.1) it does not work anymore. It does not show any search results at all (except the search form is empty).
Can maybe anyone give a tip how to reacctivate this again? Here is the code, just one php-file inside the plugins folder:
`
<?php
function super_search_exclude_activate() {
$striptags = "CREATE FUNCTION fnStripTags( Dirty longtext )
RETURNS longtext
DETERMINISTIC
BEGIN
DECLARE iStart, iEnd, iLength int;
WHILE Locate( '<', Dirty ) > 0 And Locate( '>', Dirty, Locate( '<', Dirty )) > 0 DO
BEGIN
SET iStart = Locate( '<', Dirty ), iEnd = Locate( '>', Dirty, Locate('<', Dirty ));
SET iLength = ( iEnd - iStart) + 1;
IF iLength > 0 THEN
BEGIN
SET Dirty = Insert( Dirty, iStart, iLength, '');
END;
END IF;
END;
END WHILE;
RETURN Dirty;
END;";
global $wpdb;
$wpdb->query("DROP FUNCTION IF EXISTS fnStripTags");
$wpdb->query($striptags);
}
register_activation_hook(__FILE__, 'super_search_exclude_activate');
function super_search_exclude_deactivate() {
global $wpdb;
$wpdb->query("DROP FUNCTION IF EXISTS fnStripTags");
}
register_deactivation_hook(__FILE__, 'super_search_exclude_deactivate');
function super_search_exclude_posts_search($search) {
if(is_search()) {
global $wpdb;
if(stripos($search, 'post_content LIKE')) {
$search = str_replace("{$wpdb->posts}.post_content LIKE", "fnStripTags({$wpdb->posts}.post_content) LIKE", $search);
}
}
return $search;
}
add_filter('posts_search', 'super_search_exclude_posts_search');
?>
`
What I've already tried:
deactivated the plugin and search results are listet properly but containing html tags.
deactivated other suspicious plugings like "Highlight Search Terms" – no changes.
removed the theme-specific arguments from the url and searched wir /?searchterm only – no changes.
I'm working in a DQL witch is almost ok but I need to change one 'AND' with a 'OR'... this is the query I'm getting now so far:
SELECT *
FROM amp a0_
WHERE (a0_.expediente LIKE '%zumardia 27%' OR a0_.expediente LIKE '%zumardia__27%') AND (a0_.expediente LIKE '%apertura%' OR a0_.expediente LIKE '%apertura%')
****AND**** (a0_.fecha LIKE '%zumardia 27%' OR a0_.fecha LIKE '%zumardia__27%') AND (a0_.fecha LIKE '%apertura%' OR a0_.fecha LIKE '%apertura%')
the ****AND**** is witch I need to change, this is my code right now:
foreach ($fields as $field) {
foreach ($value as $v) {
$toFind = [' ',',','?'];
$clean = str_replace($toFind, '__', $v);
$qb->andWhere(
$qb->expr()->orX(
$qb->expr()->orX($expr->like('a.'.$field, ':v'.$field.$miindex)),
$qb->expr()->orX($expr->like('a.'.$field, ':v2'.$field.$miindex))
)
)->setParameter('v'.$field.$miindex, '%'.$v.'%')
->setParameter('v2'.$field.$miindex, '%'.$clean.'%');
}
}
What I want to do is search for 2 parameters y every fields on a table
I have a query that pulls in some jobs if they have an end date and are not completed which produces the desired result:
real code
$this->createQueryBuilder('j')
->where('j.completed = :false OR j.completed is NULL')
->andWhere('j.has_due_date = :true')
->andWhere('j.has_due_date = :true')
->setParameters( array(
'false' => FALSE,
'true' => TRUE
) )
->orderBy('j.due_date', 'asc')
->getQuery();
result
SELECT j FROM App\Entity\Jobs j
WHERE (
j.completed = :false
OR j.completed is NULL
)
AND j.has_due_date = :true
ORDER BY j.due_date ASC
I'm wanting to follow the DQL best practice for this and feel like there is another way or writing this and only having a single WHERE clause per call on a ->where variant (andWhere(), orWhere())
In my mind it's something like this but I can't find anything out there to confirm it:
pseudo code
$query = $this->createQueryBuilder('j')
->where( $requiredClass->
->where('j.completed = :false')
->orWhere('j.completed is NULL')
->setParameter('false', FALSE)
)
->andWhere('j.has_due_date = :true')
->setParameter('true', TRUE)
->orderBy('j.due_date', 'asc')
->getQuery();
Main questions are:
Is there a way to do this the second way?
am I overcomplicating things unnecessarily?
if there is a second way to do this as mentioned, the first statement works so why should it matter?
Using the query builder should be easier and more understandable
public function someFunction()
{
$qb = $this->createQueryBuilder('j');
$orX = $qb->expr()->orX();
$andX = $qb->expr()->andX();
$orX->add($qb->expr()->eq('j.completed', $qb->expr()->literal(false)));
$orX->add($qb->expr()->isNull('j.completed'));
$andX->add($qb->expr()->eq('j.has_due_date', $qb->expr()->literal(true)));
$qb->andWhere($orX, $andX)
->orderBy('j.due_date', 'asc')
->getQuery()
->getResult();
}
As stated in the official documentation for QueryBuilder best practice - the right way is to use the helper method QueryBuilder::expr() and also the Doctrine\ORM\Query\Expr helper class. High level API methods
i.e.:
// create QueryBuilder
$qb = $this->createQueryBuilder('j');
// build conditions
$qb->where(
$qb->expr()->orX(
$qb->expr()->eq('j.completed', ':false'),
$qb->expr()->isNull('j.completed')
)
)
->andWhere(
$qb->expr()->eq('j.has_due_date', ':true')
)
->andWhere(
$qb->expr()->eq('j.has_due_date', ':true')
)
->setParameters(array(
'false' => FALSE,
'true' => TRUE
))
->orderBy('j.due_date', 'asc');
// get query
$query = $qb->getQuery();
// execute and get result
$result = $query->getResult();
I would like to upgrade my symfony 2 project from 2.3 to 2.7 LTS version. I have a problem in a repository to get result of a query. In 2.3, this query give me something :
public function findProtectedPublications( $steps, $start, $end)
{
$query= $this->getEntityManager()
->createQueryBuilder()
->select('d.pubRefs')
->from('ImpressionDemandBundle:Event', 'h')
->innerJoin('h.demand','d')
->where('d.protectedPublications = :pub')
->setParameter('pub', 1 )
->andWhere('h.date >= :start')
->setParameter('start', $start )
->andWhere('h.date <= :end')
->setParameter('end', $end )
->andWhere('h.stepId in (:steps)')
->setParameter('steps', $steps )
->orderBy('d.id','ASC')
->getQuery();
$results = $query->getResult();
$publications = array();
if ($results && ! empty ($results)){
foreach($results as $result){
$pubs = $result['pubRefs'];
if ($pubs && ! empty($pubs)){
foreach($pubs as $pub){
$publications[] = $pub;
}
}
}
}
return $publications;
}
But this code doesn't work in earlier version because $pubs variable in an ArrayCollection. So I changed the end of my code with this :
$results = $query->getResult();
$publications = array();
if ($results && ! empty ($results)){
foreach($results as $result){
$pubs = $result['pubRefs'];
var_dump($pubs);
if (! $pubs->isEmpty()){
$arrayPubs = $pubs->toArray();
foreach($arrayPubs as $pub){
$publications[] = $pub;
}
}
}
}
return $publications;
In this part, when I dump the $pubs variable, I have :
object(Doctrine\Common\Collections\ArrayCollection)#131 (2) {
["elements":"Doctrine\Common\Collections\ArrayCollection":private]=>
NULL
["_elements":"Doctrine\Common\Collections\ArrayCollection":private]=>
array(1) {
[0]=>
object(Impression\DemandBundle\Entity\Publication)#125 (5) {
["editor":"Impression\DemandBundle\Entity\Publication":private]=>
string(24) "Journal Le Monde 4-10-13"
["coauthors":"Impression\DemandBundle\Entity\Publication":private]=>
string(12) "Machin Machin"
["title":"Impression\DemandBundle\Entity\Publication":private]=>
string(57) "La tragédie de Lampedusa: s"émouvoir, comprendre, agir."
["nbPages":"Impression\DemandBundle\Entity\Publication":private]=>
float(1)
["nbCopies":"Impression\DemandBundle\Entity\Publication":private]=>
float(40)
}
}
}
So it seems that there are elements in this ArrayCollection, but the test $pubs->isEmpty() gives a true result, so I have nothing in $publications array.
Edit: In fact, the problem seems to be due to my data in the database : for an object previous from my upgrade, I have something like this in the database :
O:43:"Doctrine\Common\Collections\ArrayCollection":1:{s:54:"Doctrine\Common\Collections\ArrayCollection_elements";a:1:{i:0;O:42:"Impression\DemandBundle\Entity\Publication":5:{s:50:"Impression\DemandBundle\Entity\Publicationeditor";s:5:"BREAL";s:53:"Impression\DemandBundle\Entity\Publicationcoauthors";s:5:"MONOT";s:49:"Impression\DemandBundle\Entity\Publicationtitle";s:18:"USA Canada mexique";s:51:"Impression\DemandBundle\Entity\PublicationnbPages";d:150;s:52:"Impression\DemandBundle\Entity\PublicationnbCopies";d:150;}}}
and this gives the error.
For a object add after my upgrade, I have something like this in the database :
O:43:"Doctrine\Common\Collections\ArrayCollection":1:{s:53:"Doctrine\Common\Collections\ArrayCollectionelements";a:1:{i:0;O:42:"Impression\DemandBundle\Entity\Publication":5:{s:50:"Impression\DemandBundle\Entity\Publicationeditor";s:8:"dfg dfgd";s:53:"Impression\DemandBundle\Entity\Publicationcoauthors";s:7:"dfg dfg";s:49:"Impression\DemandBundle\Entity\Publicationtitle";s:5:"fdg d";s:51:"Impression\DemandBundle\Entity\PublicationnbPages";d:5;s:52:"Impression\DemandBundle\Entity\PublicationnbCopies";d:3;}}}
and the function findProtectedPublications() works without errors.
The difference between the two versions is ArrayCollection_elements for the first and ArrayCollectionelements for the second.
To correct this data, I tried with
UPDATE demand SET pub_refs = REPLACE (pub_refs, "ArrayCollection_elements', 'ArrayCollectionelements')
but this doesn't work because of special chars. Trying with
UPDATE demand SET pub_refs = REPLACE (pub_refs, "ArrayCollection�_elements', 'ArrayCollection�elements')
doesn't work better. How can I correct this data ?
Doctrine can populate results as an Array instead of an ArrayCollection, simply change the getResult() call to:
$results = $query->getResult(\Doctrine\ORM\AbstractQuery::HYDRATE_ARRAY);
This would be the most efficient way to complete your task however you could also use ArrayCollection's built-in toArray() method to convert its own data to array format:
$publications = $results->toArray();
As the problem seems to be due to a change in the storage of ArrayCollection in database between 2.3 and 2.7 version of symfony, I created an line command to update these in database.
A client has requested that I make the characters "S" and "$" interchangeable in the search function, i.e. "Search Query" and "$earch Query" should return identical results.
Is there a way to accomplish this?
Change it before WP queries the database:
$the_replacements = array(
'$' => 'S',
);
function modify_search_vars($search_vars) {
global $the_replacements;
if (!empty($search_vars['s']) && !empty($the_replacements[$search_vars['s']])) {
$search_vars['s'] = $the_replacements[$search_vars['s']];
}
return $search_vars;
}
add_filter('request', 'modify_search_vars', 99);
This seems to work well enough I guess..
add_action('pre_get_posts', 'modified_search');
function modified_search($query){
global $wp_query;
if($query->is_search){
global $wpdb;
$original_query = get_search_query();
$modified_query = preg_replace("/(s|S)/", "$", $original_query);
$new_query = "
SELECT $wpdb->posts.ID
FROM $wpdb->posts
WHERE $wpdb->posts.post_status = 'publish'
AND (($wpdb->posts.post_title LIKE '%$original_query%') OR ($wpdb->posts.post_content LIKE '%$original_query%') OR ($wpdb->posts.post_title LIKE '%$modified_query%') OR ($wpdb->posts.post_content LIKE '%$modified_query%'))
ORDER BY $wpdb->posts.post_date DESC
LIMIT 0, 10
";
$results = $wpdb->get_results($new_query);
$post_ids = array();
foreach ($results as $post_id){
$post_ids[] = $post_id->ID;
}
$query->set('post__in', $post_ids);
}
}
I'm sure there are ways to improve that, and I'm more than happy to implement suggestions, but this appears to return results using both search terms, so it's good enough.