how to compare strings in using CDBCRITERIA in Yii? - php

I am using Yii framework, I want to do some search filtering, but I am getting wrong results in some cases as follow:
I have 2 check-boxes: Canada and united states, if I check Canada I will get all the results related to Canada only, while if I check united states I will get all the results in the db regardless its related to united states or not, and this bug is absolutely happen because united states string is of 2 parts so it need to be in quotations. here is my code:
the view page:
echo '<div class="checkbox"><label>'.
CHtml::checkBox($m2->tag, false, array('value'=>"$m2->tag")).$m2->tag
.'</label></div>';
the controller:
$c = new CDbCriteria();
$c->order = "idJob DESC";
$model = Jobs::model()->findAll($c);
$model2 = Tags::model()->findAll();
$lcr = "";
$tag="";
foreach($model2 as $m2){
if(isset($_POST[$m2->tag])){
$tag = $_POST[$m2->tag];
if($m2->category=='Location')
$lcr[]= $tag;
}
}
if($lcr!="")
$c->addInCondition('location', $lcr, 'AND');
$model = Jobs::model()->findAll($c);

OK it sounds like I found a solution for this problem and its working correctly, here is the solution:
in the controller:
foreach($model2 as $m2){
if (strpos($m2->tag, ' ') !== FALSE)
$m2->tag = str_replace(" ","_",$m2->tag);
if(isset($_POST["$m2->tag"])){
....
So, as you see in the code, if the tag contain any white space it will be replaced by _ , and in the HTML the id attribute will replace the white space by _ automatically, so they are matched now.

Please check the following code on your code its will work you
$criteria->addSearchCondition('location', 'YOUR SEARCH STRING', false);

Related

PHP mention system with usernames with space

I wanted to know if it's possible to make a PHP mention system with usernames with space ?
I tried this
preg_replace_callback('##([a-zA-Z0-9]+)#', 'mentionUser', htmlspecialchars_decode($r['content']))
My function:
function mentionUser($matches) {
global $db;
$req = $db->prepare('SELECT id FROM members WHERE username = ?');
$req->execute(array($matches[1]));
if($req->rowCount() == 1) {
$idUser = $req->fetch()['id'];
return '<a class="mention" href="members/profile.php?id='.$idUser.'">'.$matches[0].'</a>';
}
return $matches[0];
It works, but not for the usernames with space...
I tried to add \s, it works, but not well, the preg_replace_callback detect the username and the other parts of the message, so the mention don't appear...
Is there any solution ?
Thanks !
I know you said that you just removed the ability to add a space, but I still wanted to post a solution. To be clear, I don't necessarily think you should use this code, because it probably is just easier to keep things simple, but I think it should work still.
Your major problem is that almost every mention will incur two lookups because #bob johnson went to the store could be either bob or bob johnson and there's no way to determine that without going to the databases. Caching will greatly reduce this problem, luckily.
Below is some code that generally does what you are looking for. I made a fake database using just an array for clarity and reproducibility. The inline code comments should hopefully make sense.
function mentionUser($matches)
{
// This is our "database" of users
$users = [
'bob johnson',
'edward',
];
// First, grab the full match which might be 'name' or 'name name'
$fullMatch = $matches['username'];
// Create a search array where the key is the search term and the value is whether or not
// the search term is a subset of the value found in the regex
$names = [$fullMatch => false];
// Next split on the space. If there isn't one, we'll have an array with just a single item
$maybeTwoParts = explode(' ', $fullMatch);
// Basically, if the string contained a space, also search only for the first item before the space,
// and flag that we're using a subset
if (count($maybeTwoParts) > 1) {
$names[array_shift($maybeTwoParts)] = true;
}
foreach ($names as $name => $isSubset) {
// Search our "database"
if (in_array($name, $users, true)) {
// If it was found, wrap in HTML
$ret = '<span>#' . $name . '</span>';
// If we're in a subset, we need to append back on the remaining string, joined with a space
if ($isSubset) {
$ret .= ' ' . array_shift($maybeTwoParts);
}
return $ret;
}
}
// Nothing was found, return what was passed in
return '#' . $fullMatch;
}
// Our search pattern with an explicitly named capture
$pattern = '##(?<username>\w+(?:\s\w+)?)#';
// Three tests
assert('hello <span>#bob johnson</span> test' === preg_replace_callback($pattern, 'mentionUser', 'hello #bob johnson test'));
assert('hello <span>#edward</span> test' === preg_replace_callback($pattern, 'mentionUser', 'hello #edward test'));
assert('hello #sally smith test' === preg_replace_callback($pattern, 'mentionUser', 'hello #sally smith test'));
Try this RegEx:
/#[a-zA-Z0-9]+( *[a-zA-Z0-9]+)*/g
It will find an at sign first, and then try to find one or more letter or numbers. It will try to find zero or more inner spaces and zero or more letters and numbers coming after that.
I am assuming the username only contains A-Za-z0-9 and space.

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

how to explode a url string?

code:
<?php
include('conn.php');
$student_id = $_SESSION['student_id'];
$college_name = $_GET['college_name'];
$college_name22 = explode('(', $college_name);
if(preg_match('#\((.*?)\)#', $college_name, $match))
{
$match[1] = lcfirst($match[1]);
}
else
{
$match[1] = 'All';
}
?>
If url having string like
cstest/view.php?college_name=Agra%20Public%20Institute%20of%20Technology%20&%20Computer%20Education,%20Artoni%20(Pharmacy)
and I want to explode the following string i.e.
Agra%20Public%20Institute%20of%20Technology%20&%20Computer%20Education,%20Artoni%20(Pharmacy)
when I echo $college_name it display only (Agra Public Institute of Technology) not full name i.e (Agra Public Institute of Technology & Computer Education, Artoni) and $match[1] contain (pharmacy) which is not showing when I print $match[1] it show 'All'. So, how can I fix this problem ?
Thank You
The & has a special meaning in URL. the value of $_GET['college_name'] is exactly "Agra%20Public%20Institute%20of%20Technology%20". The & marks the start of a new parameter.
If the ampersand is properly escaped as %26 you will have a much easier time.
You could try inserting a var_dump($_GET) and see what the data is that you are actually working with.

Matching a regex

My regex skills are poor. For my js/css to show the correct menu I am adding in a "selected" class to my li so that the js knows which is the current item (so it can display the rest of the drop down).
My problem is matching the correct uri string in codeigniter:
<li <? if((strstr($this->uri->uri_string(),"rfid_finder/finder")) || (strstr($this->uri->uri_string(),"finder"))) {?>class="selected"<?}?> rel="home"> <?= anchor('finder','HOME')?></li>
I was using this method initially but my routes are now a bit more complex to allow for searching and pagination.
I need a regex that would match all of the following routes:
$route['finder/(:any)/(:any)/(:num)'] = "rfid_finder/finder/$1/$2/$3";
$route['finder/(:any)/(:any)'] = "rfid_finder/finder/$1/$2";
$route['finder/(:any)'] = "rfid_finder/finder/$1";
$route['finder'] = 'rfid_finder/finder';
but when a user visits:
rfid_finder/search_form
the first menu is not given the selected class.
Update
I want first code snippet to match the routes and not the rfid_finder/search route- I have a second line of code which matches the rfid_finder/search_form route. my problem lies in trying to capture the route using (strstr($this->uri->uri_string(),"finder") it matches all my routes even the rfid_finder/search_form
Hmm, let me know if this works for you. It seems to work in my tests.
preg_match('|^(rfid_finder/)?finder/?([a-z0-9]+?)?(/[a-z0-9]+?)?(/\d+?)?$|i', $string)
Here's my testing example:
$route = array();
$route['finder/(:any)/(:any)/(:num)'] = "rfid_finder/finder/$1/$2/$3";
$route['finder/(:any)/(:any)'] = "rfid_finder/finder/$1/$2";
$route['finder/(:any)'] = "rfid_finder/finder/$1";
$route['finder'] = 'rfid_finder/finder';
$route['finder/2313'] = 'rfid_finder/finder';
$route['finder/asd/dsda'] = 'rfid_finder/finder';
$route['rfid_finder/finder/dd/122'] = 'rfid_finder/finder';
$route['rfid_finder/finder/dd/122/qwewe'] = 'rfid_finder/finder';
$route['rfid_finder/finder/dd/asdsad/333'] = 'rfid_finder/finder';
foreach ($route as $string=>$match) {
if ( preg_match('|^(rfid_finder/)?finder/?([a-z0-9]+?)?(/[a-z0-9]+?)?(/\d+?)?$|i', $string) ) {
echo $string.' - yes';
} else {
echo $string.' - no';
}
echo '<br />';
}
exit();
It searches the string to make sure it starts with either finder or rfid_finder (i wasn't really sure which you prefered. if you want it to only start with rfid_finder just remove the parentheses around rfid_finder and the trailing ? before finder)

MODX parse error function implode (is it me or modx?)

Update 4-June-2010: This appears to be a bug in MODx v 1.0.3, nothing to do with the implode function but rather a problem with mis-matched datatypes in the resulting filter clause. Bug has been filed with JIRA: MODX-2035.
Hi, I cannot for the life of me figure this out, maybe someone can help.
Using MODX a form takes user criteria to create a filter and return a list of documents. The form is one text field and a few checkboxes. If both text field and checkbox data is posted, the function works fine; if just the checkbox data is posted the function works fine; but if just the text field data is posted, modx gives me the following error:
Error: implode() [function.implode]: Invalid arguments passed.
I've tested this outside of modx with flat files and it all works fine leading me to assume a bug exists within modx. But I'm not convinced. Here's my code:
<?php
$order = array('price ASC'); //default sort order
if(!empty($_POST['tour_finder_duration'])){ //duration submitted
$days = htmlentities($_POST['tour_finder_duration']); //clean up post
array_unshift($order,"duration DESC"); //add duration sort before default
$filter[] = 'duration,'.$days.',4'; //add duration to filter[] (field,criterion,mode)
$criteria[] = 'Number of days: <strong>'.$days.'</strong>'; //displayed on results page
}
if(!empty($_POST['tour_finder_dests'])){ //destination/s submitted
$dests = $_POST['tour_finder_dests'];
foreach($dests as $value){ //iterate through dests array
$filter[] = 'searchDests,'.htmlentities($value).',7'; //add dests to filter[]
$params['docid'] = $value;
$params['field'] = 'pagetitle';
$pagetitle = $modx->runSnippet('GetField',$params);
$dests_array[] = ''.$pagetitle.'';
}
$dests_array = implode(', ',$dests_array);
$criteria[] = 'Destinations: '.$dests_array; //displayed on results page
}
if(is_array($filter)){
$filter = implode('|',$filter);//pipe-separated string
}
if(is_array($order)){
$order = implode(',',$order);//comma-separated string
}
if(is_array($criteria)){
$criteria = implode('<br />',$criteria);
}
echo '<br />Order: '.$order.'<br /> Filter: '.$filter.'<br /> Criteria: '.$criteria;
//next: extract docs using $filter and $order, display user's criteria using $criteria...
?>
The echo statement is displayed above the MODX error message and the $filter array is correctly imploded.
Any help will save my computer from flying out the window.
Thanks
I think your problem lies here :
$dests_array = implode(', ',$dests_array);
$dest_array may be empty and not even initialized if $dests is empty.
This really should be posted in the MODx forums. I love stackoverflow, but MODx is more niche.

Categories