Wordpress search query modify query vars - wordpress

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.

Related

Is there a correct way in Doctrine to nest 'OR' where clauses?

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();

ZF2 Doctrine Query With Multiple OR Conditions

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.

Wrap the code to translate with wordpress/poedit?

Current I have WP code like this. I need to make it translateable by poedit. How do I wrap the code to make it work? Im not sure which method is use for this case. Some thing like:
<?php my_e( 'Total sales' ); ?> or __('Total sales', 'my')
This is the code. I need to translate ["Sales amount"], ["Number of sales"]
foreach ($results as $result) {
$date = $result->formatted_post_date;
$statistics[$date]["Sales amount"] += $wp_list_table->column_total_sales($result->ID);
$statistics[$date]["Number of sales"]++;
$statistics[$date]["date"] = $date;
$max_number_of_sales = max(array($max_number_of_sales,$statistics[$date]["Number of sales"] )); }
Thank you for help
You have to use __('string','textdomain') to assign a translated string to some variable. And _e('string','textdomain') to echo a translated string. See I18n_for_WordPress_Developers.
Two observations:
you'll not be able to translate array keys, see php.net/manual/en/language.types.array.php
what you're doing seems wrong. I'd do it like:
$sales_amount = 0;
$sales_number = 0;
foreach ($results as $result) {
$sales_amount += $wp_list_table->column_total_sales($result->ID);
$sales_number++;
$date = $result->formatted_post_date;
$statistics[$date]["sales_amount"] = $sales_amount;
$statistics[$date]["sales_number"] = $sales_number;
}
echo __( 'Sales Amount', 'my' ) . $sales_amount;

get_categories order by meta key issue?

I'm trying to search for a way to order categories by meta value. From what I read, it seems like I can use:
get_categories('child_of=92&hide_empty=false&orderby=meta_value&meta_key=date&order=ASC');
However, this does not work at all, the categories are still not in the order I want. I wonder how I can:
correct this to make it work
print out the sql to see what is really going on inside?
Thank you very much in advance.
First of all, I must mention that I'm using the module custom category fields, and second of all I'm a complete WP newbie
Anyhow, after learning that this cannot be done by default, I looked into the get_categories functions and finally came up with a solution
function category_custom_field_get_terms_orderby( $orderby, $args ){
if($args['orderby'] == 'category_custom_field' && isset($args['category_custom_field']))
return 'cv.field_value';
return $orderby;
}
function category_custom_field_get_terms_fields( $selects, $args ){
if($args['orderby'] == 'category_custom_field' && isset($args['category_custom_field']))
$selects[] = 'cv.*';
return $selects;
}
function category_custom_field_terms_clauses($pieces, $taxonomies, $args){
global $wpdb;
if($args['orderby'] == 'category_custom_field' && isset($args['category_custom_field']))
$pieces['join'] .= " LEFT JOIN $wpdb->prefix" . "ccf_Value cv ON cv.term_id = tt.term_id AND cv.field_name = '".$args['category_custom_field']."'";
return $pieces;
}
add_filter('get_terms_orderby', 'category_custom_field_get_terms_orderby',1,2);
add_filter('get_terms_fields', 'category_custom_field_get_terms_fields',1,2);
add_filter('terms_clauses', 'category_custom_field_terms_clauses',1,3);
(The code above can be put into the theme functions.php file)
then the code to get categories is:
get_categories('child_of=92&hide_empty=false&orderby=category_custom_field&category_custom_field=date&order=DESC');
Any correction is greatly appreciated!
You can also give the get_categories new meta and sort using usort.
$subcategories = get_categories();
foreach ($subcategories as $subcategory) {
$subcategory->your_meta_key = your_meta_value;
}
foreach ($subcategories as $subcategory) {
blah blah blah
}
function my_cmp($a, $b) {
if ($a->ordering == $b->ordering) {
return 0;
}
return ($a->ordering < $b->ordering) ? -1 : 1;
}
usort($subcategories, "my_cmp");

drupal get list of terms of a node

How to get list of terms of a node ( by node id) belongs to a particular vocabulary. Is there any drupal function ?
taxonomy_node_get_terms function.
http://api.drupal.org/api/function/taxonomy_node_get_terms/6
Or also:
taxonomy_node_get_terms_by_vocabulary
http://api.drupal.org/api/function/taxonomy_node_get_terms_by_vocabulary/6
I know there is api for getting list of vocabularies But i am nto sure, one api exist for gettign list of terms of vocabularies.
However, you can try this function. It will work.
function myutils_get_terms_by_vocabulary($vname, $tname = "") {
$sql = "select td.*
from term_data td
inner join vocabulary v on td.vid = v.vid
where v.name = '%s'";
if($tname) {
$result = db_query($sql . " and td.name = '%s'", $vname, $tname);
return db_fetch_object($result);
} else {
$result = db_query($sql, $vname);
}
$terms = array();
while ($term = db_fetch_object($result)) {
$terms[$term->tid] = strtolower($term->name);
}
return $terms;
}
Basically i created a 'myutils' module for such common functions and added this function there. so that i can use them in all similar scenarios.

Resources