I am running a WooCommerce v. 3 store and using a payment plugin "Quickpay". The payment plugin supports adding the transactions fee to the order which is great, but it is added without tax to the order i WooCommerce.
I have located the code where the transactions fee is set. I have tried digging through the documentation fra WC, but still can't figure it out.
Can any help me setting it up, so that tax is calculated for the transactions fee?
This is the current code:
/**
* add_transaction_fee function.
*
* Adds order transaction fee to the order before sending out the order confirmation
*
* #access public
*
* #param $fee_amount
*
* #return bool
*/
public function add_transaction_fee($fee_amount)
{
if ($fee_amount > 0) {
$amount = $fee_amount / 100;
$fee = (object) array(
'name' => __('Payment Fee', 'woo-quickpay'),
'amount' => wc_format_decimal($amount),
'taxable' => FALSE,
'tax_class' => NULL,
'tax_data' => array(),
'tax' => 0,
);
if (version_compare( WC_VERSION, '3.0', '<' )) {
$this->add_fee($fee);
} else {
$item = new WC_Order_Item_Fee();
$item->set_props( array(
'name' => $fee->name,
'tax_class' => $fee->tax_class,
'total' => $amount,
'total_tax' => 0,
'order_id' => $this->get_id(),
) );
$item->save();
$this->add_item( $item );
}
$this->set_total( $this->get_total() + $amount );
return TRUE;
}
return FALSE;
}
Related
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 use custom plugin for Woocommerce shipping method. The plugin run a new class which extends WC_Shipping_MEthod, but the problem is the 'cost' price is calculated in other function outsite the class.
So in the current class I have:
public function calculate_shipping( $package=array() ) {
/* $this->add_rate( array(
'id' => $this->id . $this->instance_id,
'label' => $this->title,
'cost' => 0,
) ); */
$rate = array(
'id' => $this->id,
'label' => $this->title,
'cost' => 0,
'taxes' =>false,
//'calc_tax' => 'per_item'
);
// Register the rate
$this->add_rate( $rate );
}
Outside the class, in another file, I have a function, which calculates the cost for shipping:
//add shipping cost to checkout total
add_action('woocommerce_cart_calculate_fees', 'woo_add_cart_fee');
function woo_add_cart_fee() {
global $woocommerce;
$woocommerce->shipping;
$wc_econt = new WC_Econt_Shipping_Method;
if ( is_checkout() && (bool)$wc_econt->inc_shipping_cost == TRUE ) {
if(!isset($_SESSION)){
session_start();
}
//write_log('session econt customer shipping cost:'.$_SESSION['econt_shipping_cost']);
$extracost = (isset($_SESSION['econt_shipping_cost']) ? $_SESSION['econt_shipping_cost'] : 0 );
if ($extracost != '0') {
WC()->cart->add_fee(__('Econt Express Shipping Method','woocommerce-econt'), $extracost);
}
}
}
If just change 0 to $extracode in the class function it doesn't update the shipping cost on checkout page:
public function calculate_shipping( $package=array() ) {
/* $this->add_rate( array(
'id' => $this->id . $this->instance_id,
'label' => $this->title,
'cost' => $extracost,
) ); */
$rate = array(
'id' => $this->id,
'label' => $this->title,
'cost' => $extracost,
'taxes' =>false,
//'calc_tax' => 'per_item'
);
// Register the rate
$this->add_rate( $rate );
}
I guess the class run before the woo_add_cart_fee function, and that's why it cannot get the value of $extracost variable.
How to resolve this?
In the function to calculate the shipping cost, add a session variable with your new calculated value like this:
//add shipping cost to checkout total
add_action('woocommerce_cart_calculate_fees', 'woo_add_cart_fee');
function woo_add_cart_fee() {
global $woocommerce;
$woocommerce->shipping;
$wc_econt = new WC_Econt_Shipping_Method;
if ( is_checkout() && (bool)$wc_econt->inc_shipping_cost == TRUE ) {
if(!isset($_SESSION)){
session_start();
}
//write_log('session econt customer shipping cost:'.$_SESSION['econt_shipping_cost']);
$extracost = (isset($_SESSION['econt_shipping_cost']) ? $_SESSION['econt_shipping_cost'] : 0 );
if ($extracost != '0') {
WC()->session->set( 'Econt_Express_Shipping_Method' , $extracost );
}
}
}
Then on the calculate shipping function use the WC session variable to set the value for the cost like below:
public function calculate_shipping( $package=array() ) {
/* $this->add_rate( array(
'id' => $this->id . $this->instance_id,
'label' => $this->title,
'cost' => 0,
) ); */
$rate = array(
'id' => $this->id,
'label' => $this->title,
'cost' => WC()->session->get('Econt_Express_Shipping_Method' ),
'taxes' =>false,
//'calc_tax' => 'per_item'
);
// Register the rate
$this->add_rate( $rate );
}
Use the javascript below to update your new shipping value at checkout:
$('body').trigger('update_checkout', { update_shipping_method: true });
You may want to change the value of billing address or shipping address or country to be able to update your value if you use the above code more than once on checkout. This is also where I stuck and am forced to fake these changes so that Woocommerce can update my shipping value...am still looking for the solution though...lol :)
$("#billing_address_1").trigger("keypress").val(function(i,val){return val + 'a';});
I'm trying to setup a batch page for processing and I need an example. The example that's given in the Example module is within a form and I need a page that I can run independently of a form that will process batch requests.
For instance:
function mymodule_batch_2() {
$operations[] = array('mymodule_onefunction','mymodule_anotherfunction')
$batch = array(
'operations' => $operations,
'finished' => 'mymodule_finished',
// We can define custom messages instead of the default ones.
'title' => t('Processing batch 2'),
'init_message' => t('Batch 2 is starting.'),
'progress_message' => t('Processed #current out of #total.'),
'error_message' => t('Batch 2 has encountered an error.'),
);
batch_set($batch);
batch_process('');
}
Where the batch function would call other functions in the form of $operations.
You need to give batch process an id to work from. batch_process('mybatch')otherwise yourmexample is correct. are you having a particular problem with this strategy?
Here you can see my sample of batch relization with form that calls batch:
function my_module_menu() {
$items['admin/commerce/import'] = array(
'title' => t('Import'),
'page callback' => 'drupal_get_form',
'page arguments' => array('my_module_settings_form'),
'access arguments' => array('administer site settings'),
'type' => MENU_NORMAL_ITEM,
);
return $items;
}
/**
* Import form
*/
function my_module_settings_form() {
$form = array();
$form['import'] = array(
'#type' => 'fieldset',
'#title' => t('Import'),
'#collapsible' => TRUE,
'#collapsed' => FALSE,
);
$form['import']['submit'] = array(
'#type' => 'submit',
'#value' => t('Import'),
);
return $form;
}
function my_module_settings_form_submit($form, &$form_state) {
batch_my_module_import_start();
}
/**
* Batch start function
*/
function batch_my_module_import_start() {
$batch = array(
'title' => t('Import products'),
'operations' => array(
array('_batch_my_module_import', array()),
),
'progress_message' => t('Import. Operation #current out of #total.'),
'error_message' => t('Error!'),
'finished' => 'my_module_batch_finished',
);
batch_set($batch);
}
/**
* Import from 1C operation. Deletes Products
*/
function _batch_my_module_import(&$context) {
// Your iterms. In my case select all products
$pids = db_select('commerce_product', 'p')
->fields('p', array('sku', 'product_id', 'title'))
->condition('p.type', 'product')
->execute()
->fetchAll();
// Get Count of products
if (empty($context['sandbox']['progress'])) {
$context['sandbox']['progress'] = 0;
$context['sandbox']['max'] = count($pids);
watchdog('import', 'import products');
}
// Create Iteration variable
if (empty($context['sandbox']['iteration'])) {
$context['sandbox']['iteration'] = 0;
}
// Check for the end of cycle
if ($context['sandbox']['iteration'] < $context['sandbox']['max']) {
// Count of operation in one batch step
$limit = 10;
// Counts completed operations in one batch step
$counter = 0;
if ($context['sandbox']['progress'] != 0) {
$context['sandbox']['iteration'] = $context['sandbox']['iteration'] + $limit;
}
// Loop all Product items in xml
for ($i = $context['sandbox']['iteration']; $i < $context['sandbox']['max'] && $counter < $limit; $i++) {
/* Loop items here */
/* ... */
/* ... */
$context['results']['added']['products'][] = $product_item->title;
// Update Progress
$context['sandbox']['progress']++;
$counter++;
// Messages
$context['message'] = t('Now processing product %name. Product %progress of %count', array('%name' => $product_item->title, '%progress' => $context['sandbox']['progress'], '%count' => $context['sandbox']['max']));
$context['results']['processed'] = $context['sandbox']['progress'];
}
}
if ($context['sandbox']['progress'] != $context['sandbox']['max']) {
$context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
}
}
/**
* Finish of batch. Messagess
*/
function my_module_batch_finished($success, $results, $operations) {
if ($success) {
drupal_set_message(t('#count products added.', array('#count' => isset($results['added']) ? count($results['added']) : 0)));
}
else {
$error_operation = reset($operations);
drupal_set_message(t('An error occurred while processing #operation with arguments : #args', array('#operation' => $error_operation[0], '#args' => print_r($error_operation[0], TRUE))));
}
watchdog('import', 'import finished');
}
function module_name_import_form_submit($form, $form_state) {
// Check to make sure that the file was uploaded to the server properly
$uri = db_query("SELECT uri FROM {file_managed} WHERE fid = :fid", array(
':fid' => $form_state['input']['import']['fid'],
))->fetchField();
if(!empty($uri)) {
if(file_exists(drupal_realpath($uri))) {
// Open the csv
$handle = fopen(drupal_realpath($uri), "r");
// Go through each row in the csv and run a function on it. In this case we are parsing by '|' (pipe) characters.
// If you want commas are any other character, replace the pipe with it.
while (($data = fgetcsv($handle, 0, '|', '"')) !== FALSE) {
$operations[] = array(
'module_name_import_batch_processing', // The function to run on each row
array($data), // The row in the csv
);
}
// Once everything is gathered and ready to be processed... well... process it!
$batch = array(
'title' => t('Importing CSV...'),
'operations' => $operations, // Runs all of the queued processes from the while loop above.
'finished' => 'module_name_import_finished', // Function to run when the import is successful
'error_message' => t('The installation has encountered an error.'),
'progress_message' => t('Imported #current of #total products.'),
);
batch_set($batch);
fclose($handle);
}
}
else {
drupal_set_message(t('There was an error uploading your file. Please contact a System administator.'), 'error');
}
}
/**
* This function runs the batch processing and creates nodes with then given information
* #see
* module_name_import_form_submit()
*/
function module_name_import_batch_processing($data) {
// Lets make the variables more readable.
$title = $data[0];
$body = $data[1];
$serial_num = $data[2];
// Find out if the node already exists by looking up its serial number. Each serial number should be unique. You can use whatever you want.
$nid = db_query("SELECT DISTINCT n.nid FROM {node} n " .
"INNER JOIN {field_data_field_serial_number} s ON s.revision_id = n.vid AND s.entity_id = n.nid " .
"WHERE field_serial_number_value = :serial", array(
':serial' => $serial_num,
))->fetchField();
if(!empty($nid)) {
// The node exists! Load it.
$node = node_load($nid);
// Change the values. No need to update the serial number though.
$node->title = $title;
$node->body['und'][0]['value'] = $body;
$node->body['und'][0]['safe_value'] = check_plain($body);
node_save($node);
}
else {
// The node does not exist! Create it.
global $user;
$node = new StdClass();
$node->type = 'page'; // Choose your type
$node->status = 1; // Sets to published automatically, 0 will be unpublished
$node->title = $title;
$node->uid = $user->uid;
$node->body['und'][0]['value'] = $body;
$node->body['und'][0]['safe_value'] = check_plain($body);
$node->language = 'und';
$node->field_serial_number['und'][0]['value'] = $serial_num;
$node->field_serial_number['und'][0]['safe_value'] = check_plain($serial_num);
node_save($node);
}
}
/**
* This function runs when the batch processing is complete
*
* #see
* module_name_import_form_submit()
*/
function module_name_import_finished() {
drupal_set_message(t('Import Completed Successfully'));
}