Plugin Directory

Changeset 1760991


Ignore:
Timestamp:
11/08/2017 08:09:15 PM (8 years ago)
Author:
leadfox
Message:

Fixed incompatibility with Postman

Location:
leadfox/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • leadfox/trunk/leadfox.php

    r1760203 r1760991  
    22/**
    33 * Plugin Name: Leadfox
    4  * Version: 2.01
     4 * Version: 2.02
    55 * Author: Leadfox
    66 * Description: Leadfox converts visitors into ripe leads and paying customers.
    77 */
    88
    9 // Requires
    10 require_once(ABSPATH."wp-includes/pluggable.php");
     9// Sercurity check
     10defined("ABSPATH") or die("No script kiddies please!");
    1111
    12 // Styles
    13 wp_register_style("leadfox", plugins_url("css/leadfox.css", __FILE__));
    14 wp_enqueue_style("leadfox");
    15 
    16 // Globals
    17 global $leadfox_jwt;
    18 $leadfox_jwt = null;
    19 
    20 global $leadfox_notices;
    21 $leadfox_notices = array();
    22 
    23 // Defines
    24 define("LF_GET", "GET");
    25 define("LF_POST", "POST");
    26 define("LF_PUT", "PUT");
    27 define("LF_DELETE", "DELETE");
    28 
    29 /**
    30  * Plugin installation
    31  */
    32 function lf_install()
    33 {
    34     add_option("leadfox_apikey");
    35     add_option("leadfox_secret");
    36     add_option("leadfox_list");
    37 }
    38 register_activation_hook(__FILE__, "lf_install");
    39 
    40 /**
    41  * Uninstall leadfox plugin
    42  */
    43 function lf_uninstall()
    44 {
    45     delete_option("leadfox_apikey");
    46     delete_option("leadfox_secret");
    47     delete_option("leadfox_list");
    48 }
    49 register_deactivation_hook(__FILE__, "lf_uninstall");
    50 
    51 /**
    52  * Get a POST variable
    53  * @param {string} var - Post variable name
    54  * @return {string} - Value or null
    55  */
    56 function leadfox_post($var)
    57 {
    58     return isset($_POST[$var]) ? $_POST[$var] : null;
    59 }
    60 
    61 /**
    62  * Get the URL of an image for this plugin
    63  * @param {string} s - Image file name
    64  * @return {string} - Url of the image
    65  */
    66 function leadfox_img($s)
    67 {
    68     return plugins_url("images/".$s, __FILE__);
    69 }
    70 
    71 /**
    72  * Get options or post data
    73  * @return {array} - Options
    74  */
    75 function leadfox_options()
    76 {
    77     // Get post or configuration values
    78     return array(
    79         "apikey" => get_option("leadfox_apikey"),
    80         "secret" => get_option("leadfox_secret"),
    81         "list" => get_option("leadfox_list")
    82     );
    83 }
    84 
    85 /**
    86  * Update options
    87  */
    88 function leadfox_update_options()
    89 {
    90     update_option("leadfox_apikey", leadfox_post("apikey"));
    91     update_option("leadfox_secret", leadfox_post("secret"));
    92     update_option("leadfox_list", leadfox_post("list"));
    93     leadfox_notice(__("Your settings were saved correctly."), "success");
    94 }
    95 
    96 /**
    97  * Check if a user as one of the roles passed
    98  * @param {array} info - User roles
    99  * @param {array} roles - Roles to find
    100  * @return {boolean} - If any of the roles were found for user
    101  */
    102 function leadfox_hasrole($info, $roles)
    103 {
    104     foreach ($roles as $role) if (in_array($role, $info)) return true;
    105     return false;
    106 }
    107 
    108 /**
    109  * Get Rest API auth
    110  */
    111 function leadfox_rest_auth()
    112 {
    113     $options = leadfox_options();
    114 
    115     $auth = leadfox_rest(LF_POST, "auth", array(
    116         "apikey" => $options["apikey"],
    117         "secret" => $options["secret"]
    118     ), true);
    119 
    120     if ($auth["status"] == 200) return $auth["body"];
    121     else leadfox_notice(__("You must provide a valid API key and secret."), "error");
    122 }
    123 
    124 /**
    125  * Make a call to the Leadfox Rest API
    126  * @param {string} method - Method to use
    127  * @param {string} url - The relative endpoint url
    128  * @param {array} body - The request's body
    129  * @return {array} - The response array
    130  */
    131 function leadfox_rest($method, $url, $body = null, $isauth = false)
    132 {
     12add_action("plugins_loaded", function() {
     13    // Styles
     14    wp_register_style("leadfox", plugins_url("css/leadfox.css", __FILE__));
     15    wp_enqueue_style("leadfox");
     16   
     17    // Globals
    13318    global $leadfox_jwt;
    134 
    135     if (!$leadfox_jwt && !$isauth) $leadfox_jwt = leadfox_rest_auth();
    136 
    137     $headers = array(
    138         "Content-Type: application/json",
    139     );
    140 
    141     if ($leadfox_jwt) {
    142         array_push($headers, "Authorization: JWT ".$leadfox_jwt["jwt"]);
    143 
    144         if (isset($leadfox_jwt["clientid"])) {
    145             if (strpos($url, "?") === false) $url .= "?";
    146             else $url .= "&";
    147 
    148             $url .= "clientid=".$leadfox_jwt["clientid"];
     19    $leadfox_jwt = null;
     20   
     21    global $leadfox_notices;
     22    $leadfox_notices = array();
     23   
     24    // Defines
     25    define("LF_GET", "GET");
     26    define("LF_POST", "POST");
     27    define("LF_PUT", "PUT");
     28    define("LF_DELETE", "DELETE");
     29   
     30    /**
     31     * Plugin installation
     32     */
     33    function lf_install()
     34    {
     35        add_option("leadfox_apikey");
     36        add_option("leadfox_secret");
     37        add_option("leadfox_list");
     38    }
     39    register_activation_hook(__FILE__, "lf_install");
     40   
     41    /**
     42     * Uninstall leadfox plugin
     43     */
     44    function lf_uninstall()
     45    {
     46        delete_option("leadfox_apikey");
     47        delete_option("leadfox_secret");
     48        delete_option("leadfox_list");
     49    }
     50    register_deactivation_hook(__FILE__, "lf_uninstall");
     51   
     52    /**
     53     * Get a POST variable
     54     * @param {string} var - Post variable name
     55     * @return {string} - Value or null
     56     */
     57    function leadfox_post($var)
     58    {
     59        return isset($_POST[$var]) ? $_POST[$var] : null;
     60    }
     61   
     62    /**
     63     * Get the URL of an image for this plugin
     64     * @param {string} s - Image file name
     65     * @return {string} - Url of the image
     66     */
     67    function leadfox_img($s)
     68    {
     69        return plugins_url("images/".$s, __FILE__);
     70    }
     71   
     72    /**
     73     * Get options or post data
     74     * @return {array} - Options
     75     */
     76    function leadfox_options()
     77    {
     78        // Get post or configuration values
     79        return array(
     80            "apikey" => get_option("leadfox_apikey"),
     81            "secret" => get_option("leadfox_secret"),
     82            "list" => get_option("leadfox_list")
     83        );
     84    }
     85   
     86    /**
     87     * Update options
     88     */
     89    function leadfox_update_options()
     90    {
     91        update_option("leadfox_apikey", leadfox_post("apikey"));
     92        update_option("leadfox_secret", leadfox_post("secret"));
     93        update_option("leadfox_list", leadfox_post("list"));
     94        leadfox_notice(__("Your settings were saved correctly."), "success");
     95    }
     96   
     97    /**
     98     * Check if a user as one of the roles passed
     99     * @param {array} info - User roles
     100     * @param {array} roles - Roles to find
     101     * @return {boolean} - If any of the roles were found for user
     102     */
     103    function leadfox_hasrole($info, $roles)
     104    {
     105        foreach ($roles as $role) if (in_array($role, $info)) return true;
     106        return false;
     107    }
     108   
     109    /**
     110     * Get Rest API auth
     111     */
     112    function leadfox_rest_auth()
     113    {
     114        $options = leadfox_options();
     115   
     116        $auth = leadfox_rest(LF_POST, "auth", array(
     117            "apikey" => $options["apikey"],
     118            "secret" => $options["secret"]
     119        ), true);
     120   
     121        if ($auth["status"] == 200) return $auth["body"];
     122        else leadfox_notice(__("You must provide a valid API key and secret."), "error");
     123    }
     124   
     125    /**
     126     * Make a call to the Leadfox Rest API
     127     * @param {string} method - Method to use
     128     * @param {string} url - The relative endpoint url
     129     * @param {array} body - The request's body
     130     * @return {array} - The response array
     131     */
     132    function leadfox_rest($method, $url, $body = null, $isauth = false)
     133    {
     134        global $leadfox_jwt;
     135   
     136        if (!$leadfox_jwt && !$isauth) $leadfox_jwt = leadfox_rest_auth();
     137   
     138        $headers = array(
     139            "Content-Type: application/json",
     140        );
     141   
     142        if ($leadfox_jwt) {
     143            array_push($headers, "Authorization: JWT ".$leadfox_jwt["jwt"]);
     144   
     145            if (isset($leadfox_jwt["clientid"])) {
     146                if (strpos($url, "?") === false) $url .= "?";
     147                else $url .= "&";
     148   
     149                $url .= "clientid=".$leadfox_jwt["clientid"];
     150            }
    149151        }
    150     }
    151 
    152     $ch = curl_init();
    153 
    154     curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
    155     curl_setopt($ch, CURLOPT_URL, "https://rest.leadfox.co/v1/".$url);
    156     curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    157     curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    158 
    159     if (is_array($body)) curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($body));
    160 
    161     $response = curl_exec($ch);
    162     $status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    163     $error = curl_error($ch);
    164 
    165     curl_close ($ch);
    166 
    167     $ret = array(
    168         "body" => json_decode($response, true),
    169         "status" => $status,
    170         "error" => $error
    171     );
    172 
    173     if (!$isauth && $status >= 400)
    174     {
    175         leadfox_notice(__("There was a problem communicating with Leadfox")." ($status).", "error");
    176         error_log("Leadfox Rest API: ".json_encode($ret));
    177     }
    178 
    179     return $ret;
    180 }
    181 
    182 /**
    183  * The leadfox admin menu hook
    184  */
    185 function leadfox_admin_menu()
    186 {
    187     add_menu_page(
    188         "Leadfox",
    189         "Leadfox",
    190         "manage_options",
    191         "leadfox-menu",
    192         "leadfox_menu_output",
    193         leadfox_img("icon.png")
    194     );
    195 }
    196 add_action("admin_menu", "leadfox_admin_menu");
    197 
    198 /**
    199  * Register a notice
    200  * @param {string} class - Message class
    201  * @param {string} msg - Message
    202  */
    203 function leadfox_notice($msg, $class = "info")
    204 {
    205     global $leadfox_notices;
    206     array_push($leadfox_notices, array("msg" => $msg, "class" => $class));
    207 }
    208 
    209 /**
    210  * Leadfox notices
    211  */
    212 function leadfox_admin_notices()
    213 {
    214     global $leadfox_notices;
    215     $html = "";
    216 
    217     foreach ($leadfox_notices as $notice) $html .= '<div class="notice notice-'.esc_attr($notice["class"]).' is-dismissible"><p>'.esc_html($notice["msg"]).'</p></div>';
    218 
    219     return $html;
    220 }
    221 
    222 /**
    223  * Output the page
    224  * @param {string} buffer - Output buffer
    225  */
    226 function leadfox_output($buffer)
    227 {
    228     return leadfox_admin_notices().$buffer;
    229 }
    230 
    231 /**
    232  * The plugin's page hook
    233  */
    234 function leadfox_menu_output()
    235 {
    236     $options = leadfox_options();
    237     $lists = leadfox_rest(LF_GET, "list?sort=name");
    238 
    239     ob_start("leadfox_output");
    240 ?>
    241     <div class="leadfox-plugin">
    242         <form name="leadfox-options" method="post">
    243             <img src="<?php echo leadfox_img("logo.png") ?>" alt="Leadfox">
    244             <h1>Wordpress Integration</h1>
    245 
    246             <p><?php _e("Enter your API key and secret to integrate the LeadFox tracking codes.") ?><br>
    247             <?php _e("These can be found under the API section of the Manage menu in your Leadfox account.") ?></p>
    248             <label for="lf-key"><?php _e("API key") ?></label>
    249             <div>
    250                 <input id="lf-key" type="text" name="apikey" value="<?php echo $options["apikey"] ?>">
    251             </div>
    252 
    253             <label for="lf-secret"><?php _e("Secret") ?></label>
    254             <div>
    255                 <input id="lf-secret" type="text" name="secret" value="<?php echo $options["secret"] ?>">
    256             </div>
    257 
    258             <label for="lf-list"><?php _e("List for new contacts") ?></label>
    259             <div>
    260                 <select id="lf-list" name="list">
    261                     <option value=""><?php _e("No list") ?></option>
    262 
    263                     <?php if ($lists["body"]) foreach ($lists["body"] as $list): ?>
    264                         <option value="<?php echo $list["_id"] ?>" <?php if ($list["_id"] == $options["list"]) echo "selected"?>><?php echo $list["name"] ?></option>
    265                     <?php endforeach ?>
    266                 </select>
    267             </div>
    268 
    269             <div>
    270                 <button type="submit" name="submit"><?php _e("Submit") ?></button>
    271             </div>
    272 
    273             <hr>
    274             <label><?php _e("Sync all contacts now") ?></label>
    275             <div>
    276                 <button type="submit" name="sync"><?php _e("Sync") ?></button>
    277             </div>
    278         </form>
    279     </div> 
    280 <?php
    281     ob_end_flush();
    282 }
    283 
    284 /**
    285  * New user registration hook
    286  * @param {integer} uid - User ID
    287  * @return {boolean} - Contact updated?
    288  */
    289 function leadfox_user_register($uid)
    290 {
    291     $options = leadfox_options();
    292     $info = get_userdata($uid);
    293 
    294     if (leadfox_hasrole($info->roles, array("subscriber", "customer")) && $options["list"])
    295     {
    296         // Send new contact
    297         $body = array(
    298             "name" => $info->first_name." ".$info->last_name,
    299             "email" => $info->user_email,
    300             "properties" => array(
    301                 "firstname" => $info->first_name,
    302                 "lastname" => $info->last_name,
    303                 "phone" => get_user_meta($uid, "billing_phone", true)
    304             )
     152   
     153        $ch = curl_init();
     154   
     155        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
     156        curl_setopt($ch, CURLOPT_URL, "https://rest.leadfox.co/v1/".$url);
     157        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
     158        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
     159   
     160        if (is_array($body)) curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($body));
     161   
     162        $response = curl_exec($ch);
     163        $status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
     164        $error = curl_error($ch);
     165   
     166        curl_close ($ch);
     167   
     168        $ret = array(
     169            "body" => json_decode($response, true),
     170            "status" => $status,
     171            "error" => $error
    305172        );
    306 
    307         $contact = leadfox_rest(LF_POST, "contact/upsert", $body);
    308 
    309         // Add contact to list
    310         $url = "list/".$options["list"]."/contact/".$contact["body"]["_id"];
    311         $list = leadfox_rest(LF_POST, $url);
    312 
    313         return true;
    314     }
    315 
    316     return false;
    317 }
    318 add_action("user_register", "leadfox_user_register");
    319 
    320 /**
    321  * Sync all contacts
    322  */
    323 function leadfox_sync_contacts()
    324 {
    325     $count = 0;
    326 
    327     $users = get_users(array(
    328         "role__in" => array("subscriber", "customer"),
    329         "orderby" => "id",
    330         "fields" => array("id")
    331     ));
    332 
    333     foreach ($users as $user) if (leadfox_user_register($user->id)) $count++;
    334     leadfox_notice($count." ".__("contact(s) updated"), "success");
    335 }
    336 
    337 /**
    338  * Add the tracking code to all pages
    339  */
    340 function leadfox_footer()
    341 {
    342     global $wp;
    343     $url = home_url(add_query_arg(array(), $wp->request));
    344     $options = leadfox_options();
    345 
    346     if (strpos($url, "order-received") !== false)
    347     {
    348         echo "<script>(function(l,f,o,x){var a=f.getElementsByTagName(o)[0],b=f.createElement(o);b.async=true;b.id='__js_lm_00';b.src='//app.leadfox.co/js/api/lifecycle.js?key='+x+'&l='+l;a.parentNode.insertBefore(b,a);})(5,document,'script','".$options["apikey"]."');</script>";
    349     }
    350 
    351     echo "<script>(function(f,o,x){var a=f.getElementsByTagName(o)[0],b=f.createElement(o);b.async=true;b.id='__js_lm_00';b.src='//app.leadfox.co/js/api/init.js?key='+x;a.parentNode.insertBefore(b,a);})(document,'script','".$options["apikey"]."');</script>";
    352 }
    353 add_action("wp_footer", "leadfox_footer");
    354 
    355 // Main
    356 if (leadfox_post("submit") !== null) leadfox_update_options();
    357 if (leadfox_post("sync") !== null) leadfox_sync_contacts();
     173   
     174        if (!$isauth && $status >= 400)
     175        {
     176            leadfox_notice(__("There was a problem communicating with Leadfox")." ($status).", "error");
     177            error_log("Leadfox Rest API: ".json_encode($ret));
     178        }
     179   
     180        return $ret;
     181    }
     182   
     183    /**
     184     * The leadfox admin menu hook
     185     */
     186    function leadfox_admin_menu()
     187    {
     188        add_menu_page(
     189            "Leadfox",
     190            "Leadfox",
     191            "manage_options",
     192            "leadfox-menu",
     193            "leadfox_menu_output",
     194            leadfox_img("icon.png")
     195        );
     196    }
     197    add_action("admin_menu", "leadfox_admin_menu");
     198   
     199    /**
     200     * Register a notice
     201     * @param {string} class - Message class
     202     * @param {string} msg - Message
     203     */
     204    function leadfox_notice($msg, $class = "info")
     205    {
     206        global $leadfox_notices;
     207        array_push($leadfox_notices, array("msg" => $msg, "class" => $class));
     208    }
     209   
     210    /**
     211     * Leadfox notices
     212     */
     213    function leadfox_admin_notices()
     214    {
     215        global $leadfox_notices;
     216        $html = "";
     217   
     218        foreach ($leadfox_notices as $notice) $html .= '<div class="notice notice-'.esc_attr($notice["class"]).' is-dismissible"><p>'.esc_html($notice["msg"]).'</p></div>';
     219   
     220        return $html;
     221    }
     222   
     223    /**
     224     * Output the page
     225     * @param {string} buffer - Output buffer
     226     */
     227    function leadfox_output($buffer)
     228    {
     229        return leadfox_admin_notices().$buffer;
     230    }
     231   
     232    /**
     233     * The plugin's page hook
     234     */
     235    function leadfox_menu_output()
     236    {
     237        $options = leadfox_options();
     238        $lists = leadfox_rest(LF_GET, "list?sort=name");
     239   
     240        ob_start("leadfox_output");
     241    ?>
     242        <div class="leadfox-plugin">
     243            <form name="leadfox-options" method="post">
     244                <img src="<?php echo leadfox_img("logo.png") ?>" alt="Leadfox">
     245                <h1>Wordpress Integration</h1>
     246   
     247                <p><?php _e("Enter your API key and secret to integrate the LeadFox tracking codes.") ?><br>
     248                <?php _e("These can be found under the API section of the Manage menu in your Leadfox account.") ?></p>
     249                <label for="lf-key"><?php _e("API key") ?></label>
     250                <div>
     251                    <input id="lf-key" type="text" name="apikey" value="<?php echo $options["apikey"] ?>">
     252                </div>
     253   
     254                <label for="lf-secret"><?php _e("Secret") ?></label>
     255                <div>
     256                    <input id="lf-secret" type="text" name="secret" value="<?php echo $options["secret"] ?>">
     257                </div>
     258   
     259                <label for="lf-list"><?php _e("List for new contacts") ?></label>
     260                <div>
     261                    <select id="lf-list" name="list">
     262                        <option value=""><?php _e("No list") ?></option>
     263   
     264                        <?php if ($lists["body"]) foreach ($lists["body"] as $list): ?>
     265                            <option value="<?php echo $list["_id"] ?>" <?php if ($list["_id"] == $options["list"]) echo "selected"?>><?php echo $list["name"] ?></option>
     266                        <?php endforeach ?>
     267                    </select>
     268                </div>
     269   
     270                <div>
     271                    <button type="submit" name="submit"><?php _e("Submit") ?></button>
     272                </div>
     273   
     274                <hr>
     275                <label><?php _e("Sync all contacts now") ?></label>
     276                <div>
     277                    <button type="submit" name="sync"><?php _e("Sync") ?></button>
     278                </div>
     279            </form>
     280        </div> 
     281    <?php
     282        ob_end_flush();
     283    }
     284   
     285    /**
     286     * New user registration hook
     287     * @param {integer} uid - User ID
     288     * @return {boolean} - Contact updated?
     289     */
     290    function leadfox_user_register($uid)
     291    {
     292        $options = leadfox_options();
     293        $info = get_userdata($uid);
     294   
     295        if (leadfox_hasrole($info->roles, array("subscriber", "customer")) && $options["list"])
     296        {
     297            // Send new contact
     298            $body = array(
     299                "name" => $info->first_name." ".$info->last_name,
     300                "email" => $info->user_email,
     301                "properties" => array(
     302                    "firstname" => $info->first_name,
     303                    "lastname" => $info->last_name,
     304                    "phone" => get_user_meta($uid, "billing_phone", true)
     305                )
     306            );
     307   
     308            $contact = leadfox_rest(LF_POST, "contact/upsert", $body);
     309   
     310            // Add contact to list
     311            $url = "list/".$options["list"]."/contact/".$contact["body"]["_id"];
     312            $list = leadfox_rest(LF_POST, $url);
     313   
     314            return true;
     315        }
     316   
     317        return false;
     318    }
     319    add_action("user_register", "leadfox_user_register");
     320   
     321    /**
     322     * Sync all contacts
     323     */
     324    function leadfox_sync_contacts()
     325    {
     326        $count = 0;
     327   
     328        $users = get_users(array(
     329            "role__in" => array("subscriber", "customer"),
     330            "orderby" => "id",
     331            "fields" => array("id")
     332        ));
     333   
     334        foreach ($users as $user) if (leadfox_user_register($user->id)) $count++;
     335        leadfox_notice($count." ".__("contact(s) updated"), "success");
     336    }
     337   
     338    /**
     339     * Add the tracking code to all pages
     340     */
     341    function leadfox_footer()
     342    {
     343        global $wp;
     344        $url = home_url(add_query_arg(array(), $wp->request));
     345        $options = leadfox_options();
     346   
     347        if (strpos($url, "order-received") !== false)
     348        {
     349            echo "<script>(function(l,f,o,x){var a=f.getElementsByTagName(o)[0],b=f.createElement(o);b.async=true;b.id='__js_lm_00';b.src='//app.leadfox.co/js/api/lifecycle.js?key='+x+'&l='+l;a.parentNode.insertBefore(b,a);})(5,document,'script','".$options["apikey"]."');</script>";
     350        }
     351   
     352        echo "<script>(function(f,o,x){var a=f.getElementsByTagName(o)[0],b=f.createElement(o);b.async=true;b.id='__js_lm_00';b.src='//app.leadfox.co/js/api/init.js?key='+x;a.parentNode.insertBefore(b,a);})(document,'script','".$options["apikey"]."');</script>";
     353    }
     354    add_action("wp_footer", "leadfox_footer");
     355   
     356    // Main
     357    if (leadfox_post("submit") !== null) leadfox_update_options();
     358    if (leadfox_post("sync") !== null) leadfox_sync_contacts();
     359});
  • leadfox/trunk/readme.txt

    r1760218 r1760991  
    44Requires at least: 3.7
    55Tested up to: 4.8.2
    6 Stable tag: 2.01
     6Stable tag: 2.02
    77License: GPLv2 or later
    88
     
    3636== Changelog ==
    3737
     38= 2.02 =
     39Fixed incompatibility with other email plugins.
     40
    3841= 2.01 =
    3942Minor bug fix concerning authentification.
Note: See TracChangeset for help on using the changeset viewer.