I have built a custom class that adds a custom font library to visual composer, and it works except that the icon selector always showing even if i change the library, as you can see in this image
, on the top there is the icon selector of flat icon library while i have selected the fontawesome library.
Note: Fontawesome's icon selector also showing in the same time
Here is the class:
<?php
if (!class_exists('Fama_VC_Fonts')) {
class Fama_VC_Fonts{
/**
* #var string
*/
public $font_library;
/**
* #var array
*/
public $fonts_list;
/**
* #var array
*/
public $fonts_lib_meta;
/**
* Class constructor
* #param array $library_data Font library data
* #return void
*/
public function __construct($library_data){
//check if visual composer is active
if(!fama_is_active_plugin('js_composer/js_composer.php')) return;
if (!is_array($library_data)) return;
if(empty($library_data['font_library']) || empty($library_data['fonts_list'])) return;
$this->font_library = $library_data['font_library'];
$this->fonts_list = $library_data['fonts_list'];
$this->fonts_lib_meta = $library_data['fonts_lib_meta'];
// In the 'Icon library' dropdown for an icon content type, add a new family of icons.
add_filter( 'vc_after_init', array($this, 'add_vc_icon_library'), 40 );
/**
* This adds a new parameter to the vc_icon content block.
*
* This parameter is an icon_picker element, that displays when flaticon is picked from the dropdown.
*/
add_filter( 'vc_after_init', array($this, 'define_vc_icon_picker'), 50 );
// Add all the icons we want to display in our font family.
add_filter( 'vc_iconpicker-type-'.$this->font_library , array($this, 'add_vc_icon_list') );
// Enqueue the CSS file so that the icons display in the backend editor.
add_action( 'vc_backend_editor_enqueue_js_css', array($this, 'enqueue_vc_icon_styles') );
// Enqueue the CSS file so that the icons display in the frontend editor.
add_action( 'vc_frontend_editor_enqueue_js_css', array($this, 'enqueue_vc_icon_styles') );
add_action( 'vc_enqueue_font_icon_element', array($this,'enqueue_vc_icon_styles_on_request'), 10 );
}
/**
* In the 'Icon library' dropdown for an icon content type, add a new family of icons.
*
* #return void
*/
public function add_vc_icon_library(){
$param = WPBMap::getParam( 'vc_icon', 'type' );
$param['value'][ __( 'Flat icon', 'js_composer' ) ] = $this->font_library;
vc_update_shortcode_param( 'vc_icon', $param );
}
/**
* This adds a new parameter to the vc_icon content block.
*
* This parameter is an icon_picker element, that displays when flaticon is picked from the dropdown.
*/
public function define_vc_icon_picker(){
$settings = array(
'type' => 'iconpicker',
'heading' => $this->fonts_lib_meta['heading'],
'param_name' => 'icon_'.$this->font_library,
'settings' => array(
'emptyIcon' => false,
'type' => $this->font_library,
'iconsPerPage' => 20,
),
'dependency' => array(
'element' => 'icon_type',
'value' => $this->font_library,
),
'weight' => '2',
'description' => $this->fonts_lib_meta['description'],
);
vc_add_param( 'vc_icon', $settings );
}
/**
* Add all the icons we want to display in our font family.
* #param array $icons
* #return array Icons array
*/
public function add_vc_icon_list($icons){
$icons = $this->fonts_list;
return $icons;
}
/**
* Enqueue font library style
* #return void
*/
public function enqueue_vc_icon_styles(){
wp_enqueue_style( $this->font_library , $this->fonts_lib_meta['fonts_css_uri'] );
}
/**
* Optional - Conditionally load CSS for your icon font as requested by modules on the live site, Only required if you aren't already loading the custom font globally
* #param string $font
* #return void
*/
public function enqueue_vc_icon_styles_on_request( $font ) {
if ( ! empty( $font ) && $this->font_library == $font ) {
wp_enqueue_style( $this->font_library , $this->fonts_lib_meta['fonts_css_uri'] );
}
}
}
}
$vc_font_lib = [
'font_library' => 'flaticon',
'fonts_list' =>
[
['flaticon-world' => 'World'],
['flaticon-gliding' => 'Gliding'],
['flaticon-tour-guide' => 'Tour guide'],
['flaticon-map-of-roads' => 'Map of roads'],
['flaticon-alarm-clock' =>'Alarm Clock'],
['flaticon-manager' =>'Manager'],
['flaticon-layers' =>'Layers'],
['flaticon-wallet' =>'Wallet'],
],
'fonts_lib_meta' => [
'heading' => __( 'Icon', 'js_composer' ),
'description' => __( 'Select flat icon ', 'js_composer' ),
'fonts_css_uri' => FMA_STYLESHEET_DIR . '/assets/css/flaticon.css',
],
];
$vc_fonts = new Fama_VC_Fonts ( $vc_font_lib);
I have figured out where the problem is. It is this line:
'element' => 'icon_type',
Which should be:
'element' => 'type',
Now only selected library is showing.
Related
i want to create an Elementor-Widget with al slick Slider as JavaScript / Jquery. I can add the elements correctly in ELementor Editor Mode, but the Slider didn`t work there. The Slides will shown among themselves. When i add a alert in the javascript file after the check that the element slider is still there, its not work, before the check its works fine. I think the Element will not load correctly in the editor mode...? Have someone an idea what i can do that the slider works also in the editor-mode?
Here the JavaScript-Code:
$( document ).ready(function() {
if ($(".slider").length) {
alert("Test");
$(".slider").css({"opacity" :"1"});
$(".slider").slick({
slidesToShow: 1,
slidesToScroll: 1,
infinite: true,
arrows: true,
speed: 1000,
fade: false,
dots: false,
prevArrow: '<button type="button" class="slick-prev"><i class="arrow fa fa-minus"></i></button>',
nextArrow: '<button type="button" class="slick-next"><i class="arrow fa fa-plus"></i></button>',
responsive: [
{
breakpoint: 992,
settings: {
arrows: false,
dots: true
}
}
]
});
};
Here the Code of the PHP Widget File:
<?php
/**
* Astestimonials class.
*
....
*/
namespace ElementorAstestimonials\Widgets;
use Elementor\Widget_Base;
use Elementor\Controls_Manager;
// Security Note: Blocks direct access to the plugin PHP files.
defined( 'ABSPATH' ) || die();
/**
* Astestimonials widget class.
*
* #since 1.0.0
*/
class Astestimonials extends Widget_Base {
/**
* Class constructor.
*
* #param array $data Widget data.
* #param array $args Widget arguments.
*/
public function __construct( $data = array(), $args = null ) {
parent::__construct( $data, $args );
$plugin = get_plugin_data( __FILE__, false, false );
wp_register_style( 'astestimonialscss', plugins_url( '/assets/css/astestimonials.css', ELEMENTOR_ASTESTIMONIALS ), array(), '1.0.0' );
wp_register_script( 'astestimonialsjs', plugins_url( '/assets/js/astestimonials.js', ELEMENTOR_ASTESTIMONIALS ), array( 'jquery' ), '1.0.0' );
}
/**
* Retrieve the widget name.
*
* #since 1.0.0
*
* #access public
*
* #return string Widget name.
*/
public function get_name() {
return 'astestimonials';
}
/**
* Retrieve the widget title.
*
* #since 1.0.0
*
* #access public
*
* #return string Widget title.
*/
public function get_title() {
return __( 'astestimonials', 'elementor-astestimonials' );
}
/**
* Retrieve the widget icon.
*
* #since 1.0.0
*
* #access public
*
* #return string Widget icon.
*/
public function get_icon() {
return 'eicon-facebook-comments';
}
/**
* Retrieve the list of categories the widget belongs to.
*
* Used to determine where to display the widget in the editor.
*
* Note that currently Elementor supports only one category.
* When multiple categories passed, Elementor uses the first one.
*
* #since 1.0.0
*
* #access public
*
* #return array Widget categories.
*/
public function get_categories() {
return array( 'artisolution-addons' );
}
/**
* Enqueue styles.
*/
public function get_style_depends() {
return array( 'astestimonialscss' );
}
public function get_script_depends() {
return array( 'astestimonialsjs');
}
/**
* Register the widget controls.
*
* Adds different input fields to allow the user to change and customize the widget settings.
*
* #since 1.0.0
*
* #access protected
*/
protected function _register_controls() {
$this->start_controls_section(
'section_content',
array(
'label' => __( 'Content', 'elementor-astestimonials' ),
)
);
$this->add_control(
'slides',
[
'label' => esc_html__( 'Slides', 'elementor-astestimonials' ),
'type' => \Elementor\Controls_Manager::REPEATER,
'fields' => [
[
'name' => 'content',
'label' => __( 'Content', 'elementor-astestimonials' ),
'type' => Controls_Manager::WYSIWYG,
'default' => __( 'Content', 'elementor-astestimonials' ),
],
[
'name' => 'name',
'label' => __( 'Name', 'elementor-astestimonials' ),
'type' => Controls_Manager::TEXT,
'placeholder' => esc_html__( 'Beispielname', 'elementor-astestimonials' ),
'default' => __( 'Name', 'elementor-astestimonials' ),
],
[
'name' => 'job',
'label' => __( 'Job / Company', 'elementor-astestimonials' ),
'type' => Controls_Manager::TEXT,
'placeholder' => esc_html__( 'Beispieljob', 'elementor-astestimonials' ),
'default' => __( 'Job', 'elementor-astestimonials' ),
],
[
'name' => 'image',
'label' => esc_html__( 'Choose Image', 'elementor-astestimonials' ),
'type' => \Elementor\Controls_Manager::MEDIA,
'default' => [
'url' => \Elementor\Utils::get_placeholder_image_src(),
],
],
],
'default' => [
[
'content' => esc_html__( 'List Item #1', 'elementor-astestimonials' ),
'name' => esc_html__( 'Beispielname #1', 'elementor-astestimonials' ),
'job' => esc_html__( 'Beispiejob #1', 'elementor-astestimonials' ),
],
[
'content' => esc_html__( 'List Item #2', 'elementor-astestimonials' ),
'name' => esc_html__( 'Beispielname #2', 'elementor-astestimonials' ),
'job' => esc_html__( 'Beispiejob #2', 'elementor-astestimonials' ),
],
],
'title_field' => '{{{ name }}}',
]
);
$this->end_controls_section();
}
/**
* Render the widget output on the frontend.
*
* Written in PHP and used to generate the final HTML.
*
* #since 1.0.0
*
* #access protected
*/
protected function render() {
$settings = $this->get_settings_for_display();
?>
<div class="slider">
<?php foreach ( $settings['slides'] as $index => $item ) : ?>
<div class="slide">
<div class="review-wrap">
<div class="review-text 11">
<?php if ( '' != $item['content'] ) {
echo $item['content'];
} ?>
</div>
<div class="reviewer">
<?php if ( '' != $item['image']['url'] ): ?>
<div class="avatar"
style="background-image: url('<?php echo $item['image']['url']; ?>');"></div>
<?php endif; ?>
<div class="reviewer-info">
<h4 class="name"><?php echo $item['name']; ?></h4>
<p><?php echo $item['job']; ?></p>
</div>
</div><!-- //author -->
</div>
</div>
<?php endforeach; ?>
</div><!-- //review-slider -->
<?php
}
/**
* Render the widget output in the editor.
*
* Written as a Backbone JavaScript template and used to generate the live preview.
*
* #since 1.0.0
*
* #access protected
*/
protected function _content_template() {
?>
<div class="slider">
<#
if ( settings.slides ) {
_.each( settings.slides, function( item, index ) {
#>
<div class="slide">
<div class="review-wrap">
<div class="review-text 11">
<# if ( item.content != '' ) { #>
{{{ item.content }}}
<# } #>
</div>
<div class="reviewer">
<# if ( item.image.url != '' ) { #>
<div class="avatar"
style="background-image: url('{{ item.image.url }}');"></div>
<# } #>
<div class="reviewer-info">
<h4 class="name">{{{ item.name }}}</h4>
<p>{{{ item.job }}}</p>
</div>
</div><!-- //author -->
</div>
</div>
<#
} );
}
#>
</div><!-- //review-slider -->
<?php
}
}
Here the Image of the Editor-Mode:
Image Editor-Mode
Here the Code of the JavaScript file for the Editor:
(function ($, elementor) {
"use strict";
var myDataCollection = {
init: function () {
var widgets = {
"astestimonials": myDataCollection.AsTestimonials,
};
$.each(widgets, function (widget, callback) {
elementor.hooks.addAction("frontend/element_ready/" + widget, callback);
});
},
AsTestimonials: function ($scope) {
$scope.find('.slider').hide();
alert("Test");
},
};
$(window).on("elementor/frontend/init", myDataCollection.init);
})(jQuery, window.elementorFrontend);
Basically, your enqueue Javascript doesn't load inside the elementor editor. For loading javascript, you have to follow some easy steps.
Enqueue your javascript with dependency elementor-frontend.
wp_enqueue_script( 'script-handle', 'path/to/file.js', [ 'elementor-frontend' ], '1.0.0', true );
Now you will get a javascript hook elementor/frontend/init that loads your javascript inside the elementor.
For snippet code, you can use this.
(function ($, elementor) {
"use strict";
var myDataCollection = {
init: function () {
var widgets = {
"back-to-top.default": myDataCollection.Back_To_Top,
};
$.each(widgets, function (widget, callback) {
elementor.hooks.addAction("frontend/element_ready/" + widget, callback);
});
},
Back_To_Top: function ($scope) {
$scope.find('.BackTo').on('click', function (e) {
e.preventDefault();
$('body, html').animate({
scrollTop: 0
}, 1500)
});
$(window).on("scroll", function () {
var scrolltop = $(window).scrollTop(),
docHeight = $(document).height() / 2;
if (scrolltop > docHeight) {
$scope.fadeIn("slow");
} else {
$scope.fadeOut("slow");
}
});
},
};
$(window).on("elementor/frontend/init", myDataCollection.init);
})(jQuery, window.elementorFrontend);
Explanation of the above code :
I wrote the above code for Back to the top widget. my widget name is back-to-top. First I am taking an Immediately-invoked Function and I take 2 parameters as I enqueue my script with 2 dependency elementor-frontend and jquery so I will get back 2 parameters. For my code reusability, I make an object myDataCollection.otherwise we can do it like that. follow the below code.
elementor.hooks.addAction("frontend/element_ready/" + "back-to-top.default", "funtion_name");
It works fine but for multiple widgets, I make the first approach.
inside the object, I take a function init. inside init I take another object widget. widget is responsible for taking widget name and function name. after that I loop through it. so that we don't need to hook our widget again and again. Now I am explaining my callback function. Inside Callback, you will get a parameter like $scope.$scope is your actual widget. When your widget drags and drops inside the editor you will get the $scope.You will find your widget markup inside $scope.Now write your custom code for your widget and enjoy.
Enqueue your JS file like this.
add_action( 'elementor/frontend/before_enqueue_scripts', 'enqueue_scripts' );
function enqueue_scripts()
{
wp_enqueue_script( 'elementor-script', get_template_directory_uri( __FILE__ ) . '/assets/js/elementor.js', array( 'jquery', 'elementor-frontend' ), '1.0.0', true );
}
Now follow the first answer. I hope your problem will be solved.
I really hope someone can help me, cause i'm running out of ideas.
I made this custom shipping methon on Woocommerce, copying and pasting from the website documentation and other StakO topics.
Everything seems to be okay, apart of when i try to update my only one field called "Store Address", it doesn't works and values are not updated.
Here's the code. Thanks to everyone
if ( ! defined( 'WPINC' ) ) {
die;
}
if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) ) {
function pickupinstore_shipping_method() {
if ( ! class_exists( 'PickupInStore_Shipping_Method' ) ) {
class PickupInStore_Shipping_Method extends WC_Shipping_Method {
/**
* Constructor for your shipping class
*
* #access public
* #return void
*/
public function __construct( $instance_id = 0 ) {
$this->id = 'pickupinstore';
$this->instance_id = absint( $instance_id );
$this->method_title = __( 'Pickup in Store', 'pickupinstore' );
$this->method_description = __( 'Custom Shipping Method - Pickup in Store', 'pickupinstore' );
$this->supports = array(
'shipping-zones',
'instance-settings',
'instance-settings-modal',
);
$this->init();
$this->title = isset( $this->settings['title'] ) ? "Ritiro in Negozio | ".$this->settings['title'].": GRATIS" : __( 'Pickup in Store', 'pickupinstore' ); }
/**
* Init your settings
*
* #access public
* #return void
*/
function init() {
// Load the settings API
$this->init_form_fields();
$this->init_settings();
// Save settings in admin if you have any defined
add_action( 'woocommerce_update_options_shipping_' . $this->id, array( $this, 'process_admin_options' ) );
}
/**
* Define settings field for this shipping
* #return void
*/
function init_form_fields() {
$this->form_fields = array(
'title' => array(
'title' => __( 'Ritiro in Negozio', 'pickupinstore' ),
'type' => 'text',
'description' => __( 'Store Address', 'pickupinstore' ),
'default' => __( '197, Brooklyn Road', 'New York' ),
'desc_tip' => true,
),
);
}
/**
* This function is used to calculate the shipping cost. Within this function we can check for weights, dimensions and other parameters.
*
* #access public
* #param mixed $package
* #return void
*/
public function calculate_shipping( $package = array() ) {
$cost = 0;
$this->add_rate( array(
'id' => $this->id,
'label' => $this->title,
'cost' => $cost
) );
}
}
}
}
add_action( 'woocommerce_shipping_init', 'pickupinstore_shipping_method' );
function add_pickupinstore_shipping_method( $methods ) {
$methods['pickupinstore'] = 'PickupInStore_Shipping_Method';
return $methods;
}
add_filter( 'woocommerce_shipping_methods', 'add_pickupinstore_shipping_method' );
}
Edit:
I tried using #docker code, but when I save changes nothing compares in the title section (backend). Otherwise the form field seems to be saved, but as you can see, not diplayed.
In front end, it displays the name of the custom shipping method instead of the title I save.
Move the $this->title definition to the init() method and use $this->get_option() instead of $this->settings.
function init() {
// Load the settings API
$this->init_form_fields();
$this->init_settings();
$this->title = null != $this->get_option('title') ? "Ritiro in Negozio | " . $this->get_option('title') . ": GRATIS" : __( 'Pickup in Store', 'pickupinstore' );
// Save settings in admin if you have any defined
add_action( 'woocommerce_update_options_shipping_' . $this->id, array( $this, 'process_admin_options' ) );
}
Additionally in the init_form_fields() method you should use $this->instance_form_fields.
function init_form_fields() {
$this->instance_form_fields = array(
'title' => array(
'title' => __( 'Ritiro in Negozio', 'pickupinstore' ),
'type' => 'text',
'description' => __( 'Store Address', 'pickupinstore' ),
'default' => __( '197, Brooklyn Road', 'New York' ),
'desc_tip' => true,
),
);
}
In some cases you may need the get_instance_from_fields() method but I have a working solution without it:
/**
* Get setting form fields for instances of this shipping method within zones.
*
* #return array
*/
public function get_instance_form_fields() {
return parent::get_instance_form_fields();
}
EDIT:
This is the full working code:
<?php
/**
* Plugin Name: Pickup in Store
* Plugin URI: https://www.perspectiveweb.it/
* Description: Pickup in store - Custom Shipping Method
* Version: 1.0.0
* Author: Perspective Web
* Author URI: https://www.perspectiveweb.it/
* License: GPL-3.0+
* License URI: http://www.gnu.org/licenses/gpl-3.0.html
* Domain Path: /lang
* Text Domain: perspectiveweb
*/
if ( ! defined( 'WPINC' ) ) {
die;
}
if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) ) {
function pickupinstore_shipping_method() {
if ( ! class_exists( 'PickupInStore_Shipping_Method' ) ) {
class PickupInStore_Shipping_Method extends WC_Shipping_Method {
/**
* Constructor for your shipping class
*
* #access public
* #return void
*/
public function __construct( $instance_id = 0 ) {
$this->id = 'pickupinstore';
$this->instance_id = absint( $instance_id );
$this->method_title = __( 'Pickup in Store', 'pickupinstore' );
$this->method_description = __( 'Custom Shipping Method - Pickup in Store', 'pickupinstore' );
$this->supports = array(
'shipping-zones',
'instance-settings',
'instance-settings-modal',
);
$this->init();
}
/**
* Init your settings
*
* #access public
* #return void
*/
public function init() {
// Load the settings API
$this->init_form_fields();
$this->init_settings();
$this->title = null != $this->get_option('title') ? "Ritiro in Negozio | " . $this->get_option('title') . ": GRATIS" : __( 'Pickup in Store', 'pickupinstore' );
// Save settings in admin if you have any defined
add_action( 'woocommerce_update_options_shipping_' . $this->id, array( $this, 'process_admin_options' ) );
}
/**
* Define settings field for this shipping
* #return void
*/
public function init_form_fields() {
$this->instance_form_fields = array(
'title' => array(
'title' => __( 'Ritiro in Negozio', 'pickupinstore' ),
'type' => 'text',
'description' => __( 'Store Address', 'pickupinstore' ),
'default' => __( '197, Brooklyn Road', 'New York' ),
'desc_tip' => true,
),
);
}
/**
* This function is used to calculate the shipping cost. Within this function we can check for weights, dimensions and other parameters.
*
* #access public
* #param mixed $package
* #return void
*/
public function calculate_shipping( $package = array() ) {
$cost = 0;
$this->add_rate( array(
'id' => $this->id,
'label' => $this->title,
'cost' => $cost
) );
}
}
}
}
add_action( 'woocommerce_shipping_init', 'pickupinstore_shipping_method' );
function add_pickupinstore_shipping_method( $methods ) {
$methods['pickupinstore'] = 'PickupInStore_Shipping_Method';
return $methods;
}
add_filter( 'woocommerce_shipping_methods', 'add_pickupinstore_shipping_method' );
}
I have created woocommerce plugin which gets shipping rates from third party URL(my web site) and displays it on the checkout page. when I click on one of shipping method it also calculates correct shipping rates, but when I again refresh checkout page my selected shipping option gets lost and I have to select again. also, my custom shipping option does not reach to order after a successful order.
In below Screenshot, I pass Suburb and Postcode, and I get all rates i desire, when i click on one of shipping method it also calculates correct a shipping rates
After Click on Place Order, it takes first shipping method which is a flat rate: $5, please see below screenshot
Here is my Plugin please have a look and guide me where I am going wrong.
<?php
/**
* Plugin Name: Iconsignit Shipping
* Plugin URI: http://Iconsignit.com.au
* Description: Iconsignit Shipping Method for WooCommerce
* Version: 1.0.0
* Author: Jaimin prajapati
* Author URI: http://www.webbrainstechnologies.com
* License: GPL-3.0+
* License URI: http://www.gnu.org/licenses/gpl-3.0.html
* Domain Path: /
* Text Domain: Iconsignit
*/
if (!defined('WPINC')) {
die;
}
/*
* Check if WooCommerce is active
*/
if (in_array('woocommerce/woocommerce.php', apply_filters('active_plugins', get_option('active_plugins')))) {
function iconsignit_shipping_method()
{
if (!class_exists('Iconsignit_Shipping_Method')) {
class Iconsignit_Shipping_Method extends WC_Shipping_Method
{
/**
* Constructor for your shipping class
*
* #access public
* #return void
*/
public function __construct($instance_id = 0)
{
$this->id = 'iconsignit';
$this->instance_id = absint($instance_id);
$this->method_title = __('Iconsignit Shipping', 'iconsignit');
$this->method_description = __('Custom Shipping Method for iconsignit', 'iconsignit');
$this->init();
$this->enabled = isset($this->settings['enabled']) ? $this->settings['enabled'] : 'yes';
$this->title = isset($this->settings['title']) ? $this->settings['title'] : __('Iconsignit Shipping', 'iconsignit');
}
/**
* Init your settings
*
* #access public
* #return void
*/
function init()
{
// Load the settings API
$this->init_form_fields();
$this->init_settings();
// Save settings in admin if you have any defined
add_action('woocommerce_update_options_shipping_' . $this->id, array($this, 'process_admin_options'));
}
/**
* Define settings field for this shipping
* #return void
*/
function init_form_fields()
{
// We will add our settings here
$this->form_fields = array(
'ApiToken' => array(
'title' => __('Api Token', 'iconsignit-integration-demo'),
'type' => 'text',
'description' => __('Enter with your API Key. You can find this in "User Profile" drop-down (top right corner) > API Keys.', 'iconsignit-integration-demo'),
'desc_tip' => true,
'default' => '',
),
'ApiUrl' => array(
'title' => __('Api Url', 'iconsignit-integration-demo'),
'type' => 'text',
'default' => '',
'desc_tip' => true,
'description' => __('Website URL', 'iconsignit-integration-demo'),
),
'ConnectIconsignUrl' => array(
'title' => __('Iconsignit Url', 'iconsignit-integration-demo'),
'type' => 'text',
'default' => '',
'desc_tip' => true,
'description' => __('Url from where all shipping rates will come', 'iconsignit-integration-demo'),
),
);
}
/**
* This function is used to calculate the shipping cost. Within this function we can check for weights, dimensions and other parameters.
*
* #access public
* #param mixed $package
* #return void
*/
public function calculate_shipping($package = array())
{
// We will add the cost, rate and logics in here
$item = array();
$count = 0;
foreach ($package['contents'] as $item_id => $values) {
$item[$count]['item_qty'] = $values['quantity'];
$item[$count]['item_length'] = $values['data']->get_length();
$item[$count]['item_width'] = $values['data']->get_width();
$item[$count]['item_height'] = $values['data']->get_height();
$item[$count]['item_weight'] = $values['data']->get_weight();
$item[$count]['item_palletised'] = 0;
$count++;
}
$country = $_POST['s_country'];
$state = $_POST['s_state'];
$postcode = $_POST['s_postcode'];
$city = $_POST['s_city'];
$address = $_POST['s_address'];
$address_2 = $_POST['s_address_2'];
$isCredentials = get_option('woocommerce_iconsignit_settings');
$data = array('ApiUrl' => $isCredentials['ApiUrl'], 'ApiToken' => $isCredentials['ApiToken'], 'DeliveryTown' => $city, 'DeliveryPostcode' => $postcode, 'Items' => $item);
$isResponse = Requests::post($isCredentials['ConnectIconsignUrl'].'/api/getconsignrate', array(), $data);
$resp = json_decode($isResponse->body, true);
$counter = 1;
foreach ($resp['result'] as $key => $res) {
$rate = array(
'id' => $res['QuoteRateID'],//$this->id,
'label' => $res['carrier_nm'] . "-(" . $res['service_nm'] . ")",
'cost' => $res['total_charge'],
'calc_tax' => 'per_item',
);
$this->add_rate($rate);
$counter++;
}
}
}
}
}
add_action('woocommerce_shipping_init', 'iconsignit_shipping_method');
function add_iconsignit_shipping_method($methods)
{
$methods[] = 'Iconsignit_Shipping_Method';
return $methods;
}
add_filter('woocommerce_shipping_methods', 'add_iconsignit_shipping_method');
}
problem is solved the problem was in $this->id, it should have to be unique.
Im using Woo estimated shipping date plugin to add a custom text (field) in my products pages.
The problem is:
Example: If I use this text in that custom field: "In stock" and then I save the changes, the plugin show "In stock" in the product page...BUT if I go back to edit anything else on the product page, the plugin restore the default sentence "Estimated Delivery Date" and if I save the changes without modifying that sentences once more, the "Estimated Delivery Date" shows in the product page instead the new sentence. Its something like an annoying loop, after save the changes always back the default text and If I don't look that field my custom text is gone.
Here's the Plugin code:
<?php
/**
* No cheating please
*/
if ( ! defined( 'WPINC' ) ) exit;
/**
* WCESD_Product_Settings Class
*/
class WCESD_Product_Settings {
/**
* Hold the instance
*
* #var string
*/
private static $instance;
use helperMethods;
/**
* Constructor method
*
* #return void
*/
public function __construct() {
if ( ! $this->enabled() ) {
return;
}
$this->init_hooks();
}
/**
* Init all the hooks
*
* #return void
*/
protected function init_hooks() {
add_action( 'woocommerce_product_options_shipping', array( $this, 'wc_esd_add_estimated_shipping_date' ) );
add_action( 'woocommerce_process_product_meta', array( $this, 'wc_esd_save_shipping_date') );
}
/**
* Add wcesd form
*
* #return void
*/
public function wc_esd_add_estimated_shipping_date() {
woocommerce_wp_checkbox( array(
'id' => 'wc_esd_date_enable',
'label' => __( 'Habilitar fecha estimada entrega', 'wcesd' ),
'description' => __( 'Enable or Disable woocommerce estimated shipping date', 'wcesd' ),
'desc_tip' => true,
) );
woocommerce_wp_text_input( array(
'id' => 'wc_esd_date',
'label' => __( 'Fecha estimada en días', 'wcesd' ),
'description' => __( 'Días del posible arribo del producto', 'wcesd' ),
'desc_tip' => true,
'type' => 'number',
'placeholder' => 5,
'value' => 5,
) );
woocommerce_wp_text_input( array(
'id' => 'wc_esd_date_message',
'label' => __( 'Frase', 'wcesd' ),
'description' => __( 'Agregue su mensaje', 'wcesd' ),
'desc_tip' => true,
'placeholder' => 'Estimated Delivery Date',
'value' => 'Estimated Delivery Date',
) );
do_action( 'wc_esd_add_estimated_shipping_date' );
}
/**
* Save wcesd form data
*
* #param int $product_id
*
* #return void
*/
public function wc_esd_save_shipping_date( $product_id ) {
if ( ! is_admin() || get_post_type() !== 'product' ) {
return;
}
$wc_esd_date_enable = isset( $_POST['wc_esd_date_enable'] ) ? sanitize_text_field( $_POST['wc_esd_date_enable'] ) : '';
$wc_esd_date = isset( $_POST['wc_esd_date'] ) ? sanitize_text_field( $_POST['wc_esd_date'] ) : '';
$wc_esd_date_message = isset( $_POST['wc_esd_date_message'] ) ? sanitize_text_field( $_POST['wc_esd_date_message'] ) : '';
update_post_meta( $product_id, 'wc_esd_date_enable', $wc_esd_date_enable );
update_post_meta( $product_id, 'wc_esd_date', $wc_esd_date );
update_post_meta( $product_id, 'wc_esd_date_message', $wc_esd_date_message );
do_action( 'wc_esd_save_shipping_date', $product_id );
}
/**
* Get instance
*
* #return object
*/
public static function init() {
if ( null === self::$instance ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Disable cloning this class
*
* #return void
*/
private function __clone() {
//
}
private function __wakeup() {
//
}
}
WCESD_Product_Settings::init();
Any idea how to solve this problem?
Thank you :)
Please remove the value field
woocommerce_wp_text_input( array(
'id' => 'wc_esd_date_message',
'label' => __( 'Frase', 'wcesd' ),
'description' => __( 'Agregue su mensaje', 'wcesd' ),
'desc_tip' => true,
'placeholder' => 'Estimated Delivery Date',
/*'value' => 'Estimated Delivery Date',*/
) );
Then it should work.
I am building a custom module for Drupal 8.4.4 and is not detecting the hook_theme from a block. I get an error message saying "Theme hook gardentheme not found".
If I uninstall the module and install it again, it works fine, but as soon as I clear the cache, it doesn't find the theme_hook anymore.
I notice that die() and exit; wont do anything on my .module file after clearing the cache, I feel as after clearing the cache the .module is not run anymore.
My module file called garden.module
<?php
/**
* #file
*
*/
/**
* Implements hook_theme()
*/
function garden_theme($existing, $type, $theme, $path){
return array('gardentheme' =>
array(
'variables' => array(
'description' => NULL
),
)
);
}
My block placed on src/Plugin/Block/GardenScheduleBlock.php
<?php
namespace Drupal\garden\Plugin\Block;
use Drupal\Core\Block\BlockBase;
/**
* Provides a 'GardenSchedule' Block.
*
* #Block(
* id = "garden_schedule_block",
* admin_label = #Translation("Garden Schedule"),
* category = #Translation("Garden Schedule_Category"),
* )
*/
class GardenScheduleBlock extends BlockBase {
/**
* {#inheritdoc}
*/
public function build() {
return array(
'#theme' => 'gardentheme',
'#description' => "description test"
);
}
}
Thanks in advance for any tips.
public function build() {
$renderable = [
'#theme' => 'my_template',
'#test_var' => 'test variable',
];
return $renderable;
}
try this