Wordpress Query £ signs failure - php

I have code that takes the name of a term and pulls in a post of a custom post type of the same name. This works well. Except when a £ character is in the title.
e.g. pseudocode
$q = new WP_Query (array( 'name' => "Insurance Rating £1K"));
if($q->have_posts()){
// expected path of logic flow
} else {
// nothing was found =s
}
This post does indeed exist, yet it is not found, and this problem only affects cases with a '£' character in the title. Since Wordpress already sanitizes the titles etc, what is happening? Why does this not work?
edit:
This is a general case, not specific to any codebase of mine. I want to know why this happens and how to avoid it, the codebase this first arose in is irrelevant. So I dont need an alternative solution, as I'm looking for Why it happened
edit 2:
The database tables are using utf8_general_ci encoding.
The £ character is also being saved as is, not as a html entity, here's a screenshot from phpmyadmin:

What encoding is your PHP file in, and does it match the encoding of the database? They need to match for this to work. (Check your IDE or this link provided by #Tom)
Failing that, make sure that the character isn't a £ entity instead of the literal character.

Related

laravel. Replace %20 in url

I have simple problem, I have to replace %20 and other crap from URL. At the moment it looks like this http://exmaple/profile/about/Eddies%20Plumbing. As you can see it's profile link.
Yes I could add str_replace values before every hyperlink, but I have like 10 of them and I think it's bad practice. Maybe there is better solution? What solution would you use? Thanks.
That is not crap, that is a valid unicode representation of a space character. And it's encoded because it's one of the characters that are deemed unsafe by RFC1738:
All unsafe characters must always be encoded within a URL. For
example, the character "#" must be encoded within URLs even in
systems that do not normally deal with fragment or anchor
identifiers, so that if the URL is copied into another system that
does use them, it will not be necessary to change the URL encoding.
So in order to have pretty URLs, you should avoid using reserved and unsafe characters which need encoding to be valid as part of a URL:
Reserved characters: $ & + , / : ; = ? #
Unsafe characters: Blank/empty space and < > # % { } | \ ^ ~ [ ] `
Instead replace spaces with dashes, which serve the same purpose visually while being a safe character, for example look at the Stack Overflow URL for this question. The URL below looks just fine and readable without spaces in it:
http://exmaple/profile/about/eddies-plumbing
You can use Laravel's str_slug helper function to do the hard work for your:
str_slug('Eddies Plumbing', '-'); // returns eddies-plumbing
The str_slug does more that replace spaces with dashes, it replaces multiple spaces with a single dash and also strips all non-alphanumeric characters, so there's no reliable way to decode it.
That being said, I wouldn't use that approach in the first place. There are two main ways I generally use to identify a database entry:
1. Via an ID
The route path definition would look like this in your case:
/profiles/about/{id}/{slug?} // real path "/profiles/about/1/eddies-plumbing"
The code used to identify the user would look like this User::find($id) (the slug parameter is not needed, it's just there to make the URL more readable, that's why I used the ? to make it optional).
2. Via a slug
The route path definition would look like this in your case:
/profiles/about/{slug} // real path "/profiles/about/eddies-plumbing"
In this case I always store the slug as a column in the users table because it's a property relevant to that user. So the retrieval process is very easy User::where('slug', $slug). Of course using str_slug to generate a valid slug when saving the user to the database. I usually like this approach better because it has the added benefit of allowing the slug to be whatever you want (not really needing to be generated from the user name). This can also allow users to choose their custom URL, and can also help with search engine optimisation.
The links are urlencoded. Use urldecode($profileLink); to decode them.
I am parsing the url tha i got in this way ->
$replacingTitle = str_replace('-',' ',$title);
<a href="example.com/category/{{ str_slug($article->title) }}/" />
In your view ...
{{$comm->title}
and in controller using parsing your url as
public function showBySlug($slug) {
$title = str_replace('-',' ',$slug);
$post = Community::where('title','=',$title)->first();
return view('show')->with(array(
'post' => $post,
));
}

Codeigniter disallowed characters workaround

I have already checked quite a few other answers but to no avail.
I have been hired to fix bugs for a job that some other developer ran away from.
The application has a add comment and delete comment functionality.
The problem comes in the delete comment part. He designed the database such that all comments are simply entered into a single cell separated by pipe characters. So while deleting a comment, the entire comment needs to be placed in the url as a parameter which is then passed to the model and removed from the database.
I do know this is bad, but I cannot recode the entire functionality.
Now, when a user enters a comment such as "What's Up?", the delete comment url throws the "Codeigniter: The URI you submitted has disallowed characters." error.
I tried converting the quotes to HTML character entities but they again contain disallowed characters.
Can anybody please suggest a possible workaround for this problem?
Redesigning the database is not a viable option as I'll then have to change the extensive php code used for handling the different delimiters.
Messing with the disallowed characters list also seems to be a bad idea.
Thank you.
Open your config file and find this parameter:
$config['permitted_uri_chars'] = 'a-z 0-9~%.:_()#&-!=?';
You can change it according to your requirement ​or you can leave it blank.
Read the comment section in config file.
It says that: Leave blank to allow all characters -- but only if you are insane.
I am not sure if htmlentities will help.
Did you first call urlencode on just the parameters?
<?php
$query_string = 'foo=' . urlencode("What's Up?");
echo '<a href="mycgi?' . htmlentities($query_string) . '">';
?>
<a href="mycgi?foo=What%27s+Up%3F">
Also check if you need to add escape characters to any of these if they are treated as special characters by the database.
e.g. If % is treated as special character, then you may need to add a \ before it.

Ignore accents in greek words when using elastic search

I have a search input box that supports autosuggestion logic. The results are fetched from an elastic index whose analyzers (index_analyzer, search_analyzer) use as tokenizer: nGram, and as filter: standard, lowercase and asciifolding for the search_analyzer & lowercase and asciifolding for the index_analyzer respectively.
What I am struggling to achieve but without any effect/result yet is to get result(s) even if the user has given a greek word without the accent (tonos). Otherwise, the user gets proper results and the mechanism works as expected.
I have to mention that the given string is matched against a specific field to the document set that includes greek words with accent. Moreover, this field is of datatype string and enabled to get analyzed.
The query is formed (using example string without accent that highlights the problem):
$searchString = mb_strtolower('Προταση', 'UTF-8')
$queryText = new Elastica_Query_Text();
$queryText->setField('name', $searchString)
$query = new Elastica_Query();
$query->setQuery($queryText);
A quick solution but not appropriate cause it's kinda heavy for this purpose, is to form a fuzzy query with min_similarity set to 0.7. Then it works thoroughly but the cost is significant.
All the work has been done using the elastica, let alone php. Could you please help to solve my problem ? It is imperative for me that a solution be found.
Thank you in advance

PHP: Converting scandic characters to hex unicode

I'm working on a Joomla site with Fabrik and problem is that Fabrik serializes some data using json_encode() but does not take into account the possibility of åäö and such. Now when a database search is made, it tries to find stuff with åäö, but doesn't find anything, because
everything is \u00e4 and \u00f6
and so forth.
I'm not much for digging into Fabrik's code and inserting one flag somewhere and worry about accidentally overwriting it when I update Fabrik. So I figured, since I'm disappointed in Fabrik anyway, I could just write around it completely in a custom template. Easy.
The problem is that I can't find a way or a function like htmlentities() that I can just feed the stuff to to make it match. I could just character replace them, but that's not a good solution.
Paraphrase: I wanna make word Mörkö into -> M\u00f6rk\u00f6. How?
Maybe there's another way but that works as excepted :
$encoded = substr(json_encode('Mörkö'), 1, -1);
json_encode('Mörkö') => "M\u00f6rk\u00f6"
substr() => M\u00f6rk\u00f6

Replace '&' with 'and' on the fly in PHP

Is there a way to replace the character & with and in a PHP web form as the user types it rather than after submitting the form?
When & is inserted into our database our search engine doesn't interpret the & correctly replacing it with & returning an incorrect search result (i.e. not the result that included &).
Here is the field we would like to run this on:
<input type="text" name="project_title" id="project_title" value="<?php echo $project_title; ?>" size="60" class="btn_input2"/>
Is there a way to replace the character & with and in a PHP web form as the user types it rather than after submitting the form?
PHP is on the server, it has no control over anything taking place under any circumstances what-so-ever on the client-side. It sends raw text from the web server, a 100megaton thermonuclear device explodes, and PHP never exists anymore after the content is sent. Just the document received on your client side remains. To work with effects on your client side, you need to work with JavaScript.
To do that, you would pick your favorite JavaScript library and add an event listener for "keyup" events. Replace ampersands with "and", and drop the replacement text back in the box. mugur has posted an answer that shows you how to do this.
This is a horrible solution in practice because your users will be screaming for bloody justice to deliver them from such an awful user experience. What you've ended up doing is replacing the input text with something they didn't want. Other search tools do this, why can't yours? You hit backspace, then what? When you hit in the text, you probably lose your cursor position.
Not only that, you're treating a symptom rather than the cause. Look at why you're doing this:
The reason is when & is inserted into our database our search engine flips out and replaces it with & which then returns an incorrect result (i.e. not the result that included &).
No, your database and search engine do no such thing as "flipping out". You're not aware of what's going on and try to treat symptoms rather than learn the cause and fix it. Your symptom cure will create MORE issues down the road. Don't do it.
& is an HTML Entity Code. Every "special" charecter has one. This means your database also encodes > as > as well as characters with accents in them (such as French, German, or Spanish texts). You get "Wrong" results for all of these.
You didn't show any code so you don't get any code. But here's what your problem is.
Your code is converting raw text into HTML Entity codes where appropriate, you're searching against a non-encoded string.
Option 1: Fix the cause
Encode your search text with HTML entities so that it matches for all these cases. Match accent charecters with their non-accented cousins so searching for "francais" might return "français".
Option 2: Fix one symptom
Do a string replace for ampersands either on the client or server side, your search breaks for all other encodings. Never find texts such as "Bob > Sally". Never find "français".
Before submitting the form you'd need to use JavaScript to change as the user types it in. Not ideal since JS can be turned off.
You'd be much better to "clean" the ampersands after submitting but before inserting into the database.
A simple str_replace should work:
str_replace(' & ',' and ', $_POST['value']);
But as others have pointed out, this isn't a good solution. The best solution would be to encode the ampersands as they go into the database (which seems to be happening just now), then modify your search script to allow for this.
You can do that as they complete the form with jquery like this:
$('#input').change(function() { // edited conforming Icognito suggestion
var some_val = $('#input').val().replace('&', 'and');
$('#input').val( some_val );
});
EDIT: working example (http://jsfiddle.net/4gXZW/13/)
JS:
$('.target').change(function() {
$('.target').val($('.target').val().replace('&', 'and'));
});
HTML:
<input class="target" type="text" value="Field 1" />
Otherwise you can do that in PHP before the insert sql.
$to_insert = str_replace("&", "and", $_POST['your_variable']);

Categories