I have a form with an input name="title" and in functions.php I'm simply getting all the data from that form
Here's the code:
$title = $_POST['title'];
print_r($_POST);
var_dump($title);
var_dump(esc_attr($title));
The expected outcome would be the same string, but, I have no idea why, WordPress shows an empty string on the esc_attr one
Here's the output:
Array ( [title] => Swedish House Mafia – Doooon\'t You Worry Child ft. John Martin )
string(63) "Swedish House Mafia – Doooon\'t You Worry Child ft. John Martin"
string(0) ""
It's not related to the input field being called title or the variable being called $title and conflicting with other stuff in WordPress, I have no idea why the escape functions are not working.
Let's walk through the thought process of what might be a contributor to this problem.
With the code as presented, nothing in your code is affecting the variable or $_POST. You are just echoing out each variable one after the other (as you presented above).
That means something is wonky with esc_attr. What could the possibilities be:
The function is not available yet.
Something is overriding the returned value and behavior.
Possibility 1 is not feasible because you are working in the theme's function.php file. WordPress has loaded the escaping functions by the time the theme is called. To check that, you can do:
echo function_exists( 'esc_attr' ) ? 'yes, loaded' : 'whoops, not loaded';
That leaves us with Possibility 2. Let's look at the function in WordPress Core.
function esc_attr( $text ) {
$safe_text = wp_check_invalid_utf8( $text );
$safe_text = _wp_specialchars( $safe_text, ENT_QUOTES );
/**
* Filters a string cleaned and escaped for output in an HTML attribute.
*
* Text passed to esc_attr() is stripped of invalid or special characters
* before output.
*
* #since 2.0.6
*
* #param string $safe_text The text after it has been escaped.
* #param string $text The text prior to being escaped.
*/
return apply_filters( 'attribute_escape', $safe_text, $text );
}
There are 3 functions that interact with the text. I don't see anything in the first two. However, look at the filter event attribute_escape. Any other plugin or theme can register to that event and change the returned text, including returning an empty string.
That sounds like a highly probable candidate.
Next Steps
Something is stepping on (filtering) the text when it's passed through esc_attr(). You need to eliminate all variables, strip the site down to the bare bones basics, and then see if the problem resolves itself.
The following steps are a process to discover where the problem lies. It's an elimination methodology. As you walk through it, it'll help you to pinpoint what component (theme, plugin, or even core) is affecting it.
Step 1: Deactive ALL plugins
Step 2: Move your code to the top of the theme's functions.php file. Why? It eliminates anything in the theme from affecting the text as the functions.php file loads first.
Step 3: Manually add the title to $_POST['title']. Put as the first line in functions.php: $_POST['title'] = "Swedish House Mafia – Doooon't You Worry Child ft. John Martin";.
Step 4: Refresh the browser.
Is it working properly, meaning esc_attr() returns the string?
Nope, the problem is still happening.
Hum, that means something then in WordPress Core is not playing nice. You could investigate by digging into Core and finding what is causing the conflict. Or reload a fresh version of it.
Yes, the problem is gone
Add in one plugin at a time. Refresh the browser. Check if the problem reappears. If yes, then you found the plugin that is causing it.
Now what?
Once you find the culprit, you can take steps to fix the problem. Then you can remove the code from functions.php file that I had you add.
This might be edge case, but I had the same issue and the problem was with multibyte characters.
My code looked something like this: esc_attr( substr( $desc, 0, 152 ) )
Without esc_attr() it worked but I sometimes got the �-character. When running it through esc_attr() I got nothing back.
So my solution was to replace substr() with mb_substr(). Read about the difference in this answer.
Retrieve data with this code
echo esc_attr( $title );
Related
I have a Wordpress theme that stores a copyright line in a Wordpress option using the update_option function. In the text, I am including a link back to my website.
Copyright © 2015 ABC Company, Inc. Site design by My Company.
That information is then retrieved in the theme's footer.
<p id="footer-copyright"><?php echo get_option('copyright'); ?></p>
However, the link appears as http://www.blogsite.com/"http://www.example.com/". I am assuming that internally Wordpress is trying to create an absolute url from what it believes to be a page slug. How can I stop this behavior? I have examined the get_options function defined in wp-includes/options.php and determined that it is not the problem. The problem is occurring later in the theme processing.
Edit:
Per David's suggestion, I have check the DB. The value of this option is being altered before being written. HTML entities are being parsed and quotes are being escaped. Here is the actual value in the DB.
Copyright © 2015 ABC Company, Inc. All rights reserved. Site design by My Company.
When I manually correct this in the DB, it displays fine. Wordpress is performing some sort of post processing or parsing before writing the option value to the DB.
Wordpress unnecessarily escapes quotes in the option value during it's sanitizing process. The easiest solution is to use the pre_update_option_(option name) hook to process and remove the unnecessary escape characters before the value is written to the database. This hook can be implemented in your theme's functions.php file. (NAME in all caps should be replaced by the name of the option defined elsewhere in the update_option function.
function myplugin_update_option_NAME( $new_value, $old_value ) {
$new_value = str_replace('\"', '"', $new_value); // replaces \" with "
return $new_value;
}
function myplugin_init() {
add_filter( 'pre_update_option_NAME', 'myplugin_update_option_NAME', 10, 2 );
}
add_action( 'init', 'myplugin_init' );
I've intentionally avoided using PHP's stripslashes function in order to keep the code simple and avoid checking for magic quotes.
Wordpress is not actually prepending anything to the hyperlink destination. However, because the hyperlink is not recognized with escaped quotes, it is treated as though it were a relative link causing the described behavior.
So I'm importing ExpressionEngine fields into a php array. I want to display one field, called {gearboxx_body}, unless that field has more then 300 characters, in which case I want to display a field called {article_blurb}. I'm pretty sure there isn't a way to do this just in ExpressionEngine fields and conditionals, so I tried some PHP, which I'm just starting to learn:
<?php
$info = array('{gearboxx_body}','{article_blurb}');
if(mb_strlen($info[0]) <= 300)
echo($info[0]);
}
else {
echo($info[1]);
}
?>
So that works well, but there's a problem. If the tag includes any apostrophes or quote marks, it ends the string and the page won't load. So what can I do about this? I've tried to replace the quote marks in the string, but I have to have loaded the string from the fields first, and as soon as I do that the page is already broken.
Hopefully that made sense. Any suggestions?
I would recommend you handle this in an EE plugin rather than in the template:
Faster to render (because you don't need the overhead of PHP in the templates)
More secure and reliable
Faster to develop once you get the basics of EE development down which is a useful life skill
All around best-practice
The plugin I have in mind takes three parameters:
body, blurb and character limit.
Let's say you call your plugin "Blurby". In the template you would just have this:
{exp:blurby body="{gearboxx_body}" blurb="{article_blurb}" char_limit="300"}
It variably returns either of your fields based on the logic you define in the plugin itself.
See plugin developer documentation.
Alternatively you could use the dreaded HEREDOC syntax to set variables before passing them into your array:
$body = <<<EOT
{gearboxx_body}
EOT;
$blurb = <<<EOT
{article_blurb}
EOT;
PHP Mysql CodeIgniter Converting characters to symbols in very bizarre circumstances
Application Built on CodeIgniter.
Has been running for over a year. No problems.
Client fills in a form about a customer.
A simple trim($_POST['notes']) captures textarea form field text and saves to MySQL
no error reported in PHP or JavaScript
The other day I notice some text the client has entered, has had the brackets used in the text "()" replaced with the equivalent "()
I think... "That's strange... I don't recall any reason why those characters would have been replaced like that.!"
I take a look ... and a day later... here is my madness revealed:
The text in question is verbatim "
Always run credit card on file (we do not charge this customer for pick-up or return)
"
No matter what I did or changed on the code side.. I could not prevent the PHP... OR Javascript... Or MySQL... OR alien beings... - or whoever the heck is doing it - from converting the "()" in the text to "(). And I tried many things like cleaning the string in all ways known to man or god. Capturing the string previous to sending just before saving to the database. And the conversion would always take place just before the save to MySQL. I tried posting in different forms and fields... Same thing every time... could not stop the magic conversion to "().
What in the name of batman is in this magical text that is causing this to happen?? is it magic pixie dust sprinkled on to godaddy server it is running on??? 0_o
.......
Being the genius that I am 0_0 I decide to remove one word from the paragraph at a time.
Magically... as all the creatures of the forest gathered around - as I finally got to the word "file" in the paragraph, and removed it !!! Like magic - the "()" stay as "()" and are NOT converted to "()?!?!???!?!? :\ How come??I simply removed the word "file" from the text... How could this change anything?? What is the word "file" causing to change with how the string is saved or converted??
OK -So I tested this out on any and every form field in the app. Every single time, in any field, if you type the word "file" followed by a "(" it will convert the first "(" to "(; and the very next ")" to ")
So.. if the string is:
"file ( any number of characters or text ) any other text or characters"
On post, it will be converted mysteriously to:
"file ( any number of characters or text ) any other text or characters"
Remove the word "file" from the string, and you get:
"( any number of characters or text ) any other text or characters"
The alien beings return the abducted "()"
Anyone have a clue what the heck could be going on here?
What is causing this?
Is the word "file" a keyword that is tripping some sort of security measures? interpereting it as "file()"???
I dunno :\
It's the strangest thing I ever saw... Except for that time I walked in on Mom and Dad 0_o
Any help would be greatly appreciated, and I will buy you a beer for sure :)
The very large headed, - (way to much power for such tender egos) -, Noo-Noos here at stack have paused this question as "Off topic" LOL... honest to God these guys are so silly.
So - in an effort to placate the stack-gestapo - I will attempt to edit this question so that it is... "on topic"??? 0_o ... anything for you oh so "King" Stack Guys O_O - too bad you would never have the whit to ever notice such a bug... maybe some day. ;)
Sample code:
<textarea name="notes">Always run credit card on file (we do not charge this customer for pick-up or return) blah blah</textarea>
<?php
if(isset($_POST['notes']){
$this->db->where("ID = ".$_POST['ID']);
$this->db->update('OWNER', $_POST['notes']);
}
?>
Resulting MySQL storage:
"Always run credit card on file (we do not charge this customer for pick-up or return) blah blah"
InnoDB - Type text utf8_general_ci
I am not looking for a way to prevent it, or clean it... I am clearly asking "What causes it"
/*
* Sanitize naughty scripting elements
*
* Similar to above, only instead of looking for
* tags it looks for PHP and JavaScript commands
* that are disallowed. Rather than removing the
* code, it simply converts the parenthesis to entities
* rendering the code un-executable.
*
* For example: eval('some code')
* Becomes: eval('some code')
*/
$str = preg_replace('#(alert|cmd|passthru|eval|exec|expression|system|fopen|fsockopen|file|file_get_contents|readfile|unlink)(\s*)\((.*?)\)#si', "\\1\\2(\\3)", $str);
This is the part of XSS Clean. (system/core/Security.php)
If you want the filter to run automatically every time it encounters POST or COOKIE data you can enable it by opening your application/config/config.php file and setting this:
$config['global_xss_filtering'] = TRUE;
https://www.codeigniter.com/user_guide/libraries/security.html
try something like this
$this->db->set('OWNER', $_POST['notes'],FALSE);
$this->db->where('ID ', $_POST['ID']);
$this->db->update('table_name');
Men I think Is in your server. If Ur using Wamp try to check if you have miss Install some arguments in xhtml. This is my Idea. it's related on my experience in CodeIgniter. hope U will response if you want some advice.
Use utf8 encoding to store these values.
To avoid injections use mysql_real_escape_string() (or prepared statements).
To protect from XSS use htmlspecialchars.
How ever not sure what is the issue in ur case..
Probably try using some other sql keywords in the string and verify the solution.
Try replacing the ( and the ) with ( and ) using str_replace
If you are storing ( and ) in your database then you should try replacing it on output if not try and replace it before input.
I'm not sure if this would work, but you could try inserting a slash in or before the word 'file':
fi\le ( any number of characters or text ) any other text or characters
When I grab the title from my Word Press posts in code and pass them around as email, the punctuation gets a bit mangled.
For example "TAMAGOTCHI P’S LOVE & MELODY SET" comes out as "TAMAGOTCHI P’S LOVE & MELODY SET".
Any ideas how I prevent this?
Let me know if you need to see the specific code I'm currently using. (I'm not really sure if this is a WordPress issue, or a PHP issue.
EDIT
What happens is that this title is passed to a form via the query string. Then when the form is submitted, I take the string from the form field and email it.
So I guess I need to decode the html either before I pass it into the form field, or else before I email it.
EDIT 2
Weird, so I looked closer at the code and I'm already doing a urldecode before I pass the value into the form field
jQuery('#product_name').val("<?php echo urldecode(strip_tags($_GET['pname'])); ?>
Is there some default encoding happening when you serialize (for ajax formhandler)
var dataString = $(this).serialize();
EDIT 3
OK turns out the code is more complex. Title is also passed to some kind of wordpress session before it's hits the form. I'll figure it out where exactly I need to put urldecode. Thanks!
This is one WordPress "feature" I could do without.
Here's one down-n-dirty method to get the fancy quotes (or other entities) replaced:
$title = get_the_title( get_the_ID() );
$title = str_replace( '’', "'", $title );
echo $title;
We could integrate deeper, by hooking into the_title, if you want this same de-entities functionality throughout the site. This code block would belong in your theme's functions.php file.
function reform_title($title, $id) {
$title = str_replace( '’', "'", $title );
return $title;
}
add_filter('the_title', 'reform_title', 10, 2);
Im not really sure about wordpress, but the issue itself its that the text its coming out as URLENCODE instead of a UTF-8 or other encode.
You have two options
When you receive the text you never turn it back to normal encoding (Which is weird as usually is de-encoded by php when you access the $_GET or $_POST variables)
You are parsing the message with the urlencode() function.
I would like to apply wordpress' get_excerpt format to a string I pass to it.
I know the standard excerpt only works within the loop - but I'm hoping there is a function or something I'm missing that generates the excerpt when you don't manually define one.
Fixed answer:
You need wp_trim_words(). Yes - you're right. wp_trim_excerpt() doesn't play nice with passed strings.
http://codex.wordpress.org/Function_Reference/wp_trim_words
wp_trim_words( "I would like to apply wordpress' get_excerpt format to a string I pass to it. I know the standard excerpt only works within the loop - but I'm hoping there is a function or something I'm missing that generates the excerpt when you don't manually define one.", 5, '[...]' ); returns "I would like to apply[...]"
Previous answer:
WordPress uses wp_trim_excerpt() to generate excerpts.
http://codex.wordpress.org/Function_Reference/wp_trim_excerpt
You probably want some filtering on there too before you output (depending on the source of your text).