Symfony and Zend Lucene Error - php

I use symfony with Zend Lucene Search. I have
$query = Zend_Search_Lucene_Search_QueryParser::parse($query.'*');
$hits = self::getLuceneIndex()->find($query);
Sometimes I have error :
At least 3 non-wildcard characters are required at the beginning of pattern.
When I make like in documentations:
$pattern = new Zend_Search_Lucene_Index_Term($query.'*');
$query = new Zend_Search_Lucene_Search_Query_Wildcard($pattern);
$hits = self::getLuceneIndex()->find($query);
It finds nothing.

I do not is it right , but it is work for me :
So, query fail in my case, because it have < 3 characters or have some special characters, so in my search action :
public function executeAds(sfWebRequest $request)
{
if (!$query = $request->getParameter('query'))
{
return $this->forward('search', 'adssearch');
}
$query = str_replace(" ", "", $query);
$query = preg_replace("/[^A-Za-z0-9]/","",$query);
if (strlen(trim($query))<3)
{
$this->redirect('search/notice');
}
$this->ads = Doctrine_Core::getTable('Ads') ->getAdsLuceneQuery($query);
I do not use
$pattern = new Zend_Search_Lucene_Index_Term($query.'*');
$query = new Zend_Search_Lucene_Search_Query_Wildcard($pattern);
$hits = self::getLuceneIndex()->find($query);
Because it is not work for me.

Taken directly from the Zend Reference documentation, you can use:
Zend_Search_Lucene_Search_Query_Wildcard::getMinPrefixLength() to
query the minimum required prefix length and
use Zend_Search_Lucene_Search_Query_Wildcard::setMinPrefixLength() to
set it.
So my suggestion would be either of two things:
Set the prefixMinLength to 0 using Zend_Search_Lucene_Search_Query_Wildcard::setMinPrefixLength(0) - based on this, your original code snippet should work fine (it did for my Zend Lucene implementation)
As you yourself suggested, validate all search queries using javascript or otherwise to ensure there is a minimum of Zend_Search_Lucene_Search_Query_Wildcard::getMinPrefixLength() before any wildcards used (I recommend querying that instead of assuming the default of "3" so the validation is flexible)

Related

How can I str_replace partially in PHP in a dynamic string with unknown key content

Working in WordPress (PHP). I want to set strings to the database like below. The string is translatable, so it could be in any language keeping the template codes. For the possible variations, I presented 4 strings here:
<?php
$string = '%%AUTHOR%% changed status to %%STATUS_new%%';
$string = '%%AUTHOR%% changed status to %%STATUS_oldie%%';
$string = '%%AUTHOR%% changed priority to %%PRIORITY_high%%';
$string = '%%AUTHOR%% changed priority to %%PRIORITY_low%%';
To make the string human-readable, for the %%AUTHOR%% part I can change the string like below:
<?php
$username = 'Illigil Liosous'; // could be any unicode string
$content = str_replace('%%AUTHOR%%', $username, $string);
But for status and priority, I have different substrings of different lengths.
Question is:
How can I make those dynamic substring be replaced on-the-fly so that they could be human-readable like:
Illigil Liosous changed status to Newendotobulous;
Illigil Liosous changed status to Oldisticabulous;
Illigil Liosous changed priority to Highlistacolisticosso;
Illigil Liosous changed priority to Lowisdulousiannosso;
Those unsoundable words are to let you understand the nature of a translatable string, that could be anything other than known words.
I think I can proceed with something like below:
<?php
if( strpos($_content, '%%STATUS_') !== false ) {
// proceed to push the translatable status string
}
if( strpos($_content, '%%PRIORITY_') !== false ) {
// proceed to push the translatable priority string
}
But how can I fill inside those conditionals efficiently?
Edit
I might not fully am clear with my question, hence updating the query. The issue is not related to array str_replace.
The issue is, the $string that I need to detect is not predefined. It would come like below:
if($status_changed) :
$string = "%%AUTHOR%% changed status to %%STATUS_{$status}%%";
else if($priority_changed) :
$string = "%%AUTHOR%% changed priority to %%PRIORITY_{$priority}%%";
endif;
Where they will be filled dynamically with values in the $status and $priority.
So when it comes to str_replace() I will actually use functions to get their appropriate labels:
<?php
function human_readable($codified_string, $user_id) {
if( strpos($_content, '%%STATUS_') !== false ) {
// need a way to get the $status extracted from the $codified_string
// $_got_status = ???? // I don't know how.
get_status_label($_got_status);
// the status label replacement would take place here, I don't know how.
}
if( strpos($_content, '%%PRIORITY_') !== false ) {
// need a way to get the $priority extracted from the $codified_string
// $_got_priority = ???? // I don't know how.
get_priority_label($_got_priority);
// the priority label replacement would take place here, I don't know how.
}
// Author name replacement takes place now
$username = get_the_username($user_id);
$human_readable_string = str_replace('%%AUTHOR%%', $username, $codified_string);
return $human_readable_string;
}
The function has some missing points where I currently am stuck. :(
Can you guide me a way out?
It sounds like you need to use RegEx for this solution.
You can use the following code snippet to get the effect you want to achieve:
preg_match('/%%PRIORITY_(.*?)%%/', $_content, $matches);
if (count($matches) > 0) {
$human_readable_string = str_replace("%%PRIORITY_{$matches[0]}%%", $replace, $codified_string);
}
Of course, the above code needs to be changed for STATUS and any other replacements that you require.
Explaining the RegEx code in short it:
/
The starting of any regular expression.
%%PRIORITY_
Is a literal match of those characters.
(
The opening of the match. This is going to be stored in the third parameter of the preg_match.
.
This matches any character that isn't a new line.
*?
This matches between 0 and infinite of the preceding character - in this case anything. The ? is a lazy match since the %% character will be matched by the ..
Check out the RegEx in action: https://regex101.com/r/qztLue/1

Sphinx - How to escape user input for SphinxQL?

I have website where users can search posts by entering keywords,
I am using Sphinx search for full text search, everyhting is working as expected.
But when i enter/input some special charaters in search query the search dosnt complete and throws error.
e.g.
keyword i search for :
hello)
my query for sphinxql :
SELECT id FROM index1 WHERE MATCH('hello)')
error i get :
index index1: syntax error, unexpected ')' near ')'
my php code looks like this
<?php
$sphinxql = mysqli_connect($sphinxql_host.':'.$sphinxql_port,'','') or die('ERROR');
$q = urldecode($_GET['q']);
$sphinxql_query = "SELECT id FROM $sphinx_index WHERE MATCH('".$q."') ";
?>
How can i escape user input and make sure the query wont brake and return the result set ?
You should use SQL escaping, to avoid SQL injection.
http://php.net/manual/en/mysqli.real-escape-string.php
$sphinxql_query = ".... MATCH('".mysqli_real_escape_string($sphinxql,$q)."') ";
... BUT you may want to ALSO, escape extended syntax.
See the FIRST THREE POSTS (after that it delves into misunderstanding) in this thread in the sphinx forum
http://sphinxsearch.com/forum/view.html?id=13619
For a simple solution.
The function in that thread, can be used to make your query work. It will escape the ) and stop it being taken as a operator.
BUT, it also means you WONT be able to use any search operators - because it blindly escapes them ALL. (which is the confusion later in the thread)
If you want to be able to use some or all operators, need to use more advanced escaping. (which I dont have a good solution for)
Edit: actully lets go the whole hog...
<?php
//Escapes all the Extended syntax, so can accept anything the user throws at us.
function EscapeString ( $string ) {
$from = array ( '\\', '(',')','|','-','!','#','~','"','&', '/', '^', '$', '=' );
$to = array ( '\\\\', '\(','\)','\|','\-','\!','\#','\~','\"', '\&', '\/', '\^', '\$', '\=' );
return str_replace ( $from, $to, $string );
}
if ($allow_full_extended_syntax) {
$q = $_GET['q'];
// the user is responsible for providing valid query.
} elseif ($allow_partical_extended_syntax) {
$q = InteligentEscape($_GET['q']);
//I don't have this function, it would need to be created.
} else {
$q = EscapeString($_GET['q']);
// escapes ALL extended syntax. NO operators allowed
}
$sphinxql_query = ".... MATCH('".mysqli_real_escape_string($sphinxql,$q)."') ";
Then it sounds like you want both $allow_full_extended_syntax and $allow_partical_extended_syntax set to false. Which means no operators will work, because they will be fully escaped.
The EscapeString function needs to escape the < character as well. Also see escapeString function in PECL shpinx for reference.

Cut some word from php available?

Cut some word from php available ?
First access to page for example
www.mysite.com/test.php?ABD_07,_oU_876.00/8999&message=success
From my php code, i will get $curreny_link_redirect = test.php?ABD_07,_oU_876.00/8999&message=success
And i want to get $curreny_link_redirect_new = test.php?ABD_07,_oU_876.00/8999
( Cut &message=success )
How can i do ?
<?PHP
$current_link = "$_SERVER[REQUEST_URI]";
$curreny_link_redirect = substr($current_link,1);
$curreny_link_redirect_new = str_replace('', '&message=success', $curreny_link_redirect);
echo $curreny_link_redirect_new;
?>
Your str_replace call is inverse of what it should be. What you want to replace should be the first parameter, not the second.
//Wrong
$curreny_link_redirect_new = str_replace('', '&message=success', $curreny_link_redirect);
//Right
$curreny_link_redirect_new = str_replace('&message=success','', $curreny_link_redirect);
While simple way to do this is to use regex (or even static with str_replace()), I recommend to use built-in functions for url handling. This may be useful when working with complex parameters or multiple parameters:
$data = 'www.mysite.com/test.php?ABD_07,_oU_876.00/8999&message=success';
$url = parse_url($data);
parse_str($url['query'], $url['query']);
//now, do something with parameters:
unset($url['query']['message']);
$url['query'] = http_build_query($url['query']);
$url = http_build_url($url);
-please, note, that http_build_url() is a PECL function (pecl_http to be precise). The way above may look more complex, but it has benefits - first, as I've already mentioned, this will be easy to modify for working with complex parameters or multiple parameters. Second, it will produce valid url - i.e. encode such things as slashes, spaces, e t.c. - in result. Thus, result will always be correct url.
Do like this
<?php
$str = "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
echo $str = array_shift(explode('&',$str));
Try this:
$current_link_path = substr($_SERVER['PHP_SELF'], 1);
$params = $_GET;
if ($params['message'] == 'success') {
unset($params['message']);
}
$current_link_redirect = $current_link_path . '?' . http_build_query($params);
Maybe not an answer, but a disclaimer for future visitors:
1) I would strongly recommend the function: http://pl1.php.net/parse_url.
And in that case:
$current_link = "$_SERVER[REQUEST_URI]";
$arguments = explode('&', parse_url($current_link, PHP_URL_QUERY));
print_r($arguments);
2) To build new url, use http://pl1.php.net/manual/en/function.http-build-url.php. This is the best, future modifications ready solution I think.
In that case this solution is a little overkill, but these functions are really great, and worth to introduce here.
Best regards

Wilcard (*) Match for Zend_Controller_Router_Route_Hostname

Is it possible to create a wildcard match using the Zend Framework Zend_Controller_Router_Route_Hostname for the actual domain? I tried the simple example below but the system would not recognize the route. When I hardwired the route (login.domain.com), it would work properly.
resources.router.routes.login.type = "Zend_Controller_Router_Route_Hostname"
resources.router.routes.login.route = "login.*"
resources.router.routes.login.chains.index.type = "Zend_Controller_Router_Route"
resources.router.routes.login.chains.index.route = ":action/*"
resources.router.routes.login.chains.index.defaults.controller = "login"
resources.router.routes.login.chains.index.defaults.action = "index"
$route = new Zend_Controller_Router_Route_Hostname ('login.:domain.:net');
$_SERVER ['HTTP_HOST'] = 'login.example.com';
$request = new Zend_Controller_Request_Http ();
$match = $route->match ($request);
var_dump($match);
Is this possible without the :domain.:net both being explicit, i.e. without stipulating just one period?
i.e. I currently have
new Zend_Controller_Router_Route_Hostname('sub.example.com',array('controller' => 'x'));
..but what I'd really like to do is:
new Zend_Controller_Router_Route_Hostname('sub.:remainder',array('controller' => 'x'));
..whereby this route will match any hostname that begins with 'sub.' including sub.example.com, sub.another.example.com, sub.somethingelse.com, sub.com etc.
Doesn't seem to work though!
Anyone got this working?

PHP: Add words to pspell?

I am using pspell like this:
$ps = pspell_new("en");
if(!pspell_check($ps, $word))
{
$suggestion = pspell_suggest($ps, $word);
}
However I want to added some industry terms to the list.
I looked up pspell_add_to_session which says the first param is supposed to be int $dictionary_link But I do not know what that is and there is no example.
In your case, the $ps variable created by pspell_new() is that "dictionary link":
$ps = pspell_new("en");
pspell_add_to_session($ps, "somenewword");
The $dictionary_link integer is an integer representation of the pspell library handle, as returned by pspell_new or pspell_new_personal. The PHP documentation is incomplete in a lot of places regarding this variable.[1][2][3][4][5][6][7][8][9]

Categories