Add Custom Data to Woocommerce Order

add_action('woocommerce_checkout_update_order_meta',function( $order_id, $posted ) {
    $order = wc_get_order( $order_id );
    $order->update_meta_data( 'selected_date', $_COOKIE['selected_date'] );
    $order->save();
} , 10, 2);

On Checkout the Custom fields will get added.

Cannot redeclare wp_ajax_press_this_save_post() on WordPress

So today a client’s site that had its WordPress version updated (to 4.9.1) started throwing this error when they tried to use the Metaslider plugin to upload new images. Some searching confirmed this was happening to more than a few other people but I did not easily find any actual solutions by people asking who probably like me had sites that needed the functionality this presented. The error:

1
2
3
4
PHP Fatal error:
Cannot redeclare wp_ajax_press_this_save_post()
(previously declared in wp-includes/deprecated.php:3921)
in wp-admin/includes/ajax-actions.php on line 3197

Some digging later I found out the function was not just deprecated but in 4.9.1 and above moved outside of the core entirely to an optional plugin that you can download called Press This. This is part of a general clean up initiative where non-essential functionality is being slowly moved out of a more streamlined core and moved into optional plugins.

Just installing the now optional plugin is not enough to fix the issue entirely though at least for now the easiest fix I could come up with that was the least intrusive was to comment out two functions in this file:

1
wp-admin/includes/ajax-actions.php

If you use your text editor to locate the top function, which is wp_ajax_press_this_save_post() you will find the other one below it and they should look like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/**
 * Ajax handler for saving a post from Press This.
 *
 * @since 4.2.0
 */
function wp_ajax_press_this_save_post() {
      include( ABSPATH . 'wp-admin/includes/class-wp-press-this.php' );
      $wp_press_this = new WP_Press_This();
      $wp_press_this->save_post();
}
/**
 * Ajax handler for creating new category from Press This.
 *
 * @since 4.2.0
 */
function wp_ajax_press_this_add_category() {
      include( ABSPATH . 'wp-admin/includes/class-wp-press-this.php' );
      $wp_press_this = new WP_Press_This();
      $wp_press_this->add_category();
}

Now use PHP comments to just comment out both functions entirely from being declared, so then only does the deprecation/new plugin functionality take over to make them appear like below and save the file.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/**
 * Ajax handler for saving a post from Press This.
 *
 * @since 4.2.0
 */
//function wp_ajax_press_this_save_post() {
//      include( ABSPATH . 'wp-admin/includes/class-wp-press-this.php' );
//      $wp_press_this = new WP_Press_This();
//      $wp_press_this->save_post();
//}
/**
 * Ajax handler for creating new category from Press This.
 *
 * @since 4.2.0
 */
//function wp_ajax_press_this_add_category() {
//      include( ABSPATH . 'wp-admin/includes/class-wp-press-this.php' );
//      $wp_press_this = new WP_Press_This();
//      $wp_press_this->add_category();
//}

Then your all set, hopefully WordPress have picked up on this and will just take these two declarations out in the next version or two before it gets annoying.

Woocommerce Order Notifications

Send an email if there are any woocommerce orders created a before the current Day.

$wp_query = new WP_Query(
    array(
        'posts_per_page'=> -1,
        'post_type'=>'shop_order',
        'post_status'=>'wc-processing',
        // 'post_status'=>'wc-completed',
        // 'post_status'=>'wc-pending',
        // 'post_status'=>'wc-canceled',
    )
);
$message = "These orders are curently processing<br>";
$confirm_mail_send = 0;   
foreach ($wp_query->posts as $order) {
        date_default_timezone_set('Africa/Johannesburg');
        $current_date = strtotime(date('Y-m-d'));
        // echo $current_date."<br>";
        
        $post_date = $order->post_date;
        $post_date_exploded = explode(' ', $post_date);
        $post_date_for_diff = strtotime($post_date_exploded[0]);
        // echo $post_date_for_diff."<br>";

        $diff =  $current_date - $post_date_for_diff;
        // echo $diff."<br>";
        
        function secondsToTime($seconds) {
            $dtF = new \DateTime('@0');
            $dtT = new \DateTime("@$seconds");
            return $dtF->diff($dtT)->format('%a days');
        }
        // echo secondsToTime($diff);
        
        if ($diff > 1) {
            $href = 'https://tjhokopaint.co.za/wp-admin/post.php?post='.($order->ID).'&action=edit'; 
            $message .= '<a href="'.$href.'">Order: '.$order->ID.'</a> ';
            $confirm_mail_send++;
            // echo "True";
        }
}
echo $message;
if ($confirm_mail_send != 0) {
    $to = 'garth@webfootprint.co.za';
    $subject = 'Pending Orders';
    $headers = array('Content-Type: text/html; charset=UTF-8');
    wp_mail( $to, $subject, $message, $headers);
}

 

Convert Seconds to Time

function secondsToTime($seconds) {
    $dtF = new \DateTime('@0');
    $dtT = new \DateTime("@$seconds");
    return $dtF->diff($dtT)->format('%a days, %h hours, %i minutes and %s seconds');
}
echo secondsToTime(1640467);

Woocommerce add Custom Shipping Fee

Use your discretion and adjust the function as you need it. It should make sense when you read the function. It currently sets a shipping fee based on the total cost of the cart.

// ADD SHIPPING COST
function woo_add_cart_fee() {
    
    if (WC()->cart->cart_contents_total > 1000) {
        WC()->cart->add_fee( __('Shipping', 'woocommerce'), 100 );
    }else{
        WC()->cart->add_fee( __('Shipping', 'woocommerce'), 100 );
    }
}
add_action( 'woocommerce_cart_calculate_fees', 'woo_add_cart_fee' );

WP_QUERY

Calling your Query While or Foreach

While

<?php $query = new WP_Query($args); ?>
<?php while ( $query->have_posts() ) : the_post(); ?>
  <div>
      <?php 
      	$query->the_post();        
        get_template_part( 'content', get_post_format() ); 
    ?>
  </div>
<?php endwhile; ?>

Foreach

$query = new WP_Query( array( 'post_type' => 'page' ) );
$posts = $query->posts;

foreach($posts as $post) {
    // Do your stuff, e.g.
    // echo $post->post_name;
}

By Term

$args['tax_query'][] =
    array(
    'taxonomy' => 'category',
    'field' => 'slug',
    'terms' => 'category slug must go here'
  );

By Post Type

$args['post_type'] = 'courses';

By Post Status

$args['post_status'] = 'publish';

Posts Per Page

$args['posts_per_page'] = 10;

Posts By Category

$args['cat'] = $_GET['category-id'];

Start Making A WordPress Plugin From Scratch

This post requires developer discretion. The file names are written as an example for this post. As long as you make sure your files are been linked up correctly, you can name your files whatever you like. There’s loads of comments to help you along the way.
You need 2 files for this process. Unless you want to set a custom Icon then you will need 3 files.
All of these files need to be inside their own folder in order to build up your plugin.


Plugin Folder :

plugin-index.php
main-page.php
Your ICON. (Your icon dimensions must be 16×16)


plugin-index.php is your starting file. This is the file where your plugin starts. And it will contain the following.

  /*
  Plugin Name: coverweb Custom Woocommerce Extra's
  */

  // Main Menu Tabs
    // add_menu_page();
  //(Sub Menu Tabs) List of possible pages you can add from pre built wp stuff (using the below functions will add a sub menu into the matching page tab )
    // add_dashboard_page();
    // add_posts_page();
    // add_pages_page();
    // add_comments_page();
    // add_plugins_page();
    // add_users_page();
    // add_theme_page();  /*for the appearance tab*/
    // add_management_page();  /*for the tools tab*/
    // add_options_page();  /*for the settings tab*/

  function my_admin_menu() {
      //(This will aqppear in place of the browser tab name)
      	$page_title = 'Clear Stock'; 
      //(This will aqppear in place of the tab name)
      	$menu_title = 'Clear Stock'; 
      //(Capability is required to display plugin menu in admin panel)
      	$capability = 'manage_options';
      //(Menu Slug is the text that refers this plugin page. It displays as page name in URL We always CALL a plugin page by the menu slug)
        $menu_slug = 'clear-stock';
      //(This calls the function below which has been set up to include a page that is in the plugin folder.)
        $function = 'clear_stock_function';
      //(This will get the icon you upload into your plugin file, Leave blank like so '' if you don't have an ICON and you will get a default Cog Icon)
        $icon_url = plugins_url('recycle.png',__FILE__);
      //(The position is just an integer. The higher you go. The lower down the position is in the admin section of wordpress)
        $position = 56;
      add_menu_page( $page_title, $menu_title, $capability, $menu_slug, $function, $icon_url, $position);
  }
  add_action( 'admin_menu', 'my_admin_menu' );

  function clear_stock_function(){
    include ("main-page.php"); //this must be inside your plugins folder
  }

main-page.php is where you start writing your plugin content that will show up in your admin section. (Just start with the code below to get started)

<!DOCTYPE html>
<html>
<head>
  <title>Custom Plugin</title>
</head>
<body>
  <div>
    <h1>Your new plugin Is ready to start been developed.</h1>
  </div>
</body>
</html>

Your ICON : Must be 16×16.
A word of advice… make sure it’s a light icon that doesn’t disappear in the dark default wordpress dark grey colour.

Step 1 Adding a Plugin

function my_admin_menu() {
    $page_title = 'Clear Stock';
    $menu_title = 'Clear Stock';
    $capability = 'manage_options';
    $menu_slug = '/clear_stock';
    $function = 'clear_stock';
    $icon_url = '';
    $position = -1;
    add_menu_page( $page_title, $menu_title, $capability, $menu_slug, $function, $icon_url, $position);
}
add_action( 'admin_menu', 'my_admin_menu' );

PHP Dates broken down parameters

<?php 
  echo date_default_timezone_set('UTC');
  /* The terrminology for this function
    h : 12 hour format
    H : 24 hour format
    i : Minutes
    s : Seconds
    u : Microseconds
    a : Lowercasw am or pm
    l : Full text for the day
    F : Full text for the month
    j : Day of the month
    S : Suffix for the day st, nd, rd, etc
    Y : 4 digit y
    e : timezone
  */
  echo date('h:i:s:u a, l F jS Y e');
$h = 'h'; 
$H = 'H'; 
$i = 'i'; 
$s = 's'; 
$u = 'u'; 
$a = 'a'; 
$l = 'l'; 
$F = 'F'; 
$j = 'j'; 
$S = 'S'; 
$Y = 'Y'; 
$e = 'e';
echo "12 hour format : ";echo date($h); echo "<br>";
echo "24 hour format : ";echo date($H); echo "<br>";
echo "Minutes : ";echo date($i); echo "<br>";
echo "Seconds : ";echo date($s); echo "<br>";
echo "Microseconds : ";echo date($u); echo "<br>";
echo "Lowercasw am or pm : ";echo date($a); echo "<br>";
echo "Full text for the day : ";echo date($l); echo "<br>";
echo "Full text for the month : ";echo date($F); echo "<br>";
echo "Day of the month : ";echo date($j); echo "<br>";
echo "Suffix for the day st, nd, rd, etc : ";echo date($S); echo "<br>";
echo "4 digit y : ";echo date($Y); echo "<br>";
echo "timezone : ";echo date($e); echo "<br>";
?>

WordPress Update meta_value by meta_key

// Clear Stock
function clear_current_stock(){ 
// Declare the $wpdb var
    global $wpdb;
// Run My SQL Query (My Query is setting the meta value for stock to zero)
    $wpdb->query("UPDATE wp_postmeta SET meta_value = 0 WHERE meta_key = '_stock'");
// Check if there were any errors or if my query was successful.
    if ( is_wp_error( $wpdb ) ) {
         echo $wpdb->get_error_message();
    }
    else {
         echo 'true';
    }
}

Then you can call the function like this

<?php clear_current_stock(); ?>

Check User Role ( if statement included )

<?php
  $user_id = get_current_user_id();
  if (!empty($user_id)) {
  $user = wp_get_current_user();
  $role = ( array ) $user->roles;
  // echo $role[0];
  if ($role[0] == 'free-client' OR $role[0] == 'administrator') {
    //code here...
  }
  }
?>