I'm building a WooCommerce site for a client using WordPress at the moment and I've written a piece of code that dynamically generates tables with products and product attributes in them. When I call the get_title() method, it gives me a title with the product's parent product first, the "→" sign, then the actual title of the product. I wrote this code to remove the "→" sign and everything before it.
$name_raw = $product->get_title();
$name = substr($name_raw, ($pos = strpos($name_raw, '→')) !== false ? $pos + 1 : 0);
It used to work perfectly, but not anymore. This code also works perfectly with every other character I've put in to test it, but not with that stupid little arrow. It seems like a recent update to something I'm using must've removed this method's ability to handle non-conventional characters. Can anyone recommend any possible solutions?
Since it's a WP environment title, the right arrow character probably has been entered using the WP form for a post. I think this character would be converted to it's HTML code, one of these:
→
→
→
→
→
→
→
So I'd do something like this:
function no_right_arrow_name($name_raw) {
if (empty($name_raw))
return $name_raw;
$right_arrows = array(
'→',
'→',
'→',
'→',
'→',
'→',
'→'
);
$name_new = $name_raw;
// removes all possible combinations of right arrows
foreach ($right_arrows as $right_arrow)
$name_new = str_replace($right_arrow, '', $name_new);
return $name_new;
}
$name_raw = $product->get_title();
$name = no_right_arrow_name($name_raw);
Related
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 );
I’m using WP All Import to import products. I’ve run into a bit of an issue with trying to map product variation images.
My XML file contains an <ItemNo>
Each variation has the same product name and variations are handled by different item numbers in this manner
<ItemNo>450042-02</ItemNo>
<ItemNo>450042-05</ItemNo>
<ItemNo>450042-07</ItemNo>
These are the image url is
/ImageServices/image.ashx?itemid=450042&config=02&format=l&imagenumber=1
if you break this down
450042&config=02 would match to 450042-02
450042&config=05 would match to 450042-05
and so on
&format=l, &format=s (this represents large or small image
and i think image number is irrelevant at this point)
if I put below in the image url
/ImageServices/image.ashx?itemid={ItemNo[1]}&format=l&imagenumber=1
it would output the following which won’t work
https://domain.com/ImageServices/image.ashx?itemid=450042-02&format=l&imagenumber=1
so i’d need to change the hyphen to &config=
wp all import accepts custom functions, anyone know a function to replace the - to &config= in the {ItemNo[1]} in only the image section?
It seems that you are trying to achieve something like the following:
$string = '450042-02';
echo "\n";
// part before the -, itemid
print_r(substr($string, 0, strpos($string, "-")));
echo "\n";
//part after the -, config
print_r(substr($string, strpos($string, "-") + 1));
echo "\n";
Although I have never used WP All Import
But Referencing here http://www.wpallimport.com/documentation/advanced/execute-php/
It seems that you can run php function within [] square brackets.
So you field mappings should become like
/ImageServices/image.ashx?itemid=[substr({ItemNo[1]}, 0, strpos({ItemNo[1]}, "-"))]&config=[substr({ItemNo[1]},strpos({ItemNo[1]}, "-") + 1)]&format=l&imagenumber=1
What I am not sure about, would it be able to handle the + operators etc or not but you can try.
If it doesn't work then you can create custom functions like get_my_itemid($string), get_my_config($string), using code(the substr logic) above and then use it in your Img. URL instead of substr
Using MKDIR
File Name Test – () _ <>
However the folder that is created it:
File Name Test – () _ <>
Evidently the "-" seems to cause an issue.
The code
Here are the cars I am using as well:
$web_video_location = get_the_title();
$category = get_the_category();
$catname = $category[0]->cat_name;
if (wp_mkdir_p('./wp-content/uploads/webvideos/'.$catname."/".$web_video_location)) {
echo "";
}
I am not quite sure what I am missing. The folder is created on a webserver.
update
If I make a WP title, such as:
File Name Test-() _ <>
It make a folder:
File Name Test-() _ <>
it appears it is something to do with the spaces.
Update
I also tried this:
$mkdir_cat = "$webdir$catname";
$mkdir_file = "$mkdir_cat/$web_video_location";
if (wp_mkdir_p( $mkdir_file )) {
echo "";
}
Still not joy. I think this is a little over my head.
If the cat has a - it works? I do not get it.
This is WordPress trying to be helpful - the wptexturize function is automatically run all over the place, including in the filter the_title applied by the_title()/get_the_title(). It does various "smart" transforms, including turning - (space hyphen space) into – (en-dash).
However, it does this by emitting HTML entities like –. This is not so useful when you are trying to use content for something other than HTML display.
I can think of a few workarounds:
allow WordPress to format the dash, then unescape it with html_entity_decode, e.g. $web_video_location = html_entity_decode(get_the_title());
disable wptexturize globally, e.g. using run_wptexturize, so it leaves your titles alone
grab the title a different way, e.g. accessing $post->post_title directly; you can see the source of the get_the_title function for some hints on how
use something other than the title as the filename, e.g. a Custom Field on the post
I am trying to use the Progress Bar plugin in wordpress to create a widget that shows a progress bar under the shopping cart of how much more they need to spend in order to get free shipping.
I need to first take the value of the cart:
global $woocommerce;
$price = $woocommerce->cart->get_cart_total();
Secondly Strip the dollar sign and round to nearest integer
?
Thirdly Output the value into the shortcode, so it displays properly into the HTML. As it is now, it outputs this for the width instead of a number.<span class="red" style="width: .$cartnumber%;">
I need this to output a plain number so it will work with the width. Below is the code so far.
<?php
global $woocommerce;
$total = $woocommerce->cart->get_cart_total();
$cartnumber = str_replace("$", "", $total);
echo do_shortcode('[wppb progress='.$cartnumber.' option=red text="Free Shipping"]');
?>
I have enabled PHP execution within widgets for
I have encountered this before, and below is what I have used last.
http://www.php.net/manual/en/class.numberformatter.php
Before I am using preg_match using [0-9\,\s.]+ pattern. Then I have replaced all special characters and letters to blank to get the integer. (not a good solution)
Example code taken from http://www.pagecolumn.com/tool/pregtest.htm
<?php
$ptn = "/[0-9\,\s\.]+/";
$str = "$9,988,776.65 in the United States";
preg_match($ptn, $str, $matches);
print_r($matches);
?>
Output
Array
(
[0] => 9,988,776.65
)
After I realised that it was not a good solution, I revised it to simpler solution using the code below. from: Remove non-numeric characters (except periods and commas) from a string
$number = "$9,988,776.65";
echo preg_replace("/[^0-9]/", "", $number);
Output
998877665
if you did not remove the thousands and decimal symbol it will get the number format of the currency.
Regarding the progress bar, you need to convert the totals to 100%. I assume that your formula is similar below:
(price/free_shipping_minimum)*100
if result goes over 100 then set it to 100%. if you don't want decimals in your percentage cast it to int or use php's round/ceil/floor function.
http://www.php.net/manual/en/function.round.php
I hope this helps a lot.
Why you don't use
WC()->cart->subtotaĺ
Return a float, so no need to remove $ sign
10/25/2012 - Still Not solved! Please see below:
My client has a WordPress Tag Cloud (tag array) with tags which include ["] character as well as [The] prefix for some tags. I.e:
"rose"
"autumn"
The Abby
The Cloud
The Elephant
Obviously all the tags enclosed in the quotations marks ["] are sorted on the top of the list and all the words starting with [The] prefix are sorted somewhere around the letter [T] (following the logical ASC order).
It was sprinkled on me that: "All tags (in the WP tag cloud) have to be ordered Ascending but those which contain the [" "] or [The] characters have to be sorted with all other tags in the chronological order, ignoring the ["] and [The] prefix.
I looked into the WP core function:
**function wp_generate_tag_cloud**
but I have no idea where to start. In the raw SQL statement, I could probably use the trim() to filter out the [" "] and [The] characters form the tag cloud array but that is only a thought which I have no idea how to apply.
wp_generate_tag_cloud() invokes a filter named tag_cloud_sort, which can override the sort order specified in the $args parameter. The tag_cloud_sort filter receives an array of tags and the actual $args parameter passed to wp_generate_tag_cloud(), so it can inspect the full settings of the wp_generate_tag_cloud() invocation and adjust its behavior accordingly.
You could try something like this:
function custom_tag_sort($tags, $args) {
if ($args['orderby'] != 'name') {
// do not reorder if sort order is not by name.
// wp_generate_tag_cloud() is smart enough to notice order
// is not changed and will proceed with its regular sort logic.
return $tags;
}
uasort($tags, 'custom_tag_sort_compare');
}
function custom_tag_sort_compare($a, $b) {
return strnatcasecmp(
custom_tag_sort_normalize($a->name),
custom_tag_sort_normalize($b->name)
);
}
function custom_tag_sort_normalize($tag) {
// strip quote marks
$tag = trim($tag, '"');
// strip leading definitive article
$tag = preg_replace('/^\s*the\s+/i', '', $tag);
return $tag;
}
add_filter('tag_cloud_sort', 'custom_tag_sort');
Disclaimer: I've written this after only a cursory inspection of the wp_generate_tag_cloud() function. I haven't tested it on a live WordPress installation; I have only verified that the sorting function works correctly on your sample tag cloud:
The Abby
"autumn"
The Cloud
The Elephant
"rose"
ok so you want to avoid modifying the core code of wordpress... when your client hits the update button after you told him not to, then your going to have to go in and mess with it again.. use action hooks instead. there is conveniently one for hooking into the output for the tag cloud function. add this to your themes functions file
function tagCloudFilter($tagCloudString, $args)
{
$tagCloudString = str_replace('The','', $tagCloudString);
$tagCloudString = str_replace('"','', $tagCloudString);
}
add_filter('wp_tag_cloud', 'tagCloudFilter', 10, 2);
That will atleast get rid of the stuff you dont want. as far as sorting it im not to sure but this should get you on your way. it may be easier to sort it with jquery
If you really want to modify the core code run a foreach loop in the tag array before its formatted and use the str_replaces from above in that loop.. The just run sort() on that array and you should be good. But if it were me i would go with the half solution and not have it alphabetized than to modify the wordpress core
Here's a thought:
you could copy the original tag_cloud function and create your own on your functions.php.
You make the changes you want to make and add this filter inside the function:
$return = apply_filters( 'YOUR_tag_cloud_function', $return, $args );
And then create the previous filter to add your function to the hook:
add_filter('wp_tag_cloud', 'YOUR_tag_cloud_function');
I don't know if it works, I didn't test it. What do you think?