Wordpress- Cancel post saving process - wordpress

I need to abort the post saving process when the post content contains a specific string and then display a message to the user.
I found a method to display the message but didn't find a way to refuse post saving.
So far here's what i've done
add_action( "pre_post_update", "checkPost");
function checkPost($post_ID) {
$post = get_post($post_ID);
$postContent = $post->post_content;
if ( wp_is_post_revision( $post_ID ) )
return;
if(preg_match("/bad string/", $postContent) == 1) {
//
// cancel post save
//
// then
add_filter("redirect_post_location", "my_redirect_post_location_filter", 99);
}
}
function my_redirect_post_location_filter($location) {
remove_filter('redirect_post_location', __FUNCTION__, 99);
$location = add_query_arg('message', 99, $location);
return $location;
}
add_filter('post_updated_messages', 'my_post_updated_messages_filter');
function my_post_updated_messages_filter($messages) {
$messages['post'][99] = 'Publish not allowed';
return $messages;
}

Hope this helps you to check post content
function to_err_is_human( $post_id ) {
// If this is just a revision, don't check
if ( wp_is_post_revision( $post_id ) )
return;
$post_content = wp_unslash(!empty($_REQUEST['content']) ? $_REQUEST['content'] : $post_data['content']);
if ($post_content=="abc")
{ add_filter("redirect_post_location", "my_redirect_post_location_filter", 99);}
}
add_action( 'save_post', 'to_err_is_human' );
function my_redirect_post_location_filter($location) {
remove_filter('redirect_post_location', __FUNCTION__, 99);
$location = add_query_arg('message', 99, $location);
return $location;
}
add_filter('post_updated_messages', 'my_post_updated_messages_filter');
function my_post_updated_messages_filter($messages) {
$messages['post'][99] = 'Publish not allowed';
return $messages;
}

Related

Wordpress save_post creates duplicate content in 1 entry

I am encountering issue whereby my post content got duplicated. I want to be able to modify the content only on first publish. I tried to use wp_insert_post_data filter but it keeps crashing. So i use save_post. Here is what I want to achieve.
Example:
This is my post and I [bbsmall]create it using[/bbsmall] save_post
Filter:
Remove tag and use only simple html tags and do many other modification.
Ideal Output:
This is my post and I create it using save_post
However, my current output is:
This is my post and I create it using save_post
This is my post and I create it using save_post
This is my code
add_action('save_post', 'my_modified_content');
function my_modified_content($post_id) {
$post_content = get_post( $post_id );
if( $post_content->post_type != "post" ) {
return;
}else{
if (isset($post_content->post_status) && 'auto-draft' == $post_content->post_status ) {
return;
}
else{
$add_extra_tag = $myweb_settings['myoption_set'];
$post_checked = get_post_meta( $post_id, 'my_post_meta_style', true );
$alreadydone = get_post_meta( $post_id, 'check_post_style', true );
if ($alreadydone!=1){
if (isset($add_extra_tag) and $add_extra_tag=="Yes"){
remove_action('save_post', 'my_modified_content');
$content = add_simple_tags($post_content->post_content);
$title =add_simple_tags($post_content->post_title);
update_post_meta($post_id, 'check_post_style', '1');
$my_post = array();
$my_post['ID'] = $post_id;
$my_post['post_title'] = $title;
$my_post['post_content'] = $content;
$my_post['post_status'] = 'publish';
wp_update_post($my_post);
add_action('save_post', 'my_modified_content');
}else{
if (isset($post_checked ) ) {
remove_action('save_post', 'my_modified_content');
$content = add_simple_tags($post_content->post_content);
$title =add_simple_tags($post_content->post_title);
update_post_meta($post_id, 'check_post_style', '1');
$my_post = array();
$my_post['ID'] = $post_id;
$my_post['post_title'] = $title;
$my_post['post_content'] = $content;
$my_post['post_status'] = 'publish';
wp_update_post($my_post);
add_action('save_post', 'my_modified_content');
}else{
return ;
}
}
}else{
return ;
}
}
}
}
Okay so I am able to fix the issue.
Instead of using save_post, I use wp_insert_post_data filter.
Previously I failed to use the filter due to the wrong format of coding and I did not return the $data.
So these are the modifications I did. Hope this is helpful for others who are facing the same issue.
add_filter('wp_insert_post_data', 'my_modified_content',10,3);
function my_modified_content($data, $postarr, $unsanitized_postarr) {
if( $data['post_type'] != "post" ) {
return;
}else{
if (isset($data['post_status']) && 'auto-draft' == $data['post_status'] ) {
return;
}
else{
$add_extra_tag = $myweb_settings['myoption_set'];
$post_checked = $postarr['my_post_meta_style'];
//Do other checks and modifications
}
}
return $data;
}

Uncaught Error: Call to a member function get_cart() on null

On Woocommerce, I have an error message on my function but i don't unserstand why it happens.
Uncaught Error: Call to a member function get_cart() on null in ...
The function checks id a category product is in the cart.
The error is displayed in the order detail in backend
It's used in functions.php , executed on checkout page,
called by these hooks:
woocommerce_before_order_notes
woocommerce_checkout_process
woocommerce_checkout_update_order_meta
woocommerce_admin_order_data_after_billing_address
woocommerce_email_order_meta_keys
https://i.stack.imgur.com/v7Atp.png
function is_in_the_cart() {
$found=false;
// Find if product is in the cart price <=40
foreach( WC()->cart->get_cart() as $cart_item_key => $values )
{
$cart_product = $values['data'];
$price = accessProtected($values['data'], 'changes')['price'];
if ($price >=40 && $cart_product->id=='969') {$found=true;}
}
if ( $found ) {
return true;
} else {
return false;
}
}
add_action('woocommerce_checkout_process', 'wps_select_checkout_field_process');
function wps_select_checkout_field_process() {
if (is_in_the_cart())
{
global $woocommerce;
// Check if set, if its not set add an error.
if ($_POST['dvd'] == "blank")
wc_add_notice( '<strong>Merci de séléctionner un DVD</strong>', 'error' );
}
}
//* Update the order meta with field value
add_action('woocommerce_checkout_update_order_meta', 'wps_select_checkout_field_update_order_meta');
function wps_select_checkout_field_update_order_meta( $order_id ) {
if (is_in_the_cart())
{
if ($_POST['dvd']) update_post_meta( $order_id, 'dvd', esc_attr($_POST['dvd']));
}
}
add_action( 'woocommerce_admin_order_data_after_billing_address', 'wps_select_checkout_field_display_admin_order_meta', 10, 1 );
function wps_select_checkout_field_display_admin_order_meta($order){
if (is_in_the_cart())
{
echo '<p><strong>DVD: </strong> ' . get_post_meta( $order->id, 'dvd', true ) . '</p>';
}
}
//* Add selection field value to emails
add_filter('woocommerce_email_order_meta_keys', 'wps_select_order_meta_keys');
function wps_select_order_meta_keys( $keys ) {
if (is_in_the_cart())
{
$keys['Dvd:'] = 'dvd';
return $keys;
}
}
I think you want to check to make sure the cart isn't empty before your function.
Also... You can access price by using get_price() from the product object which you are retrieving with $values['data']
function is_in_the_cart(){
// Make sure it's only on front end
if (is_admin()) return false;
$found = false;
// If cart is empty - bail and return false
if (empty (WC()->cart->get_cart())) {
return false;
} else {
foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
$cart_product = $values[ 'data' ];
// Find if product is in the cart price <=40
$price = floatval($cart_product->get_price());
if ( $price >= 40 && $cart_product->id == '969' ) {
$found = true;
}
}
if ( $found ) {
return true;
} else {
return false;
}
}
}
UPDATED - added is_admin to prevent from running on backend.

Making update notice functionality for my themes

I've created one of my themes.I want to add update functionality through api
The notice should be visible when I use the theme, if required for theme update
Actually i have no idea so please give me your suggestion or give me a code,so i can add functionality for update theme.
Note : If you have a no idea for api so you can provide another code
You can use site_transient_update_themes here:
add_filter ( 'site_transient_update_themes', 'theme_check_for_update' );
function theme_check_for_update ( $transient ) {
// Check Theme is active or not.
if( empty( $transient->checked['Your-Theme-Name'] ) )
return $transient;
$request = theme_fetch_data_of_latest_version();
if ( is_wp_error( $request ) || wp_remote_retrieve_response_code( $request ) != 200 ) {
return $transient;
} else {
$response = wp_remote_retrieve_body( $request );
}
$data = json_decode( $response );
if ( version_compare( $transient->checked['Your-Theme-Name'], $data->new_version, '<' ) ) {
$transient->response['Your-Theme-Name'] = (array) $data;
add_action('admin_notices', 'theme_update_admin_notice');
}
return $transient;
}
function theme_fetch_data_of_latest_version() {
// Your API call to check for new version
$request = wp_safe_remote_get( 'https://yourdomain.com/api/upgrade-json/' );
/*
Response Shoul be in following format:
{
"new_version": "1.0.4",
"url": "https://yourdomain.com/theme/changelog/",
"package": "https://yourdomain.com/theme/theme.zip"
}
*/
return $request;
}
function theme_update_admin_notice(){
echo '<div class="notice notice-warning notice-alt is-dismissible">
<p>New Theme Update is available.</p>
</div>';
}

Custom order action success message

Everytime I fire my custom action an success message "Order updated" is displayed.
Is there a way to hide this message after firing custom order action? For example if my action do not process?
function _custom_order_action_process( $order ) {
// some code
// some code
// some code
if ( ! $valid1 ) {
// Oooops...
return;
}
if ( ! $valid2 ) {
return;
}
//here we go...
}
add_action( 'woocommerce_order_action_custom_order_action','_custom_order_action_process' );
One thing you can do is change the message value.
we can use redirect_post_location for that.
function _custom_order_action_process( $order ) {
// some code
// some code
// some code
if ( ! $valid1 ) {
// Oooops...
add_filter( 'redirect_post_location', 'redirect_post_location', 99 );
}
if ( ! $valid2 ) {
add_filter( 'redirect_post_location', 'redirect_post_location', 99 );
}
//here we go...
}
add_action( 'woocommerce_order_action_custom_order_action','_custom_order_action_process' );
function redirect_post_location( $location ) {
remove_filter( 'redirect_post_location', __FUNCTION__, 99 ); // remove this filter so it will only work with your validations.
$location = add_query_arg('message', 99, $location); // 99 is empty message, it will not show. Or if by any chance it has a message, you change to higher number.
return $location;
}

Wordpress validation for title

Need to add blank and already exist validation for 'supports' => array( 'title') on my custom post type. But i dont want to use any plugin for this.
Thanks in advance.
add_action( 'admin_notices', 'custom_error_notice' );
function custom_error_notice(){
global $current_screen, $post;
if ( $current_screen->parent_base == 'edit' ){
if((!$post->post_name) && $_GET['post']) {
wp_redirect(admin_url('post-new.php?empty=1'));
}
if($_GET['empty']) echo '<div class="error"><p>Warning - Please fill up all fields correctly!</p></div>';
}
}
But this not working properly.
This may help you:-
add_action('save_post', 'album_save_post', 10, 2);
function album_save_post( $album_id, $album ) {
if( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE || $album->post_type != 'music_album') return;
// echo '<pre>';
// print_r($album);
// echo '</pre>';
// die();
$errors = array();
// Validation filters
$title = $album->post_title;
if ( ! $title ) {
$errors['title'] = "The title is required";
}
// if we have errors lets setup some messages
if (! empty($errors)) {
// we must remove this action or it will loop for ever
remove_action('save_post', 'album_save_post');
// save the errors as option
update_option('album_errors', $errors);
// Change post from published to draft
$album->post_status = 'draft';
// update the post
wp_update_post( $album );
// we must add back this action
add_action('save_post', 'album_save_post');
// admin_notice is create by a $_GET['message'] with a number that wordpress uses to
// display the admin message so we will add a filter for replacing default admin message with a redirect
add_filter( 'redirect_post_location', 'album_post_redirect_filter' );
}
}
function album_post_redirect_filter( $location ) {
// remove $_GET['message']
$location = remove_query_arg( 'message', $location );
// add our new query sting
$location = add_query_arg( 'album', 'error', $location );
// return the location query string
return $location;
}
// Add new admin message
add_action( 'admin_notices', 'album_post_error_admin_message' );
function album_post_error_admin_message() {
if ( isset( $_GET['album'] ) && $_GET['album'] == 'error' ) {
// lets get the errors from the option album_errors
$errors = get_option('album_errors');
// now delete the option album errors
delete_option('album_errors');
$display = '<div id="notice" class="error"><ul>';
// Because we are storing as an array we should loop through them
foreach ( $errors as $error ) {
$display .= '<li>' . $error . '</li>';
}
$display .= '</ul></div>';
// finally echo out our display
echo $display;
// add some jQuery
?>
<script>
jQuery(function($) {
$("#title").css({"border": "1px solid red"})
});
</script>
<?php
}
}
i got the solution.
/** ADD Validation for title */
function force_post_title_init()
{
wp_enqueue_script('jquery');
}
function force_post_title()
{
echo "<script type='text/javascript'>\n";
echo "
jQuery('#publish').click(function(){
var testervar = jQuery('[id^=\"titlediv\"]')
.find('#title');
if (testervar.val().length < 1)
{
jQuery('[id^=\"titlediv\"]').css('border', '1px solid red');
alert('Post title is required');
return false;
}
});
";
echo "</script>\n";
}
add_action('admin_init', 'force_post_title_init');
add_action('edit_form_advanced', 'force_post_title');
// Add this row below to get the same functionality for page creations.
add_action('edit_page_form', 'force_post_title');
May be this also help for all of you.

Resources