Get Order Ids in a WooCommerce Plugin - php

Trying to update order post meta in testmain(), I can update it when I manually assign a order id, but struggling to figure out how to get order ids, where am I going wrong?
<?php
/**
* Plugin Name: MyTestPlugin
*/
defined('ABSPATH') or die('Bye');
if (in_array( 'woocommerce/woocommerce.php', apply_filters('active_plugins', get_option('active_plugins')))){
if (! wp_next_scheduled('my_test_cron')){
wp_schedule_event(time(), 'hourly', 'my_test_cron');
}
if (! class_exists('MyTest')) :
class MyTest {
public function __construct(){
add_filter('manage_edit-shop_order_columns', array($this, 'my_manage_edit_shop_order_columns'));
add_action('manage_posts_custom_column', array($this, 'my_manage_posts_custom_column'));
add_action('my_test_cron', array($this, 'testmain'));
$this->pluginPath = dirname(__FILE__);
}
public function testmain(){
// $the_id = '9001'; // <-- ORDER ID
$the_data = 'Sample Data';
update_post_meta(get_the_ID(), '_my_test', $the_data);
}
public function my_manage_edit_shop_order_columns($col_th){
return wp_parse_args(array('_my_test' => 'My Test'), $col_th);
}
public function my_manage_posts_custom_column($column_id){
if($column_id == '_my_test')
echo get_post_meta(get_the_ID(), '_my_test', true);
}
}
$MyTest = new MyTest();
endif;
}

I was going the wrong way about trying to update the meta data.
Solved.
public function testmain(){
$args = array(
'limit' => -1,
);
$orders = wc_get_orders( $args );
foreach ($orders as $order){
$order->update_meta_data('_my_test', 'Sample Data');
$order->save();
}
}

Related

trigger function in custom class on WooCommerce action

I am using the following class to have a directory created with dynamic value - based on a woo custom checkout field. Works perfect on page refresh and directory is created like expected.
just need this to only trigger/instantiate on the WooCommerce actions
woocommerce_order_status_completed
or
woocommerce_order_status_changed
or
woocommerce_thankyou_page
how can this be done so that it does not always run every time a page is loaded to decrease the load and have better efficiency in general.
here is the complete class
//add_action( 'plugins_loaded', array( 'pos__URL', 'init' )); //uncomment to trigger on page refresh
class pos__URL {
public static function init() {
$POS__sys_URL = __CLASS__;
new $POS__sys_URL;
}
public function __construct()
{
add_action('init', array($this, 'pos__URL_Field'));
}
public function pos__URL_Field()
{
//--------to access the value----start-----
$orders = wc_get_orders(array(
'customer_id' => get_current_user_id(),
'return' => 'ids',
));
//add the id of the custom meta field that lies in the order
$meta_data = array();
foreach ($orders as $order_id) {
$meta_data[$order_id] = get_post_meta($order_id, '_engx_text_field_id', true);
}
//--------to access the value----end-----
if( isset($meta_data[$order_id]) ) { //is the field set
$curdir = getcwd(); //delcare variables
if (!file_exists($meta_data[$order_id])) {
if( mkdir( $curdir . "/" . $meta_data[$order_id], 0777) ) {
//below section for for testing purposes to see if the command ran - and yes shows correctly and creates directory as expected IF the POS url is set - (triggers at the moment on page refresh)
echo "directory created"; //comment out when done testing
}else{
echo "directory NOT created"; //comment out when done testing
}
}
}else{
if( empty($meta_data[$order_id]) ) {
//do nothing
}
}
}
} //end function
I have tried the following to set the action on the inside of class but I am not doing it right and it didn't work
class pos__URL
{
public function init()
{
add_action( 'woocommerce_order_status_changed', array('pos__URL') );
}
public function __construct()
{
add_action('init', array($this, 'pos__URL_Field'));
}
public function pos__URL_Field()
{
//--------to access the value----start-----
$orders = wc_get_orders(array(
'customer_id' => get_current_user_id(),
'return' => 'ids',
));
//add the id of the custom meta field that lies in the order
$meta_data = array();
foreach ($orders as $order_id) {
$meta_data[$order_id] = get_post_meta($order_id, '_engx_text_field_id', true);
}
//--------to access the value----end-----
if( isset($meta_data[$order_id]) ) { //is the field set
$curdir = getcwd(); //delcare variables
if (!file_exists($meta_data[$order_id])) {
if( mkdir( $curdir . "/" . $meta_data[$order_id], 0777) ) {
//below section for for testing purposes to see if the command ran - and yes shows correctly and creates directory as expected IF the POS url is set - triggers at momment on page refresh
echo "directory created"; //comment out when done testing
}else{
echo "directory NOT created"; //comment out when done testing
}
}
}else{
if( empty($meta_data[$order_id]) ) {
//do nothing
}
}
}
}
You should follow the same pattern you use for the plugins_loaded but this time replace it with whatever action you want to trigger the callback for. eg:
add_action( 'woocommerce_order_status_completed', array( 'pos__URL', 'init' ));
add_action( 'woocommerce_order_status_changed', array( 'pos__URL', 'init' ));
add_action( 'woocommerce_thankyou_page', array( 'pos__URL', 'init' ));
The init function of the pos_URL class will trigger when any of the above actions occur.

Checking user role on a hooked function breaking website in WooCommerce

I am trying to add a tab to the My Account page if a specific user exists.
I created a check_user_role function that checks if a specific role exists.
If the premium_member role exists an extra tab should be added to the My Account page.
Right now when I add the check_user_role function it breaks my website.
Everything is in the functions.php file
function check_user_role($roles, $user_id = null) {
if ($user_id) $user = get_userdata($user_id);
else $user = wp_get_current_user();
if (empty($user)) return false;
foreach ($user->roles as $role) {
if (in_array($role, $roles)) {
return true;
}
}
return false;
}
// ------------------
// 1. Register new endpoint (URL) for My Account page
// Note: Re-save Permalinks or it will give 404 error
function vehicle_intake_form_endpoint() {
add_rewrite_endpoint( 'vehicle-intake-form', EP_ROOT | EP_PAGES );
}
add_action( 'init', 'vehicle_intake_form_endpoint' );
// ------------------
// 2. Add new query var
function vehicle_intake_form_query_vars( $vars ) {
$vars[] = 'vehicle-intake-form';
return $vars;
}
add_filter( 'query_vars', 'vehicle_intake_form_query_vars', 0 );
// ------------------
// 3. Insert the new endpoint into the My Account menu
if(check_user_role(array('premium_member'))) {
function vehicle_intake_form_link_my_account( $items ) {
$items['vehicle-intake-form'] = 'Vehicle Intake Form';
return $items;
}
add_filter( 'woocommerce_account_menu_items', 'vehicle_intake_form_link_my_account' );
}
// ------------------
// 4. Add content to the new tab
function vehicle_intake_form_content() {
echo '<h3>Premium WooCommerce Support</h3><p>Welcome to the WooCommerce support area. As a premium customer, you can submit a ticket should you have any WooCommerce issues with your website, snippets or customization. <i>Please contact your theme/plugin developer for theme/plugin-related support.</i></p>';
//echo do_shortcode( ' /* your shortcode here */ ' );
}
add_action( 'woocommerce_account_vehicle-intake-form_endpoint', 'vehicle_intake_form_content' );
Your If statement needs to be inside the function, never outside it.
You can use current_user_can() function, but inside your hooked function like:
add_filter( 'woocommerce_account_menu_items', 'vehicle_intake_form_link_my_account' );
function vehicle_intake_form_link_my_account( $items ) {
if( current_user_can('premium_member') ) {
$items['vehicle-intake-form'] = __('Vehicle Intake Form');
}
return $items;
}
Or use check_user_role() revisited function to be used inside your hooked function like:
function check_user_role( $roles, $user_id = null ) {
$user = $user_id ? new WP_User( $user_id ) : wp_get_current_user();
if ( is_a($user, 'WP_User') && count( array_intersect($roles, $user->roles) ) > 0 ) {
return true;
}
return false;
}
add_filter( 'woocommerce_account_menu_items', 'vehicle_intake_form_link_my_account' );
function vehicle_intake_form_link_my_account( $items ) {
if( check_user_role( array('premium_member') ) ) {
$items['vehicle-intake-form'] = __('Vehicle Intake Form');
}
return $items;
}
Code goes in functions.php file of the active child theme (or active theme). Tested and works.

Page template option not showing after update to 4.7

I've used this plugin for adding specific templates for page.
class PageTemplater {
protected $plugin_slug;
private static $instance;
protected $templates;
public static function get_instance() {
if( null == self::$instance ) {
self::$instance = new PageTemplater();
}
return self::$instance;
}
private function __construct() {
$this->templates = array();
add_filter('page_attributes_dropdown_pages_args', array($this, 'register_project_templates'));
// add_filter('wp_insert_post_data', array($this, 'register_project_templates'));
add_filter('template_include', array($this, 'view_project_template'));
$this->templates = array(
'page-json.php' => 'JSON list',
);
}
public function register_project_templates( $atts ) {
// Create the key used for the themes cache
$cache_key = 'page_templates-' . md5( get_theme_root_uri() . '/' . get_stylesheet() );
// Retrieve the cache list.
// If it doesn't exist, or it's empty prepare an array
$templates = wp_get_theme()->get_page_templates();
if ( empty( $templates ) ) {
$templates = array();
}
// New cache, therefore remove the old one
wp_cache_delete( $cache_key , 'themes');
// Now add our template to the list of templates by merging our templates
// with the existing templates array from the cache.
$templates = array_merge( $templates, $this->templates );
// Add the modified cache to allow WordPress to pick it up for listing
// available templates
wp_cache_add( $cache_key, $templates, 'themes', 1800 );
return $atts;
}
/**
* Checks if the template is assigned to the page
*/
public function view_project_template( $template ) {
global $post;
if (!isset($this->templates[get_post_meta( $post->ID, '_wp_page_template', true)])) {
}
$file = plugin_dir_path(__FILE__) . get_post_meta($post->ID, '_wp_page_template', true);
// Just to be safe, we check if the file exists first
if (file_exists($file)) {
return $file;
} else {
echo $file;
}
return $template;
}
}
add_action( 'plugins_loaded', array( 'PageTemplater', 'get_instance' ) );
But when I've have updated a WordPress to 4.7 page template options had stopped to show. Maybe I use some deprecated functions?
Please help.
Fixed code:
// Add a filter to the attributes metabox to inject template into the cache.
if ( version_compare( floatval( get_bloginfo( 'version' ) ), '4.7', '<' ) ) {
// 4.6 and older
add_filter(
'page_attributes_dropdown_pages_args',
array( $this, 'register_project_templates' )
);
} else {
// Add a filter to the wp 4.7 version attributes metabox
add_filter(
'theme_page_templates', array( $this, 'add_new_template' )
);
}
/**
* Adds our template to the page dropdown for v4.7+
*
*/
public function add_new_template( $posts_templates ) {
$posts_templates = array_merge( $posts_templates, $this->templates );
return $posts_templates;
}
source: http://www.wpexplorer.com/wordpress-page-templates-plugin/

How save product id of 1st item added to cart in woocommerce for a visitor in empty cart page?

I am trying to display the product id which is added to cart at first in empty cart page(cart-empty.php). Can anyone please help me with any solution.
Here is my code I have tried for cart-totals.php page..which save both product slug and its parent slug which is added at last to the cart.
$items = $woocommerce->cart->get_cart();
foreach($_SESSION['items'] as $item => $values) {
$_product = $values['data']->post;
$cartproductid = $_product->ID;
}
$product_cats = wp_get_post_terms( $cartproductid, 'product_cat' );
$url=$product_cats[0]->slug;
$parenturl=$product_cats[0]->parent;
$terms = get_the_terms($cartproductid, "product_cat");
$cat = get_term_by("id", $parenturl, "product_cat");
$newurl = $cat->slug;
This code displays a message whenever a user removes an item from their cart. It may not be exactly what you want but it gives you something to start off with. Add this code to your theme functions.php or custom plugin code:
function this_function( $title , $cart_item){
wc_add_notice( 'Visit deleted product ' . $title . '' );
return $title;
}
add_filter( 'woocommerce_cart_item_removed_title', 'this_function', 10, 2 );
EDIT - More accurate solution: This code displays a message on the empty cart page with a link to the last deleted product. It works for users who are logged in. If you want the code to work for non-logged in visitors you'll need to modify this to use cookies.
class empty_cart
{
public $last_product;
protected static $_instance = null;
public static function instance() {
if ( is_null( self::$_instance ) ) {
self::$_instance = new self();
}
return self::$_instance;
}
function __construct()
{
add_filter( 'woocommerce_cart_item_removed_title', array($this, 'product_removed'), 10, 2 );
add_action( 'woocommerce_cart_is_empty', array($this, 'cart_is_empty'));
}
function product_removed( $title , $cart_item){
update_user_meta( get_current_user_id(), 'last_removed_product', $cart_item['product_id']);
$this->last_product = $cart_item['product_id'];
return $title;
}
function cart_is_empty(){
$last_product = $this->get_last_product();
echo 'Visit deleted product ' . get_the_title( $last_product ) . '';
}
function get_last_product(){
if( isset($this->last_product) )
return $this->last_product;
else
return get_user_meta( get_current_user_id(), 'last_removed_product',true );
}
}
function empty_cart() {
return empty_cart::instance();
}
empty_cart();

WooCommerce Webhooks Custom/Action not saving

Every time you try and set a custom/action topic within webhooks (from WooCommerce > Settings > Webhooks) it would unset it as soon as you update your changes to the webhook. In other words, it will undo your custom topic and return it back to 'Select an option' for the topic dropdown.
Any help at all is appreciated. Thank you very much!
edit: In addition to my comment below, I've also attempted to create my own custom topic via the following filter woocommerce_webhook_topic_hooks, however, it doesn't show within the dropdown list as an option.
The below code runs from functions.php as with any WordPress hook..
Code
function custom_woocommerce_webhook_topics( $topic ) {
$topic['order.refunded'] = array(
'woocommerce_process_shop_order_meta',
'woocommerce_api_edit_order',
'woocommerce_order_edit_status',
'woocommerce_order_status_changed'
);
return $topic;
}
add_filter( 'woocommerce_webhook_topic_hooks', 'custom_woocommerce_webhook_topics', 10, 1 );
edit 2: Added more context
I was having the same issue. Selecting any of the built-in topics worked fine. But selection Action and entering any WooCommerce Subscription actions kept reverting. I had also tried creating a new custom topic in the same file (wp-content/plugins/woocommerce-subscriptions/includes/class-wcs-webhooks.php) that the built-in topics are created, mirroring 1:1 the code of one of the topics that 'stick' (e.g subscription.created) for a new 'subscription.paymentcomplete' topic. It appears in the drop down, but after saving the drop-down reverts to the default 'Selection an option...'.
//wp-content/plugins/woocommerce-subscriptions/includes/class-wcs-webhooks.php
public static function init() {
...
add_action( 'woocommerce_subscription_created_for_order', __CLASS__ . '::add_subscription_created_callback', 10, 2 );
add_action( 'woocommerce_subscription_payment_complete', __CLASS__ . '::add_subscription_payment_complete_callback', 10, );
...
}
public static function add_topics( $topic_hooks, $webhook ) {
if ( 'subscription' == $webhook->get_resource() ) {
$topic_hooks = apply_filters( 'woocommerce_subscriptions_webhook_topics', array(
'subscription.created' => array(
'wcs_api_subscription_created',
'wcs_webhook_subscription_created',
'woocommerce_process_shop_subscription_meta',
),
'subscription.paymentcomplete' => array(
'wcs_webhook_subscription_payment_complete'
'woocommerce_process_shop_subscription_meta',
),
...
), $webhook );
}
return $topic_hooks;
}
public static function add_topics_admin_menu( $topics ) {
$front_end_topics = array(
'subscription.created' => __( ' Subscription Created', 'woocommerce-subscriptions' ),
'subscription.paymentcomplete' => __( ' Subscription Payment Complete', 'woocommerce-subscriptions' ),
...
);
return array_merge( $topics, $front_end_topics );
}
public static function add_subscription_created_callback( $order, $subscription ) {
do_action( 'wcs_webhook_subscription_created', $subscription->id );
}
public static function add_subscription_payment_complete_callback( $order, $subscription ) {
do_action( 'wcs_webhook_subscription_payment_complete', $subscription->id );
}
The solution was:
add_filter( 'woocommerce_valid_webhook_events', __CLASS__ . '::add_event', 10, 1 );
public static function add_event( $events) {
$events[] = 'paymentcomplete';
return $events;
}

Categories