How to Prevent Wordpress to encode html in post - wordpress

As as title, how to prevent wp not to encode html in a post?
currently i just need to prevent '&' change to '&'
The result need to be looks like on editor with html tab mode selected.
$content = $wpdb->get_row("SELECT post_content FROM $wpdb->posts WHERE ID=xxx");
$content = str_replace('amp;','',$content->post_content);//remove amp;
$wpdb->query("UPDATE $wpdb->posts SET post_content = $content WHERE ID = xxx;");
but that code still encode the html.
update:
and also how to implement content filter(prevent to encode some text) in collaboration with wp_insert_post() function
update[SOLVED]: stackexchange
$content = get_post_field('post_content', XXX, 'raw');
$content = str_replace('amp;', '', $content);
$wpdb->update( $wpdb->posts, array( 'post_content' => $content ), array( 'ID' => XXX ) );

<?php $content = htmlentities( html_entity_decode($content) ); ?>
This code will print HTML tags, and then decode HTML entities (like & to &).
Oh, and with wp_insert_post(), do:
// Create post object
$my_post = array(
'post_content' => $content,
'post_id' => POST_ID # update the post with the same ID as POST_ID
);
You can use the escape function as a shortcode:
function escape_html_func( $attrs, $content = "" ) {
return htmlentities( html_entity_decode($content) );
}
add_shortcode( 'escape', 'escape_html_func' );
like [escape]<span>Hello!</span>[/escape] in blog posts. Is this what you meant by content filter?

Related

WordPress - Add tags taxonomy to comments

I'm working on a project that requires comments to have tags and be searchable by tags. Is there a way to implement it in WP, or should I look for some workaround (like create child post type instead of comments and apply tags to it)?
If there is, how can I do it?
Thank you.
You can use comment meta to store and retrieve tags of a particular comment.
First of all, add the tag field to the comment form and populate the tags. The following code will add a "select" field immediately after comment textarea and populate it with the tags.
add_filter( 'comment_form_defaults', 'change_comment_form_defaults');
function change_comment_form_defaults( $default ) {
$commenter = wp_get_current_commenter();
$out = '<label for="comment_tags">Tags:</label><select name="comment_tags" multiple>';
foreach ( get_tags() as $tag ) {
$out .= '<option value="<?php echo $tag->term_id; ?>"><?php echo $tag->name; ?></option>';
}
$out .= '</select>';
$default[ 'comment_field' ] .= $out;
return $default;
}
The comment_post action is triggered immediately after a comment is stored in the database. You can use it to store post meta.
add_action('comment_post', 'add_tags_to_comment', 10, 2);
function add_tags_to_comment( $comment_ID, $comment_approved ) {
foreach($_POST["comment_tags"] as $comment_tag) {
add_comment_meta( $comment_ID, "comment_tag", $comment_tag );
}
}
Instead of storing the selected tags as an array in a single record, I prefer to store each tag as a separate record. This will make it easier to search the comments based on tags.
When you want to retrieve the tags of a comment, You can get_comment_meta
$tags = get_comment_meta($comment_ID, "comment_tag");
foreach($tags as $tag_id) {
$tag_term = get_term($tag_id, 'post_tag');
echo $tag_term->name;
}
Use WP_Comment_Query to search comments based on tags.
$tags = array(1,32,5,4); /* Replace it with tags you want to search */
$args = array(
'meta_query' => array(
array(
'key' => 'comment_tag',
'value' => $tags,
'compare' => 'IN'
)
)
);
$comment_query = new WP_Comment_Query( $args );
Hope this helped you.

Wordpress - Check if post exists,if yes update fields

I use a frontend form to post, and what i want is to check if a post exists by title.If yes and metafield value is bigger than the old one,just replace the value.
Anyone that has implemented something like that in the past?
<?php
session_start();
$user_email = $_SESSION['user_email'];
$user_name = $_SESSION['user_name'];
$user_img_url = 'https://graph.facebook.com/'.$user_name.'/picture?width=200&height=200';
global $wpdb;
global $post;
$title = $user_name; // get the inputted title
$content = $_POST['content']; // get the inputted content
$categorie = $_POST['cat']; // get the category selected by user
$zombies = $_POST['zombies'];
$kliks = $_POST['klik'];
$timess = $_POST['times'];
$name = $_POST['namn'];
if( 'POST' == $_SERVER['REQUEST_METHOD'] ) { // if form has been submitted
$my_post = array(
'post_title' => $title,
'post_content' => $content,
'post_status' => 'publish',
'post_author' => 2,
'post_category' => array(2),
);
$my_post = wp_insert_post($my_post);
add_post_meta($my_post, 'Zombies', $zombies);
add_post_meta($my_post, 'klik', $kliks);
add_post_meta($my_post, 'times', $timess);
add_post_meta($my_post, 'namn', $name);
add_post_meta($my_post, 'profile_photo', $user_img_url);
wp_redirect( home_url() );
# if $verifica is not empty, then we don't insert the post and we display a message
}
?>
Your question is not quite clear to me but if you want to query a post by it's title then you can use get_page_by_title() function as given below
$post = get_page_by_title( $_POST['post_title'], OBJECT, 'post' );
To get a custom meta field you can use get_post_meta() function as given below
$meta_value = get_post_meta($post->ID, 'field_name', true);
Then compare and update the meta value you can use, for example,
if( $_POST['custom_meta_field'] > $meta_value )
{
// Update the meta value
update_post_meta( $post->id, 'field_name', $meta_value );
}
The update_post_meta() function is being used to update the custom meta field.
Update: (Based on comment)
You can use following to get the post that is available by Facebook ID
$post = get_page_by_title( $_POST['facebook_id'], OBJECT, 'post' );
Also if the meta field is time string (12:10 am) then you have to convert it to timestamp/numeric value before you compare it, like,
$meta_value = strtotime(get_post_meta($post->ID, 'field_name', true));
So, it'll become something like 1363493400 and you can compare like
if( $_POST['custom_meta_field'] > $meta_value ){ ... }
In this case your custom_meta_field should be also a timestamp/numeric value or you have to convert it using strtotime() function just like $meta_value has been converted.

Wordpress - get tags for posts with custom field

I have a custom field, say, "mood", and I need to display list of tags for all posts that have "mood" = "grumpy". Is it possible to do this without fetching all posts and then fetching tags for each of them?
You can use the function get_posts();
$args = array(
'meta_key' => 'mood',
'meta_value' => 'grumpy',
);
$your_posts = get_posts( $args );
Untested, but this should achieve what you want. Just look out for typos and missed semi-colons!
While you don't get the whole post, you do still have to query the database for the ID of posts with 'mood' = 'grumpy', so unless you have lots of posts, it's probably easier to just go with the answer #Dorel gave.
$query = $wpdb->prepare('
SELECT ID
FROM %1$s
LEFT JOIN %2$s
ON %1$s.ID = %2$s.post_id
WHERE %2$s.meta_key = "mood"
AND %2$s.meta_value = "grumpy"
', $wpdb->posts, $wpdb->postmeta
);
$ids = $wpdb->get_col($query);
if(!empty($ids)) : foreach($ids as $post_id) :
$tags = wp_get_post_tags($post_id, $args);
if(!empty($ids)) : foreach($tags as $tag) :
$tags[] = $tag->name;
endforeach;
endif;
endforeach;
endif;
// Now you have an array of Tag names, output them as you wish
Codex for wp_get_post_tags = http://codex.wordpress.org/Function_Reference/wp_get_post_tags
Codex for wp_get_object_terms (to see what $args are available for wp_get_post_tags) =
http://codex.wordpress.org/Function_Reference/wp_get_object_terms#Argument_Options

Wordpress : excluding images 'inserted into post' from get_children

I have a page which has a slideshow at the top, and images inserted inline into the content area.
I need to exclude the images that have been inserted into the post from the slideshow.
Currently I am excluding the 'Featured Image', but this limits me to one image that can be inserted into the post.
Here is my existing code:
$thumbnail = get_post_thumbnail_id();
$images = get_children( 'post_type=attachment&post_mime_type=image&order=asc&orderby=menu_order&post_parent='.$post->ID .'&exclude='.$thumbnail);
Previously I have used the description field of the image meta data to exclude images by entering 'exclude'. This isn't as nice for the end user as I'd like it to be.
Any suggestions, plugins or code based!
Update:
I've updated the code, so now I get any image URLs from the post_content and check them against the slideshow images.
$content = $post->post_content;
$inlineImages = array();
preg_match( '/src="([^"]*)"/i', $content, $inlineImages ) ;
$thumbnail = get_post_thumbnail_id($post->ID);
$images = get_children( 'post_type=attachment&post_mime_type=image&order=asc&orderby=menu_order&post_parent='.$post->ID .'&exclude='.$thumbnail);
if ($images) {
echo '<div id="slideshow">';
foreach ( $images as $attachment_id => $attachment ) {
$image = wp_get_attachment_image_src( $attachment_id,array(900,265));
if (!in_array($image[0],$inlineImages)) {
echo '<img src="'.$image[0].'" width="'. $image[1] .'" height="'. $image[2].'">';
}
}
echo '</div>';
}
This is an OK solution, although the regex could be improved.
A nicer step would be to add the array of images to a custom field field, which
is updated on post / page update or publish.
Any suggestions on how to go about this?
Just needed to do the same thing. Your original approach is the way I wanted to do it -- simply exclude any images that had been inserted into the post from appearing in the slider. But I didn't want the client to have to do anything special to make it happen. Here's my code.
$args = array( 'post_type' => 'attachment', 'post_mime_type'=>'image','numberposts' => -1, 'post_status' => null, 'post_parent' => $post->ID );
$attachments = get_posts($args);
preg_match_all("/<img[^']*?src=\"([^']*?)\"[^']*?>/", $post->post_content, $matches, PREG_PATTERN_ORDER);
/* $matches[1] holds the urls as an array */
foreach ( $attachments as $attachment ) {
if(in_array($attachment->guid, $matches[1])){ continue;}
wp_get_attachment_image( $attachment->ID , 'slider_size');
}
First bit gets all of the images associated with the post. The $preg_match_all gets all of the images in the post body. Then as we loop through the images to display them in the slider the in_array checks the urls of the images that were inserted with the url of the image about to be added to the slider and skips on to the next one if there is a match.
Thanks for you post, got me thinking in the right direction.
I've updated the code, so now I get any image URLs from the post_content and check them against the slideshow images.
$content = $post->post_content;
$inlineImages = array();
preg_match( '/src="([^"]*)"/i', $content, $inlineImages ) ;
$thumbnail = get_post_thumbnail_id($post->ID);
$images = get_children( 'post_type=attachment&post_mime_type=image&order=asc&orderby=menu_order&post_parent='.$post->ID .'&exclude='.$thumbnail);
if ($images) {
echo '<div id="slideshow">';
foreach ( $images as $attachment_id => $attachment ) {
$image = wp_get_attachment_image_src( $attachment_id,array(900,265));
if (!in_array($image[0],$inlineImages)) {
echo '<img src="'.$image[0].'" width="'. $image[1] .'" height="'. $image[2].'">';
}
}
echo '</div>';
}
I think the easiest thing to do would be using the Meteor Slideshow plugin to create a slideshow for each page, then insert the shortcode for the proper slideshow in the content area of the proper page. Yes, it means you'll have to edit each page "outside" the page editor, but it also gives you easy, complete control over which photos do and do not appear in each slideshow, and the shortcode is very easy to put in with the page editor.
The Media Custom Fields plugin lets you add custom data to media items exactly as you would with custom post fields, providing a user-friendly way of flagging slideshow-only images. From the plugin FAQ:
In addition to giving you the option to add custom fields, your custom fields will show up in all appropriate places. If you go to the media section to manage your media like you usually do, they will show up on the edit media form. The custom fields also show up when you are uploading an image to a post, and in all other expected locations.
One approach is to install this plugin and add a custom field such as Slide with value TRUE to your slide images via the Dashboard -> Media menu. Then your filter code might be:
$thumbnail = get_post_thumbnail_id();
$images = get_children( /* removed for brevity */ );
if ($images) {
// ..
foreach ( $images as $attachment_id => $attachment ) {
// skip images not marked for slideshow
if ( !get_post_meta($attachment_id, 'Slide') ) continue;
// otherwise do slideshow things
}
// ..
}
Note that with this approach the value for Slide can be set to anything except the empty string. You may want to define Slide as a class constant somewhere to avoid hard-coding.
Advantages
Doesn't require any work on the poster's part
Future-proof: the plugin appears to be based on good-old post functionality, and attachments are just one kind of post anyway, so there's nothing weird.
Here is another approach to this.
I would not prefer using urls, because the picture inserted inside the content area could be of different size like medium, thumbnail or full. So, the url only would not match.
Using the above code,
function printMeImages() {
$content = $post->post_content;
$inlineImages = array();
// populate ids of images from wp-image-id
preg_match_all( '/wp-image-([^"]*)"/i', $content, $inlineImages ) ;
$thumbnail = get_post_thumbnail_id($post->ID);
$images = get_children( 'post_type=attachment&post_mime_type=image&order=asc&orderby=menu_order&post_parent='.$post->ID .'&exclude='.$thumbnail);
$out = "";
if ($images) {
$out .= '<ul id="slideshow">';
foreach ( $images as $attachment_id => $attachment ) {
$image = wp_get_attachment_image_src( $attachment_id,'desiredImageSize');
// $inlineImages[1] has ids to be discarded
if (!in_array($attachment_id,$inlineImages[1])) {
$out .= '<li><img src="'.$image[0].'" width="'. $image[1] .'" height="'. $image[2].'"></li>';
}
}
$out .= '</ul>';
}
return $out;
}
The images which are not set as featured and not used inside the post are retrieved.
For performance reasons I would not execute the code while the page is being rendered, but rather bind the code to the save_post hook. When the post content is edited and saved, the hook will be called and all attached images (or their ids) which are not used in the content are saved into a postmeta table. When the slider is rendered the image ids can be accessed via get_post_meta($post_id, 'image_ids_for_slider').
Like this I can avoid to do the preg_match_all operation on page rendering. This might not be a performance reason when the post content is small and when there's only one slider loaded, but generally I find this a approach a little cleaner for scaling reasons.
//hook this function to save post action
function save_ids_of_image_attachments_not_used_in_the_content( $post_id, $post ) {
$args = array( 'post_type' => 'attachment',
'post_mime_type'=>'image',
'numberposts' => -1,
'post_status' => null,
'post_parent' => $post_id
);
$attachments = get_posts($args);
preg_match_all("/<img[^']*?src=\"([^']*?)\"[^']*?>/", $post->post_content, $matches, PREG_PATTERN_ORDER);
$ids_of_attached_images_not_in_content = array();
/* $matches[1] holds the urls as an array */
foreach ( $attachments as $attachment ) {
if(in_array($attachment->guid, $matches[1])){
continue;
}
$ids_of_attached_images_not_in_content[] = $attachment->ID;
}
// save the image_ids as postmeta
update_post_meta($post_id, 'image_ids_for_slider', $ids_of_attached_images_not_in_content);
}
add_action( 'save_post', 'save_ids_of_image_attachments_not_used_in_the_content', 10, 2 );
I haven't fully understood your problem, but how about excluding the div ID within which the slideshow is present?
$thumbnail = get_post_thumbnail_id();
$images = get_children('post_type=attachment&post_mime_type=image&order=asc&orderby=menu_order&post_parent='.$post->ID .'&exclude='.$thumbnail. '&NAME');
Replace 'NAME' after thumbnail.' in the parenthesis.
Hope this helps.

How can I get a post by title in Wordpress?

Wordpress 3.0
I want to have the contents of a specific post into a page by using the title of the post. As far as I can tell, I can't do it directly with get_post().
I can assume what the brute force way might be, but I suspect there's a more elegant way?
get_page_by_title($id, OBJECT, 'post');
There ye go.
<!--1.Get post ID by post title if you know the title or the title variable-->
<?php
$posttitle = 'post_title';
$postid = $wpdb->get_var( "SELECT ID FROM $wpdb->posts WHERE post_title = '" . $posttitle . "'" );
echo $postid;
?>
<!--2.use get_post($post_id) to get whatever you want to echo-->
<?php
$getpost= get_post($postid);
$postcontent= $getpost->post_content;
echo $postcontent;
?>
No need to SQL query's when you can use wordpress own functions for this.
$page = get_page_by_title( 'Startsida' );
$page_id = $page->ID;
post_exists is a good function for that :
https://developer.wordpress.org/reference/functions/post_exists/
<?php
$post_id = post_exists('Your title');
// return id or 0 if post doesn't exists.
if($post_id>0)
get_post($post_id);
See my answer on a very similar question. Do not query the data base with an unescaped string.
You can use this:
1)
global $wpdb;
$your_title = "yourtitle";
$id = $wpdb->get_var("SELECT ID FROM $wpdb->posts WHERE post_name = $your_title");
echo $id;
or 2)
$slug_to_get = 'my_title_or_slug';
// you can use custom post type too
$posttypee='post';
$args=array(
'title' => $slug_to_get,
'post_type' => $posttypee,
'post_status' => 'publish'
);
$my_posts = get_posts($args);
if( $my_posts ) {
echo 'ID on the first post found '.$my_posts[0]->ID;
}

Resources