Jump to content

AngusD

Members
  • Content count

    101
  • Joined

  • Last visited


Reputation Activity

  1. Like
    AngusD reacted to Harald Ponce de Leon in Legacy Code and PHP 7.3 Compatibility Checks (HOWTO)   
    Hi All..
    Here are instructions on how to check how compatible your online store installation / PHP code is against all PHP versions from 5.0 up to the latest version (currently 7.3). This guide requires a minimum PHP 5.4 version to run.
    This is a medium level skill guide and requires the installation of Composer - a dependency manager for PHP that manages the installation and updates of third party libraries. I will link to the installation instructions of Composer instead of writing how to install it here.
    It's possible to perform this guide either remotely on the web server in a ssh terminal, or locally on a backup copy of the PHP code.
    Step 1 - Install Composer
    Composer can be installed on Windows, Linux, Mac, and Unix. If you're installing on Linux, there may be a Linux distribution package that can be installed depending on your access privileges on the server, otherwise a manual installation is required. The manual installation can be performed locally in your home directory without special user permissions.
    Instructions for how to install Composer on Windows can be found here:
    https://getcomposer.org/doc/00-intro.md#installation-windows
    Instructions for how to install Composer on Linux, Mac, and Unix can be found here:
    https://getcomposer.org/doc/00-intro.md#installation-linux-unix-macos
    Step 2 - Create Composer Project File
    Composer needs to create a composer project file in the directory where your online store installation or PHP code resides. This will create two files that will be publicly accessible through the web server - this will not pose any security issues. The setup will also eventually create a "vendor" directory however Composer will be configured to place this in the "includes" directory to block public web server requests to the directory.
    Copy and paste the following to composer.json in the directory where your online store installation resides:
    { "config": { "vendor-dir": "includes/thirdparty/composer" }, "require-dev": { "squizlabs/php_codesniffer": "^3.4", "phpcompatibility/php-compatibility": "^9.2" } } Step 3 - Install PHP_CodeSniffer
    PHP_Codesniffer detects violations of defined rules in your code. There are several coding standard rule sets available to make sure each PHP file meets the coding standards. There is no rule set currently available for OSCOM v2.x - for v3 the PSR12 rule set is used.
    As there will be a lot of violations running this with a coding standard, we will instead run it to use only one rule set to check compatibility against the latest PHP version. We will also configure PHP_CodeSniffer to ignore certain violations which is already taken care of in the online store installation.
    Run the following command to install PHP_CodeSniffer:
    composer install After this installs PHP_CodeSniffer and the PHP Compatibility rule set, a PHP_CodeSniffer configuration file will be created to configure the rule set that should be used.
    Copy and paste the following to phpcs.xml in the directory where your online store installation resides:
    <?xml version="1.0"?> <ruleset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="PHP_CodeSniffer" xsi:noNamespaceSchemaLocation="phpcs.xsd"> <description>The coding standard for osCommerce.</description> <file>.</file> <exclude-pattern>*/includes/thirdparty/*$</exclude-pattern> <arg name="basepath" value="."/> <arg name="colors"/> <arg value="nps"/> <rule ref="PHPCompatibility"/> <config name="installed_paths" value="includes/thirdparty/composer/phpcompatibility/php-compatibility" /> </ruleset> Step 4 - Run PHP_CodeSniffer
    PHP_CodeSniffer can now be executed with the following command. It will automatically use the configuration file created in step 3:
    ./includes/thirdparty/composer/bin/phpcs which will produce the following output report:
    FILE: admin/includes/functions/compatibility.php --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- FOUND 15 ERRORS AFFECTING 12 LINES --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 32 | ERROR | Global variable '$HTTP_GET_VARS' is deprecated since PHP 5.3 and removed since PHP 5.4; Use $_GET instead (PHPCompatibility.Variables.RemovedPredefinedGlobalVariables.http_get_varsDeprecatedRemoved) 33 | ERROR | Global variable '$HTTP_POST_VARS' is deprecated since PHP 5.3 and removed since PHP 5.4; Use $_POST instead (PHPCompatibility.Variables.RemovedPredefinedGlobalVariables.http_post_varsDeprecatedRemoved) 34 | ERROR | Global variable '$HTTP_COOKIE_VARS' is deprecated since PHP 5.3 and removed since PHP 5.4; Use $_COOKIE instead | | (PHPCompatibility.Variables.RemovedPredefinedGlobalVariables.http_cookie_varsDeprecatedRemoved) FILE: admin/includes/functions/database.php ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- FOUND 25 ERRORS AFFECTING 24 LINES ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 179 | ERROR | Extension 'mysql_' is deprecated since PHP 5.5 and removed since PHP 7.0; Use mysqli instead (PHPCompatibility.Extensions.RemovedExtensions.mysql_DeprecatedRemoved) 181 | ERROR | Extension 'mysql_' is deprecated since PHP 5.5 and removed since PHP 7.0; Use mysqli instead (PHPCompatibility.Extensions.RemovedExtensions.mysql_DeprecatedRemoved) 185 | ERROR | Extension 'mysql_' is deprecated since PHP 5.5 and removed since PHP 7.0; Use mysqli instead (PHPCompatibility.Extensions.RemovedExtensions.mysql_DeprecatedRemoved) Here we can see which files violate a PHP Compatibility rule set, the line in the file where the violation occurs, the reason for the violation, and the actual rule set that was violated that we'll be using to ignore the false positive reports with.
    In the example output, it states that $HTTP_GET_VARS, $HTTP_POST_VARS, and $HTTP_COOKIE_VARS are deprecated since PHP 5.3 and are still used in your online store installation. This is a false positive as osCommerce Online Merchant already has its own implementation to work with or around it. In this case, the variables are safely defined in admin/includes/functions/compatibility.php and includes/functions/compatibility.php.
    It also states that "mysql_" is deprecated in PHP 5.5 and still used in the online store installation. This is also a false positive as osCommerce Online Merchant wraps calls to the "mysql_" functions if "mysqli" does not exist.
    We'll add to the PHP_CodeSniffer configuration the rules that can be ignored. The rules can be seen in the output report in brackets ( ). Below is an updated phpcs.xml file with a list of rules being safely ignored for a osCommerce Online Merchant v2.3.4.1 installation:
    <?xml version="1.0"?> <ruleset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="PHP_CodeSniffer" xsi:noNamespaceSchemaLocation="phpcs.xsd"> <description>The coding standard for osCommerce.</description> <file>.</file> <exclude-pattern>*/includes/thirdparty/*$</exclude-pattern> <arg name="basepath" value="."/> <arg name="colors"/> <arg value="nps"/> <rule ref="PHPCompatibility"/> <config name="installed_paths" value="includes/thirdparty/composer/phpcompatibility/php-compatibility" /> <rule ref="PHPCompatibility.Variables.RemovedPredefinedGlobalVariables.http_get_varsDeprecatedRemoved"> <severity>0</severity> </rule> <rule ref="PHPCompatibility.Variables.RemovedPredefinedGlobalVariables.http_post_varsDeprecatedRemoved"> <severity>0</severity> </rule> <rule ref="PHPCompatibility.Variables.RemovedPredefinedGlobalVariables.http_cookie_varsDeprecatedRemoved"> <severity>0</severity> </rule> <rule ref="PHPCompatibility.Variables.RemovedPredefinedGlobalVariables.http_session_varsDeprecatedRemoved"> <severity>0</severity> </rule> <rule ref="PHPCompatibility.Variables.RemovedPredefinedGlobalVariables.http_server_varsDeprecatedRemoved"> <severity>0</severity> </rule> <rule ref="PHPCompatibility.Variables.RemovedPredefinedGlobalVariables.http_post_filesDeprecatedRemoved"> <severity>0</severity> </rule> <rule ref="PHPCompatibility.Extensions.RemovedExtensions.mysql_DeprecatedRemoved"> <severity>0</severity> </rule> <rule ref="PHPCompatibility.IniDirectives.RemovedIniDirectives.session_bug_compat_42DeprecatedRemoved"> <severity>0</severity> </rule> <rule ref="PHPCompatibility.IniDirectives.RemovedIniDirectives.session_bug_compat_warnDeprecatedRemoved"> <severity>0</severity> </rule> <rule ref="PHPCompatibility.FunctionUse.RemovedFunctions.session_registerDeprecatedRemoved"> <severity>0</severity> </rule> <rule ref="PHPCompatibility.FunctionUse.RemovedFunctions.session_is_registeredDeprecatedRemoved"> <severity>0</severity> </rule> <rule ref="PHPCompatibility.FunctionUse.RemovedFunctions.session_unregisterDeprecatedRemoved"> <severity>0</severity> </rule> <rule ref="PHPCompatibility.FunctionUse.RemovedFunctions.mysql_escape_stringDeprecatedRemoved"> <severity>0</severity> </rule> </ruleset> Please remember that a lot of false positives will be reported and will need to be individually checked to see if a workaround exists in the PHP code. Additional rules to ignore can be added to the PHP_CodeSniffer configuration file.
    Happy PHP 7.3 incompatibility hunting!
  2. Like
    AngusD got a reaction from Tsimi in PayPal shows blank page   
    Update: The vanishing order error has been resolved, too.
     
    In our case, it was caused by the "Order Status" setting in the "PayPal Payments Standard" config.
     
    The option "Store Default Order Status" caused the order to be deleted after checkout. There's no reason why it does this. There are no "delete"-queries anywhere near the checkout_process/checkout_success-scripts.
     
    We set the "Order Status" to "Delivered". This seemed to fix the issue.
     
    AD 
  3. Like
    AngusD reacted to Tsimi in Admin BS - Reloaded   
    Some of you might remember my rather poor attempt to bootstrap the admin a while back. :wacko:
    Well I went over all the files again and recoded/fixed it and now finally I can say things work as they should. B)
    I also took the bootstrapped install package from the EDGE version. Now we have at least a full responsive osC from A-Z.
    There might be minor bugs around and it is recommended to use at least a tablet to work with it.
    Anyway here is my "complete" version.

    https://github.com/Tsimi78/osCommerce-GOLD-AdminBS

    Enjoy and if anything is you know where to find me. ;)
  4. Like
    AngusD got a reaction from Mort-lemur in Wishlist for 2.3 - Last Problem   
    Hello,
     
    the problem is the missing "public_id" in the form.
     
     
    Find the "tep_draw_form"-line and change it to:
    <?php echo tep_draw_form('wishlist_form',tep_href_link($PHP_SELF, 'public_id='. (int)$public_id, 'SSL')); ?> Could work. No promisses.
    AD
  5. Like
    AngusD reacted to De Dokta in Categories Menu with multiple subs in the header navbar   
    Hi
     
    I have long been looking for a way to integrate the categories menu with multiple sub categories into  the header navbar, but I always failed to embed the appropriate code into the category_tree.php.  :(  With the help of the code gadlol has recently posted, some JS and CSS I have now found a way without changing the category_tree.php.
    Looks like this:

    How it works:

     In includes/functions/html_output.php add a new function:
    function tep_show_tree($root_id = 0,$mainUlClass='dropdown-menu',$submenuUlClass='dropdown-menu sub-menu'){     global $languages_id,$cPath_array;     $categories_query = tep_db_query("select c.categories_id, cd.categories_name, c.parent_id from " . TABLE_CATEGORIES . " c, " . TABLE_CATEGORIES_DESCRIPTION . " cd where c.categories_id = cd.categories_id and cd.language_id='" . (int)$languages_id ."' order by sort_order, cd.categories_name");     $items = array();     while ($categories = tep_db_fetch_array($categories_query))  {         $items[$categories['categories_id']] = array('name' => $categories['categories_name'], 'parent_id' => $categories['parent_id'], 'id' => $categories['categories_id']);     }     $citems=count($items);          if($citems<=0) return '';     elseif($citems==1) $children[] = $items; //in case we have one category item without subcategories, rare but possible     else foreach( $items as $item ) $children[$item['parent_id']][] = $item;         $loop = !empty( $children[$root_id] );         $parent = $root_id;         $parent_stack = array();     $html=array();//store html code         $stack=array();//helper array so to know the current level     $pic=''; //products_in_category string         $html[]='<ul class="'.$mainUlClass.'">';         while ( $loop && ( ( $option = each( $children[$parent] ) ) || ( $parent > $root_id ) ) ){             if ( $option === false ){                 $parent = array_pop( $parent_stack );                 $html[] = '</ul>';                 $html[] = '</li>';                 array_pop( $stack );             }elseif ( !empty( $children[$option['value']['id']] ) ){                 $stack[]=$option['value']['id'];                   $rt=$root_id>0 ? $root_id.'_' : '';                   $cpath_new=count($stack)<=0 ? 'cPath='.$rt.$option['value']['id'] : 'cPath='.$rt.implode('_',$stack);                 $html[]= '<li><a class="trigger right-caret" href="'.tep_href_link(FILENAME_DEFAULT, $cpath_new).'">';           if (SHOW_COUNTS == 'true') {             $products_in_category = tep_count_products_in_category($option['value']['id']);             if ($products_in_category > 0) {               $pic=' (' . $products_in_category . ')';             }           }           $sm=0;                   if((isset($cPath_array) && in_array($option['value']['id'], $cPath_array))){             $sm=1;             $html[]='<strong>'.stripslashes($option['value']['name']).$pic.'</strong>';           }else{             $html[]=stripslashes($option['value']['name']) . $pic;           }             $html[]='</a>';             $html[] = '<ul class="'.$submenuUlClass.'">';                 $parent_stack[]=$option['value']['parent_id'];                 $parent = $option['value']['id'];           }else{         $rt=$root_id>0 ? $root_id.'_' : '';                 $cpath_new= count($stack)<=0 ? 'cPath='.$rt.$option['value']['id'] : 'cPath='.$rt.implode('_',$stack).'_'.$option['value']['id'];                 $html[]= '<li><a href="'.tep_href_link(FILENAME_DEFAULT, $cpath_new).'" >';         if (SHOW_COUNTS == 'true') {           $products_in_category = tep_count_products_in_category($option['value']['id']);           if ($products_in_category > 0) {             $pic=' (' . $products_in_category . ')';           }         }                 if (isset($cPath_array) && in_array($option['value']['id'], $cPath_array)) {           $html[]='<strong>'.stripslashes($option['value']['name']).$pic.'</strong>';         }else{           $html[]=stripslashes($option['value']['name']).$pic;         }         $html[]='</a>';         }        }         $html[]='</ul>';      $data = '<li class="dropdown">' .              '<a class="dropdown-toggle" data-toggle="dropdown">' . HEADER_CATS . '</a>' .                implode($html) .              '</li>';       return $data;   } includes/footer.php add:
    <script type="text/javascript"> $(function(){     $(".dropdown-menu > li > a.trigger").one("click",function(e){         e.preventDefault();         var current=$(this).next();         var grandparent=$(this).parent().parent();         if($(this).hasClass('left-caret')||$(this).hasClass('right-caret'))             $(this).toggleClass('right-caret left-caret');         grandparent.find('.left-caret').not(this).toggleClass('right-caret left-caret');         grandparent.find(".sub-menu:visible").not(current).hide();         current.toggle();         e.stopPropagation();     });     $(".dropdown-menu > li > a:not(.trigger)").one("click",function(){         var root=$(this).closest('.dropdown');         root.find('.left-caret').toggleClass('right-caret left-caret');         root.find('.sub-menu:visible').hide();     }); })(jQuery); </script> user.css add:
    .dropdown-menu>li /* To prevent selection of text */ {   position:relative;     padding-left: 5px;     -webkit-user-select: none; /* Chrome/Safari */             -moz-user-select: none; /* Firefox */     -ms-user-select: none; /* IE10+ */     /* Rules below not implemented in browsers yet */     -o-user-select: none;     user-select: none;     cursor:pointer; } .dropdown-menu .sub-menu {     left: 100%;     position: absolute;     top: 0;     display:none;     margin-top: -1px;     box-shadow:none; } .right-caret:after,.left-caret:after  {  content:"";     border: 5px solid transparent;     border-top: 5px solid transparent;     display: inline-block;     height: 0;     vertical-align: middle;     width: 0;     margin-left:15px; } .right-caret:after {        border-left: 5px solid #ffaf46; } .left-caret:after {     border-right: 5px solid #ffaf46; } in includes/header.php after:
    <?php echo '<li><a class="store-brand" href="' . tep_href_link(FILENAME_DEFAULT) . '">' . HEADER_HOME . '</a></li>'; ?> add:
    <?php echo '<li>' . tep_show_tree() . '</li>'; ?> or somewhere else where you like it!
    includes/languages/english.php add:
    define('HEADER_CATS', '<i class="glyphicon glyphicon-cog"></i><span class="hidden-sm"> Categories</span> <span class="caret"></span>'); or any other glyphicon.
     
    I tested it with Mozilla 30. IE 8, Chrome and Opera - seems to work properly in full and collapsed size. 
     
    Hope you enjoy it!
     
    J.J.
×