I've added a custom "save_post" action to my theme (code is below). However, when I place images or video code in the post, its stripped away. The only way I can get it to stay is to comment out the add_action line. What do I need to do in order to keep all the post info intact?
add_action('save_post', 'custom_add_save');
function custom_add_save($postID){
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
return $postID;
}
else
{
// called after a post or page is saved
if($parent_id = wp_is_post_revision($postID))
{
$postID = $parent_id;
}
if ($_POST['my_customHeader'])
{
update_custom_meta($postID, $_POST['my_customHeader'], 'my_customHeader');
}
else
{
update_custom_meta($postID, '', 'my_customHeader');
}
if ($_POST['my_customTitle'])
{
update_custom_meta($postID, $_POST['my_customTitle'], 'my_customTitle');
}
else
{
update_custom_meta($postID, '', 'my_customTitle');
}
}
}
function update_custom_meta($postID, $newvalue, $field_name) {
// To create new meta
if(!get_post_meta($postID, $field_name)){
add_post_meta($postID, $field_name, $newvalue);
}else{
// or to update existing meta
update_post_meta($postID, $field_name, $newvalue);
}
}
you also need to add a nonce value to prevent concurrency
add a hidden input in your form:
<input type="hidden" name="customCategory_noncename" id="customCategory_noncename" value="<?= wp_create_nonce('customCategory'); ?>" />
and add this to your save code
// verify this with nonce because save_post can be triggered at other times
if (!wp_verify_nonce($_POST['_noncename'], 'my_customHeader')) return $post_id;
also by default i think wordpress strips out html formatting in the editor in favour of its own 'smart' html tagging
I'm not exactly very well-versed with the Wordpress hooks related to saving posts, but based on your PHP alone, I'm seeing that your custom_add_save() function is not returning the post id when it's processing a manual save (i.e. when you click the Save Draft / Publish button on the Wordpress UI).
It's certainly returning the post id during an auto-save (as per the first block of code as you enter custom_add_save), though.
Maybe you'd like to look into that. :)
Related
Requirement: On the each publish/update post, we need all tags from
the post and do some functionality on that.
Case 1:
Create post, add tags and Publish immediately
=== WORKS PERFECT ===
Case 2:
Update Old post and hit Update button.
=== WORKS PERFECT ===
Case 3:
Create post, add tags and save it to draft and close.. again open the same post and just hit the publish without changing anything
=== FAIL === Nothing in the post result.. no tags found but tags already available in the post,
but if we change something or just remove and add the same tag then it works.
I want 3rd case to be worked.. How to get the tags of drafted post on publish..
BELOW IS MY CODE
// This is hook which calls automatically on publish the post
add_action( 'publish_post', array($this, 'post_published_notification'), 10, 2 );
// The function calls on publish the post
public static function post_published_notification( $ID, $post )
{
$request_body = file_get_contents('php://input');
PostPublishNotification::saveDataInNotificationTable($ID,$request_body);
}
// We neen the tags here..
public static function saveDataInNotificationTable($ID,$request_body)
{
$post_data = json_decode($request_body);
// Here is nothing when I publish the drafted post. otherwise it works when I publish/update the new/old post
var_dump($post_data);
exit;
$tags = $post_data->tags;
if(isset($tags) && is_array($tags) && count($tags) > 0)
{
// SOME CODE
}
}
Found Solution :
If there is no data in the request_body, the we can also fetch it from the postID which is already we have.
Changed Code: added condition if data not available, then get it from post id
public static function saveDataInNotificationTable($ID,$request_body)
{
$post_data = json_decode($request_body);
$tags = $post_data->tags;
if($post_data == "" || $post_data == null)
{
$tags = get_the_tags($ID);
}
if(isset($tags) && is_array($tags) && count($tags) > 0)
{
// SOME CODE
}
}
I would like show the admin notice while post text is being edited (before Save post). I suppose admin_notice hook wont work in this (it doesn't for me). Any idea how to show some error message to alert the user that Post content is not going to be accepted ?
I prefer inline display like admin notice instead of popups that could be blocked.
Following doesn't work
function secure_oembed_filter($html, $url, $attr, $post_ID) {
if (strlen($html) > 0 && strpos($html, "http://")) {
//wp_die("Unsecure link in embeds", "Unsecured post");
} else {
add_action('admin_notices', array($this, 'show_error'));
}
return $html;
}
private function show_error () {
echo '<div class="error"><p>This is an error</p></div>';
}
In that case wp_remote_get() will work fine.
Create a notice.php file and uploaded it on my server.
Then I have added these code into my plugin and it works for me.
<?php
$remote_data = wp_remote_get( 'http://example.com/notice.php' );
$remote_body = wp_remote_retrieve_datat( $remote_data );
?>
<div class="notice">
<?php echo $remote_body ?>
</div>
Hope that helps.
I'm developing a plugin, in which the administrator has the ability to add and remove ZIP codes on the backend. I found that the best way to do this is by creating a custom post type named zip_code with only a title being supported, as that functionality is already built-in to WordPress.
I'm having trouble with validating the title, as it must be a valid ZIP code to avoid errors on the front end.
I've added the following action hooks:
// Action hook to intercept WordPress' default post saving function and redirect to ours
add_action('save_post', 'zip_code_save');
$validator = new Validator();
// Called after the redirect
add_action('admin_head-post.php', array($validator, 'add_plugin_notice'));
zip_code_save function:
public function zip_code_save() {
global $post;
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
if (isset($_POST['post_type']) && $_POST['post_type'] == 'zip_code') {
$validator = new Validator();
if (!$validator->validate(get_the_title($post->ID))) {
$validator->update_option(1);
return false;
} else {
update_post_meta(
$post->ID,
'zip_code', get_the_title($post->ID));
}
}
}
And finally this is my Validator class:
class Validator {
//This for your your admin_notices hook
function show_error() {
echo '<div class="error">
<p>The ZIP Code entered is not valid. <b>Note</b>: only US ZIP codes are accepted.</p>
</div>';
}
//update option when admin_notices is needed or not
function update_option($val) {
update_option('display_my_admin_message', $val);
}
// Function to use for your admin notice
function add_plugin_notice() {
if (get_option('display_my_admin_message') == 1) {
// Check whether to display the message
add_action('admin_notices', array(&$this, 'show_error'));
// Turn off the message
update_option('display_my_admin_message', 0);
}
}
function validate($input) {
$zip = (isset($input) && !empty($input)) ? sanitize_text_field($input) : '';
if ( !preg_match( '/(^\d{5}$)|(^\d{5}-\d{4}$)/', $zip ) ) {
return false;
} else {
return true;
}
}
}
The above code successfully outputs an error message if the entered ZIP is not valid, however regardless of the error, it does publish the post. Is there a way to block the publishing of the post if the title is not valid?
Also, is there a way to prevent WordPress from creating drafts automatically? Since there is so little data, it's really irrelevant here, and more a hassle.
I have a function for creating post. Before save the new post, there is a hook for manipulating data before save:
function save(){
$data = apply_filters('data_before_save',array(....));
$post_id = wp_insert_post( $data );
return $post_id;
}
Now I am adding stuffs to the $data:
add_filter('data_before_save','conditional_save',10,1 );
function conditional_save( $data ){
//...some stuffs
if( $data['x']== $blabla ){
wp_safe_redirect( $link);
exit();
}else{
$data['x'] = $x;
}
return $data;
}
Will the function save be exited by the function conditional_save before the line save_post ?
I don't want return any data if condition meet. I tried my code, it seems works-- redirected and didn't create new post. But I want to make sure the function save is really stopped running.
exit() will abruptly halt all execution of the code.
Its not usually a good idea.
Make use of FLAGS instead.
EDIT :
FLAG is not a reserved keyword.
Just set a var to true/false on your conditional save, check for the flag on your save(). Depends on the result of the var you can restrict what to do and what not to.
Cannot find where to add validation for a checkbox on wordpress login form. I have an additional checkbox set up called 'terms' that I need the user to check each time they want to log in.
Problem is that I cannot stop wordpress logging in if they don't check it. Where it the login code.
There is also a plugin installed that may be complicating matters called them-my-login.
I have all the code in front of me, just tell me what I'm looking for.
I know this is fairly old but I just stumbled across it and was able to look at the codex and work out a solution. Hope this helps somebody. Thanks to #Jason for pointing in the right direction.
This code will need to be added to your theme's functions.php file:
<?php
// As part of WP authentication process, call our function
add_filter('wp_authenticate_user', 'wp_authenticate_user_acc', 99999, 2);
function wp_authenticate_user_acc($user, $password) {
// See if the checkbox #login_accept was checked
if ( isset( $_REQUEST['login_accept'] ) && $_REQUEST['login_accept'] == 'on' ) {
// Checkbox on, allow login
return $user;
} else {
// Did NOT check the box, do not allow login
$error = new WP_Error();
$error->add('did_not_accept', 'You must accept the terms and conditions' );
return $error;
}
}
// As part of WP login form construction, call our function
add_filter ( 'login_form', 'login_form_acc' );
function login_form_acc(){
// Add an element to the login form, which must be checked
echo '<label><input type="checkbox" name="login_accept" id="login_accept" /> I agree</label>';
}
The answer Patrick Moore gave did not work for me, but I did modify it to provide a valid solution. This may be because he answered it back in 2013, and now the code has changed. I changed the filter to login_form_middle, and modified the function at the end as a variable, and then passing the value back through a return:
<?php
// As part of WP authentication process, call our function
add_filter('wp_authenticate_user', 'wp_authenticate_user_acc', 99999, 2);
function wp_authenticate_user_acc($user, $password) {
// See if the checkbox #login_accept was checked
if ( isset( $_REQUEST['login_accept'] ) && $_REQUEST['login_accept'] == 'on' ) {
// Checkbox on, allow login
return $user;
} else {
// Did NOT check the box, do not allow login
$error = new WP_Error();
$error->add('did_not_accept', 'You must accept the terms and conditions' );
return $error;
}
}
// As part of WP login form construction, call our function
add_filter ( 'login_form_middle', 'login_form_acc' );
function login_form_acc(){
// Add an element to the login form, which must be checked
$termsLink = '<label><input type="checkbox" name="login_accept" id="login_accept" /> I agree</label>';
return $termsLink;
}
WordPress Filters/Actions are your friend.
Take a look at:
admin_init
wp_login