Why wp_update_post strip slashes? - php

I'm trying to update the post_content:
<?php
$something = '<a class=\"class_name\" href=\"#\">';
$my_post = array(
'ID' => 1,
'post_content' => $something,
);
wp_update_post( $my_post );
?>
Could anyone tell me why this always strips slashes from the $something?
What can I do to avoid this situation and update it just as it's in $something?

#miken32
I've looked into database and it's stripped there :-) I need this because I want to update data that's been stored by another plugin which needs specifically this format in order to work properly.
I already fixed this by replacing wp_update_post with wpdb->update. It seems that this one updates exactly as I wanted.

Related

Simple math isn't working in php function if called through ajax

I am running a WordPress site and recently tried to implement a like-dislike system. Everything works fine ... post meta updates perfectly. I can show updated like/dislike count using json_encode. My PHP function code is something like this(it's called when a specific div is clicked) -
$post_likes = array(
$current_user->ID => array(
'date' => date("d/m/Y"),
'IP' => get_client_ip())
);
$new_likes = array(
'date' => date("d/m/Y"),
'IP' => get_client_ip());
$post_likes[$current_user->ID] = $new_likes;
update_post_meta( $post_id, 'post_likes_id', $post_likes );
$output_count = count(get_post_meta( $post_id, "post_likes_id", true ));
$output = array( 'likecount' => $output_count );
echo json_encode( $output );
exit();
The above code works perfectly and shows the updated post like count when clicked on a specific div using json_encode.
What I am currently trying to do is -
$output_count = count(get_post_meta( $post_id, "post_likes_id", true )) - count(get_post_meta( $post_id, "post_dislikes_id", true ));
I am trying to get the difference between like and dislike counts instead of just like count. Which doesn't work. It doesn't show any change when clicked on the specific div which calls the ajax. (It does update the post_likes_id meta).
Could anyone please tell me what am I missing? Thanks in advance.
If you need more data, like the jquery code and the full function, I will post that in the comment.

Wordpress: update_post_meta not working

I am modifying an existing plugin and I want to add a new field to the form and then have that field be submitted along with the post. The post gets submitted to wp_posts. I have read on Google that to do this one simply needs to use update_post_meta. I am trying to insert data into a new column I made in PHPMyAdmin. I named the column post_amount. The field name is amount_field. Although I'm a beginner, something about "just use update_post_meta" that I've read seems too simple to be all that I need. But I might be wrong. Maybe I'm using it wrong?
Note - this whole attempt is due to me wanting to create a new column in the wp_posts table and add data to it with each posts. Is this even the correct way to do this? I see the words "meta_key" and "meta_value" and it makes me think that this will actually end up adding data in the wp_postmeta table....or is that the intended destination?
$question_array = array(
'post_title' => $fields['title'],
'post_author' => $user_id,
'post_content' => apply_filters('ap_form_contents_filter', $fields['description']),
'post_type' => 'question',
'post_status' => $status,
'comment_status' => 'open',
);
if(isset($fields['parent_id']))
$question_array['post_parent'] = (int)$fields['parent_id'];
$question_array = apply_filters('ap_pre_insert_question', $question_array );
$post_id = wp_insert_post($question_array);
$post_amount = $fields['amount_field']; //My code
update_post_meta($post_id, 'post_amount', $post_amount); //My code
I think you made a mistake updating your post_id.
In update_post_meta($post_id, 'post_amount', $post_amount);
you don't have ID of the post or the ID you want to update.
$post_id parameter is declared to Insert Post in your above code.
$post_id = wp_insert_post($question_array); So, update post query didn't find the ID.
You need ID to update post meta. It didn't find any id so it didn't update meta_key. SORRY FOR MY ENGLISH.
Try using add_post_meta instead of update_post_meta.
See the Reference

Check for duplicate Wordpress Post with Custom Meta Data on Publish

I have a site that uses a custom meta-box with the following fields using Meta-Box plugin. Code is as follows
`
$meta_boxes[] = array(
'title' => 'MLS ID',
'pages' => array('property'),
'fields' => array(
array(
'name' => 'MLS ID',
'id' => "IntegratorPropertyID",
'desc' => 'MLS: e.g. 240091025-217',
'type' => 'text',
),
array(
'name' => 'Test MLS',
'id' => "mlsTest",
'desc' => 'Test MLS for Duplicate',
'type' => 'button',
),
),
'validation' => array(
'rules' => array(
"IntegratorPropertyID" => array(
'required' => true
),
),
'messages' => array(
"IntegratorPropertyID" => array(
'required' => 'MLS is required',
),
)
)
);
Now what im looking for is to add an 'add_action( 'save_post', 'checkMLS' );' function that checks all previous CPT property for MLS number to make sure it hasn't been input before. The code I used was:
function checkMLS( $post_id ) {
$slug = 'property';
if ( $slug != $_POST['post_type'] ) {
return;
}
$mls2 = rwmb_meta('IntegratorPropertyID', 'type=text', $post_id);
$args = array( 'post_type' => 'property' );
$loop = new WP_Query( $args );
while ( $loop->have_posts() ) : $loop->the_post();
$this1 = get_the_ID();
$mls1 = rwmb_meta('IntegratorPropertyID', 'type=text', $this1);
if ( $mls2 == $mls1 ) {
$my_post = array(
'ID' => $post_id,
'IntegratorPropertyID' => 'DUPLICATE!'
);
wp_update_post($my_post);
return;
}
endwhile;
}
add_action( 'save_post', 'checkMLS' );
That code is found in the functions.php and when I try to post the screen goes white. Debugging mode does not offer any help either. :/
I'm sure I'm making some programming Major mistake somewhere. Can someone point it out? or maybe point me in the right direction? or suggest something completely different?
Thanks
Keith
OK. Firstly, your white page with no indication of why, is probably either an 'out of memory' error, or a php 'max execution time' error. This stims from one major flaw in the way the checkMLS() function works. The flaw is that you are literally cycling through ALL 'property' posts in your database. Depending on the size of your dataset, this can be a LOT, especially considering you are dealing with MLS lists.
MY RECOMMENDATION:
Figure out how the rwmb_meta() function is grabbing it's information. It is probably just a wrapper function for the get_post_meta() function, but maybe not. Assuming that it is, I propose doing the following, which I will explain the details of after as well as in the comments:
// the save_post action runs after a post has been saved/created, and has two parameters
// param 1: the id of the post
// param 2: the post object
function checkMLS($post_id, $post) {
// use the post object post_type to determine if this is a property or not.
// it will be a lot more reliable
if ($post->post_type != 'property') return;
// meta_key should be equal to the 'meta_key' field in the wp_postmeta table, for the
// id you are trying to check against. your example used IntegratorPropertyID.
// again you may want to check rwmb_meta() function to figure out if there is a
// 'prefix' or 'suffix' added to this. despite that, it is almost certainly going to
// be looking in the wp_postmeta table, so this should work nicely
$meta_key = 'IntegratorPropertyID';
// look up the current mls id for this post, which you just saved/created
$mls_id = get_post_meta($post_id, $meta_key, true);
// lookup in the actual database table for any matching row, that has the same MLS id
// that is not this post.
global $wpdb;
$q = $wpdb->prepare('select post_id from '.$wpdb->postmeta.' where meta_key = %s and meta_value = %s and post_id != %d limit 1', $meta_key, $mls_id, $post_id);
$exists = $wpdb->get_var($q);
// if it already exists, mark the value as a duplicate
if ($exists) update_post_meta($post_id, $meta_key, 'DUPLICATE!');
}
// add your check function late in the actions, at priority 10000
add_action('save_post', 'checkMLS', 10000, 2);
From the top, we create a callback with two params, because the save_post action sends two, $post_id and $post. Since save_post runs after the post has been saved, you already have an object ($post) which has all the post info in it. We can then use that $post object to determine the type of the post, which is more reliable than looking at a $_REQUEST value, mainly because $post is pulled directly from the database and passed to you.
Now, as stated before I assume that rwmb_meta() is just a kinda wrapper function for get_post_meta(). It probably adds a prefix or suffix to the $meta_key, but a little research into the rwmb_meta() function should tell you how the $meta_key is changed when passing it to the get_post_meta() function, and you can modify $meta_key from there. With the correct $meta_key, we can now get the MLS id of the property you just saved.
With that MLS id, we need to do a direct lookup in the database, to determine if there is another property with that id already. While the way in your demo function does work on small sets of data, there is no way it would work on any appreciable amount of properties. Thus the direct approach is needed. Simply we craft some special SQL to look in the wp_postmeta table for any post_id that has an MLS id that is equal to the one entered for this property, that is not this property. If we find one match that is not this property, then it is a dupe. If it is a dupe, we need to mark it as a dupe.
Notice that this solution does not do any looping at all. There is no potential for it to loop over 10000 records to find a dup id. This is streamlined. It looks up the id directly in the db, to see if there are dups.
Hopefully this is helpful to you, and hopefully others find it helpful as well. My company does WordPress work, almost exclusively. Through our years of working with WordPress we have encountered problems from the super simple to the overly complex. This same problem, in different settings, has manifested with many of our clients. This solution is simple and to the point, though highly custom. It will however, work.

How to inject a virtual post (i.e. without adding it to the database)

I use a WordPress blog and I want to show a post without adding anything to database.
What I want to say is:
I generate a post when page loads,and prepend it in homepage.
I've searched and found wp_insert_post() function but it also add to database.
How can i do this with php?
For example:
There is a post array which is generated by a query.How can I insert my post to this array before page loaded?
I want clear my idea.Here's step by step what i want.
*1)*Im generating an array like that
$arr['title] = "my title",
$arr['content'] = "my content",
*2)*WP sends a query to database and have the posts am i right? And there is an array,to show on the theme and main page?
At this point i want to add my external array(generated in step1 ) to this array(generated by WP via a query)
3) By this way i will be able to add a post without adding it to my database.
You can simply add your virtual post in one of your theme templates as raw HTML.
Alternatively, if you're feeling adventurous, you could modify the main query results and include your post inside:
add_action('loop_start', function($query){
// create the post and fill up the fields
$post = new WP_Post((object)array(
'ID' => -1,
'post_title' => 'Bla blah',
'post_content' => 'Your content',
));
// add it to the internal cache, so WP doesn't fire a database query for it
// -1 is the ID of your post
if(!wp_cache_get(-1, 'posts'))
wp_cache_set(-1, $post, 'posts');
// prepend it to the query
array_unshift($query->posts, $post);
});
The currently accepted answer causes the new post to delete the last post in the loop, because it doesn't update the post count. Here's my modified version that also includes:
Support for empty categories.
Only one place to declare the new post's ID.
Adding is_main_query() as the person who originally answered mentioned in a comment.
A setting to decide if the new post should be appended or prepended.
Hiding the post's date because otherwise you get something like 00000000. I could have used a dynamic date but it may be bad SEO to keep updating the date without updating the content.
Hiding the post's comment link because it just leads to the homepage.
A setting to control the post type. You might prefer "page" because "post" displays a general category, which I found no way to bypass. "Page" also looks more distinguished among other posts, assuming that's a good thing.
Here's the modified code:
function virtual_post($query) {
$post_type = 'page'; // default is post
if (get_class($query)=='WP')
$query = $GLOBALS['wp_query'];
if ($query->is_main_query()) {
$append = true; // or prepend
// create the post and fill up the fields
$post = new WP_Post((object)array(
'ID' => -1,
'post_title' => 'Dummy post',
'post_content' => 'This is a fake virtual post.',
'post_date' => '',
'comment_status' => 'closed'
));
if ($post_type <> 'post')
$post->post_type = $post_type;
// add it to the internal cache, so WP doesn't fire a database query for it
if(!wp_cache_get($post->ID, 'posts')) {
wp_cache_set($post->ID, $post, 'posts');
if ($query->post_count==0 || $append)
$query->posts[] = $post;
else
array_unshift($query->posts, $post);
$query->post_count++;
}
}
}
$virtual_post_settings = array('enable' => true, 'include_empty_categories' => true);
if ($virtual_post_settings['enable']) {
if ($virtual_post_settings['include_empty_categories'])
add_action('wp', 'virtual_post');
else
add_action('loop_start', 'virtual_post');
}

Wordpress specific order of echo post meta checkboxes

I'm a php newbie and a first time poster.
I am working on a wordpress site where I need a discography.
I have successfully:
Created my custom post type : Albums
Added custom meta boxes and custom fields to admin post edit page
Made an archive page and echoed all the custom field meta.
http://squarerecording.com/albums/
One of my custom fields is a series of 5 checkboxes: the last line of each album on that archive page
array(
'name' => 'Services Rendered',
'desc' => 'field description (optional)',
'id' => $prefix . 'services',
'type' => 'multicheck',
'options' => array(
'R' => 'Recorded',
'Mi' => 'Mixed',
'Ma' => 'Mastered',
'P' => 'Produced',
'RMV' => 'Re-mastered for vinyl',
),
),
although I have successfully echoed the "Services Rendered" in a comma separated format, the order is different for each post (P,RMV,R,Mi,Ma-for the first one, P,Ma,Mi,R,RMV-for the second, etc.)
Here is the code for the archive page that outputs "Services Rendered":
<?php $key="sqr_services"; get_post_meta($post->ID, $key);
$sqr_services = get_post_meta( $post->ID, $key );
$comma_sep_services = implode(",", $sqr_services );
echo $comma_sep_services;
?>
My question is: What do I need to do so that they are listed in the same order that they appear on the edit page ( R,Mi,Ma,P,RMV)? Bearing in mind that they will not always ALL be checked.
I have tried messing around with unserializing but i don't know enough about it.
Any help or a point in the right direction would be greatly appreciated!
Thanks
This post might be of interest. It's one of the few solutions I've seen that doesn't involve editing Wordpress core files.
You could also try this modified get_post_custom function that orders the key/value pairs by meta id instead of the "date modified" order returned by get_post_custom.
A third option would be to sift through this answer.
Update: Silly Me! PHP can sort arrays any darn way you want, and it just gets a teeny bit tricky when that's not numerical or alphabetical. If alphabetization works for you, attempt the following:
$key="sqr_services";
get_post_meta($post->ID, $key);
$sqr_services = get_post_meta( $post->ID, $key );
asort($sqr_services);
foreach ($sqr_services as $key => $val) {
echo "$val\n";
}
If you want to learn yourself more complex array sorting, be my guest. Me? I'll stick to ABCs.
Update: Silly You!
In response to your comment about checking for and displaying individual values in your $sqr_services array, alls you needs to do is check in_array():
if (in_array('Recorded', $sqr_services)){echo 'Recorded';}
if (in_array('Mixed',$sqr_services)){echo 'Mixed';}
if (in_array('Mastered',$sqr_services)){echo 'Mastered';}
if (in_array('Produced',$sqr_services)){echo 'Produced';}
if (in_array('Re-mastered for vinyl',$sqr_services)){echo 'Re-mastered for vinyl';}
It's less flexible in that if you add a value to the array (add a new tax term), it won't start showing up until you check for it in your loop. I'm guessing that's not gonna be a problem, though, as this seems like a pretty finite set of options.

Categories