I would like to add a custom icon to my payment gateway. I have read the WOO gateway API and have zero help. This is my code below. please help me find a functional way to include the icon so I have an icon on my front end. Thanks
<?php if ( ! defined( 'ABSPATH' ) ) { exit; }
add_filter( 'woocommerce_payment_gateways', 'init_wpuw_gateway' );
function init_wpuw_gateway ( $methods )
{
$methods[] = 'WC_Gateway_WPUW';
return $methods;
}
if( class_exists('WC_Payment_Gateway') ):
class WC_Gateway_WPUW extends WC_Payment_Gateway {
/**
* Constructor for the gateway.
*/
public function __construct() {
$plugin_dir = plugin_dir_url(__FILE__);
$this->id = 'wpuw';
//If you want to show an image next to the gateway’s name on the frontend, enter a URL to an image.
$this->icon = apply_filters( 'woocommerce_gateway_icon', ''.$plugin_dir.'/assets/paysecure.png' );
$this->method_title = __( 'User Wallet', 'woocommerce' );
$this->method_description = __( 'Have your customers pay with their user wallet balance.', 'woocommerce' );
$this->has_fields = false;
Try with backslash instead of slash without concatenating the initial empty string with the variable $plugin_dir
$this->icon = apply_filters( 'woocommerce_gateway_icon', $plugin_dir.'\assets\paysecure.png' );
Using the WooCommerce filter woocommerce_gateway_icon you can add the icon to the payment gateway this way:
/**
* Add Custom Icon
*/
function custom_gateway_icon( $icon, $id ) {
if ( $id === 'custom' ) {
return '<img src="' . plugins_url( 'img/custom.png', __FILE__ ) . '" > ';
} else {
return $icon;
}
}
add_filter( 'woocommerce_gateway_icon', 'custom_gateway_icon', 10, 2 );
I would suggest woocommerce_available_payment_gateways filter.
/**
Add Custom Icon For Cash On Delivery
**/
function cod_gateway_icon( $gateways ) {
if ( isset( $gateways['cod'] ) ) {
$gateways['cod']->icon = get_stylesheet_directory_uri() . '/images/cod.png';
}
return $gateways;
}
add_filter( 'woocommerce_available_payment_gateways', 'cod_gateway_icon' );
try this:
$this->icon = trailingslashit( WP_PLUGIN_URL ) . plugin_basename( dirname( __FILE__ ) ) . '/assets/paysecure.png';
Related
I'm developing a plugin for custom product type. Here's my class that is being registered on plugins_loaded hook:
class WC_Product_Subscription extends WC_Product {
public function __construct( $product ) {
$this->product_type = 'subscription';
$this->purchasable = true;
$this->downloadable = false;
$this->virtual = true;
$this->sold_individually = true;
$this->manage_stock = false;
$this->supports[] = 'ajax_add_to_cart';
parent::__construct( $product );
}
public function is_purchasable() {
return true;
}
}
The problem is that I cannot see "Add to Cart" button on the product page which means my product cannot be purchased. I tried adding
public function add_to_cart_url() {
return apply_filters( 'woocommerce_product_add_to_cart_url', get_permalink( $this->get_id() ), $this );
}
public function add_to_cart_text() {
$text = $this->is_purchasable() && $this->is_in_stock() ? __( 'Add to cart', 'woocommerce' ) : __( 'Read more', 'woocommerce' );
return apply_filters( 'woocommerce_product_add_to_cart_text', $text, $this );
}
to the class but without success. I'm stuck.
It appears there are some missing steps to make your custom product type work.
Try the steps below:
#1. Make sure that your plugin is active.
#2. Make sure the product is in stock and has a price set. WooCommerce checks both of these conditions before displaying the Add to Cart button.
#3. Check if the custom product type is registered correctly. Use the following code to check:
add_action( 'init', 'check_registered_product_types' );
function check_registered_product_types() {
$product_types = wc_get_product_types();
var_dump( $product_types );
}
#4. Make sure that the WooCommerce product type is supported. Use the following code to check:
add_filter( 'product_type_selector', 'custom_product_type_selector' );
function custom_product_type_selector( $product_types ) {
var_dump( $product_types );
return $product_types;
}
#5. Make sure that the product class is correctly loaded. Use the following code to check:
add_action( 'plugins_loaded', 'check_product_class' );
function check_product_class() {
$product_class = 'WC_Product_Subscription';
var_dump( class_exists( $product_class ) );
}
#6. Ensure you have a product template for your custom product type in your theme's WooCommerce folder (e.g. single-product-subscription.php).
#7. If everything else seems to be working, you might have to override the WooCommerce templates to display the Add to Cart button.
Edit:
You can create a template in your plugin directory by using the following code:
add_filter( 'woocommerce_locate_template', 'wc_subscription_template', 10, 3 );
function wc_subscription_template( $template, $template_name, $template_path ) {
if ( 'single-product-subscription.php' === $template_name ) {
$template = untrailingslashit( plugin_dir_path( __FILE__ ) ) . '/templates/single-product-subscription.php';
}
return $template;
}
This will tell WooCommerce to use your custom template in the templates folder within your plugin directory. Make sure you put the code in a file that is included in your plugin, so it will run when the plugin is activated.
Maybe someone could give me a hand resolving this challenge.
I was looking for a solution which would allow me to add products to cart by SKU's instead of WooCommerce generated ID's as I would like to use the same products across different CMS systems.
I have stumbled upon the below code, but it seems not to be compatible anymore? Any advice?
<?php
/**
* Plugin Name: WooCommerce: Add Product to Cart by SKU
* Plugin URI: http://remicorson.com
* Description: Just a demo!
* Version: 1.0
* Author: Remi Corson
* Author URI: http://remicorson.com/
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
/**
* WC Product Add to Cart by SKU class
*/
class WC_Add_to_Cart_by_SKU {
/**
* Constructor
*/
public function __construct() {
define( 'WC_ADD_TO_CART_BY_SKU_VERSION', '1.0' );
define( 'WC_ADD_TO_CART_BY_SKU_PATH', untrailingslashit( plugin_dir_path( __FILE__ ) ) );
define( 'WC_ADD_TO_CART_BY_SKU_PLUGIN_URL', untrailingslashit( plugins_url( basename( plugin_dir_path( __FILE__ ) ), basename( __FILE__ ) ) ) );
}
/**
* get_product_id_by_product_sku()
*
* Return product ID from product SKU
*/
public function get_product_id_by_product_sku( $add_to_cart ) {
global $wpdb;
$product_id = $wpdb->get_var( $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key='_sku' AND meta_value='%s' LIMIT 1", $add_to_cart ) );
if ( $product_id ) return $product_id;
return $add_to_cart;
}
}
add_filter( 'woocommerce_add_to_cart_product_id', array( new WC_Add_to_Cart_by_SKU(), 'get_product_id_by_product_sku' ) );
Source: https://gist.github.com/corsonr/c02b46bd34a8471327bbf3adee6507c8
There is no need to use a custom SQL query, as you can use the wc_get_product_id_by_sku() WooCommerce function.
Using this function is much more lighter and effective but also takes into account products that are not in trash. Something your current code doesn't do.
So, this snippet will suffice:
function filter_woocommerce_add_to_cart_product_id( $product_id ) {
// Retrieves the post type of the current post or of a given post
if ( get_post_type( $product_id ) === 'product' ) {
return $product_id;
} else {
$sku = $product_id;
}
// Get product ID by SKU
$product_id = wc_get_product_id_by_sku( $sku );
return $product_id;
}
add_filter( 'woocommerce_add_to_cart_product_id', 'filter_woocommerce_add_to_cart_product_id', 10, 1 );
Note: SKU is assumed to be a numerical value
As you can read in the note, the above answer will only work for numerical values, to make this work for all SKU values, you can use as custom query string = /?add-to-cart-sku=THE-SKU
So you get:
function action_wp_loaded( $url = false ) {
// Make sure WC is installed and add-to-cart-sku query arg exists
if ( ! class_exists( 'WC_Form_Handler' ) || ! isset( $_REQUEST['add-to-cart-sku'] ) || ! is_string( $_REQUEST['add-to-cart-sku'] ) ) {
return;
}
// Remove WooCommerce's hook, as it's useless
remove_action( 'wp_loaded', array( 'WC_Form_Handler', 'add_to_cart_action' ), 20 );
wc_nocache_headers();
$product_id = wc_get_product_id_by_sku( wp_unslash( $_REQUEST['add-to-cart-sku'] ) );
$was_added_to_cart = false;
$adding_to_cart = wc_get_product( $product_id );
if ( ! $adding_to_cart ) {
return;
}
$add_to_cart_handler = apply_filters( 'woocommerce_add_to_cart_handler', $adding_to_cart->get_type(), $adding_to_cart );
if ( 'variable' === $add_to_cart_handler || 'variation' === $add_to_cart_handler ) {
$was_added_to_cart = woo_hack_invoke_private_method( 'WC_Form_Handler', 'add_to_cart_handler_variable', $product_id );
} elseif ( 'grouped' === $add_to_cart_handler ) {
$was_added_to_cart = woo_hack_invoke_private_method( 'WC_Form_Handler', 'add_to_cart_handler_grouped', $product_id );
} elseif ( has_action( 'woocommerce_add_to_cart_handler_' . $add_to_cart_handler ) ) {
do_action( 'woocommerce_add_to_cart_handler_' . $add_to_cart_handler, $url ); // Custom handler.
} else {
$was_added_to_cart = woo_hack_invoke_private_method( 'WC_Form_Handler', 'add_to_cart_handler_simple', $product_id );
}
// If we added the product to the cart we can now optionally do a redirect.
if ( $was_added_to_cart && 0 === wc_notice_count( 'error' ) ) {
$url = apply_filters( 'woocommerce_add_to_cart_redirect', $url, $adding_to_cart );
if ( $url ) {
wp_safe_redirect( $url );
exit;
} elseif ( 'yes' === get_option( 'woocommerce_cart_redirect_after_add' ) ) {
wp_safe_redirect( wc_get_cart_url() );
exit;
}
}
}
// Fire before the WC_Form_Handler::add_to_cart_action callback.
add_action( 'wp_loaded', 'action_wp_loaded', 15 );
/**
* Invoke class private method
*
* #since 0.1.0
*
* #param string $class_name
* #param string $methodName
*
* #return mixed
*/
function woo_hack_invoke_private_method( $class_name, $methodName ) {
if ( version_compare( phpversion(), '5.3', '<' ) ) {
throw new Exception( 'PHP version does not support ReflectionClass::setAccessible()' );
}
$args = func_get_args();
unset( $args[0], $args[1] );
$reflection = new ReflectionClass( $class_name );
$method = $reflection->getMethod( $methodName );
$method->setAccessible( true );
$args = array_merge( array( $reflection ), $args );
return call_user_func_array( array( $method, 'invoke' ), $args );
}
Based on: Allow adding multiple products to the cart via the add-to-cart query string & /includes/class-wc-form-handler.php
please try this one, i have include the filter call inside __constructor:
<?php
/**
* Plugin Name: WooCommerce: Add Product to Cart by SKU
* Plugin URI: http://remicorson.com
* Description: Just a demo!
* Version: 1.0
* Author: Remi Corson
* Author URI: http://remicorson.com/
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
/**
* WC Product Add to Cart by SKU class
*/
class WC_Add_to_Cart_by_SKU {
/**
* Constructor
*/
public function __construct() {
define( 'WC_ADD_TO_CART_BY_SKU_VERSION', '1.0' );
define( 'WC_ADD_TO_CART_BY_SKU_PATH', untrailingslashit( plugin_dir_path( __FILE__ ) ) );
define( 'WC_ADD_TO_CART_BY_SKU_PLUGIN_URL', untrailingslashit( plugins_url( basename( plugin_dir_path( __FILE__ ) ), basename( __FILE__ ) ) ) );
add_filter( 'woocommerce_add_to_cart_product_id', array(
$this,
'get_product_id_by_product_sku'
) );
}
/**
* get_product_id_by_product_sku()
*
* Return product ID from product SKU
*/
public function get_product_id_by_product_sku( $add_to_cart ) {
global $wpdb;
$product_id = $wpdb->get_var( $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key='_sku' AND meta_value='%s' LIMIT 1", $add_to_cart ) );
if ( $product_id ) {
return $product_id;
}
return $add_to_cart;
}
}
new WC_Add_to_Cart_by_SKU();
I would like to understand the sequence various classes are loaded in Wordpress.
There are many plugins available in Wordpress, then who will be loaded earlier than another.
Consider I would like to develop a plugin that will use some existing class of Woocommerce. Basically my custom plugin will extend some class of Woocommerce (for example : WC_Gateway_COD)
How I can ensure the existing class ‘WC_Gateway_COD’ is already defined & loaded before it execute the below statement ?
if (class_exists('WC_Gateway_COD')) {
class WC_my_custom_class extends WC_Gateway_COD {
…..
….
}
}
To make a custom gateway based on an existing WooCommerce payment method as COD, It's recommended to copy the source code from WC_Gateway_COD Class in a plugin (adapting the code for your needs) like:
defined( 'ABSPATH' ) or exit;
// Make sure WooCommerce is active
if ( ! in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) ) {
return;
}
add_filter( 'woocommerce_payment_gateways', 'wc_custom_add_to_gateways' );
function wc_custom_add_to_gateways( $gateways ) {
$gateways[] = 'WC_Gateway_COD2';
return $gateways;
}
add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), 'wc_gateway_custom_plugin_links' );
function wc_gateway_custom_plugin_links( $links ) {
$plugin_links = array(
'' . __( 'Configure', 'payment_cod2' ) . ''
);
return array_merge( $plugin_links, $links );
}
add_action( 'plugins_loaded', 'wc_gateway_cod2_init', 11 );
function wc_gateway_cod2_init() {
class WC_Gateway_COD2 extends WC_Payment_Gateway {
public $domain; // The text domain (optional)
/**
* Constructor for the gateway.
*/
public function __construct() {
$this->domain = 'payment_cod2'; // text domain name (for translations)
// Setup general properties.
$this->setup_properties();
// Load the settings.
$this->init_form_fields();
$this->init_settings();
// Get settings.
$this->title = $this->get_option( 'title' );
$this->description = $this->get_option( 'description' );
$this->instructions = $this->get_option( 'instructions' );
$this->enable_for_methods = $this->get_option( 'enable_for_methods', array() );
$this->enable_for_virtual = $this->get_option( 'enable_for_virtual', 'yes' ) === 'yes';
add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ) );
add_action( 'woocommerce_thankyou_' . $this->id, array( $this, 'thankyou_page' ) );
add_filter( 'woocommerce_payment_complete_order_status', array( $this, 'change_payment_complete_order_status' ), 10, 3 );
// Customer Emails.
add_action( 'woocommerce_email_before_order_table', array( $this, 'email_instructions' ), 10, 3 );
}
/**
* Setup general properties for the gateway.
*/
protected function setup_properties() {
$this->id = 'cod2';
$this->icon = apply_filters( 'woocommerce_cod2_icon', '' );
$this->method_title = __( 'Cash on delivery', 'woocommerce' );
$this->method_description = __( 'Have your customers pay with cash (or by other means) upon delivery.', 'woocommerce' );
$this->has_fields = false;
}
// and so on (the rest of the code)…
}
}
You can unset / remove original COD payment gateway changing the 1st function like:
add_filter( 'woocommerce_payment_gateways', 'wc_custom_add_to_gateways' );
function wc_custom_add_to_gateways( $gateways ) {
$gateways[] = 'WC_Gateway_COD2';
unset($gateways['WC_Gateway_COD']; // Remove COD gateway
return $gateways;
}
Well, the functionality of adding the product to the cart via ajax is 100% working, however a message below appears like this
Well, the code generated is this, automatic whenever the product is added to the cart successfully
View Cart
I want to know how you can edit this particular line
This works for me every time. Let me know if it works for you.
/**
* #snippet Edit "successfully added to your cart"
* #how-to Watch tutorial # https://businessbloomer.com/?p=19055
* #sourcecode https://businessbloomer.com/?p=494
* #author Rodolfo Melogli
* #testedwith WooCommerce 2.5.2
*/
add_filter( 'wc_add_to_cart_message', 'bbloomer_custom_add_to_cart_message' );
function bbloomer_custom_add_to_cart_message() {
global $woocommerce;
$return_to = get_permalink(woocommerce_get_page_id('shop'));
$message = sprintf('%s %s', $return_to, __('Continue Shopping', 'woocommerce'), __('Product successfully added to your cart.', 'woocommerce') );
return $message;
}
#credited to helgatheviking on her answer here
You can filter the checkout url via woocommerce_get_checkout_url
function so_37863005_checkout_url( $url ){
// Force SSL if needed
$scheme = ( is_ssl() || 'yes' === get_option( 'woocommerce_force_ssl_checkout' ) ) ? 'https' : 'http';
$url = site_url( '/custom-page/', $scheme );
return $url;
}
add_filter( 'woocommerce_get_checkout_url', 'so_37863005_checkout_url', 10, 2 );
Try this unique way
function text_view_cart_strings( $translated_text, $text, $domain ) {
switch ( $translated_text ) {
case 'View Cart' :
$translated_text = __( 'Check On Out', 'woocommerce' );
break;
}
return $translated_text;
}
add_filter( 'gettext', 'text_view_cart_strings', 20, 3 );
I am using the Wordpress plugin "Woocommerce Product Image Flipper" to flip images on hover.
It works perfectly on a product category page, but the not on the homepage.
How do I make the images flip on the homepage?
I am displaying the Homepage Template and it shows the following sections:
"New In" , "On Sale", "Bestsellers"
When I hover over them, I would like the images to flip like they do on the product category pages.
The code of the plugin is as follows:
<?php
/*
Plugin Name: WooCommerce Product Image Flipper
Plugin URI:
Version: 0.4.0
Description: Adds a secondary image on product archives that is revealed on hover. Perfect for displaying front/back shots of clothing and other products.
Author: jameskoster
Author URI:
Text Domain: woocommerce-product-image-flipper
Domain Path: /languages/
License: GNU General Public License v3.0
License URI:
*/
/**
* Check if WooCommerce is active
*/
if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) ) {
/**
* Localisation (with WPML support)
*/
add_action( 'init', 'plugin_init' );
function plugin_init() {
load_plugin_textdomain( 'woocommerce-product-image-flipper', false, dirname( plugin_basename( __FILE__ ) ) . '/languages' );
}
/**
* Image Flipper class
*/
if ( ! class_exists( 'WC_pif' ) ) {
class WC_pif {
public function __construct() {
add_action( 'wp_enqueue_scripts', array( $this, 'pif_scripts' ) );
add_action( 'woocommerce_before_shop_loop_item_title', array( $this, 'woocommerce_template_loop_second_product_thumbnail' ), 11 );
add_filter( 'post_class', array( $this, 'product_has_gallery' ) );
}
/**
* Class functions
*/
public function pif_scripts() {
if ( apply_filters( 'woocommerce_product_image_flipper_styles', true ) ) {
wp_enqueue_style( 'pif-styles', plugins_url( '/assets/css/style.css', __FILE__ ) );
}
}
public function product_has_gallery( $classes ) {
global $product;
$post_type = get_post_type( get_the_ID() );
if ( ! is_admin() ) {
if ( $post_type == 'product' ) {
$attachment_ids = $this->get_gallery_image_ids( $product );
if ( $attachment_ids ) {
$classes[] = 'pif-has-gallery';
}
}
}
return $classes;
}
/**
* Frontend functions
*/
public function woocommerce_template_loop_second_product_thumbnail() {
global $product, $woocommerce;
$attachment_ids = $this->get_gallery_image_ids( $product );
if ( $attachment_ids ) {
$attachment_ids = array_values( $attachment_ids );
$secondary_image_id = $attachment_ids['1'];
$secondary_image_alt = get_post_meta( $secondary_image_id, '_wp_attachment_image_alt', true );
$secondary_image_title = get_the_title($secondary_image_id);
echo wp_get_attachment_image(
$secondary_image_id,
'shop_catalog',
'',
array(
'class' => 'secondary-image attachment-shop-catalog wp-post-image wp-post-image--secondary',
'alt' => $secondary_image_alt,
'title' => $secondary_image_title
)
);
}
}
/**
* WooCommerce Compatibility Functions
*/
public function get_gallery_image_ids( $product ) {
if ( ! is_a( $product, 'WC_Product' ) ) {
return;
}
if ( is_callable( 'WC_Product::get_gallery_image_ids' ) ) {
return $product->get_gallery_image_ids();
} else {
return $product->get_gallery_attachment_ids();
}
}
}
$WC_pif = new WC_pif();
}
}