Can't get the "right" settings array in custom shipping plugin

I'm creating a new custom shipping plugin following the "plugin-template.php" file.

Here's what happens:

– when i click on "save" it correctly stores my settings (eg. mp[shipping][plugin_name][mysetting1], etc.)

– it reloads and show them, fine.

…..but if i change the shipping method using the selectbox, for example i select "Table Rate", and later come back to "My Shipping Plugin"…..my data is not there anymore.

To understand what is going on i'm now printing with a "var_dump" of the "$settings" array received in the function "shipping_settings_box($settings)" and i've noticed that if i go, for example, to the "Table Rate" plugin it prints:

["method"]=> string(10) "table-rate"

(that i guess is fine)

and right afer it prints the array:

["my-shipping-plugin"]=> array(20) ….

While…if i go to "My Shipping Plugin" it prints:

["method"]=> string(18) "my-shipping-plugin"

(that i guess is fine)

and right afer it prints the array of the table-rate plugin:

["table-rate"]=> array(2) ….

So i'm now wondering….

Is there something wrong?

Why the rate plugin is loading my plugin custom settings and my plugin is getting the table-rate plugin data??

Thank you very much,

Enrico.

  • Gary
    • Design Lord, Child of Thor

    I know this will sound silly, however I know I’ve done something very similar before myself… so…

    Did you have both files open in the editor, and was the custom plugin created initially as a copy of the table rate plugin?

    Is it possible that you did something like this?

    1. Changed the plugin name at the top of the new plugin file

    2. Got distracted, switching between the files

    3. Zipped down through the ORIGINAL plugin file, changing references to table-rate to the new name

    Just an initial gut feeling reading your description of the problem.

    cheers

    Gary

  • chickenrun
    • Site Builder, Child of Zeus

    Hello guys, thanks for your super-fast answers.

    @gary:

    both files open, yes, but i’ve started from the example plugin…

    abt the 1,2,3 points….none of the above :s

    @david:

    yes, i’ve tried to look into it, did a couple of “ctrl+f” to look for “table-rate” and all other tests of the case…no luck.

    I’ll try to take a deeper calm look and get back here (in around 12 hour) with or without a solution…

    anyway…..in case anybody else experienced this before, please let me know…

    Thanks,

    Enrico.

  • chickenrun
    • Site Builder, Child of Zeus

    php extension seems not allowed…here’s a txt version…:

    <?php
    /*
    MarketPress Singolo-Paese Shipping Plugin
    Author: Enrico Icardi (http://www.aboutme.it)
    */

    class Singolo_Paese extends MP_Shipping_API {

    //private shipping method name. Lowercase alpha (a-z) and dashes (-) only please!
    var $plugin_name = 'singolo-paese';

    //public name of your method, for lists and such.
    var $public_name = 'Singolo Paese';

    //set to true if you need to use the shipping_metabox() method to add per-product shipping options
    var $use_metabox = false;

    /**
    * Runs when your class is instantiated. Use to setup your plugin instead of __construct()
    */
    function on_creation() {
    //set name here to be able to translate
    $this->public_name = __('Singolo Paese', 'mp');
    }

    /**
    * Echo anything you want to add to the top of the shipping screen
    */
    function before_shipping_form() {

    }

    /**
    * Echo anything you want to add to the bottom of the shipping screen
    */
    function after_shipping_form() {

    }

    /**
    * Echo a table row with any extra shipping fields you need to add to the shipping checkout form
    */
    function extra_shipping_field() {

    }

    /**
    * Use this to process any additional field you may add. Use the $_POST global,
    * and be sure to save it to both the cookie and usermeta if logged in.
    */
    function process_shipping_form() {

    }

    /**
    * Echo a settings meta box with whatever settings you need for you shipping module.
    * Form field names should be prefixed with mp[shipping][plugin_name], like "mp[shipping][plugin_name][mysetting]".
    * You can access saved settings via $settings array.
    */
    function shipping_settings_box($settings) {
    global $mp;
    ?>
    <div id="mp_singolo_paese" class="postbox">
    <h3 class='hndle'><span><?php _e('Single Country Settings', 'mp'); ?></span></h3>
    <div class="inside">
    <span class="description"><?php _e('Be sure to enter a shipping price for every option or those customers may get free shipping.', 'mp') ?></span>
    <table class="form-table" id="singleCountryTable">
    <tr>
    <td><strong><?php _e('Country', 'mp'); ?></strong></td>
    <td><strong><?php _e('Price', 'mp'); ?></strong></td>
    </tr>
    <?php
    //var_dump($settings);
    $cCodeBef = '';
    if($settings["shipping"]["singolo-paese"]){
    foreach ($settings["shipping"]["singolo-paese"] as $key=>$theCountry){
    $cCode = '';
    $cCode = explode("-",$key);
    $cCode = $cCode[1];
    //echo $cCode. "-";

    if($settings['shipping']['singolo-paese']['price-'.$cCode]){
    //avoid re-printing (cause there are 3 values with same cCode)
    if($cCode!=$cCodeBef){
    $cCodeBef = $cCode;
    $jsArr .= "'".$cCode."',";
    echo "<tr id='val-".$cCode."'><td><label>".$settings['shipping']['singolo-paese']['name-'.$cCode]."</label></td><td><input type='text' name='mp[shipping][singolo-paese][price-".$cCode."]' value='".$settings['shipping']['singolo-paese']['price-'.$cCode]."'></td><input type='hidden' name='mp[shipping][singolo-paese][name-".$cCode."]' value='".$settings['shipping']['singolo-paese']['name-'.$cCode]."'><input type='hidden' name='mp[shipping][singolo-paese][code-".$cCode."]' value='".$cCode."'></td></tr>";
    }
    }
    //var_dump($key);

    }
    //cust last comma
    $jsArr = substr($jsArr,0,-1);
    }
    ?>
    </table>
    </div>
    </div>

    <script type="text/javascript">
    //var $j = jQuery.noConflict();
    jQuery(document).ready(function ($) {

    //create array with already printed countries
    printedCountries = new Array(<?=$jsArr?>);
    console.log(printedCountries);

    //each country in list
    jQuery('#mp-target-countries label input').each(function(index){

    //get country name
    htmlCountrieName = jQuery(this).parent();
    var cName = htmlCountrieName.text();
    //console.log(cName);

    //create prices div for each country
    createDivCountry(jQuery(this).val(), cName);

    //check selected/unselected countries from main list...
    var nameC = jQuery(this).val();
    if(jQuery(this).attr('checked') == 'checked'){
    jQuery('#val-'+nameC).css('display','table-row');
    }else{
    jQuery('#val-'+nameC).css('display','none');
    }

    //if new country get selected/unselected from main list...
    jQuery(this).change(function(event){
    var nameC = jQuery(this).val();
    if(jQuery(this).attr('checked') == 'checked'){
    jQuery('#val-'+nameC).css('display','table-row');
    }else{
    jQuery('#val-'+nameC).css('display','none');
    }
    alert(jQuery(this).val());
    });

    });

    //create divs for countries
    function createDivCountry(cCode, cName){
    //console.log(cCode);
    if(jQuery.inArray(cCode,printedCountries) < 0){
    var inputNameAndValue = 'name="mp[shipping][singolo-paese][price-'+cCode+']" value=""';
    var inputNameAndValueH = 'name="mp[shipping][singolo-paese][name-'+cCode+']" value="'+cName+'"';
    var inputNameAndValueHCode = 'name="mp[shipping][singolo-paese][code-'+cCode+']" value="'+cCode+'"';

    jQuery('<tr style="display:none;" id="val-'+cCode+'"><td><label>'+cName+'</label></td><td><input type="text" '+inputNameAndValue+'></td><input type="hidden" '+inputNameAndValueH+'><input type="hidden" '+inputNameAndValueHCode+'></td></tr>').appendTo('#singleCountryTable');
    }else{
    //check in main list of already printed rows (although it should be already printed)
    jQuery('#mp-target-countries label input[value="'+cCode+'"]').attr('checked','checked');
    }
    }
    }); //close jquery ready
    </script>

    <?php
    }

    /**
    * Filters posted data from your form. Do anything you need to the $settings['shipping']['plugin_name']
    * array. Don't forget to return!
    */
    function process_shipping_settings($settings) {

    return $settings;
    }

    /**
    * Echo any per-product shipping fields you need to add to the product edit screen shipping metabox
    *
    * @param array $shipping_meta, the contents of the post meta. Use to retrieve any previously saved product meta
    * @param array $settings, access saved settings via $settings array.
    */
    function shipping_metabox($shipping_meta, $settings) {
    global $mp;
    ?>
    <label><?php _e('Extra Shipping Cost', 'mp'); ?>:<br />
    <?php echo $mp->format_currency(); ?><input type="text" size="6" id="mp_extra_shipping_cost" name="mp_extra_shipping_cost" value="<?php echo ($shipping_meta['extra_cost']) ? $mp->display_currency($shipping_meta['extra_cost']) : '0.00'; ?>" />
    </label>
    <?php
    }

    /**
    * Save any per-product shipping fields from the shipping metabox using update_post_meta
    *
    * @param array $shipping_meta, save anything from the $_POST global
    * return array $shipping_meta
    */
    function save_shipping_metabox($shipping_meta) {
    //process extra per item shipping
    $shipping_meta['extra_cost'] = (!empty($_POST['mp_extra_shipping_cost'])) ? round($_POST['mp_extra_shipping_cost'], 2) : 0;

    return $shipping_meta;
    }

    /**
    * Use this function to return your calculated price as an integer or float
    *
    * @param int $price, always 0. Modify this and return
    * @param float $total, cart total after any coupons and before tax
    * @param array $cart, the contents of the shopping cart for advanced calculations
    * @param string $address1
    * @param string $address2
    * @param string $city
    * @param string $state, state/province/region
    * @param string $zip, postal code
    * @param string $country, ISO 3166-1 alpha-2 country code
    *
    * return float $price
    */
    function calculate_shipping($price, $total, $cart, $address1, $address2, $city, $state, $zip, $country) {
    global $mp;
    $settings = get_option('mp_settings');

    return $price;
    }

    }

    //register plugin
    mp_register_shipping_plugin( 'Singolo_Paese', 'singolo-paese', __('Singolo Paese', 'mp') );
    ?>

  • chickenrun
    • Site Builder, Child of Zeus

    Here’s a new test…new plugin SUPER simple…same error….if i press “save” it saves and shows the right variables….(and dump the right settings array)

    but when i select another shipping method and come back to my custom one…it returns the settings of another one….

    <?php
    /*
    MarketPress Example Shipping Plugin Template
    */

    class Zone_Fasce extends MP_Shipping_API {

    //private shipping method name. Lowercase alpha (a-z) and dashes (-) only please!
    var $plugin_name = 'zone-fasce';

    //public name of your method, for lists and such.
    var $public_name = '';

    //set to true if you need to use the shipping_metabox() method to add per-product shipping options
    var $use_metabox = false;

    /**
    * Runs when your class is instantiated. Use to setup your plugin instead of __construct()
    */
    function on_creation() {
    //declare here for translation
    $this->public_name = __('Zone Fasce', 'mp');
    }

    /**
    * Echo anything you want to add to the top of the shipping screen
    */
    function before_shipping_form() {

    }

    /**
    * Echo anything you want to add to the bottom of the shipping screen
    */
    function after_shipping_form() {

    }

    /**
    * Echo a table row with any extra shipping fields you need to add to the form
    */
    function extra_shipping_field() {

    }

    /**
    * Use this to process any additional field you may add. Use the $_POST global,
    * and be sure to save it to both the cookie and usermeta if logged in.
    */
    function process_shipping_form() {

    }

    /**
    * Echo a settings meta box with whatever settings you need for you shipping module.
    * Form field names should be prefixed with mp[shipping][plugin_name], like "mp[shipping][plugin_name][mysetting]".
    * You can access saved settings via $settings array.
    */
    function shipping_settings_box($settings) {
    global $mp;
    var_dump($settings);
    ?>
    <div id="mp_zone_fasce" class="postbox">
    <h3 class='hndle'><span><?php _e('Single Country Settings', 'mp'); ?></span></h3>
    <div class="inside">
    <span class="description"><?php _e('Be sure to enter a shipping price for every option or those customers may get free shipping.', 'mp') ?></span>
    <table class="form-table">
    <tr>
    <td><strong><?php _e('Country', 'mp'); ?></strong></td>
    <td><strong><?php _e('Price', 'mp'); ?></strong></td>
    </tr>

    <tr>
    <td>
    <label><?php $settings['shipping']['zone-fasce']['prezzo-min'] ?></label>
    </td>
    <td>
    <input type='text' name='mp[shipping][zone-fasce][prezzo-min]' value='<?=$settings['shipping']['zone-fasce']['prezzo-min']?>'>
    </td>
    </tr>

    </table>
    </div>
    </div>
    <?php
    }

    /**
    * Filters posted data from your form. Do anything you need to the $settings['shipping']['plugin_name']
    * array. Don't forget to return!
    */
    function process_shipping_settings($settings) {

    return $settings;
    }

    /**
    * Echo any per-product shipping fields you need to add to the product edit screen shipping metabox
    *
    * @param array $shipping_meta, the contents of the post meta. Use to retrieve any previously saved product meta
    * @param array $settings, access saved settings via $settings array.
    */
    function shipping_metabox($shipping_meta, $settings) {

    }

    /**
    * Save any per-product shipping fields from the shipping metabox using update_post_meta
    *
    * @param array $shipping_meta, save anything from the $_POST global
    * return array $shipping_meta
    */
    function save_shipping_metabox($shipping_meta) {

    return $shipping_meta;
    }

    /**
    * Use this function to return your calculated price as an integer or float
    *
    * @param int $price, always 0. Modify this and return
    * @param float $total, cart total after any coupons and before tax
    * @param array $cart, the contents of the shopping cart for advanced calculations
    * @param string $address1
    * @param string $address2
    * @param string $city
    * @param string $state, state/province/region
    * @param string $zip, postal code
    * @param string $country, ISO 3166-1 alpha-2 country code
    *
    * return float $price
    */
    function calculate_shipping($price, $total, $cart, $address1, $address2, $city, $state, $zip, $country) {
    return $price;
    }

    }

    //register plugin - uncomment to register
    mp_register_shipping_plugin( 'Zone_Fasce', 'zone-fasce', __('Zone Fasce', 'mp') );
    ?>

  • chickenrun
    • Site Builder, Child of Zeus

    One thing i’ve noticed….

    It returns the settings of the method i select to “go out from mine”…

    Eg. Now:

    1- i’ve select mine

    2- saved my variable

    3- page refreshed and showed the right setting array

    4- i select a new shipping method (Flat Rate)

    5- go back to my custom plugin (“zone-fasce”:wink:

    6- and this is the dump of the “method” (the right one) and the “settings array” (wrong)

    [“method”]=> string(10) “zone-fasce” [“flat-rate”]=> array(4) { [“lower_48”]=> string(0) “” [“hi_ak”]=> string(0) “” [“canada”]=> string(0) “” [“international”]=> string(0) “” } } [“gateways”]=> array(2) { [“paypal-express”]=> array(3) { [“locale”]=> string(2) “US” [“currency”]=> string(3) “USD” [“mode”]=> string(7) “sandbox” } [“paypal-chained”]=> array(2) { [“currency”]=> string(3) “USD” [“mode”]=> string(7) “sandbox” } } [“msg”]=> array(7) { [“product_list”]=> string(0) “” [“order_status”]=> string(87)

    Question is….: what am i doing wrong?

  • Gary
    • Design Lord, Child of Thor

    OK, what I think is happening is when a different plugin is selected from the dropdown list, the code performs a full form submit. So it’s submitting the settings for one plugin along with the plugin name of another. If that’s then being processed and saved, that will cause the settings to be overwritten with the mixed version.

    When a different shipping method is selected the code shouldn’t submit, process and save the form.

    It should work more like:

    if (posted shipping method == current plugin name)
    {
    get values from posted form data
    merge into existing settings
    save new settings
    }
    else
    {
    load newly selected plugin details
    }

    That’s code in marketpress.php not your plugin!

    Put a var_dump in the table-rate and flat-rate plugins and simply switch between those two and you’ll see the same behaviour…

  • Gary
    • Design Lord, Child of Thor

    Yup – assuming I am correct in what I have said, the error is definitely in MP itself.

    I did have a go at making a change to the code, it didn’t work. Then I got side-tracked. Might have another look tonight.

    Basically the MP code needs to not save settings if the form has been submitted due to a change in plugin selected.

  • chickenrun
    • Site Builder, Child of Zeus

    Ok.

    I’ve found the problem.

    It’s slightly complicated but i understand why this works the way it works…:

    lines 387 to 392 of “marketpress.php”

    if (isset($_POST['shipping_settings'])) {
    $settings = get_option('mp_settings');
    //allow plugins to verify settings before saving
    $settings = array_merge($settings, apply_filters('mp_shipping_settings_filter', $_POST['mp']));
    update_option('mp_settings', $settings);
    }

    Saves the actual status

    and by switching the method: the “mp_settings” get saved on the db in a “mixed status”

    showing (passsing from new_method –to–> old_method) the new selected metod (eg. “new_method”:wink: but keeping the old array of values (eg. “old_method_values”:wink:.

    The behavior i was expecting by switching back to my previous method (new_method) was:

    1- new_method

    2- new_method_values

    Problem is that the entire form gets sent, therefore switching back (from old_method –to–> new_metod)

    sends all the values of the form (in this case: old_method_values) getting again…a “mixed status” like:

    1- new_method

    2- old_method_values

    This is because it merges the settings array.

    Therefore the behavior i was expecting comes ONLY when i press the button “Save” that will actually and obviously save on db the “current_method” and “current_method_values”.

    Took me quite a while to figure this out and, still, now that i understand how it works, doesn’t make much sense to me

    and it should be done in another way. (cause switching the method through the select doesn’t necessarily means that the user REALLY wants to change it…………:wink:

    I anyway know this limitation and i’m not going to modify “marketpress.php” although i think the MP team should look into this, since the expected behavior is different from what it does and the GUI looks like it should be doing something else….

Thank NAME, for their help.

Let NAME know exactly why they deserved these points.

Gift a custom amount of points.