Jump to content
  • Checkout
  • Login
  • Get in touch

osCommerce

The e-commerce.

greasemonkey

Members
  • Posts

    1,371
  • Joined

  • Last visited

  • Days Won

    25

Posts posted by greasemonkey

  1. @@raiwa ok here is short list from the install so far:

     

    1) the English defines for the reports and tools admin boxes are missing...

     

    2) Getting this on qtprodoctor.php

     Fatal error: Call to undefined function qtpro_normal_product_count() in /home/XXXXXXXXX/public_html/sandbox/admin/qtprodoctor.php on line 67
    

    Should the function not be included/required somewhere????

      require('includes/functions/qtpro_functions.php');
    

    Now just trying to figure out how to use it.... I will go through the manual and report back anything else...

  2. @@raiwa Just to confirm... these are no longer required then....

    # Insert configuration group for Product Information page
    DELETE FROM configuration_group WHERE configuration_group_id=888001;
    INSERT INTO configuration_group (configuration_group_id, configuration_group_title, configuration_group_description, sort_order, visible) VALUES (888001, 'Prod Info (QTPro)', 'Configuration options for the Product Information page. This configuration menu is acctually the menu for the contribution QTPro.', 8, 1);
    
    # Insert configuration keys for Product Information Page
    DELETE FROM configuration WHERE configuration_key='PRODINFO_ATTRIBUTE_PLUGIN';
    INSERT INTO configuration (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added, use_function, set_function) VALUES ('Product Info Attribute Display Plugin', 'PRODINFO_ATTRIBUTE_PLUGIN', 'multiple_dropdowns', 'The plugin used for displaying attributes on the product information page.', 888001, 1, now(), NULL, 'tep_cfg_pull_down_class_files(\'pad_\',');
    
    DELETE FROM configuration WHERE configuration_key='PRODINFO_ATTRIBUTE_SHOW_OUT_OF_STOCK';
    INSERT INTO configuration (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added, use_function, set_function) VALUES ('Show Out of Stock Attributes', 'PRODINFO_ATTRIBUTE_SHOW_OUT_OF_STOCK', 'True', '<b>If True:</b> Attributes that are out of stock will be displayed.<br /><br /><b>If False:</b> Attributes that are out of stock will <b><em>not</em></b> be displayed.</b><br /><br /><b>Default is True.</b>', 888001, 10, now(), NULL, 'tep_cfg_select_option(array(\'True\', \'False\'),');
    
    DELETE FROM configuration WHERE configuration_key='PRODINFO_ATTRIBUTE_MARK_OUT_OF_STOCK';
    INSERT INTO configuration (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added, use_function, set_function) VALUES ('Mark Out of Stock Attributes', 'PRODINFO_ATTRIBUTE_MARK_OUT_OF_STOCK', 'Right', 'Controls how out of stock attributes are marked as out of stock.', 888001, 20, now(), NULL, 'tep_cfg_select_option(array(\'None\', \'Right\', \'Left\'),');
    
    DELETE FROM configuration WHERE configuration_key='PRODINFO_ATTRIBUTE_OUT_OF_STOCK_MSGLINE';
    INSERT INTO configuration (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added, use_function, set_function) VALUES ('Display Out of Stock Message Line', 'PRODINFO_ATTRIBUTE_OUT_OF_STOCK_MSGLINE', 'True', '<b>If True:</b> If an out of stock attribute combination is selected by the customer, a message line informing on this will displayed.', 888001, 30, now(), NULL, 'tep_cfg_select_option(array(\'True\', \'False\'),');
    
    DELETE FROM configuration WHERE configuration_key='PRODINFO_ATTRIBUTE_NO_ADD_OUT_OF_STOCK';
    INSERT INTO configuration (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added, use_function, set_function) VALUES ('Prevent Adding Out of Stock to Cart', 'PRODINFO_ATTRIBUTE_NO_ADD_OUT_OF_STOCK', 'True', '<b>If True:</b> Customer will not be able to ad a product with an out of stock attribute combination to the cart. A javascript form will be displayed.', 888001, 40, now(), NULL, 'tep_cfg_select_option(array(\'True\', \'False\'),');
    
    DELETE FROM configuration WHERE configuration_key='PRODINFO_ATTRIBUTE_ACTUAL_PRICE_PULL_DOWN';
    INSERT INTO configuration (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added, use_function, set_function) VALUES ('Use Actual Price Pull Downs', 'PRODINFO_ATTRIBUTE_ACTUAL_PRICE_PULL_DOWN', 'False', '<font color="red"><b>NOTE:</b></font> This can only be used with a satisfying result if you have only one option per product.<br /><br /><b>If True:</b> Option prices will displayed as a final product price.<br /><br /><b>Default is false.</b>', 888001, 40, now(), NULL, 'tep_cfg_select_option(array(\'True\', \'False\'),');
    
    DELETE FROM configuration WHERE configuration_key='PRODINFO_ATTRIBUTE_DISPLAY_STOCK_LIST';
    INSERT INTO configuration (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added, use_function, set_function) VALUES ('Display table with stock information', 'PRODINFO_ATTRIBUTE_DISPLAY_STOCK_LIST', 'True', '<b>If True:</b> A table with information on whats on stock will be displayed to the customer. If product doesn\'t have any attributes with tracked stock; the table won\'t be displayed.<br /><br /><b>Default is true.</b>', 888001, 50, now(), NULL, 'tep_cfg_select_option(array(\'True\', \'False\'),');
    
    
  3. @@auzStar Ok so I found it... although it was/is prob not a big deal.... in includes\modules\content\category\templates\cm_category_new_products_carousel.php and includes\modules\content\index\templates\cm_i_new_products_carousel.php

    $(window).load(function() {
    

    needs to be updated to

     $(window).on(\'load\', function () {
    

    Please confirm.... as this is far from my expertise....

     

    Source.... here

  4. @@auzStar hey Dominic, I believe I'm having a conflict with jquery 3.1.1 (one of many with 3.1.1..... :x :x :x :x )

     

    Getting the following showing in the console

     

    TypeError: a.indexOf is not a function

     

    r.fn.load https://www.XXXXX.com/sandbox/ext/jquery/jquery-3.1.1.min.js:4:19060
        <anonymous> https://www.XXXXXX.com/sandbox/:1143:1

     

    Which is pointing to;

    $(window).load(function() {
    

    I believe this is suppose to be updated to

    $(window).on('load', function() {
    

    but I'm not 100% sure.... Nor can I find this in the owl js file or header tag.... Maybe I'm missing something????

  5. @@burt, somewhat related question.... in my checkout_success content mod, to grab and store the customers IP address, you had suggested to use the built in function to get the IP.

       $customers_ip = tep_db_prepare_input(tep_get_ip_address());
    

    In place of

        $client  = @$_SERVER['HTTP_CLIENT_IP'];
        $forward = @$_SERVER['HTTP_X_FORWARDED_FOR'];
        $remote  = $_SERVER['REMOTE_ADDR'];
     
        if(filter_var($client, FILTER_VALIDATE_IP))
        {
            $ip = $client;
        }
        elseif(filter_var($forward, FILTER_VALIDATE_IP))
        {
            $ip = $forward;
        }
        else
        {
            $ip = $remote;
        }
    

    Which I certainly understand.... however, have you noticed the built in function does not get IPV6 addresses?

     

    I've noticed, by looking at "who's online", about 25% of customers online have a "blank" IP address... and now that I have moved this over to my live site also notice about 25% of the orders are have no IP.

     

    I've drawn the conclusion - based on my original  code where 100% had an IP and about 25% of those IP's where IPV6 (I believe... example below)....

     

     

    xxxx:1970:48e2:xx

     

    Thoughts????

  6. Ok I made an error in my hook... carrying over code from the previous version that required edits to the order class.

    	    global $order;
    	  
    	      $customers_ip = $order->customer['customers_ip'];
    

    So, I have redone the hook to include its own query....

    <?php
    /*
      $Id$
    
      osCommerce, Open Source E-Commerce Solutions
      http://www.oscommerce.com
    
      Copyright (c) 2014 osCommerce
    
      Released under the GNU General Public License
    */
    
      class hook_admin_orders_location {
    
        function listen_orderTab() {
          global $_GET;
    
              $customer_ip_query = tep_db_query("select customers_ip from orders where orders_id = '" . (int)$_GET['oID'] . "'");
    		  $customer_ip_raw = tep_db_fetch_array($customer_ip_query);		
    		  $customers_ip = $customer_ip_raw['customers_ip'];
    	  
              $tab_title = Location;
              $tab_link = substr(tep_href_link('orders.php', tep_get_all_get_params()), strlen($base_url)) . '#section_location_content';
    
              $geo = unserialize(file_get_contents("http://www.geoplugin.net/php.gp?ip=$customers_ip"));
    
              $country = $geo["geoplugin_countryName"];
              $city = $geo["geoplugin_city"];
              $region = $geo["geoplugin_regionName"];
    		  $latitude = $geo["geoplugin_latitude"];
    		  $longitude = $geo["geoplugin_longitude"];
    
             
    		 $output = <<<EOD
    <script>
    $(function() {
      $('#orderTabs ul').append('<li><a href="{$tab_link}">{$tab_title}</a></li>');
    });
    </script>
    
    <div id="section_location_content" style="padding: 10px;">
     <p><strong>Customers Location: </strong>{$customers_ip}<br><br>{$country}<br>{$city}<br>{$region}<br>{$latitude}<br>{$longitude}</p> 
     
    </div>
    EOD;
    
          return $output;
        }
      }
    ?>
    
  7. @@burt any issues with something like this? Geoplugin seems reputable...

              $geo = unserialize(file_get_contents("http://www.geoplugin.net/php.gp?ip=$customers_ip"));
    
              $country = $geo["geoplugin_countryName"];
              $city = $geo["geoplugin_city"];
              $region = $geo["geoplugin_regionName"];
              $latitude = $geo["geoplugin_latitude"];
              $longitude = $geo["geoplugin_longitude"];
    

    And then output like...

     <p><strong>Customers Location: </strong>{$customers_ip}<br><br>{$country}<br>{$city}<br>{$region}<br>{$latitude}<br>{$longitude}</p>
    

    Now... I could set up a Google Map api on the city, or even the lat/long...... they have lots of examples.... here

     

    But then you would be required to get a Google map API key.

  8. @@burt thanks Gary.

     

    I'll put it together into and addon once I've had a chance to double check it and test...

     

    Now the original idea was to supply the IP address AND the country - do you have any ideas on how to supply the country data for the IP in the cleanest possible way? In a perfect world a map... but I would be happy with just the country.

     

    It looks like the Google API is out... geolocation is only via W3C.

     

    IP2location is do-able... they provide a free country database I think (but I think you have to register.... and the DB has to be downloaded and maintained)

     

    There are mutiple free API's but they are all small....

  9. Ok.... I get (got it) it.....

    <?php
    /*
      $Id$
    
      osCommerce, Open Source E-Commerce Solutions
      http://www.oscommerce.com
    
      Copyright (c) 2014 osCommerce
    
      Released under the GNU General Public License
    */
    
      class hook_admin_orders_location {
    
        function listen_orderTab() {
    	    global $order;
    	  
    	      $customers_ip = $order->customer['customers_ip'];
              $tab_title = Location;
              $tab_link = substr(tep_href_link('orders.php', tep_get_all_get_params()), strlen($base_url)) . '#section_location_content';
    
              $output = <<<EOD
    <script>
    $(function() {
      $('#orderTabs ul').append('<li><a href="{$tab_link}">{$tab_title}</a></li>');
    });
    </script>
    
    <div id="section_location_content" style="padding: 10px;">
    
     <p><strong>Customers Location: </strong>{$customers_ip}</p>	
    </div>
    EOD;
    
          return $output;
        }
      }
    ?>
    
  10. @@burt I see I made a mistake in my code above... not giving a global to $order_id

        function execute() {
          global $oscTemplate;
    

    Needs to be:

        function execute() {
          global $oscTemplate, $order_id;
    

    Now... I'm a little confused on how to make an admin (or any) hook... I'm trying to deconstruct the paypal hook.

    Questions... the file /includes/hooks/admin/orders/paypal.php (.... I will call the new file locations.php)

     

    Is this the only file that would be required (and a language file?)? The paypal hook looks to point to the app... with         include(DIR_FS_CATALOG . 'includes/apps/paypal/hooks/admin/orders/action.php');......  because I'm not making a app I presume it would go something like (not tested):

      class hook_admin_orders_location {
    
        function listen_orderTab() {
    	global $orders;
    	  
              $tab_title = addslashes($this->_app->getDef('tab_title'));
              $tab_link = substr(tep_href_link('orders.php', tep_get_all_get_params()), strlen($base_url)) . '#section_location_content';
    
              $output = <<<EOD
    <script>
    $(function() {
      $('#orderTabs ul').append('<li><a href="{$tab_link}">{$tab_title}</a></li>');
    });
    </script>
    
    <div id="section_location_content" style="padding: 10px;">
     <p><strong>Customers Location: </strong><?php echo $order->customer['customers_ip'];?></p>	
    </div>
    EOD;
          $hook = new location_hook_admin_orders_tab();
    
          return $hook->execute();
        }
      }
    
  11. @@AlexandrZuyev

     

    Here is a simplified version of your modification that would work in 2.3.4 BS or above... It removes the outside CURL call but still gives you the IP.

     

    No core changes.... it adds (and removes on un-install) the required column to the orders table (there is no way that I know of to do a check (if exists) on a column... so the only way I can see adding the column is to remove the column on un-install... thereby REMOVING/DELETING the IP data in the column.

     

    Displaying the IP without a core change would still be on the to do list....

     

    for includes/modules/content/checkout_success/cm_customers_location.php

    <?php
    /*
      THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    */
    
      class cm_customers_location {
        var $code;
        var $group;
        var $title;
        var $description;
        var $sort_order;
        var $enabled = false;
    
        function cm_customers_location() {
          $this->code = get_class($this);
          $this->group = basename(dirname(__FILE__));
    
          $this->title = MODULE_CONTENT_CUSTOMER_LOCATION_TITLE;
          $this->description = MODULE_CONTENT_CUSTOMER_LOCATION_DESCRIPTION;
          $this->description .= '<div class="secWarning">' . MODULE_CONTENT_BOOTSTRAP_ROW_DESCRIPTION . '</div>';
    
          if ( defined('MODULE_CONTENT_CUSTOMER_LOCATION_STATUS') ) {
            $this->sort_order = MODULE_CONTENT_CUSTOMER_LOCATION_SORT_ORDER;
            $this->enabled = (MODULE_CONTENT_CUSTOMER_LOCATION_STATUS == 'True');
          }
        }
    
        function execute() {
          global $oscTemplate;
          
        $content_width = (int)MODULE_CONTENT_CUSTOMER_LOCATION_CONTENT_WIDTH;
    	
       $customers_ip = tep_db_prepare_input(tep_get_ip_address());
    
       tep_db_query("update orders set customers_ip = '" . tep_db_input($customers_ip) . "' where orders_id = '" . (int)$order_id . "' ");	
          
          ob_start();
          include(DIR_WS_MODULES . 'content/' . $this->group . '/templates/customer_location.php');
          $template = ob_get_clean();
    
          $oscTemplate->addContent($template, $this->group);
        }
    
        function isEnabled() {
          return $this->enabled;
        }
    
        function check() {
          return defined('MODULE_CONTENT_CUSTOMER_LOCATION_STATUS');
        }
    
        function install() {
          tep_db_query("insert into configuration (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, date_added) values ('Enable Customers Location Module', 'MODULE_CONTENT_CUSTOMER_LOCATION_STATUS', 'True', 'Do you want to enable this module?', '6', '1', 'tep_cfg_select_option(array(\'True\', \'False\'), ', now())");
          tep_db_query("insert into configuration (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, date_added) values ('Content Width', 'MODULE_CONTENT_CUSTOMER_LOCATION_CONTENT_WIDTH', '4', 'What width container should the content be shown in?', '6', '1', 'tep_cfg_select_option(array(\'12\', \'11\', \'10\', \'9\', \'8\', \'7\', \'6\', \'5\', \'4\', \'3\', \'2\', \'1\'), ', now())");
          tep_db_query("insert into configuration (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Sort Order', 'MODULE_CONTENT_CUSTOMER_LOCATION_SORT_ORDER', '0', 'Sort order of display. Lowest is displayed first.', '6', '0', now())");
    	  tep_db_query("ALTER TABLE orders ADD customers_ip varchar(25) NOT NULL");
        }
    
        function remove() {
          tep_db_query("delete from configuration where configuration_key in ('" . implode("', '", $this->keys()) . "')");
    	  tep_db_query("ALTER TABLE orders DROP customers_ip");	  
        }
    
        function keys() {
          return array('MODULE_CONTENT_CUSTOMER_LOCATION_STATUS', 'MODULE_CONTENT_CUSTOMER_LOCATION_CONTENT_WIDTH', 'MODULE_CONTENT_CUSTOMER_LOCATION_SORT_ORDER');
        }
      }
    
    
    

    for includes/modules/content/checkout_success/templates/customer_location.php

    <div class="col-sm-<?php echo $content_width; ?> text-center">  
      <div class="panel panel-danger">
        <div class="panel-heading"> 
          <?php echo MODULE_CONTENT_CUSTOMER_LOCATION_PUBLIC_TITLE; ?>
        </div>
        <div class="panel-body panel-large">
          <?php 
          // $happy is the number of customer
          echo sprintf(MODULE_CONTENT_CUSTOMER_LOCATION_PUBLIC_TEXT, $customers_ip); 
          ?>
        </div>    
      </div>
    </div>
    

    And for a language file....

      <?php
    
      define('MODULE_CONTENT_CUSTOMER_LOCATION_TITLE', 'Customers Location');
      define('MODULE_CONTENT_CUSTOMER_LOCATION_DESCRIPTION', 'Shows Customers Location');
      
      define('MODULE_CONTENT_CUSTOMER_LOCATION_PUBLIC_TITLE', 'Location and IP Address');
      define('MODULE_CONTENT_CUSTOMER_LOCATION_PUBLIC_TEXT', '<p>%s</p>');
    
  12. Ok, now.... how to display the IP "somewhere" in orders.php without a core change?????

     

    I will post the content mod here for someone to test.....

     

    @@burt.... someone with some skill ( ;) ) could probably use call to google to find the customers location from the IP and compare to the delivery address to "flag" a store owner something is up.... That would be valuable ;) ;) ;) ;) ;)

  13. @@burt that should be a good start... thank you very kindly.

     

    It should be easy to create the required column in the orders table on install of the module...

     

     

    The code posted by OP is far from ideal - none of that should be used. If it was me...I would simply be storing IP address, and then (if needed) lookup from within admin on an as-needed basis.

    I can certainly understand why you  wouldn't like the outside curl.... but I do you see anything wrong with;

        $client  = @$_SERVER['HTTP_CLIENT_IP'];
        $forward = @$_SERVER['HTTP_X_FORWARDED_FOR'];
        $remote  = $_SERVER['REMOTE_ADDR'];
     
        if(filter_var($client, FILTER_VALIDATE_IP))
        {
            $ip = $client;
        }
        elseif(filter_var($forward, FILTER_VALIDATE_IP))
        {
            $ip = $forward;
        }
        else
        {
            $ip = $remote;
        }
    

    To get the IP.... thoughts?

  14. @@Jack_mcs thanks Jack... yes I have seen that one... The great thing about the outside connection (which I didn't actually use - I deliver our site on cloudflare SDN which has a built in function available by using HTTP_CF_IPCOUNTRY;

    	$location = $_SERVER["HTTP_CF_IPCOUNTRY"];
    

    it returns countries_iso_code_2 which I then look up in the DB to get the full country name.... But for those (most if not everyone) that don't use cloudflare you can use the geoplugin address (not ideal of course).

     

    The great thing about getting the country with the IP is it allows a quick easy check (by entry level staff) to confirm the customers "actual" location to their delivery address - without turning on Address Verification (if you have it) in your credit card processing (payment) module..... I've had huge issues losing orders with AV turned on.... every 10th order had an issue with 2nd address lines, postal code input (spaces, dash etc) wrong State/Province (Quebec as an example can go  by QC or PQ)....

     

    @@burt

     

    thank you for the hint....

     

    Now to turn

            $check_query = tep_db_query("select 1 from " . TABLE_ORDERS . " where orders_id = '" . (int)$order_id . "' and date_purchased < date_sub(now(), interval '" . (int)MODULE_CONTENT_CHECKOUT_SUCCESS_REDIRECT_OLD_ORDER_MINUTES . "' minute)");
    

    Into something like (not tested)

            $query = tep_db_query("insert info " . TABLE_ORDERS . " where orders_id = '" . (int)$order_id . "' and date_purchased, '$customers_ip')");
    

    Am I in the right direction????

  15. @@AlexandrZuyev I love your idea.... Although I think I've seen it around here before.

     

    I added it to the orders.php page in place of the email.

     

    However, in the thought of going forward with OsCommerce - the question really becomes how to accomplish adding to the orders table without modifing checkout_process.php?

     

    I have made this up into a quick and easy checkout_confirmation content module, however have no idea how you could write to the database without involving checkout_process.

     

    Any ideas?

  16. Hi, thanks for the quick help!

     

    The sort order is indeed correct with the default values of 400 and 1000 for the shipping and total modules respectively.

     

    Here's the Canada Post module I use: http://addons.oscommerce.com/info/7900

     

    The shipping quote is very simple, we charge the rates we get from the Canada Post server, with no handling fees. The rest is done on the CanadaPost server. We also use two other shipping modules: store pickup (as seen in screen grab) and snail mail when the product size allows (doesn't apply here).

     

    Here's the screen shot with example data. Thanks!

     

    Untitled-1.gif

    You may want to test with the newer REST Canada Post module - their sellonline service is slated to be discontinued (not sure when).

     

    I have this working with http://addons.oscommerce.com/info/8887

×
×
  • Create New...