How to create simple Offline payment gateway for WooCommerce? - php

Good afternoon, I want to make simple copy of Cash on Delivery (COD) payment method in my store and rename it to Coupon on Delivery.
How to implement it?
Up
I have tried this code, but it shows error 500 on WC settings page:
<?php
/**
* Plugin Name: My New WooCommerce Gateway
* Plugin URI:
* Description: WooCommerce gateway to ....
* Author: .....
* Version: 1.0
* Author URI: https://example.org/
* Text Domain: woocommerce-my-gateway
* Domain Path: /languages/
*/
add_action( 'plugins_loaded', 'init_my_gateway_class' );
function init_my_gateway_class() {
if ( !class_exists( 'WooCommerce' ) ) return;
class WC_Gateway_COD_Renamed extends WC_Payment_Gateway {
}
}
function add_my_gateway_class( $methods ) {
$methods[] = 'WC_Gateway_my_gateway';
return $methods;
}
add_filter( 'woocommerce_payment_gateways', 'add_my_gateway_class' );
function my_load_textdomain(){
load_plugin_textdomain( 'woocommerce-my-gateway', false, dirname( plugin_dir_path( __FILE__ ) . '/languages/' ) );
}
add_action('plugins_loaded', 'my_load_textdomain');
Source of code

In your main plugin file you can include the class and filter the gateways at the same time:
function add_my_gateway_class( $methods ) {
include( 'class-wc-gateway-cod-renamed.php');
$methods[] = 'WC_Gateway_COD_Renamed';
return $methods;
}
add_filter( 'woocommerce_payment_gateways', 'add_my_gateway_class' );
There's no real need to check if WooCommerce is active this way as woocommerce_payment_gateways only exists if WooCommerce is running.
Then in another file called class-wc-gateway-cod-renamed.php you can define your class:
class WC_Gateway_COD_Renamed extends WC_Gateway_COD {
/**
* Setup general properties for the gateway.
*/
protected function setup_properties() {
$this->id = 'coupon-on-delivery';
$this->icon = apply_filters( 'woocommerce_coupon-on-deliver_icon', '' );
$this->method_title = __( 'Coupon on delivery', 'your-plugin' );
$this->method_description = __( 'Have your customers pay with a coupon upon delivery.', 'your-plugin' );
$this->has_fields = false;
}
/**
* Initialise Gateway Settings Form Fields.
*/
public function init_form_fields() {
$shipping_methods = array();
foreach ( WC()->shipping()->load_shipping_methods() as $method ) {
$shipping_methods[ $method->id ] = $method->get_method_title();
}
$this->form_fields = array(
'enabled' => array(
'title' => __( 'Enable/Disable', 'your-plugin' ),
'label' => __( 'Enable coupon on delivery', 'your-plugin' ),
'type' => 'checkbox',
'description' => '',
'default' => 'no',
),
'title' => array(
'title' => __( 'Title', 'your-plugin' ),
'type' => 'text',
'description' => __( 'Payment method description that the customer will see on your checkout.', 'your-plugin' ),
'default' => __( 'coupon on delivery', 'your-plugin' ),
'desc_tip' => true,
),
'description' => array(
'title' => __( 'Description', 'your-plugin' ),
'type' => 'textarea',
'description' => __( 'Payment method description that the customer will see on your website.', 'your-plugin' ),
'default' => __( 'Pay with coupon upon delivery.', 'your-plugin' ),
'desc_tip' => true,
),
'instructions' => array(
'title' => __( 'Instructions', 'your-plugin' ),
'type' => 'textarea',
'description' => __( 'Instructions that will be added to the thank you page.', 'your-plugin' ),
'default' => __( 'Pay with coupon upon delivery.', 'your-plugin' ),
'desc_tip' => true,
),
'enable_for_methods' => array(
'title' => __( 'Enable for shipping methods', 'your-plugin' ),
'type' => 'multiselect',
'class' => 'wc-enhanced-select',
'css' => 'width: 400px;',
'default' => '',
'description' => __( 'If coupon upon delivery is only available for certain methods, set it up here. Leave blank to enable for all methods.', 'your-plugin' ),
'options' => $shipping_methods,
'desc_tip' => true,
'custom_attributes' => array(
'data-placeholder' => __( 'Select shipping methods', 'your-plugin' ),
),
),
'enable_for_virtual' => array(
'title' => __( 'Accept for virtual orders', 'your-plugin' ),
'label' => __( 'Accept coupon if the order is virtual', 'your-plugin' ),
'type' => 'checkbox',
'default' => 'yes',
),
);
}
}
Extend the WC_Gateway_COD class so that you can inherit methods from it and only override the methods that have to do with the naming of things.

In WooCommerce plugin, you can enable payment gateway COD from admin section:
Admin >> WooCommerce >> Settings >> Checkout >> Cash on delivery.
Check option for enable COD.
Please refer below link for create offline payment gateway.
How to Create A WooCommerce Payment gateway

Related

Saving Woocommerce Payment Gateway settings on a custom admin page

I'm trying to create a custom admin page which has Woocommerce Stripe Payment gateway options. Specifically just the Stripe API keys related fields. Reason for this is I need to limit access to Woocommerce settings pages and only want to expose very few things, so bringing just the few things to a custom page seems like the simplest thing.
However, this has been trickier than I expected. I've been trying to do this through extending WC_Payment_Gateway class, but this now seems like the wrong idea. Since I don't think I can extend a specific Gateway's class? I would basically need to rewrite the Stripe plugin I guess.
Also thinking there must be an easier way. Has anyone done this before?
Is it possible to create a settings forms with Woocommerce Settings API outside of the normal WC settings page?
Using this method, I didn't actually even get the form to print out, just the fields (i.e. no Submit button).
class WoocommerceStripeInt extends WC_Payment_Gateway
{
public function __construct () {
$this->id = 'stripe';
$this->method_title = __( 'Stripe', 'woocommerce-gateway-stripe' );
/* translators: 1) link to Stripe register page 2) link to Stripe api keys page */
$this->method_description = __( 'Stripe works by adding payment fields on the checkout and then sending the details to Stripe for verification.', 'woocommerce-gateway-stripe' );
$this->has_fields = true;
// Load the settings fields.
$this->init_form_fields();
// Load the settings.
$this->init_settings();
// Get setting values.
$this->title = $this->get_option( 'title' );
$this->description = $this->get_option( 'description' );
$this->instructions = $this->get_option( 'instructions' );
$this->order_status = $this->get_option( 'testmode' );
add_action('woocommerce_update_options_payment_gateways', array(&$this, 'process_admin_options'));
}
/**
* Initialise Gateway Settings Form Fields
*/
function init_form_fields() {
$this->form_fields = apply_filters(
'wc_stripe_settings', array(
'testmode' => [
'title' => __( 'Test mode', 'woocommerce-gateway-stripe' ),
'label' => __( 'Enable Test Mode', 'woocommerce-gateway-stripe' ),
'type' => 'checkbox',
'description' => __( 'Place the payment gateway in test mode using test API keys.', 'woocommerce-gateway-stripe' ),
'default' => 'yes',
'desc_tip' => true,
],
'test_publishable_key' => [
'title' => __( 'Test Publishable Key', 'woocommerce-gateway-stripe' ),
'type' => 'text',
'description' => __( 'Get your API keys from your stripe account. Invalid values will be rejected. Only values starting with "pk_test_" will be saved.', 'woocommerce-gateway-stripe' ),
'default' => '',
'desc_tip' => true,
],
'test_secret_key' => [
'title' => __( 'Test Secret Key', 'woocommerce-gateway-stripe' ),
'type' => 'password',
'description' => __( 'Get your API keys from your stripe account. Invalid values will be rejected. Only values starting with "sk_test_" or "rk_test_" will be saved.', 'woocommerce-gateway-stripe' ),
'default' => '',
'desc_tip' => true,
],
'publishable_key' => [
'title' => __( 'Live Publishable Key', 'woocommerce-gateway-stripe' ),
'type' => 'text',
'description' => __( 'Get your API keys from your stripe account. Invalid values will be rejected. Only values starting with "pk_live_" will be saved.', 'woocommerce-gateway-stripe' ),
'default' => '',
'desc_tip' => true,
],
'secret_key' => [
'title' => __( 'Live Secret Key', 'woocommerce-gateway-stripe' ),
'type' => 'password',
'description' => __( 'Get your API keys from your stripe account. Invalid values will be rejected. Only values starting with "sk_live_" or "rk_live_" will be saved.', 'woocommerce-gateway-stripe' ),
'default' => '',
'desc_tip' => true,
],
)
);
}
function admin_options() {
?>
<h2><?php _e('Stripe Settings','woocommerce'); ?></h2>
<table class="form-table">
<?php $this->generate_settings_html(); ?>
</table> <?php
}
}
Any help would be appreciated, thanks.

Custom WooCommerce Shipping Method

I have this working code which generating and saving properly a custom shipping method under woocommerce setting > shipping zones.
My problem is that I can't make the shipping method show on the checkout page.
Any help on how to resolve this issue and maybe extend the code a bit would be greatly appreciated.
add_filter('woocommerce_shipping_methods', 'add_local_shipping');
function add_local_shipping($methods) {
$methods['local_shipping'] = 'Local_Shipping_Method';
return $methods;
}
class Local_Shipping_Method extends WC_Shipping_Method {
public function __construct($instance_id = 0) {
$this->id = 'local_shipping';
$this->instance_id = absint($instance_id);
$this->domain = 'local_shipping';
$this->method_title = __('Pickup', $this->domain);
$this->method_description = __('Pickup Location for WooCommerce', $this->domain);
$this->title = __('Pickup Location', $this->domain);
$this->supports = array(
'shipping-zones',
'instance-settings',
'instance-settings-modal',
);
$this->instance_form_fields = array(
'enabled' => array(
'title' => __( 'Enable/Disable' ),
'type' => 'checkbox',
'label' => __( 'Enable this shipping method' ),
'default' => 'yes',
),
'title' => array(
'title' => __( 'Method Title' ),
'type' => 'text',
'description' => __( 'This controls the title which the user sees during checkout.' ),
'default' => __( 'Pickup Location' ),
'desc_tip' => true
),
'tax_status' => array(
'title' => __( 'Tax status', 'woocommerce' ),
'type' => 'select',
'class' => 'wc-enhanced-select',
'default' => 'taxable',
'options' => array(
'taxable' => __( 'Taxable', 'woocommerce' ),
'none' => _x( 'None', 'Tax status', 'woocommerce' ),
),
),
'cost' => array(
'title' => __( 'Cost', 'woocommerce' ),
'type' => 'text',
'placeholder' => '0',
'description' => __( 'Optional cost for pickup.', 'woocommerce' ),
'default' => '',
'desc_tip' => true,
),
);
$this->enabled = $this->get_option( 'enabled' );
$this->title = __('Pickup Location', $this->domain);
add_action('woocommerce_update_options_shipping_' . $this->id, array($this, 'process_admin_options'));
}
public function calculate_shipping( $package = array() ) {
$this->add_rate( array(
'id' => $this->id . $this->instance_id,
'label' => $this->title,
'cost' => 0,
) );
}
}
The way you have tried it is wrong. And it's not recommended to keep the text domain in a variable or a method.
To Create a Custom Shipping Method You have to follow these steps I have corrected on your code.
Hope this helps. You can learn more about how to create new shipping method here. Feel free
// To initialize your new shipping method you have to keep it in function
function local_shipping_init() {
if ( ! class_exists( Local_Shipping_Method ) ) {
class Local_Shipping_Method extends WC_Shipping_Method {
public function __construct( $instance_id = 0 ) {
$this->id = 'local_shipping';
$this->instance_id = absint( $instance_id );
$this->method_title = __( 'Pickup', 'text-domain' );
$this->method_description = __( 'Pickup Location for WooCommerce', 'text-domain' );
$this->title = __( 'Pickup Location', 'text-domain' );
$this->supports = array(
'shipping-zones',
'instance-settings',
'instance-settings-modal',
);
// then you have to call this method to initiate your settings
$this->init();
}
public function init() {
// this method used to initiate your fields on settings
$this->init_form_fields();
// this is settings instance where you can declar your settings field
$this->init_instance_settings();
// user defined values goes here, not in construct
$this->enabled = $this->get_option( 'enabled' );
$this->title = __( 'Pickup Location', 'text-domain' );
// call this action in init() method to save your settings at the backend
add_action( 'woocommerce_update_options_shipping_' . $this->id, array( $this, 'process_admin_options' ) );
}
public function init_instance_settings() {
// you have to keep all the instance settings field inside the init_instance_settings method
$this->instance_form_fields = array(
'enabled' => array(
'title' => __( 'Enable/Disable' ),
'type' => 'checkbox',
'label' => __( 'Enable this shipping method' ),
'default' => 'yes',
),
'title' => array(
'title' => __( 'Method Title' ),
'type' => 'text',
'description' => __( 'This controls the title which the user sees during checkout.' ),
'default' => __( 'Pickup Location' ),
'desc_tip' => true
),
'tax_status' => array(
'title' => __( 'Tax status', 'woocommerce' ),
'type' => 'select',
'class' => 'wc-enhanced-select',
'default' => 'taxable',
'options' => array(
'taxable' => __( 'Taxable', 'woocommerce' ),
'none' => _x( 'None', 'Tax status', 'woocommerce' ),
),
),
'cost' => array(
'title' => __( 'Cost', 'woocommerce' ),
'type' => 'text',
'placeholder' => '0',
'description' => __( 'Optional cost for pickup.', 'woocommerce' ),
'default' => '',
'desc_tip' => true,
),
);
}
public function calculate_shipping( $package = array() ) {
$this->add_rate( array(
'id' => $this->id, // you should define only your shipping method id here
'label' => $this->title,
'cost' => 0,
) );
}
}
}
}
add_action( 'woocommerce_shipping_init', 'local_shipping_init' ); // use this hook to initialize your new custom method
function add_local_shipping( $methods ) {
$methods['local_shipping'] = 'Local_Shipping_Method';
return $methods;
}
add_filter( 'woocommerce_shipping_methods', 'add_local_shipping' );
The code is tested and works fine. See the screenshot below.

Changing the array description text without editing plugin's core files with a filter function in wordpress

I have checked many questions from this forum about this solution, but I could not get it at all. I'm learning how to overwrite some text from existing array in plugin without editing it's core files so I will not loose my changes when the core plugin is updated in wordpress.
What I have is this code right from the plugin. There is one string which I can not translate from po.edit. Please get that I'm just learning this solution so I do not know how to really get it at all so that's why I'm asking for your advice.
Core code
/**
* Initialize integration settings form fields.
*
* #return void
*/
public function init_form_fields() {
$this->form_fields = array(
'authorization' => array(
'title' => __( 'Authorization', 'woocommerce-bookings' ),
'type' => 'google_calendar_authorization',
),
'testing' => array(
'title' => __( 'Connect with a custom Google Calendar App', 'woocommerce-bookings' ),
'type' => 'title',
'description' => 'Enter the credentials below to use a custom Google Calendar API app. Disconnect existing connection to enter credentials.',
),
'client_id' => array(
'title' => __( 'Client ID', 'woocommerce-bookings' ),
'type' => 'text',
'description' => __( 'Enter the Google Client ID associated with your Calendar API app.', 'woocommerce-bookings' ),
'disabled' => $this->is_using_wooconnect_method(),
'desc_tip' => true,
'default' => '',
),
'client_secret' => array(
'title' => __( 'Client Secret', 'woocommerce-bookings' ),
'type' => 'text',
'description' => __( 'Enter the Google Client Secret associated with your Calendar API app.', 'woocommerce-bookings' ),
'disabled' => $this->is_using_wooconnect_method(),
'desc_tip' => true,
'default' => '',
),
'custom_authorization' => array(
'title' => __( 'Authorization', 'woocommerce-bookings' ),
'type' => 'custom_google_calendar_authorization',
),
'calendar_connection_settings' => array(
'title' => __( 'Connected Calendar Settings', 'woocommerce-bookings' ),
'type' => 'title',
'display_check' => array( $this, 'display_connection_settings' ),
),
'calendar_id' => array(
'title' => __( 'Calendar', 'woocommerce-bookings' ),
'type' => 'select',
'description' => __( 'Select your Calendar.', 'woocommerce-bookings' ),
'desc_tip' => true,
'default' => '',
'options' => $this->get_calendar_list_options(),
'display_check' => array( $this, 'display_connection_settings' ),
),
'sync_preference' => array(
'type' => 'select',
'title' => __( 'Sync Preference', 'woocommerce-bookings' ),
'options' => array(
'both_ways' => __( 'Sync both ways - between Store and Google', 'woocommerce-bookings' ),
'one_way' => __( 'Sync one way - from Store to Google', 'woocommerce-bookings' ),
),
'description' => __( 'Manage the sync flow between your Store calendar and Google calendar.', 'woocommerce-bookings' ),
'desc_tip' => true,
'default' => 'one_way',
'display_check' => array( $this, 'display_connection_settings' ),
),
'debug' => array(
'title' => __( 'Debug Log', 'woocommerce-bookings' ),
'type' => 'checkbox',
'label' => __( 'Enable logging', 'woocommerce-bookings' ),
'default' => 'no',
/* translators: 1: log file path */
'description' => sprintf( __( 'Log Google Calendar events, such as API requests, inside %s', 'woocommerce-bookings' ), '<code>woocommerce/logs/' . $this->id . '-' . sanitize_file_name( wp_hash( $this->id ) ) . '.txt</code>' ),
),
);
}
/**
* Generate Settings HTML.
*
* Extends base class html generation to add 'display_check' parameter to each
* field. 'display_check', is a callable that enables/disables the display of
* the field.
*
* #param array $form_fields (default: array()) Array of form fields.
* #param bool $echo Echo or return.
* #return string the html for the settings
* #since 1.15.0
*/
public function generate_settings_html( $form_fields = array(), $echo = true ) {
if ( empty( $form_fields ) ) {
$form_fields = $this->get_form_fields();
}
foreach ( $form_fields as $index => $field ) {
// Delete fields if they have an "enable_check" function that returns false.
if ( isset( $field['display_check'] ) && ! call_user_func( $field['display_check'] ) ) {
unset( $form_fields[ $index ] );
}
}
return parent::generate_settings_html( $form_fields, $echo );
}
Now there is a testing array in the core code where I need to change its description
'testing' => array(
'title' => __( 'Connect with a custom Google Calendar App', 'woocommerce-bookings' ),
'type' => 'title',
'description' => 'Enter the credentials below to use a custom Google Calendar API app. Disconnect existing connection to enter credentials.',
),
I have tried this but I think its not the right solution for my problem because I can not get it work.
add_filter( 'init_form_fields', 'replace_text', 11, 2 );
function replace_text( $form_fields ) {
$form_fields = array(
'testing'=> array(
'title'=> __( 'Connect with a custom Google Calendar App', 'woocommerce-bookings' ),
'type'=> 'title',
'description' => 'New description',
),
);
return $form_fields;
}
Could you please help me to find a right solution. Thank you

How to add iframe payment gateway in woocommerce?

I am trying to add another WooCommerce payment method called xxxx Bank Gateway on checkout page and when selected, this payment method will load an iframe like below (the iframe will redirect to the banks site lets call it $url).
How can I declare the content that will be displayed below the Checkout option?
//Frontend:
<input id="payment_method_xxxx" type="radio" class="input-radio" name="payment_method" value="xxxx" data-order_button_text="">
<label for="payment_method_xxx">
xxx Payment </label>
Here is my code so far:
<?php
/*
Plugin Name: xxxxxxx WooCommerce Payment Gateway
Plugin URI: http://www.xxxxxxx.com/
Description: xxxxxxx enables merchants to authorize, settle and manage credit card and electronic check transactions via Web sites, retail stores, mail order/telephone order (MOTO) call centers and mobile devices.
Version: 1.0.0
*/
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
/*
* This action hook registers our PHP class as a WooCommerce payment gateway
*/
add_filter( 'woocommerce_payment_gateways', 'xxxxxxx_add_gateway_class' );
function xxxxxxx_add_gateway_class( $gateways ) {
$gateways[] = 'WC_xxxxxxx_Gateway'; // your class name is here
return $gateways;
}
/*
* The class itself, please note that it is inside plugins_loaded action hook
*/
add_action( 'plugins_loaded', 'xxxxxxx_init_gateway_class' );
function xxxxxxx_init_gateway_class() {
class WC_xxxxxxx_Gateway extends WC_Payment_Gateway {
/**
* Constructor
*/
public function __construct() {
// global ID
$this->id = 'xxxxxxx'; // payment gateway plugin ID
$this->icon = ''; // URL of the icon that will be displayed on checkout page near your gateway name
$this->has_fields = true; // in case you need a custom credit card form
// Show Title
$this->method_title = 'xxxxxxx Gateway';
// Show Description
$this->method_description = 'Description of xxxxxxx payment gateway'; // will be displayed on the options page
// setting defines
$this->init_form_fields();
$this->init_settings();
$this->title = $this->get_option( 'title' );
// further check of SSL if you want
//add_action( 'admin_notices', array( $this, 'do_ssl_check' ) );
// This action hook saves the settings
add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ));
}
public function init_form_fields(){
$this->form_fields = array(
'enabled' => array(
'title' => 'Enable/Disable',
'label' => 'Enable Epcipay Gateway',
'type' => 'checkbox',
'description' => '',
'default' => 'no'
),
'title' => array(
'title' => __( 'Title', 'woocommerce' ),
'type' => 'text',
'description' => __( 'This controls the title which the user sees during checkout.', 'woocommerce' ),
'default' => __( 'xxxxxxx Payment', 'woocommerce' ),
'desc_tip' => true,
),
'description' => array(
'title' => __( 'Description', 'woocommerce' ),
'type' => 'textarea',
'default' => ''
),
'terminal_id' => array(
'title' => 'Terminal Id',
'type' => 'text'
),
'api_key' => array(
'title' => 'API Key',
'type' => 'password',
),
'password' => array(
'title' => 'Password',
'type' => 'text'
),
'pageid' => array(
'title' => 'Page Id',
'type' => 'text'
)
);
}
public function payment_fields() {
//how to add script tag to show the hosted checkout
// credit card form loaded from third party server -- Iframe
}
}

WordPress - Custom Post type, Custom role, Custom Capability

I am stuck in a problem assigning custom capability with custom post type to a custom role.
The issue is i want to remove the Add New ( Not with a CSS hack or by unsetting menu item ) option of my custom post type. I have already come across answers that suggest many solutions but none of them works perfectly.
Closest to what i want is this :
register_post_type( 'custom_post_type_name', array(
'capability_type' => 'post',
'capabilities' => array(
'create_posts' => 'do_not_allow', // false < WP 4.5, credit #Ewout
),
'map_meta_cap' => true, // Set to `false`, if users are not allowed to edit/delete existing posts
));
This code removes the Add New link but it assigns the default post slug for capabilities.Notice line 2 of above code. If i change it to my custom post type slug, it stops working and i can't even go posts page.
One thing to keep in mind is that i am working with custom role, which has only read capability by default.
If i also assign the edit_posts capability then my objective is achieved, but then user can also access posts and comments, which i do not want.
Woocommerce is doing this. I dive into woocommerce code and add this line where it registers its products and orders.
'capabilities' => array( 'create_posts' => 'do_not_allow' ),
And everything works as i want. I have explored woocommerce code all day but can't find how it is doing this. Can someone else help me out on this with another pair of eyes ? :)
Much appreciated. Thanks..
I already mention to you that give us little more details about the plan that you want to do?
Here is the solution that I think it would be helpful for you.
If you want to used map_meta_cap => true then you will need to change capability_type as well with your own type, see more https://codex.wordpress.org/Function_Reference/register_post_type#capability_type
But if you set your own capability_type value then you will need to add capability to users role those you want to add.
here is a complete example.
if ( !class_exists( 'WPSE64458_CPT_Register' ) ) {
class WPSE64458_CPT_Register {
function __construct() {
add_action( 'init', array( $this, 'wpse64458_register_post_types' ), 5 );
add_action( 'admin_init', array( $this, 'wpse64458_add_caps' ), 5 );
add_filter( 'register_post_type_args', array( $this, 'wpse64458_modify_cpt_registry' ) , 10, 2 );
}
/**
* Register core post types.
*/
public function wpse64458_register_post_types() {
if ( ! is_blog_installed() || post_type_exists( 'member' ) ) {
return;
}
register_post_type( 'member',
apply_filters( 'wpse64458_callb_post_type_member',
array(
'labels' => array(
'name' => __( 'Members', 'domaintext' ),
'singular_name' => __( 'Member', 'domaintext' ),
'all_items' => __( 'All Members', 'domaintext' ),
'menu_name' => _x( 'Members', 'Admin menu name', 'domaintext' ),
'add_new' => __( 'Add New', 'domaintext' ),
'add_new_item' => __( 'Add new member', 'domaintext' ),
'edit' => __( 'Edit', 'domaintext' ),
'edit_item' => __( 'Edit member', 'domaintext' ),
'new_item' => __( 'New member', 'domaintext' ),
'view' => __( 'View member', 'domaintext' ),
'view_item' => __( 'View member', 'domaintext' ),
'search_items' => __( 'Search members', 'domaintext' ),
'not_found' => __( 'No members found', 'domaintext' ),
'not_found_in_trash' => __( 'No members found in trash', 'domaintext' ),
'parent' => __( 'Parent member', 'domaintext' ),
'featured_image' => __( 'Member image', 'domaintext' ),
'set_featured_image' => __( 'Set member image', 'domaintext' ),
'remove_featured_image' => __( 'Remove member image', 'domaintext' ),
'use_featured_image' => __( 'Use as member image', 'domaintext' ),
'insert_into_item' => __( 'Insert into member', 'domaintext' ),
'uploaded_to_this_item' => __( 'Uploaded to this member', 'domaintext' ),
'filter_items_list' => __( 'Filter members', 'domaintext' ),
'items_list_navigation' => __( 'Members navigation', 'domaintext' ),
'items_list' => __( 'Members list', 'domaintext' ),
),
'public' => true,
'show_ui' => true,
'capability_type' => 'member',
'map_meta_cap' => true,
'menu_icon' => 'dashicons-groups',
'publicly_queryable' => true,
'exclude_from_search' => false,
'hierarchical' => false, // Hierarchical causes memory issues - WP loads all records!
'rewrite' => array( 'slug' => 'member' ),
'query_var' => true,
'supports' => array( 'title', 'editor', 'thumbnail', 'excerpt' ),
'has_archive' => 'members',
'show_in_nav_menus' => true,
'show_in_rest' => true,
)
)
);
} // end of wpse64458_register_post_types
/**
* Get capabilities.
*
* #return array
*/
private function wpse64458_set_caps() {
$capabilities = array();
$capability_types = array( 'member' );
foreach ( $capability_types as $capability_type ) {
$capabilities[ $capability_type ] = array(
// Post type
"edit_{$capability_type}",
"read_{$capability_type}",
"delete_{$capability_type}",
"edit_{$capability_type}s",
"edit_others_{$capability_type}s",
"publish_{$capability_type}s",
"read_private_{$capability_type}s",
"delete_{$capability_type}s",
"delete_private_{$capability_type}s",
"delete_published_{$capability_type}s",
"delete_others_{$capability_type}s",
"edit_private_{$capability_type}s",
"edit_published_{$capability_type}s",
// Terms
// "manage_{$capability_type}_terms",
// "edit_{$capability_type}_terms",
// "delete_{$capability_type}_terms",
// "assign_{$capability_type}_terms",
);
}
return $capabilities;
}
/*
Add Capability
*/
public function wpse64458_add_caps(){
global $wp_roles;
if ( ! class_exists( 'WP_Roles' ) ) {
return;
}
if ( ! isset( $wp_roles ) ) {
$wp_roles = new WP_Roles();
}
$capabilities = $this->wpse64458_set_caps();
foreach ( $capabilities as $cap_group ) {
foreach ( $cap_group as $cap ) {
$wp_roles->add_cap( 'editor', $cap );
$wp_roles->add_cap( 'administrator', $cap );
}
}
}
public function wpse64458_modify_cpt_registry( $args, $post_type ){
// Do not filter any other post type
if ( 'member' !== $post_type ) {
// Give other post_types their original arguments
return $args;
}
if( current_user_can('editor') ) {
$args['capabilities']['create_posts'] = false;
}
// Give the custom-css-js post type it's arguments
return $args;
}
}
}
then inherite the class with new WPSE64458_CPT_Register();
With this example I disable editor role to add new member post functionality. modify whatever you like, or you can do this others as well. but you previously mention that you already tried to follow WooCommerce, actually they also do this way,
Hope it make sense to you.
HappyCodding!
You can restrict specific user role to custom post by below script :
Add custom Role
add_action('init','add_my_custom_role');
function add_my_custom_role() {
add_role('my_custom_role',
'Custom Role',
array(
'read' => true,
'edit_posts' => false,
'delete_posts' => false,
'publish_posts' => false,
'upload_files' => false,
'publish_posts' => false,
'create_posts' => false,
)
);
}
Register Custom post
add_action( 'init', 'my_custom_post_type');
function my_custom_post_type() {
$args = array(
'label' => __( 'Custom post', 'custom-text-domain' ),
'description' => __( 'Custom post', 'custom-text-domain' ),
'labels' => $labels,
'supports' => array( 'title', 'comments', 'revisions', ),
'hierarchical' => false,
'public' => true,
'show_ui' => true,
'rewrite' => $rewrite,
'capability_type' => array('custom_post','custom_post'),
'map_meta_cap' => true, // Set to `false`, if users are not allowed to edit/delete existing posts
);
register_post_type( 'custom_post', $args );
}
Allow user capabilities for post on the basis of roles
add_action('admin_init','custom_post_add_role_caps',999);
function custom_post_add_role_caps() {
// Add the roles you'd like to administer the custom post types
$roles = array('my_custom_role','editor');
// Loop through each role and assign capabilities
foreach($roles as $the_role) {
$role = get_role($the_role);
$role->add_cap( 'read' );
$role->add_cap( 'read_custom_post');
$role->add_cap( 'read_private_custom_post' );
$role->add_cap( 'edit_custom_post' );
$role->add_cap( 'edit_custom_post' );
$role->add_cap( 'edit_others_custom_post' );
$role->add_cap( 'edit_published_custom_post' );
$role->add_cap( 'publish_custom_post' );
$role->add_cap( 'delete_others_custom_post' );
$role->add_cap( 'delete_private_custom_post' );
$role->add_cap( 'delete_published_custom_post' );
}
}
I hope this will help you, to get more help please visit
https://codex.wordpress.org/Function_Reference/register_post_type
and
https://codex.wordpress.org/Roles_and_Capabilities

Categories