Wordpress get custom fields value - wordpress

So I am trying to get custom post values in WP. The thing is I can have multiple custom fields value. So I don't want to hard code in the code. What I am thinking of doing is providing the a prefix in the key value something like
abc_email
abc_website
So I want to use this function
get_post_meta
or some other to get all the key,value pair that starts with abc. That way I can just add values on the back end and don't have to update my code. One way would be to get all the meta data using above function and then loop over it and filter. But is there any other way where I can send in the pattern I am looking for?
Thanks

You could directly query the database for a posts entries containing the prefix (relevant table etc here https://wordpress.stackexchange.com/questions/104434/where-are-custom-field-values-stored-in-the-database )
but this is more complex, still involves a loop and doesn't provide you with anything you could do using WP and PHP. If you want to cater for unknowns you will have to loop or interogate an index etc.
I may be missing something in your question but this seems straight forward:
You are trying to avoid this scenario:
process_field($abc_known1);
process_field($abc_known2);
// continually edit code for new entries e.g.:
process_field($abc_NEW1);
Something like this will handle later additions without modification.
// get array of ALL cust fields for post
$all_cust_fields = get_post_meta( get_queried_object_id());
foreach ($all_cust_fields as $key => $value) {
// some function for determing if $value starts with "abc_"
// if so either:
// add to an "abc" array for later use/processing
// or take action in this loop e.g.
process_field($value);
}
I am not sure whether you are talking about keys or values prefixed "abc_" but the same principle applies.

you should write code like this,
$email_meta = get_post_meta( 'your_post_id', 'abc_email', true );
$website_meta = get_post_meta( 'your_post_id', 'abc_website', true );
Or
you can follow these links,
example
example
Hope this will help you.

Related

Cron Wordpress Update four post every hour

I have function that update post content automatically based from custom field like this:
function update_content(){
$mycustomfield = get_post_meta( get_the_ID(), 'customfield', true);
$post = array();
$post['ID'] = get_the_ID();
$post['post_content' ] = $mycustomfield ;
$post['post_title' ] = $mycustomfield ;
// Update the post into the database
wp_update_post( $post );
We update only custom field to make content. For now, we launch this function manually on save_post hook, but the articles are so many and we need now a cron to automate this function: process 4 posts every hour until all posts are completed, then start over.
How to make this, thank you
WordPress actually has a built-in psuedo cron system called WP Cron. It doesn't function exactly like a proper server cron, but can perform a similar function in many cases. You can find documentation on it here:
https://developer.wordpress.org/plugins/cron/#:~:text=WP%2DCron%20is%20how%20WordPress,post%2C%20utilize%20WP%2DCron.&text=WP%2DCron%20works%20by%20checking,what%20needs%20to%20be%20run.
However thinking about your use case and looking at your function above, I'm wondering what the purpose of your cron is? It looks from that function like all you're doing is taking some content already in your database and putting it somewhere else. Why? Why not simply display your custom field in the correct spot? Or better yet, use the fields as intended?
Even if that is necessary - maybe I don't understand fully from the example above - I think your initial inclination to run this on save_post is much more correct. Unless there's some information external to your site that's changing, the only time these values will change is when you save the post. So what is the purpose of running it on a schedule?

This use of posts_where() function is not clear

I have this very short function that I do not understand at all, and the comment is laughable:
// This function makes the meta query work
function my_posts_where( $where ) {
$where = str_replace("meta_key = 'bonuses_%", "meta_key LIKE 'bonuses_%", $where);
return $where;
}
add_filter('posts_where', 'my_posts_where');
The meta query in question is a standard WP query with array_push($args['meta_query'],$bonusesArgs); pushing $bonusesArgs (the meta query) into it.
Without the my_posts_where function, the meta query doesn't work. And I have no idea why (and neither did the developer apparently...!)
I am hoping that someone can explain the my_posts_where function - what is it doing, I've looked all over and can't make sense of it.
Well.. all it seems to be doing is rebuilding the meta query in a different, but using LIKE instead of a direct =
Like performs a search for the value in the string, instead of a direct equality.
So it would seem that this function is completely superfluous, if the original meta query just used the compare = 'LIKE' value.
But without seeing the entire code, it'd be really tough to tell exactly what repercussions this might have. But no matter what, there are better ways to interact with a query object than running some weird str_replace on its data.

How bad is $wp_rewrite->flush_rules() on 'init' action hook?

According to the Codex:
[...] This function can be extremely costly in terms of performance. It should be used as sparingly as possible - such as during activation or deactivation of plugins or themes. Every attempt should be made to avoid using it in hooks that execute on each page load, such as init.
Ok, so, I know it shouldn't be used in every page load and I'm not, but I still need a very conditional rewrite rule on this project.
I have these 2 url structures:
- example.com/products/tables/fancy-computer-table //This is a product url, here I expect the normal behavior from wp.
- example.com/products/tables/office //This should be some kind of a filter, where the site gets all the tables related to the office department. Note how both URL structure matches.
To make it work, I narrowed it down to these very specific URLs, using some regex. If matched, I'll run 2 queries to verify if the url I'm in is for the filter I want that rule to apply, or if it's a product url. In the latter, I want wordpress to behave normally. But I have to flush the rules either way, whether it's a product or it's the category and the filter, so that both pages work properly and dinamically.
I do all this to narrow down the use of this function to the least possible, but the Codex doesn't really tell me how bad it does affect the performance, or why.
I'm passing the parameter on that function as false by the way, so it doesn't rewrite my htaccess file, but I'm not sure where that rewrite rule option is stored, if it's on the memory somewhere, or on the database, wish they would provide some clarification on that.
Thanks in advance for reading this question. Any pointers are appreciated here, even if you want to point me to some other way of doing this. :)
EDIT: Posting some code here so you guys can actually understand what I mean and let me know if this maybe this could be bad practice... maybe a suggestion on how to do it better.
<?php function custom_rewrite_products()
{
// regex to match either "products/tables/fancy-computer-table" or "products/tables/office"
preg_match('#products\/([^\/]+)\/([^\/]+)\/?#', $_SERVER['REQUEST_URI'], $url_matches);
if(is_array($url_matches)) {
$query_category = new WP_Query('category_name='.$url_matches[1]);
$query_category->get_posts();
$args = array(
'post_type' => 'filters',
'name' => $url_matches[2]
);
$query_post = new WP_Query($args);
$query_post->get_posts();
if($query_category->have_posts() && $query_post->have_posts()) {
$category_ID = '';
$filter = '';
$category_ID = '' . $query_category->query_vars['cat'] . '';
$filter = '' . $query_post->query_vars['name'] . '';
$string = "index.php?cat={$category_ID}&filter={$filter}";
add_rewrite_rule('products/([^/]+)/([^/]+)/?$', $string, 'top');
}
global $wp_rewrite;
//Call flush_rules() as a method of the $wp_rewrite object
$wp_rewrite->flush_rules(false);
}
}
add_action('init', 'custom_rewrite_products');
I still don't understand why, but the flush is needed here, so the $category_ID and $filter variables actually get passed to the rewrite rules. If I take it out, the rewrite just goes to the index page, the place where the values should be are empty.
In case you're wondering, I created the filters on a custom post type and they are related to each post by using a custom field, since they're like four or five and they're present on every category on this project. As you can see, I already have a category/subcategory structure and I didn't find it smart to create these filters once again by hand inside each main category.
There is a 'rewrite_rules' record in the 'wp_options' table that includes all the rewrite rules. When calling flush_rules(), WordPress will clear this record and regenerate all the new rules, including the ones you're not changing.

Saving an array to Advanced Custom Fields WordPress

I'm using the ACF plugin for WordPress. I'm posting to a custom post type programmatically via my theme. Now, I thought I would be able to save an array of items to a custom field quite easily, but whenever I try to, nothing gets input. I simply get this error when I check the post screen in the admin area:
Warning: htmlspecialchars() expects parameter 1 to be string, array given in /home/lukeseag/public_html/spidr-wp/wp-content/plugins/advanced-custom-fields/core/fields/text.php on line 127
Now, I'm kind of throwing this out there for suggestions as to how I can go about solving this problem.
To give some context, I'm programmatically saving data input by a user, and creating a post with it. Much of the data is simple strings and numbers that can each have their own custom field.
But I have an unknown number of text strings and URL's (with an id number for each) coming through this page too, that need to be linked with the same post. I need to be able to output each set of text string and URL into their own div on the single.php post page. Now, ideally these text/url pairs would be saved in a single array so I can just loop through the array and output the data, but it looks like ACF doesn't want to let this happen?
Any suggestions as to how I can save this data and then output it easily on the single.php page? Each set of results will have an ID (number), text string and url.
Thanks!
This is exactly why all those "frameworks" are usually more pain than gain. they are designed to look flexible to the lazy but then they always prove useless on a real case scenario that is a bit more complex than anything that would actually be easily achieved without them.
Anyhow, as for your question.
The problem is that you are passing array instead of a string .
I am not going to go into debugging the plugin, and anyhow , more code and info is needed , so i will just give you ONE possible and easy solution, and that is to compose a pseudo-array string like so :
'ID|URL|STRING'
note that the delimiter pipe (|) is just an example, you could use ( , ) ( : ) ( # ) or whatever.
in other words :
$url = 'http://myurl.url/something';
$id = 35;
$string = 'my string';
$pseudo_r = $id . '|' . $url . '|' . $string . '|'; // results in 'ID|URL|STRING';
or you can use the implode() function
$pseudo_r = array(
"url" => $url,
"id" => $id ,
"string" => $string
);
$pseudo_r = implode("|", $pseudo_r); // gives a string
and pass it as a string that later on you can decompose it with explode() like so :
$pseudo_r = explode( '|', $pseudo_r ); // gives back the original array
( Please note that now the array is NON ASSOCIATIVE anymore . )
now, since you mentioned that each one of those is a set, you can compose the same pseudo array from the sets, using a different delimiter.
This might work for you , but essentially it is wrong .
why is it wrong ?
Because this is a generic and somewhat hackish solution that actually ignores your data type .
You are mixing 3 types of data types , URL , ID and a STRING .
All 3 ( should ) have potentially different validation schemes , and I suspect that the htmlspecialchars() part belong to the URL.
Another solution is just to find the right data field in the ACF settings or use a different field for each and then just DISPLAY it together , also using the implode() and explode() functions.
Yo can save the array using json_encode($your_array) and json_decode() to recover it. This works also for associative arrays.

Wordpress the_category() reverse order so parents come first?

A template i'm using is calling the_category() to list the categories which a post belongs to. It's ordering them by default with the child name first then parents. Is there a way to reverse the order so that the categories are listed as Parent, Child, Second Child?
You could filter get_the_terms and modify the results to suit your needs. You will need to add or remove the filter or use a conditional to only modify this where you need it. Here is an example for reversing the order of the retrieved terms.
function reverse_categories($terms, $id, $taxonomy){
if($taxonomy == 'category'){
$terms = array_reverse($terms, true);
}
return $terms;
}
add_filter('get_the_terms', 'reverse_categories', 10, 3);
You can do this with a one-liner without creating a function/filter wherever you may implement get_the_category_list() function:
implode(', ',array_reverse(explode(',',get_the_category_list(','))))
Change the implode string to one of your choice if you don't want ", ".
I can personally confirm this works in WordPress 3.5 -- but i am sure it will work in just about any version of WordpPress since 1.5.2 when get_the_category_list() was introduced.

Resources