Jump to content
Latest News: (loading..)

Dnj1964

Members
  • Content count

    72
  • Joined

  • Last visited

Everything posted by Dnj1964

  1. Were you able to get it to work with Edge. I am using Edge Gold BS4 and it doesn't seem to be working.... At least for me!
  2. When adding product options the standard layout is to display options to the right of the product image. Wanting to display the options below the image tried modifying the code in \includes\modules\content\product_info\cm_pi_gallery.php My knowledge of php is throw html at it until it works or breaks. Then start again. This is on CE BS4 Php 7.1.25 The add-on is: JcM Product info description_tabs CE By JcMagpie Add-on works perfectly, it is a width issue with the attributes beside the image instead of below it
  3. Dnj1964

    Product Options/Attributes

    Wanting to eliminate a lot of dead real estate and move the product attributes directly under image. (Shortening Product Description is the obvious answer. Not an option) Description 8/60 & Gallery 4/60 Setting the Attributes to 4/65 would think would move Attributes unless description set at 60 pushes the 65 setting to the bottom regardless. Thanks in advance. I know someone has the answers and solutions that elude me!
  4. Dnj1964

    Shipping Add-On Update (Canada)

    greasemonkey A big thanks for the help. Switching to commercial instead of counter solved the issue even without a contract id. May need a contract id in production but works in test mode. Thanks again.
  5. Trying to update a Canada post shipping add-on https://apps.oscommerce.com/7hk8T&amp;canada-post-rest-rate-service-oscommerce Warning: constant(): Couldn't find constant CANADA_POST_Array in /includes/modules/shipping/canadapost.php on line 508 function get_multioption_canadapost_xml($values) { if (tep_not_null($values)) { $values_array = explode(',', $values); foreach ($values_array as $key => $_method) { if ($_method == '--none--') { $method = $_method; } else { $method = constant('CANADA_POST_' .get_canada_post_service_code($_method)); } $readable_values_array[] = $method; } $readable_values = implode(', ', $readable_values_array); return $readable_values; } else { return ''; } } function get_canada_post_service_code($key) { $km = str_replace('.','_',trim($key)); if(substr($km,0,2)=='D_') $km = 'DOM_'.substr($km,2); else if(substr($km,0,2)=='U_') $km = 'USA_'.substr($km,2); else if(substr($km,0,2)=='I_') $km = 'INT_'.substr($km,2); return $km; } function canadapost_cfg_select_multioption($select_array, $key_value, $key = '') { for ($i=0; $i<sizeof($select_array); $i++) { $name = (($key) ? 'configuration[' . $key . '][]' : 'configuration_value'); $string .= '<br><input type="checkbox" name="' . $name . '" value="' . $select_array[$i] . '"'; $key_values = explode( ", ", $key_value); if ( in_array($select_array[$i], $key_values) ) $string .= ' CHECKED'; $string .= '> ' . constant('CANADA_POST_' . get_canada_post_service_code($select_array[$i])); } $string .= '<input type="hidden" name="' . $name . '" value="--none--">'; return $string; } ?> Read a post from 2008 where the same function was used. Solution was: So tried adding define('CANADA_POST_--none--', 'None'); to /includes/languages/english/modules/shipping/canadapost.php Thinking that the warning would also disappear. No such luck. Plus just started testing and now get: Shipping is currently not available for the selected shipping address. Please select or create a new shipping address to use with your purchase.
  6. Dnj1964

    Community Rift

    About 15 years I happened upon oscommerce and started using it, that was way before a Milestone version was even thought of. It was at times frustrating as the updates were sometimes 2 a week and any add-on was pages and pages of code changes. It was great as the community behind it made it great! Came back to oscommerce in December 2018 after all those years.... Logged into oscommerce and downloaded the official version. Started looking at add-ons some were labelled CE, some BS, some, some Edge, some Frozen. After configuring the official and realizing that support was almost dead for that version, and then configuring and re-configuring a few times finally settled on EDGE: Gold + Extra Commits such as bugfixes: Seemed to most supported and an active community following behind it. Which leads to thee reasoning for this post. A lot had changed since the pre-milestone which back then relied a lot on html to make changes which was easy. Fast forward to the era of standalone add-ons and it is easy to be lost when you haven't looked at code in over 10 years. A lot of the add-ons I found were from JcMagpie I installed the add-ons, chopped them up to what I wanted with tons of errors and posted in the forums for help in fixing what I broke... JcMagpie not only responded but helped fix the code, supplied new code. Made suggestions of things to make the layout more appealing, and add-in codes for errors. So yesterday while fighting unsuccessfully to update the code in an old Canada Post shipping add-on I ran across an issue with a previous add-on and posted the issue and got back a reply JcMagpie from that I would think sends a big negative blow to the community. Shortened version of a message from JcMagpie Maybe the community needs to rally behind him and support him the same way that he has helped so many people. I for one wouldn't have my site anywhere close to where it is without his help and support. Can't think or believe that I am the only one?
  7. Dnj1964

    Shipping Add-On Update (Canada)

    I will PM you. ReferenceError: $ is not defined[Learn More] index.php:572:5 <anonymous> http://www.naughtypleasures.ca/index.php:572 <script> $('ul.nav li.dropdown').hover(function() { $(this).find('.dropdown-menu').stop(true, true).delay(200).fadeIn(500); }, function() { $(this).find('.dropdown-menu').stop(true, true).delay(200).fadeOut(500); }); </script>
  8. Dnj1964

    Shipping Add-On Update (Canada)

    Logging out gives the same problem Loading failed for the <script> with source “http://www.naughtypleasures.ca/ext/responsivemenu/js/responsivemultimenu-LANGUAGE_CODE.js”. And another ReferenceError: $ is not defined <script> $('ul.nav li.dropdown').hover(function() { Checked the test site and these errors are not present.
  9. Dnj1964

    Shipping Add-On Update (Canada)

    <script type="text/javascript" src="ext/responsivemenu/js/responsivemultimenu-LANGUAGE_CODE.js"></script> Loading failed for the <script> with source “http://www.naughtypleasures.ca/ext/responsivemenu/js/responsivemultimenu-LANGUAGE_CODE.js”. checkout_shipping_address.php:216:1 JcM Categories Navbar 1.3 CE by - JcMagpie \includes\modules\navbar_modules\templates\tpl_nb_horizontal_multi_menu.php <script type="text/javascript" src="ext/responsivemenu/js/responsivemultimenu-<?php echo LANGUAGE_CODE; ?>.js"></script> Only using 1 language so no big deal changing to <script type="text/javascript" src="ext/responsivemenu/js/responsivemultimenu-en.js"></script> Making the above change makes it worse - ReferenceError: jQuery is not defined Guessing this error is why I have no Canada Post Shipping showing, and why it says can't ship that address. ReferenceError: $ is not defined[Learn More] checkout_shipping_address.php:574:5
  10. Dnj1964

    Shipping Add-On Update (Canada)

    What am I Missing....??????? Updated the deprecated $HTTP_POST_VARS to $_POST & $HTTP_GET_VARS to $_GET Updated 'FILENAME.... . to 'actual-filename.php' Updates DIR_WS_INCLUDES to 'includes/..... or DIR_WS_IMAGES to 'images/..... /admin/modules.php <?php /* $Id$ osCommerce, Open Source E-Commerce Solutions http://www.oscommerce.com Copyright (c) 2010 osCommerce Released under the GNU General Public License */ require('includes/application_top.php'); $set = (isset($_GET['set']) ? $_GET['set'] : ''); $modules = $cfgModules->getAll(); if (empty($set) || !$cfgModules->exists($set)) { $set = $modules[0]['code']; } $module_type = $cfgModules->get($set, 'code'); $module_directory = $cfgModules->get($set, 'directory'); $module_language_directory = $cfgModules->get($set, 'language_directory'); $module_key = $cfgModules->get($set, 'key');; define('HEADING_TITLE', $cfgModules->get($set, 'title')); $template_integration = $cfgModules->get($set, 'template_integration'); $action = (isset($_GET['action']) ? $_GET['action'] : ''); if (tep_not_null($action)) { switch ($action) { case 'save': reset($_POST['configuration']); while (list($key, $value) = each($_POST['configuration'])) { if (is_array($value) ) { $value = implode( ", ", $value); $value = preg_replace ("/, --none--/", "", $value); } tep_db_query("update " . TABLE_CONFIGURATION . " set configuration_value = '" . $value . "' where configuration_key = '" . $key . "'"); } tep_redirect(tep_href_link('modules.php', 'set=' . $set . '&module=' . $_GET['module'])); break; case 'install': case 'remove': $file_extension = substr($PHP_SELF, strrpos($PHP_SELF, '.')); $class = basename($_GET['module']); if (file_exists($module_directory . $class . $file_extension)) { include($module_directory . $class . $file_extension); $module = new $class; if ($action == 'install') { $module->install(); $modules_installed = explode(';', constant($module_key)); $modules_installed[] = $class . $file_extension; tep_db_query("update " . TABLE_CONFIGURATION . " set configuration_value = '" . implode(';', $modules_installed) . "' where configuration_key = '" . $module_key . "'"); tep_redirect(tep_href_link('modules.php', 'set=' . $set . '&module=' . $class)); } elseif ($action == 'remove') { $module->remove(); $modules_installed = explode(';', constant($module_key)); unset($modules_installed[array_search($class . $file_extension, $modules_installed)]); tep_db_query("update " . TABLE_CONFIGURATION . " set configuration_value = '" . implode(';', $modules_installed) . "' where configuration_key = '" . $module_key . "'"); tep_redirect(tep_href_link('modules.php', 'set=' . $set)); } } tep_redirect(tep_href_link('modules.php', 'set=' . $set . '&module=' . $class)); break; } } require('includes/template_top.php'); $modules_installed = (defined($module_key) ? explode(';', constant($module_key)) : array()); $new_modules_counter = 0; $file_extension = substr($PHP_SELF, strrpos($PHP_SELF, '.')); $directory_array = array(); if ($dir = @dir($module_directory)) { while ($file = $dir->read()) { if (!is_dir($module_directory . $file)) { if (substr($file, strrpos($file, '.')) == $file_extension) { if (isset($_GET['list']) && ($_GET['list'] = 'new')) { if (!in_array($file, $modules_installed)) { $directory_array[] = $file; } } else { if (in_array($file, $modules_installed)) { $directory_array[] = $file; } else { $new_modules_counter++; } } } } } sort($directory_array); $dir->close(); } ?> <table border="0" width="100%" cellspacing="0" cellpadding="2"> <tr> <td width="100%"><table border="0" width="100%" cellspacing="0" cellpadding="0"> <tr> <td class="pageHeading"><?php echo HEADING_TITLE; ?></td> <td class="pageHeading" align="right"><?php echo tep_draw_separator('pixel_trans.gif', HEADING_IMAGE_WIDTH, HEADING_IMAGE_HEIGHT); ?></td> <?php if (isset($_GET['list'])) { echo ' <td class="smallText" align="right">' . tep_draw_button(IMAGE_BACK, 'triangle-1-w', tep_href_link('modules.php', 'set=' . $set)) . '</td>'; } else { echo ' <td class="smallText" align="right">' . tep_draw_button(IMAGE_MODULE_INSTALL . ' (' . $new_modules_counter . ')', 'plus', tep_href_link('modules.php', 'set=' . $set . '&list=new')) . '</td>'; } ?> </tr> </table></td> </tr> <tr> <td><table border="0" width="100%" cellspacing="0" cellpadding="0"> <tr> <td valign="top"><table border="0" width="100%" cellspacing="0" cellpadding="2"> <tr class="dataTableHeadingRow"> <td class="dataTableHeadingContent"><?php echo TABLE_HEADING_MODULES; ?></td> <td class="dataTableHeadingContent" align="right"><?php echo TABLE_HEADING_SORT_ORDER; ?></td> <td class="dataTableHeadingContent" align="right"><?php echo TABLE_HEADING_ACTION; ?>&nbsp;</td> </tr> <?php $installed_modules = array(); for ($i=0, $n=sizeof($directory_array); $i<$n; $i++) { $file = $directory_array[$i]; include($module_language_directory . $language . '/modules/' . $module_type . '/' . $file); include($module_directory . $file); $class = substr($file, 0, strrpos($file, '.')); if (tep_class_exists($class)) { $module = new $class; if ($module->check() > 0) { if (($module->sort_order > 0) && !isset($installed_modules[$module->sort_order])) { $installed_modules[$module->sort_order] = $file; } else { $installed_modules[] = $file; } } if ((!isset($_GET['module']) || (isset($_GET['module']) && ($_GET['module'] == $class))) && !isset($mInfo)) { $module_info = array('code' => $module->code, 'title' => $module->title, 'description' => $module->description, 'status' => $module->check(), 'signature' => (isset($module->signature) ? $module->signature : null), 'api_version' => (isset($module->api_version) ? $module->api_version : null)); $module_keys = $module->keys(); $keys_extra = array(); for ($j=0, $k=sizeof($module_keys); $j<$k; $j++) { $key_value_query = tep_db_query("select configuration_title, configuration_value, configuration_description, use_function, set_function from " . TABLE_CONFIGURATION . " where configuration_key = '" . $module_keys[$j] . "'"); $key_value = tep_db_fetch_array($key_value_query); $keys_extra[$module_keys[$j]]['title'] = $key_value['configuration_title']; $keys_extra[$module_keys[$j]]['value'] = $key_value['configuration_value']; $keys_extra[$module_keys[$j]]['description'] = $key_value['configuration_description']; $keys_extra[$module_keys[$j]]['use_function'] = $key_value['use_function']; $keys_extra[$module_keys[$j]]['set_function'] = $key_value['set_function']; } $module_info['keys'] = $keys_extra; $mInfo = new objectInfo($module_info); } if (isset($mInfo) && is_object($mInfo) && ($class == $mInfo->code) ) { if ($module->check() > 0) { echo ' <tr id="defaultSelected" class="dataTableRowSelected" onmouseover="rowOverEffect(this)" onmouseout="rowOutEffect(this)" onclick="document.location.href=\'' . tep_href_link('modules.php', 'set=' . $set . '&module=' . $class . '&action=edit') . '\'">' . "\n"; } else { echo ' <tr id="defaultSelected" class="dataTableRowSelected" onmouseover="rowOverEffect(this)" onmouseout="rowOutEffect(this)">' . "\n"; } } else { echo ' <tr class="dataTableRow" onmouseover="rowOverEffect(this)" onmouseout="rowOutEffect(this)" onclick="document.location.href=\'' . tep_href_link('modules.php', 'set=' . $set . (isset($_GET['list']) ? '&list=new' : '') . '&module=' . $class) . '\'">' . "\n"; } ?> <td class="dataTableContent"><?php echo $module->title; ?></td> <td class="dataTableContent" align="right"><?php if (is_numeric($module->sort_order)) echo $module->sort_order; ?></td> <td class="dataTableContent" align="right"><?php if (isset($mInfo) && is_object($mInfo) && ($class == $mInfo->code) ) { echo tep_image('images/icon_arrow_right.gif'); } else { echo '<a href="' . tep_href_link('modules.php', 'set=' . $set . (isset($_GET['list']) ? '&list=new' : '') . '&module=' . $class) . '">' . tep_image('images/icon_info.gif', IMAGE_ICON_INFO) . '</a>'; } ?>&nbsp;</td> </tr> <?php } } if (!isset($_GET['list'])) { ksort($installed_modules); $check_query = tep_db_query("select configuration_value from " . TABLE_CONFIGURATION . " where configuration_key = '" . $module_key . "'"); if (tep_db_num_rows($check_query)) { $check = tep_db_fetch_array($check_query); if ($check['configuration_value'] != implode(';', $installed_modules)) { tep_db_query("update " . TABLE_CONFIGURATION . " set configuration_value = '" . implode(';', $installed_modules) . "', last_modified = now() where configuration_key = '" . $module_key . "'"); } } else { tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Installed Modules', '" . $module_key . "', '" . implode(';', $installed_modules) . "', 'This is automatically updated. No need to edit.', '6', '0', now())"); } if ($template_integration == true) { $check_query = tep_db_query("select configuration_value from " . TABLE_CONFIGURATION . " where configuration_key = 'TEMPLATE_BLOCK_GROUPS'"); if (tep_db_num_rows($check_query)) { $check = tep_db_fetch_array($check_query); $tbgroups_array = explode(';', $check['configuration_value']); if (!in_array($module_type, $tbgroups_array)) { $tbgroups_array[] = $module_type; sort($tbgroups_array); tep_db_query("update " . TABLE_CONFIGURATION . " set configuration_value = '" . implode(';', $tbgroups_array) . "', last_modified = now() where configuration_key = 'TEMPLATE_BLOCK_GROUPS'"); } } else { tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Installed Template Block Groups', 'TEMPLATE_BLOCK_GROUPS', '" . $module_type . "', 'This is automatically updated. No need to edit.', '6', '0', now())"); } } } ?> <tr> <td colspan="3" class="smallText"><?php echo TEXT_MODULE_DIRECTORY . ' ' . $module_directory; ?></td> </tr> </table></td> <?php $heading = array(); $contents = array(); switch ($action) { case 'edit': $keys = ''; reset($mInfo->keys); while (list($key, $value) = each($mInfo->keys)) { $keys .= '<strong>' . $value['title'] . '</strong><br />' . $value['description'] . '<br />'; if ($value['set_function']) { eval('$keys .= ' . $value['set_function'] . "'" . $value['value'] . "', '" . $key . "');"); } else { $keys .= tep_draw_input_field('configuration[' . $key . ']', $value['value']); } $keys .= '<br /><br />'; } $keys = substr($keys, 0, strrpos($keys, '<br /><br />')); $heading[] = array('text' => '<strong>' . $mInfo->title . '</strong>'); $contents = array('form' => tep_draw_form('modules', 'modules.php', 'set=' . $set . '&module=' . $_GET['module'] . '&action=save')); $contents[] = array('text' => $keys); $contents[] = array('align' => 'center', 'text' => '<br />' . tep_draw_button(IMAGE_SAVE, 'disk', null, 'primary') . tep_draw_button(IMAGE_CANCEL, 'close', tep_href_link('modules.php', 'set=' . $set . '&module=' . $_GET['module']))); break; default: $heading[] = array('text' => '<strong>' . $mInfo->title . '</strong>'); if ($mInfo->status == '1') { $keys = ''; reset($mInfo->keys); while (list(, $value) = each($mInfo->keys)) { $keys .= '<strong>' . $value['title'] . '</strong><br />'; if ($value['use_function']) { $use_function = $value['use_function']; if (preg_match('/->/', $use_function)) { $class_method = explode('->', $use_function); if (!isset(${$class_method[0]}) || !is_object(${$class_method[0]})) { include('includes/classes' . $class_method[0] . '.php'); ${$class_method[0]} = new $class_method[0](); } $keys .= tep_call_function($class_method[1], $value['value'], ${$class_method[0]}); } else { $keys .= tep_call_function($use_function, $value['value']); } } else { $keys .= $value['value']; } $keys .= '<br /><br />'; } $keys = substr($keys, 0, strrpos($keys, '<br /><br />')); $contents[] = array('align' => 'center', 'text' => tep_draw_button(IMAGE_EDIT, 'document', tep_href_link('modules.php', 'set=' . $set . (isset($_GET['module']) ? '&module=' . $_GET['module'] : '') . '&action=edit')) . tep_draw_button(IMAGE_MODULE_REMOVE, 'minus', tep_href_link('modules.php', 'set=' . $set . '&module=' . $mInfo->code . '&action=remove'))); if (isset($mInfo->signature) && (list($scode, $smodule, $sversion, $soscversion) = explode('|', $mInfo->signature))) { $contents[] = array('text' => '<br />' . tep_image('images/icon_info.gif', IMAGE_ICON_INFO) . '&nbsp;<strong>' . TEXT_INFO_VERSION . '</strong> ' . $sversion . ' (<a href="http://sig.oscommerce.com/' . $mInfo->signature . '" target="_blank">' . TEXT_INFO_ONLINE_STATUS . '</a>)'); } if (isset($mInfo->api_version)) { $contents[] = array('text' => tep_image('images/icon_info.gif', IMAGE_ICON_INFO) . '&nbsp;<strong>' . TEXT_INFO_API_VERSION . '</strong> ' . $mInfo->api_version); } $contents[] = array('text' => '<br />' . $mInfo->description); $contents[] = array('text' => '<br />' . $keys); } elseif (isset($_GET['list']) && ($_GET['list'] == 'new')) { if (isset($mInfo)) { $contents[] = array('align' => 'center', 'text' => tep_draw_button(IMAGE_MODULE_INSTALL, 'plus', tep_href_link('modules.php', 'set=' . $set . '&module=' . $mInfo->code . '&action=install'))); if (isset($mInfo->signature) && (list($scode, $smodule, $sversion, $soscversion) = explode('|', $mInfo->signature))) { $contents[] = array('text' => '<br />' . tep_image('images/icon_info.gif', IMAGE_ICON_INFO) . '&nbsp;<strong>' . TEXT_INFO_VERSION . '</strong> ' . $sversion . ' (<a href="http://sig.oscommerce.com/' . $mInfo->signature . '" target="_blank">' . TEXT_INFO_ONLINE_STATUS . '</a>)'); } if (isset($mInfo->api_version)) { $contents[] = array('text' => tep_image('images/icon_info.gif', IMAGE_ICON_INFO) . '&nbsp;<strong>' . TEXT_INFO_API_VERSION . '</strong> ' . $mInfo->api_version); } $contents[] = array('text' => '<br />' . $mInfo->description); } } break; } if ( (tep_not_null($heading)) && (tep_not_null($contents)) ) { echo ' <td width="25%" valign="top">' . "\n"; $box = new box; echo $box->infoBox($heading, $contents); echo ' </td>' . "\n"; } ?> </tr> </table></td> </tr> </table> <?php require('includes/template_bottom.php'); require('includes/application_bottom.php'); ?> /admin/packaging.php <?php /* $Id: packaging.php, v1.02 2019 Exp $ Copyright (c) Oscommerce */ require('includes/application_top.php'); require('classes/currencies.php'); $currencies = new currencies(); require('includes/template_top.php'); ?> <!-- body //--> <table border="0" width="100%" cellspacing="2" cellpadding="2"> <tr> <td class="pageHeading"> <?php echo HEADING_TITLE; ?> <table border="0" width="100%" cellspacing="0" cellpadding="0"> <tr> <td class="dataTableContent" width="75%" valign="top"> <?php $activeid = $_GET['id']; //********** New Package if(($_POST['name'] != "" && $_POST["action"] == "newpackage") || ($_POST['id'] != "" && $_POST["action"] == "updatepackage")) { if (number_format(trim($_POST['length']), 2, '.', '') <= 0) { $error = MIN_LENGTH_NOT_MET; } else if (number_format(trim($_POST['width']), 2, '.', '') <= 0) { $error = MIN_WIDTH_NOT_MET; } else if (number_format(trim($_POST['height']), 2, '.', '') <= 0) { $error = MIN_HEIGHT_NOT_MET; } else if (number_format(trim($_POST['empty_weight']), 2, '.', '') < 0) { $error = MIN_EMPTY_WEIGHT_NOT_MET; } else if (number_format(trim($_POST['max_weight']), 2, '.', '') < 0) { $error = MIN_MAX_WEIGHT_NOT_MET; } else { $sql_data_array = array( 'package_name' => $_POST['name'], 'package_description' => $_POST['description'], 'package_length' => $_POST['length'], 'package_width' => $_POST['width'], 'package_height' => $_POST['height'], 'package_empty_weight' => $_POST['empty_weight'], 'package_max_weight' => $_POST['max_weight'], 'package_cost' => $_POST['cost'] ); if ($_POST["action"] == "newpackage") { tep_db_perform(TABLE_PACKAGING, $sql_data_array); } else { tep_db_perform(TABLE_PACKAGING, $sql_data_array, "update", "package_id = '" . $_POST['id'] . "'"); } } } //********** Delete Package if($_POST['id'] != "" && $_POST["action"] == "deletepackage") { tep_db_query("delete from " . TABLE_PACKAGING . " where package_id = '" . $_POST['id'] . "'"); } // ********* Display Packages DisplayPackages($activeid, $error); switch ($_GET['action']) { case "shownewpackageform": showNewPackageForm(); break; case "showupdatepackageform": showUpdatePackageForm(); break; case "showconfirmdeletepackageform": showConfirmDeletePackageForm(); break; case "": default: showPackageInfoForm(); break; } //******************* function getPackages() { $packages = array(); $packages_query = tep_db_query("select * from " . TABLE_PACKAGING . " order by package_cost;"); while ($package = tep_db_fetch_array($packages_query)) { $packages[] = array( 'id' => $package['package_id'], 'name' => $package['package_name'], 'description' => $package['package_description'], 'length' => $package['package_length'], 'width' => $package['package_width'], 'height' => $package['package_height'], 'empty_weight' => $package['package_empty_weight'], 'max_weight' => $package['package_max_weight'], 'cost' => $package['package_cost'] ); } return $packages; } //************************ DisplayPackages() // shows the main menu, lists the admins function DisplayPackages($activeid,$error) { ?> <table border="0" width="100%" cellspacing="0" cellpadding="2" width="100%"> <tr class="dataTableHeadingRow"> <td class="dataTableHeadingContent"><?php echo HEADING_NAME; ?></td> <td class="dataTableHeadingContent" align="left"><?php echo HEADING_DESCRIPTION; ?></td> <td class="dataTableHeadingContent" align="center"><?php echo HEADING_LENGTH; ?></td> <td class="dataTableHeadingContent" align="center"><?php echo HEADING_WIDTH; ?></td> <td class="dataTableHeadingContent" align="center"><?php echo HEADING_HEIGHT; ?></td> <td class="dataTableHeadingContent" align="center"><?php echo HEADING_EMPTY_WEIGHT; ?></td> <td class="dataTableHeadingContent" align="center"><?php echo HEADING_MAX_WEIGHT; ?></td> <td class="dataTableHeadingContent" align="center"><?php echo HEADING_COST; ?></td> <td class="dataTableHeadingContent" align="left"><?php echo HEADING_ACTION; ?></td> </tr> <?php $packages = getPackages(); if (count($packages) == 0) { echo '<tr><td colspan="8">' . NO_PACKAGES_DEFINED . '</td></tr>'; } if ($error != "") { echo '<SPAN class="errorText">'.$error.'</SPAN>'; } for ($i = 0; $i < count($packages); $i++) { if (($_GET["action"] != "shownewpackageform") && ($error == "")) { if ($activeid == "") { $activeid = $packages[0]['id']; } } if ($activeid == $packages[$i]['id']) { echo '<tr class="dataTableRowSelected" onmouseover="this.style.cursor=\'hand\'" onclick="document.location.href=\'' . tep_href_link('packaging.php', 'id=' . $packages[$i]['id'] ).'\'">' . "\n"; } else { echo '<tr class="dataTableRow" onmouseover="this.className=\'dataTableRowOver\';this.style.cursor=\'hand\'" onmouseout="this.className=\'dataTableRow\'" onclick="document.location.href=\'' . tep_href_link('packaging.php', 'id=' .$packages[$i]['id'] ). '\'">' . "\n"; } echo '<td class="dataTableContent" align="left"><br>' . $packages[$i]['name'] . '</td>'; echo '<td class="dataTableContent" align="left"><br>' . $packages[$i]['description'] . '</td>'; echo '<td class="dataTableContent" align="center"><br>' . $packages[$i]['length'] . '</td>'; echo '<td class="dataTableContent" align="center"><br>' . $packages[$i]['width'] . '</td>'; echo '<td class="dataTableContent" align="center"><br>' . $packages[$i]['height'] . '</td>'; echo '<td class="dataTableContent" align="center"><br>' . $packages[$i]['empty_weight'] . '</td>'; echo '<td class="dataTableContent" align="center"><br>' . $packages[$i]['max_weight'] . '</td>'; echo '<td class="dataTableContent" align="center"><br>' . $packages[$i]['cost'] . '</td>'; if ($activeid == $packages[$i]['id'] ) { echo '<td>' . tep_image('images/icon_arrow_right.gif', ''); } else { echo '<td><a href="' . tep_href_link('packaging.php', 'id=' . $packages[$i]['id'] ). '">' . tep_image('images/icon_info.gif', ICON_INFO) . '</a>'; } } echo '</td></tr></table><br>'."\n"; echo tep_draw_button(NEW_PACKAGE, 'plus', tep_href_link('packaging.php', 'action=shownewpackageform'));//'<a href="' . tep_href_link( 'packaging.php' , 'action=shownewpackageform') . '">'.tep_image_button('button_new_package.gif', 'New Package').'</a>&nbsp;'; if ($activeid == "") { $activeid = $packages[0]['id']; } echo tep_draw_button(IMAGE_EDIT, 'pencil', tep_href_link('packaging.php', 'action=showupdatepackageform&id='.$activeid));//'<a href="' . tep_href_link( 'packaging.php' , 'action=showupdatepackageform&id='.$activeid.'') . '">'.tep_image_button('button_edit.gif', IMAGE_EDIT).'ddd</a>&nbsp;' ; echo tep_draw_button(HEADING_DELETE, 'close', tep_href_link('packaging.php', 'action=showconfirmdeletepackageform&id='.$activeid));//'<a href="' . tep_href_link( 'packaging.php' , 'action=showconfirmdeletepackageform&id='.$activeid.'') . '">'.tep_image_button('button_delete.gif', IMAGE_DELETE).'</a>' ; echo '</td><td class="infoBoxContent" valign="top">'."\n"; } //****************************** showNewPackageForm() // Show the form to create a new package function showNewPackageForm() { $packages = getPackages(); $cost = 0; for ($i = 0; $i < count($packages); $i++) { if ($packages[$i]['cost'] > $cost) { $cost = $packages[$i]['cost'] + 1; } } echo "<table cellspacing='0' width='100%' cellpadding='0'><tr>\n"; echo "<td colspan='2' class='infoBoxHeading'>". CREATE_NEW_PACKAGE."</td></tr></table>\n"; echo tep_draw_form("newpackage", 'packaging.php'); echo tep_draw_hidden_field("action", "newpackage"); echo '<table><tr><td class="infoBoxContent"><strong>'.HEADING_NAME.'</strong></td></tr><tr><td class="infoBoxContent">'.HEADING_NAME_TEXT.'</td></tr><tr><td class="infoBoxContent">'.tep_draw_input_field("name").'</td></tr>'."\n"; echo '<tr><td class="infoBoxContent"><strong>'.HEADING_DESCRIPTION.'</strong></td></tr><tr><td class="infoBoxContent">'.HEADING_DESCRIPTION_TEXT.'</td></tr><tr><td class="infoBoxContent">'.tep_draw_input_field("description").'</td></tr>'."\n"; echo '<tr><td class="infoBoxContent"><strong>'.HEADING_LENGTH.'</strong></td></tr><tr><td class="infoBoxContent">'.HEADING_LENGTH_TEXT.'</td></tr><tr><td class="infoBoxContent">'.tep_draw_input_field("length").'</td></tr>'."\n"; echo '<tr><td class="infoBoxContent"><strong>'.HEADING_WIDTH.'</strong></td></tr><tr><td class="infoBoxContent">'.HEADING_WIDTH_TEXT.'</td></tr><tr><td class="infoBoxContent">'.tep_draw_input_field("width").'</td></tr>'."\n"; echo '<tr><td class="infoBoxContent"><strong>'.HEADING_HEIGHT.'</strong></td></tr><tr><td class="infoBoxContent">'.HEADING_HEIGHT_TEXT.'</td></tr><tr><td class="infoBoxContent">'.tep_draw_input_field("height").'</td></tr>'."\n"; echo '<tr><td class="infoBoxContent"><strong>'.HEADING_EMPTY_WEIGHT.'</strong></td></tr><tr><td class="infoBoxContent">'.HEADING_EMPTY_WEIGHT_TEXT.'</td></tr><tr><td class="infoBoxContent">'.tep_draw_input_field("empty_weight").'</td></tr>'."\n"; echo '<tr><td class="infoBoxContent"><strong>'.HEADING_MAX_WEIGHT.'</strong></td></tr><tr><td class="infoBoxContent">'.HEADING_MAX_WEIGHT_TEXT.'</td></tr><tr><td class="infoBoxContent">'.tep_draw_input_field("max_weight").'</td></tr>'."\n"; echo '<tr><td class="infoBoxContent"><strong>'.HEADING_COST.'</strong></td></tr><tr><td class="infoBoxContent">'.HEADING_COST_TEXT.'</td></tr><tr><td class="infoBoxContent">'.tep_draw_input_field("cost", $cost).'</td></tr>'; echo '<tr><td colspan="2">'.tep_draw_button(IMAGE_SAVE, 'disk', null, 'primary'); //tep_image_submit('button_update.gif', 'Save these values as a new package.') ; // echo '&nbsp;&nbsp;'.tep_draw_button(IMAGE_CANCEL, 'trash', null, 'primary'); //<a href="' . tep_href_link( 'packaging.php' ) . '">'.tep_image_button('button_cancel.gif', IMAGE_CANCEL) .'</A>' ; echo "</td></tr></table>" ; echo ("</form>"); } //****************************** showUpdatePackageForm() // Show the form to update a package function showUpdatePackageForm() { $packages = getPackages(); $activepackage = $packages[0]; if ($_GET['id'] != "") { for ($i = 0; $i < count($packages); $i++) { if ($_GET['id'] == $packages[$i]['id']) { $activepackage = $packages[$i]; } } } echo "<table cellspacing='0' width='100%' cellpadding='0'> <tr><td colspan='2' class='infoBoxHeading'>". UPDATE_PACKAGE."</td></tr></table>\n"; echo tep_draw_form("updatepackage", 'packaging.php', 'id='.$activepackage['id'], 'post'); echo tep_draw_hidden_field("action", "updatepackage"); echo tep_draw_hidden_field("id", $activepackage['id']); echo '<table><tr><td class="infoBoxContent"><strong>'.HEADING_NAME.'</strong></td></tr><tr><td class="infoBoxContent">'.HEADING_NAME_TEXT.'</td></tr><tr><td class="infoBoxContent">'.tep_draw_input_field("name", $activepackage['name']).'</td></tr>'."\n"; echo '<tr><td class="infoBoxContent"><strong>'.HEADING_DESCRIPTION.'</strong></td></tr><tr><td class="infoBoxContent">'.HEADING_DESCRIPTION_TEXT.'</td></tr><tr><td class="infoBoxContent">'.tep_draw_input_field("description", $activepackage['description']).'</td></tr>'."\n"; echo '<tr><td class="infoBoxContent"><strong>'.HEADING_LENGTH.'</strong></td></tr><tr><td class="infoBoxContent">'.HEADING_LENGTH_TEXT.'</td></tr><tr><td class="infoBoxContent">'.tep_draw_input_field("length", $activepackage['length']).'</td></tr>'."\n"; echo '<tr><td class="infoBoxContent"><strong>'.HEADING_WIDTH.'</strong></td></tr><tr><td class="infoBoxContent">'.HEADING_WIDTH_TEXT.'</td></tr><tr><td class="infoBoxContent">'.tep_draw_input_field("width", $activepackage['width']).'</td></tr>'."\n"; echo '<tr><td class="infoBoxContent"><strong>'.HEADING_HEIGHT.'</strong></td></tr><tr><td class="infoBoxContent">'.HEADING_HEIGHT_TEXT.'</td></tr><tr><td class="infoBoxContent">'.tep_draw_input_field("height", $activepackage['height']).'</td></tr>'."\n"; echo '<tr><td class="infoBoxContent"><strong>'.HEADING_EMPTY_WEIGHT.'</strong></td></tr><tr><td class="infoBoxContent">'.HEADING_EMPTY_WEIGHT_TEXT.'</td></tr><tr><td class="infoBoxContent">'.tep_draw_input_field("empty_weight", $activepackage['empty_weight']).'</td></tr>'."\n"; echo '<tr><td class="infoBoxContent"><strong>'.HEADING_MAX_WEIGHT.'</strong></td></tr><tr><td class="infoBoxContent">'.HEADING_MAX_WEIGHT_TEXT.'</td></tr><tr><td class="infoBoxContent">'.tep_draw_input_field("max_weight", $activepackage['max_weight']).'</td></tr>'."\n"; echo '<tr><td class="infoBoxContent"><strong>'.HEADING_COST.'</strong></td></tr><tr><td class="infoBoxContent">'.HEADING_COST_TEXT.'</td></tr><tr><td class="infoBoxContent">'.tep_draw_input_field("cost", $activepackage['cost']).'</td></tr>'; echo '<tr><td colspan="2">'.tep_draw_button(IMAGE_SAVE, 'disk', null, 'primary');// tep_image_submit('button_update.gif', 'Update the package with these values.') ; //echo '&nbsp;&nbsp;'.tep_draw_button(IMAGE_CANCEL, 'trash', null, 'primary');//<a href="' . tep_href_link( 'packaging.php','id='.$activepackage['id'] ) . '">'.tep_image_button('button_cancel.gif', IMAGE_CANCEL) .'</a>'."\n"; echo "</td></tr></table>\n" ; echo ("</form>\n"); } //*************************** showConfirmDeletePackageForm() // Shows the form to confirm package deletion function showConfirmDeletePackageForm() { $packages = getPackages(); $package_name = ""; for ($i = 0; $i < count($packages); $i++) { if ($packages[$i]['id'] == $_GET['id']) { $package_name = $packages[$i]['name']; } } echo "<table cellspacing='0' width='100%' cellpadding='0'> <tr><td colspan='2' class='infoBoxHeading'>". DELETE_PACKAGE."</td></tr></table>"; echo tep_draw_form("confirmDeletePackage", 'packaging.php'); echo tep_draw_hidden_field("action", "deletepackage"); echo tep_draw_hidden_field("id", $_GET['id']); echo '<table cellpadding="5"><tr><td class="infoBoxContent">'.CONFIRM_DELETE.'</td></tr>' ; echo "<tr><td>".$package_name."</td></td>"; echo "<tr><td>"; // echo '<a href="' . tep_href_link( 'packaging.php' ) . '">'.tep_image_button('button_confirm.gif', IMAGE_CONFIRM) .'</a>' ; //tep_draw_button(IMAGE_EDIT, 'pencil', tep_href_link('packaging.php', 'action=showupdatepackageform&id='.$activeid)) echo tep_draw_button(IMAGE_CONFIRM, 'close', null, 'primary'); //echo tep_image_submit('button_confirm.gif', IMAGE_CONFIRM) ; echo '&nbsp;&nbsp;'.tep_draw_button(HEADING_CANCEL, 'arrowreturn-1-w', tep_href_link('packaging.php'));//<a href="' . tep_href_link( 'packaging.php' ) . '">'.tep_image_button('button_cancel.gif', IMAGE_CANCEL) .'</a>' ; echo '</td></tr></table>'."\n"; echo '</form>'."\n"; } //************************ ShowPackageInfo() // Shows the info a package function showPackageInfoForm() { $packages = getPackages(); $activepackage = $packages[0]; $activeid = $_GET["id"]; if ($activeid != "") { for ($i = 0; $i < count($packages); $i++) { if ($activeid == $packages[$i]['id']) { $activepackage = $packages[$i]; } } } if ($error != "") { echo '<SPAN class="errorText">'.$error.'</SPAN>'; } echo "<table cellspacing='0' width='100%' cellpadding='0'><tr>\n<td colspan='2' class='infoBoxHeading'><strong>". HEADING_INFO ."</strong></td></tr></table>\n"; if (count($packages) != 0) { echo '<table>'."\n"; echo '<tr><td class="infoBoxContent"><strong>'. HEADING_NAME .'</strong></td></tr><tr><td class="infoBoxContent">'.$activepackage['name'].'</td></tr>'."\n"; echo '<tr><td class="infoBoxContent"><strong>'. HEADING_DESCRIPTION.'</strong></td></tr><tr><td class="infoBoxContent">'.$activepackage['description'].'</td></tr>'."\n"; echo '<tr><td class="infoBoxContent"><strong>'. HEADING_LENGTH .'</strong></td></tr><tr><td class="infoBoxContent">'.$activepackage['length'].'</td></tr>'."\n"; echo '<tr><td class="infoBoxContent"><strong>'. HEADING_WIDTH .'</strong></td></tr><tr><td class="infoBoxContent">'.$activepackage['width'].'</td></tr>'."\n"; echo '<tr><td class="infoBoxContent"><strong>'. HEADING_HEIGHT .'</strong></td></tr><tr><td class="infoBoxContent">'.$activepackage['height'].'</td></tr>'."\n"; echo '<tr><td class="infoBoxContent"><strong>'.HEADING_EMPTY_WEIGHT.'</strong></td></tr><tr><td class="infoBoxContent">'.$activepackage['empty_weight'].'</td></tr>'."\n"; echo '<tr><td class="infoBoxContent"><strong>'. HEADING_MAX_WEIGHT .'</strong></td></tr><tr><td class="infoBoxContent">'.$activepackage['max_weight'].'</td></tr>'."\n"; echo '<tr><td class="infoBoxContent"><strong>'. HEADING_COST .'</strong></td></tr><tr><td class="infoBoxContent">'.$activepackage['cost'].'</td></tr>'."\n"; echo "</table>\n"; } echo ""; } ?> </td> </tr> </table> </td> <!-- body_text_eof //--></tr> <!-- body_eof //--> <!-- footer //--> <?php require('includes/footer.php'); ?> <!-- footer_eof //--> <br> <?php require('includes/template_bottom.php'); require('includes/application_bottom.php'); ?> \includes\classes\packing.php <?php /* $Id: packaging.php, v1.0 Exp $ osCommerce, Open Source E-Commerce Solutions http://www.oscommerce.com Copyright (c) 2019 osCommerce Released under the GNU General Public License Adapted from the UPSXML contribution dimensions support = 0: no dimensions support dimensions support = 1: ready-to-ship support only dimensions support = 2: full dimensions support */ class packing { var $item, $totalWeight, $items_qty; function packing() { global $shipping_weight, $shipping_num_boxes, $total_weight, $boxcount, $cart, $order; $this->unit_weight = SHIPPING_UNIT_WEIGHT; $this->unit_length = SHIPPING_UNIT_LENGTH; $this->items_qty = 0; $this->totalWeight = 0; $this->item = array(); if (defined('SHIPPING_DIMENSIONS_SUPPORT') && SHIPPING_DIMENSIONS_SUPPORT == 'Ready-to-ship only') { $this->dimensions_support = 1; } elseif (defined('SHIPPING_DIMENSIONS_SUPPORT') && SHIPPING_DIMENSIONS_SUPPORT == 'With product dimensions') { $this->dimensions_support = 2; } else { $this->dimensions_support = 0; } if (defined('SHIPPING_STORE_BOXES_USED') && SHIPPING_STORE_BOXES_USED == 'true') { $this->store_boxes_used = 1; } else { $this->store_boxes_used = 0; } if (method_exists($cart, 'get_products_for_packaging') ) { $productsArray = $cart->get_products_for_packaging(); } else { $productsArray = $cart->get_products(); } if ($this->dimensions_support > 0) { $productsArray = $this->more_dimensions_to_productsArray($productsArray); // debug only // echo '<pre>Products to pack:<br>'; // print_r($productsArray); // exit; } if ($this->dimensions_support == 2) { // sort $productsArray according to ready-to-ship (first) and not-ready-to-ship (last) usort($productsArray, ready_to_shipCmp); // Use packing algorithm to return the number of boxes we'll ship $boxesToShip = $this->packProducts($productsArray); /* echo '<pre>Boxes to ship:<br>'; print_r($boxesToShip); exit; */ if ($this->store_boxes_used == 1) { $storeBoxesToShip = base64_encode(serialize($boxesToShip)); $storeQueryArray = array('date' => 'now()', 'customers_id' => $_SESSION['customer_id'], 'boxes' => $storeBoxesToShip); tep_db_perform(TABLE_UPS_BOXES_USED, $storeQueryArray); } // Quote for the number of boxes for ($i = 0; $i < count($boxesToShip); $i++) { $this->_addItem($boxesToShip[$i]['length'], $boxesToShip[$i]['width'], $boxesToShip[$i]['height'], $boxesToShip[$i]['current_weight'], $boxesToShip[$i]['price']); $this->totalWeight += $boxesToShip[$i]['current_weight']; } } elseif ($this->dimensions_support == 1) { $this->totalWeight = 0; $total_non_ready_to_ship_weight = 0; $total_non_ready_to_ship_value = 0; // sort $productsArray according to ready-to-ship (first) and not-ready-to-ship (last) usort($productsArray, ready_to_shipCmp); $non_ready_to_shipArray = array(); // walk through the productsArray, separate the items ready-to-ship and add them to // the items (boxes) list, add the weight to the totalWeight // and add the other items to a separate array for ($i = 0; $i < count($productsArray); $i++) { if ($productsArray[$i]['ready_to_ship'] == '1') { for ($z = 0 ; $z < $productsArray[$i]['quantity']; $z++) { $this->_addItem($productsArray[$i]['length'], $productsArray[$i]['width'], $productsArray[$i]['height'], $productsArray[$i]['weight'], $productsArray[$i]['final_price']); $this->totalWeight += $productsArray[$i]['weight']; } // end for ($z = 0 ; $z < $productsArray[$i]['quantity']; $z++) } // end if($productsArray['ready_to_ship'] == '1') else { $non_ready_to_shipArray[] = $productsArray[$i]; } } // end for ($i = 0; $i < count($productsArray); $i++) // Ready_to_ship items out of the way, now assess remaining weight and remaining value of products for ($x = 0 ; $x < count($non_ready_to_shipArray) ; $x++) { $total_non_ready_to_ship_weight += ($non_ready_to_shipArray[$x]['weight'] * $non_ready_to_shipArray[$x]['quantity']); $total_non_ready_to_ship_value += ($non_ready_to_shipArray[$x]['final_price'] * $non_ready_to_shipArray[$x]['quantity']); } // end for ($x = 0 ; count($non_ready_to_shipArray) ; $x++) if (tep_not_null($non_ready_to_shipArray)) { // adapted code from includes/classes/shipping.php $shipping_non_ready_to_ship_boxes = 1; $shipping_non_ready_to_ship_weight = $total_non_ready_to_ship_weight; if (SHIPPING_BOX_WEIGHT >= $total_non_ready_to_ship_weight*SHIPPING_BOX_PADDING/100) { $total_non_ready_to_ship_weight = $total_non_ready_to_ship_weight+SHIPPING_BOX_WEIGHT; } else { $total_non_ready_to_ship_weight += $total_non_ready_to_ship_weight*SHIPPING_BOX_PADDING/100; } if ($total_non_ready_to_ship_weight > SHIPPING_MAX_WEIGHT) { // Split into many boxes $shipping_non_ready_to_ship_boxes = ceil($total_non_ready_to_ship_weight/SHIPPING_MAX_WEIGHT); $shipping_non_ready_to_ship_weight = round($total_non_ready_to_ship_weight/$shipping_non_ready_to_ship_boxes,1); } // end adapted code from includes/classes/shipping.php // weight and number of boxes of non-ready-to-ship is determined, now add them to the items list for ($y = 0; $y < $shipping_non_ready_to_ship_boxes ; $y++) { $this->_addItem(0, 0, 0, $shipping_non_ready_to_ship_weight, number_format(($total_non_ready_to_ship_value/$shipping_non_ready_to_ship_boxes), 2, '.', '')); $this->totalWeight += $shipping_non_ready_to_ship_weight; } // end for ($y = 0; $y < $shipping_non_ready_to_ship_boxes ; $y++) } // end if (tep_not_null($non_ready_to_shipArray)) } // if/else ($this->dimensions_support == '#') } // end function packing($dimensions_support = '0') //******************************************** function _addItem($length, $width, $height, $weight, $price = 0 ) { // Add box or item to shipment list. Round weights to 1 decimal places. if ((float)$weight < 1.0) { $weight = 1; } else { $weight = round($weight, 1); } $index = $this->items_qty; $this->item[$index]['item_length'] = ($length ? (string)$length : '0' ); $this->item[$index]['item_width'] = ($width ? (string)$width : '0' ); $this->item[$index]['item_height'] = ($height ? (string)$height : '0' ); $this->item[$index]['item_weight'] = ($weight ? (string)$weight : '0' ); $this->item[$index]['item_price'] = $price; $this->items_qty++; } //******************** function getPackagesByVol() { $packages = array(); $packages_query = tep_db_query("select *, (package_length * package_width * package_height) as volume from " . TABLE_PACKAGING . " order by volume"); $counter = 0; while ($package = tep_db_fetch_array($packages_query)) { $packages[] = array( 'id' => $package['package_id'], 'name' => $package['package_name'], 'description' => $package['package_description'], 'length' => $package['package_length'], 'width' => $package['package_width'], 'height' => $package['package_height'], 'empty_weight' => $package['package_empty_weight'], 'max_weight' => $package['package_max_weight'], 'volume' => $package['volume']); // sort dimensions from low to high, used in the function fitsInBox $dimensions = array($package['package_length'], $package['package_width'], $package['package_height']); sort($dimensions); foreach($dimensions as $key => $value) { if ($key == 0 ) { $packages[$counter]['x'] = $value; } if ($key == 1 ) { $packages[$counter]['y'] = $value; } if ($key == 2 ) { $packages[$counter]['z'] = $value; } } $counter++; } return $packages; } //******************************** function packProducts($productsArray) { $definedPackages = $this->getPackagesByVol(); $emptyBoxesArray = array(); for ($i = 0; $i < count($definedPackages); $i++) { $definedBox = $definedPackages[$i]; $definedBox['remaining_volume'] = $definedBox['volume']; $definedBox['current_weight'] = $definedBox['empty_weight']; $emptyBoxesArray[] = $definedBox; } if (count($emptyBoxesArray) == 0) { print("ERROR: No boxes to ship unpackaged product<br />\n"); break; } $packedBoxesArray = array(); $currentBox = NULL; $index_of_largest_box = count($emptyBoxesArray)-1; // Get the product array and expand multiple qty items. $productsRemaining = array(); for ($i = 0; $i < count($productsArray); $i++) { $product = $productsArray[$i]; // sanity checks on the product, no need for ready-to-ship items if ((int)$product['ready_to_ship'] == 0) { $product['ready_to_ship'] = '1'; for ($x = 0; $x <= $index_of_largest_box; $x++) { if ($this->fitsInBox($product, $emptyBoxesArray[$x])) { $product['ready_to_ship'] = '0'; $product['largest_box_it_will_fit'] = $x; } } // end for ($x = 0; $x <= $index_of_largest_box; $x++) } // end if ((int)$product['ready_to_ship'] == 0) for ($j = 0; $j < $productsArray[$i]['quantity']; $j++) { $productsRemaining[] = $product; } } // end for ($i = 0; $i < count($productsArray); $i++) // make sure the products that did not fit the largest box and are now set as ready-to-ship // are out of the way as soon as possible usort($productsRemaining, ready_to_shipCmp); // Worst case, you'll need as many boxes as products ordered $index_of_largest_box_to_use = count($emptyBoxesArray) -1; while (count($productsRemaining)) { // Immediately set aside products that are already packed and ready. if ($productsRemaining[0]['ready_to_ship'] == '1') { $packedBoxesArray[] = array ( 'length' => $productsRemaining[0]['length'], 'width' => $productsRemaining[0]['width'], 'height' => $productsRemaining[0]['height'], 'current_weight' => $productsRemaining[0]['weight'], 'price' => $productsRemaining[0]['final_price']); $productsRemaining = array_slice($productsRemaining, 1); continue; } // Cycle through boxes, increasing box size if all doesn't fit // but if the remaining products only fit in a box of smaller size, use that one to pack it away for ($b = 0; $b < count($emptyBoxesArray) && tep_not_null($productsRemaining); $b++) { $result = $this->fitProductsInBox($productsRemaining, $emptyBoxesArray[$b], $packedBoxesArray, $b, $index_of_largest_box_to_use); $packedBoxesArray = $result['packed_boxes']; $productsRemaining = $result['remaining']; if (isset($result['index_of_largest_box_to_use']) && $result['index_of_largest_box_to_use'] >= 0 ) { $index_of_largest_box_to_use = $result['index_of_largest_box_to_use']; } } } // end while return $packedBoxesArray; } //***************************** function fitsInBox($product, $box) { if ($product['x'] > $box['x'] || $product['y'] > $box['y'] || $product['z'] > $box['z']) { return false; } if ($product['volume'] <= $box['remaining_volume']) { if ($box['max_weight'] == 0 || ($box['current_weight'] + $product['weight'] <= $box['max_weight'])) { return true; } } return false; } //*********************************** function putProductInBox($product, $box) { $box['remaining_volume'] -= $product['volume']; $box['products'][] = $product; $box['current_weight'] += $product['weight']; $box['price'] += $product['final_price']; return $box; } //********************* function fitProductsInBox($productsRemaining, $emptyBox, $packedBoxesArray, $box_no, $index_of_largest_box) { $currentBox = $emptyBox; $productsRemainingSkipped = array(); $productsRemainingNotSkipped = array(); $largest_box_in_skipped_products = -1; // keep apart products that will not fit this box anyway for ($p = 0; $p < count($productsRemaining); $p++) { if ($productsRemaining[$p]['largest_box_it_will_fit'] < $box_no) { $productsRemainingSkipped[] = $productsRemaining[$p]; // check on skipped products: if they will not fit in the largest box // the $index_of_largest_box should be the one they *will* fit // otherwise the packing algorithm gets stuck in a loop if ($productsRemaining[$p]['largest_box_it_will_fit'] > $largest_box_in_skipped_products) { $largest_box_in_skipped_products = $productsRemaining[$p]['largest_box_it_will_fit']; } } else { $productsRemainingNotSkipped[] = $productsRemaining[$p]; } } unset($productsRemaining); $productsRemaining = $productsRemainingNotSkipped; unset($productsRemainingNotSkipped); if (count($productsRemaining) == 0) { // products remaining are the ones that will not fit this box (productsRemaimingSkipped) $result_array = array('remaining' => $productsRemainingSkipped, 'box_no' => $box_no, 'packed_boxes' => $packedBoxesArray, 'index_of_largest_box_to_use' => $largest_box_in_skipped_products); return ($result_array); } //Try to fit each product that can fit in box for ($p = 0; $p < count($productsRemaining); $p++) { if ($this->fitsInBox($productsRemaining[$p], $currentBox)) { //It fits. Put it in the box. $currentBox = $this->putProductInBox($productsRemaining[$p], $currentBox); if ($p == count($productsRemaining) - 1) { $packedBoxesArray[] = $currentBox; $productsRemaining = array_slice($productsRemaining, $p + 1); $productsRemaining = array_merge($productsRemaining, $productsRemainingSkipped); $result_array = array('remaining' => $productsRemaining, 'box_no' => $box_no, 'packed_boxes' => $packedBoxesArray); return ($result_array); } } else { if ($box_no == $index_of_largest_box) { //We're at the largest box already, and it's full. Keep what we've packed so far and get another box. $packedBoxesArray[] = $currentBox; $productsRemaining = array_slice($productsRemaining, $p); $productsRemaining = array_merge($productsRemaining, $productsRemainingSkipped); $result_array = array('remaining' => $productsRemaining, 'box_no' => $box_no, 'packed_boxes' => $packedBoxesArray); return ($result_array); } // Not all of them fit. Stop packing remaining products and try next box. $productsRemaining = array_merge($productsRemaining, $productsRemainingSkipped); $result_array = array('remaining' => $productsRemaining, 'box_no' => $box_no, 'packed_boxes' => $packedBoxesArray); return ($result_array); } // end else } // end for ($p = 0; $p < count($productsRemaining); $p++) } // end function fitProductsInBox // ****************************** function more_dimensions_to_productsArray($productsArray) { $counter = 0; foreach ($productsArray as $key => $product) { // in case by accident or by choice length, width or height is not set // we will estimate it by using a set density and the product['weight'] variable // will only be used in the check for whether it fits the largest box // after that it will already be set, if product['weight'] is set at least if ($product['length'] == 0 || $product['width'] == 0 || $product['height'] == 0) { $density = 0.7; if ($this->unit_length == 'CM') { $product['length']=$product['width']=$product['height']= round(10*(pow($product['weight']/$density, 1/3)),1); } else { // non-metric: inches and pounds $product['length']=$product['width']=$product['height']= round(pow($product['weight']*27.67/$density, 1/3),1); } } // end if ($product['length'] == 0 || $product['width'] == 0 etc. // sort dimensions from low to high, used in the function fitsInBox $dimensions = array($product['length'], $product['width'], $product['height']); sort($dimensions); foreach($dimensions as $key => $value) { if ($key == 0 ) { $productsArray[$counter]['x'] = $value; } if ($key == 1 ) { $productsArray[$counter]['y'] = $value; } if ($key == 2 ) { $productsArray[$counter]['z'] = $value; } } $productsArray[$counter]['volume'] = $product['length'] * $product['width'] * $product['height']; $counter++; } // end foreach ($productsArray as $key => $product) return($productsArray); } function getPackedBoxes() { return $this->item; } function getTotalWeight() { return $this->totalWeight; } function getNumberOfBoxes() { return $this->items_qty; } } // end class packing // ****************************** function ready_to_shipCmp( $a, $b) { if ( $a['ready_to_ship'] == $b['ready_to_ship'] ) return 0; if ( $a['ready_to_ship'] > $b['ready_to_ship'] ) return -1; return 1; } ?> \includes\modules\shipping\canadapost.php <?php /* $Id: canadapost.php v0.1 2019 Exp $ */ class canadapost { var $code, $title, $description, $icon, $enabled, $types, $boxcount; //*************** function canadapost() { global $order, $packing; $this->code = 'canadapost'; $this->title = MODULE_SHIPPING_CANADA_POST_TEXT_TITLE; $this->description = MODULE_SHIPPING_CANADA_POST_TEXT_DESCRIPTION; $this->sort_order = MODULE_SHIPPING_CANADA_POST_SORT_ORDER; $this->icon = 'icons/shipping_canadapost_small.gif'; $this->tax_class = MODULE_SHIPPING_CANADA_POST_TAX_CLASS; $this->enabled = ((MODULE_SHIPPING_CANADA_POST_STATUS == 'True') ? true : false); $this->access_username = MODULE_SHIPPING_CANADA_POST_USERNAME; $this->access_password = MODULE_SHIPPING_CANADA_POST_PASSWORD; $this->access_customer_number = MODULE_SHIPPING_CANADA_POST_CUSTOMER_NUMBER; $this->timeout = '60'; $this->quotetype = MODULE_SHIPPING_CANADA_POST_QUOTE_TYPE; $this->contract_id = MODULE_SHIPPING_CANADA_POST_CONTRACT_ID; $this->origin_postalcode = MODULE_SHIPPING_CANADA_POST_POSTALCODE; $this->use_insurance =((MODULE_SHIPPING_CANADA_POST_INSURE == 'True') ? true : false); $sdate = MODULE_SHIPPING_CANADA_POST_TURNAROUNDTIME; $this->turnaround = date('Y-m-d', strtotime( '+'.$sdate.' day' ) ); $this->handling_fee = MODULE_SHIPPING_CANADA_POST_HANDLING; $this->handling_type = MODULE_SHIPPING_CANADA_POST_HANDLING_TYPE; //calculate turnaround time // the variables for unit weight, unit length, and dimensions support were moved to // shop admin -> Configuration -> Shipping/Packaging in // Run the configuration_shipping.sql to add these to your configuration if (defined('SHIPPING_UNIT_WEIGHT')) { $this->unit_weight = SHIPPING_UNIT_WEIGHT; } else { // for those who will undoubtedly forget or not know how to run the configuration_shipping.sql // we will set the default to pounds (LBS) and inches (IN) $this->unit_weight = 'LBS'; } if (defined('SHIPPING_UNIT_LENGTH')) { $this->unit_length = SHIPPING_UNIT_LENGTH; } else { $this->unit_length = 'IN'; } if (defined('SHIPPING_DIMENSIONS_SUPPORT') && SHIPPING_DIMENSIONS_SUPPORT == 'Ready-to-ship only') { $this->dimensions_support = 1; } elseif (defined('SHIPPING_DIMENSIONS_SUPPORT') && SHIPPING_DIMENSIONS_SUPPORT == 'With product dimensions') { $this->dimensions_support = 2; } else { $this->dimensions_support = 0; } $this->protocol = 'https'; $this->host = ((MODULE_SHIPPING_CANADA_POST_MODE == 'Test') ? 'ct.soa-gw.canadapost.ca' : 'soa-gw.canadapost.ca'); $this->port = '443'; $this->path = '/rs/ship/price'; $this->items_qty = 0; // insurance addition $this->insure_package = false; if (MODULE_SHIPPING_CANADA_POST_INSURE == 'True') { $this->insure_package = true; } // end insurance addition $this->pkgvalue = ceil($order->info['subtotal']); // is divided by number of boxes later if ( ($this->enabled == true) && ((int)MODULE_SHIPPING_FEDEX_WEB_SERVICES_ZONE > 0) ) { $check_flag = false; $check_query = tep_db_query ("select zone_id from " . TABLE_ZONES_TO_GEO_ZONES . " where geo_zone_id = '" . MODULE_SHIPPING_FEDEX_WEB_SERVICES_ZONE . "' and zone_country_id = '" . $order->delivery['country']['id'] . "' order by zone_id"); while( $check = tep_db_fetch_array($check_query)) { if ($check ['zone_id'] < 1) { $check_flag = true; break; } elseif ($check ['zone_id'] == $order->delivery['zone_id']) { $check_flag = true; break; } $check->MoveNext(); } if ($check_flag == false) { $this->enabled = false; } } } // end function upsxml //************** function check() { if (!isset($this->_check)) { $check_query = tep_db_query("select configuration_value from " . TABLE_CONFIGURATION . " where configuration_key = 'MODULE_SHIPPING_CANADA_POST_STATUS'"); $this->_check = tep_db_num_rows($check_query); } return $this->_check; } //**************** function remove() { tep_db_query("delete from " . TABLE_CONFIGURATION . " where configuration_key in ('" . implode("', '", $this->keys()) . "')"); } function install() { tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, date_added) values ('Enable Canada Post Shipping Service(REST)', 'MODULE_SHIPPING_CANADA_POST_STATUS', 'True', 'Do you want to offer Canada Post shipping?', '6', '0', 'tep_cfg_select_option(array(\'True\', \'False\'), ', now())"); tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Canada Post Customer Number', 'MODULE_SHIPPING_CANADA_POST_CUSTOMER_NUMBER', '', 'Enter the Your Canada Post Customer Number.', '6', '1', now())"); tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Canada Post API Username', 'MODULE_SHIPPING_CANADA_POST_USERNAME', '', 'Enter your Canada Post (API Keys) username.', '6', '2', now())"); tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Canada Post API Password', 'MODULE_SHIPPING_CANADA_POST_PASSWORD', '', 'Enter your Canada Post (API Keys) password.', '6', '3', now())"); tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Canada Post Contract ID', 'MODULE_SHIPPING_CANADA_POST_CONTRACT_ID', '', 'Enter your Canada Post contract id (for commercial/contracted rates only).', '6', '4', now())"); tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, date_added) values ('Canada Post Quote Type', 'MODULE_SHIPPING_CANADA_POST_QUOTE_TYPE', 'commercial', 'Either commercial (for the contract holder) or counter (regular price for consumers)', '6', '5', 'tep_cfg_select_option(array(\'commercial\', \'counter\'), ', now())"); tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, date_added) values ('Enable Insurance', 'MODULE_SHIPPING_CANADA_POST_INSURE', 'True', 'Do you want to insure packages shipped by Canada Post?', '6', '6', 'tep_cfg_select_option(array(\'True\', \'False\'), ', now())"); tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Origin City', 'MODULE_SHIPPING_CANADA_POST_CITY', '', 'Enter the name of the origin city.', '6', '7', now())"); tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Origin State/Province', 'MODULE_SHIPPING_CANADA_POST_STATEPROV', '', 'Enter the two-letter code for your origin state/province.', '6', '8', now())"); tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Origin Country', 'MODULE_SHIPPING_CANADA_POST_COUNTRY', '', 'Enter the two-letter code for your origin country.', '6', '9', now())"); tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Origin Zip/Postal Code', 'MODULE_SHIPPING_CANADA_POST_POSTALCODE', '', 'Enter your origin zip/postalcode (from which the parcel will be sent).', '6', '10', now())"); tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, date_added) values ('Test or Production Mode', 'MODULE_SHIPPING_CANADA_POST_MODE', 'Test', 'Use this module in Test or Production mode? <br /><br />Your API Keys username and password are different in Test and Production mode', '6', '11', 'tep_cfg_select_option(array(\'Test\', \'Production\'), ', now())"); tep_db_query("insert into " . TABLE_CONFIGURATION . " ( configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, use_function, set_function, date_added) values ('Disallowed Shipping Methods', 'MODULE_SHIPPING_CANADA_POST_TYPES', '', 'Select the Canada Post services <span style=\'color: red; font-weight: bold\'>not</span> to be offered.', '6', '12', 'get_multioption_canadapost_xml', 'canadapost_cfg_select_multioption(array(\'D.RP\',\'D.EP\',\'D.XP\',\'D.XP.CERT\',\'D.PC\',\'D.LIB\',\'U.EP\',\'U.PW.ENV\',\'U.PW.PAK\',\'U.PW.PARCEL\',\'U.SP.AIR\',\'U.SP.SURF\',\'U.XP\',\'I.XP\',\'I.IP.AIR\',\'I.IP.SURF\',\'I.PW.ENV\', \'I.PW.PAK\',\'I.PW.PARCEL\',\'I.SP.AIR\',\'I.SP.SURF\'),', now())"); tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, date_added) values ('Handling Type', 'MODULE_SHIPPING_CANADA_POST_HANDLING_TYPE', 'Flat Fee', 'Handling type for this shipping method.', '6', '13', 'tep_cfg_select_option(array(\'Flat Fee\', \'Percentage\'), ', now())"); tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Handling Fee', 'MODULE_SHIPPING_CANADA_POST_HANDLING', '0', 'Handling fee for this shipping method.', '6', '14', now())"); tep_db_query ("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, use_function, set_function, date_added) values ('Shipping Zone', 'MODULE_SHIPPING_CANADA_POST_ZONE', '0', 'If a zone is selected, only enable this shipping method for that zone.', '6', '98', 'tep_get_zone_class_title', 'tep_cfg_pull_down_zone_classes(', now())"); tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, use_function, set_function, date_added) values ('Tax Class', 'MODULE_SHIPPING_CANADA_POST_TAX_CLASS', '0', 'Use the following tax class on the shipping fee.', '6', '15', 'tep_get_tax_class_title', 'tep_cfg_pull_down_tax_classes(', now())"); tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Sort order of display.', 'MODULE_SHIPPING_CANADA_POST_SORT_ORDER', '0', 'Sort order of display. Lowest is displayed first.', '6', '16', now())"); // add key for enabling email error messages tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, date_added) values ('Email Canada Post errors', 'MODULE_SHIPPING_CANADA_POST_EMAIL_ERRORS', 'Yes', 'Do you want to receive Canada Post errors by email?', '6', '17', 'tep_cfg_select_option(array(\'Yes\', \'No\'), ', now())"); tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Enter Turn Around Time', 'MODULE_SHIPPING_CANADA_POST_TURNAROUNDTIME', '1', 'Turn Around Time (days)', '6', '0', now())"); } //************* function keys() { return array('MODULE_SHIPPING_CANADA_POST_STATUS','MODULE_SHIPPING_CANADA_POST_CUSTOMER_NUMBER','MODULE_SHIPPING_CANADA_POST_USERNAME', 'MODULE_SHIPPING_CANADA_POST_PASSWORD','MODULE_SHIPPING_CANADA_POST_CONTRACT_ID','MODULE_SHIPPING_CANADA_POST_QUOTE_TYPE', 'MODULE_SHIPPING_CANADA_POST_INSURE','MODULE_SHIPPING_CANADA_POST_CITY','MODULE_SHIPPING_CANADA_POST_STATEPROV','MODULE_SHIPPING_CANADA_POST_COUNTRY', 'MODULE_SHIPPING_CANADA_POST_POSTALCODE','MODULE_SHIPPING_CANADA_POST_MODE','MODULE_SHIPPING_CANADA_POST_TYPES','MODULE_SHIPPING_CANADA_POST_HANDLING_TYPE', 'MODULE_SHIPPING_CANADA_POST_HANDLING','MODULE_SHIPPING_CANADA_POST_ZONE','MODULE_SHIPPING_CANADA_POST_TAX_CLASS','MODULE_SHIPPING_CANADA_POST_SORT_ORDER','MODULE_SHIPPING_CANADA_POST_EMAIL_ERRORS', 'MODULE_SHIPPING_CANADA_POST_TURNAROUNDTIME'); } //********************************************** function _canadaPostOrigin($city, $stateprov, $country, $postal){ $this->_canadaPostOriginCity = $city; $this->_canadaPostOriginStateProv = $stateprov; $this->_canadaPostOriginCountryCode = $country; $postal = str_replace(' ', '', $postal); if ($country == 'US') { $this->_canadaPostOriginPostalCode = substr($postal, 0, 5); } else { $this->_canadaPostOriginPostalCode = strtoupper($postal); } } //********************************************** function _canadaPostDest($city, $stateprov, $country, $postal) { $this->_canadaPostDestCity = $city; $this->_canadaPostDestStateProv = $stateprov; $this->_canadaPostDestCountryCode = $country; $postal = str_replace(' ', '', $postal); if ($country == 'US') { $this->_canadaPostDestPostalCode = substr($postal, 0, 5); } else if ($country == 'BR') { $this->_canadaPostDestPostalCode = substr($postal, 0, 5); } else if( $country == 'CA') { $this->_canadaPostDestPostalCode = strtoupper($postal); } else { $this->_canadaPostDestPostalCode = $postal; } } //******************************************** function _addItem($length, $width, $height, $weight, $price = 0 ) { // Add box or item to shipment list. Round weights to 1 decimal places. if ((float)$weight < 1.0) { $weight = 1; } else { $weight = round($weight, 3); } $index = $this->items_qty; $this->item_length[$index] = ($length ? (string)round((float)$length,1) : '0' ); $this->item_width[$index] = ($width ? (string)round((float)$width,1) : '0' ); $this->item_height[$index] = ($height ? (string)round((float)$height,1) : '0' ); $this->item_weight[$index] = ($weight ? (string)round((float)$weight,1) : '0' ); $this->item_price[$index] = $price; $this->items_qty++; } /***************************************************************************************************************************************************************/ // class methods function quote($method = '') { global $_POST, $order, $shipping_weight, $shipping_num_boxes, $total_weight, $boxcount, $cart, $packing; $state = $order->delivery['state']; $zone_query = tep_db_query("select zone_code from " . TABLE_ZONES . " where zone_name = '" . tep_db_input($order->delivery['state']) . "' and zone_country_id = '" . $order->delivery['country']['id'] . "'"); if (tep_db_num_rows($zone_query)) { $zone = tep_db_fetch_array($zone_query); $state = $zone['zone_code']; } $this->_canadaPostOrigin(MODULE_SHIPPING_CANADA_POST_CITY, MODULE_SHIPPING_CANADA_POST_STATEPROV, MODULE_SHIPPING_CANADA_POST_COUNTRY, MODULE_SHIPPING_CANADA_POST_POSTALCODE); $this->_canadaPostDest($order->delivery['city'], $state, $order->delivery['country']['iso_code_2'], $order->delivery['postcode']); // the check on $packing being an object will puzzle people who do things wrong (no changes when // you enable dimensional support without changing checkout_shipping.php) but better be safe if ($this->dimensions_support > 0 && is_object($packing)) { $boxValue = 0; $totalWeight = $packing->getTotalWeight(); $boxesToShip = $packing->getPackedBoxes(); for ($i = 0; $i < count($boxesToShip); $i++) { $this->_addItem($boxesToShip[$i]['item_length'], $boxesToShip[$i]['item_width'], $boxesToShip[$i]['item_height'], $boxesToShip[$i]['item_weight'], $boxesToShip[$i]['item_price']); } // end for ($i = 0; $i < count($boxesToShip); $i++) } else { // The old method. Let osCommerce tell us how many boxes, plus the weight of each (or total? - might be sw/num boxes) $this->items_qty = 0; //reset quantities // $this->pkgvalue has been set as order subtotal around line 108, it will cause overcharging // of insurance if not divided by the number of boxes for ($i = 0; $i < $shipping_num_boxes; $i++) { $this->_addItem(0, 0, 0, $shipping_weight, number_format(($this->pkgvalue/$shipping_num_boxes), 2, '.', '')); } } $canadaPostQuote = $this->_canadaPostGetQuote(); if ((is_array($canadaPostQuote)) && (sizeof($canadaPostQuote) > 0)) { $this->quotes = array('id' => $this->code, 'module' => $this->title); usort($canadaPostQuote, array($this, "rate_sort_func")); $methods = array(); for ($i=0; $i < sizeof($canadaPostQuote); $i++) { //list($type, $cost) = each($canadaPostQuote[$i]); $basetype = $canadaPostQuote[$i]['service-code']; $cost = $canadaPostQuote[$i]['base']; $type = $canadaPostQuote[$i]['service-name']; $ddate = $canadaPostQuote[$i]['expected-delivery-date']; if ($this->exclude_choices($basetype)) continue; if ( $method == '' || $method == $basetype ) { $_type = $type; // changed to make handling percentage based if ($this->handling_type == "Percentage") { if ($_type) $methods[] = array('id' => $basetype, 'title' => $_type. ', '. $ddate, 'cost' => ((($this->handling_fee * $cost)/100) + $cost)); } else { if ($_type) $methods[] = array('id' => $basetype, 'title' => $_type. ', '. $ddate, 'cost' => ($this->handling_fee + $cost)); } } } if ($this->tax_class > 0) { $this->quotes['tax'] = tep_get_tax_rate($this->tax_class, $order->delivery['country']['id'], $order->delivery['zone_id']); } $this->quotes['methods'] = $methods; } else { if ( $canadaPostQuote != false ) { $errmsg = $canadaPostQuote; } else { $errmsg = MODULE_SHIPPING_CANADAPOST_TEXT_UNKNOWN_ERROR; } $errmsg .= '<br>'. STORE_NAME.' via <a href="mailto:'.STORE_OWNER_EMAIL_ADDRESS.'"><u>Email</u></a>.'; $this->quotes = array('module' => $this->title, 'error' => $errmsg); } if (tep_not_null($this->icon)) { $this->quotes['icon'] = tep_image($this->icon); } return $this->quotes; } //********************* function _canadaPostGetQuote() { //need to loop throught all items or packages $capost= array(); //first item/package for ($i=0; $i<sizeof($this->item_width); $i++) { $xmlRequest = $this->_GetRequestXml(0); $result = $this->_post($xmlRequest); if($result===false) return false; $box = $this->_parseResult($result); if($box===false) return false; for($i3=0; $i3 < sizeof($box);$i3++) { $merge = true; for($i2=0; $i2 < sizeof($capost);$i2++) { if (strcmp($capost[$i2]['service-code'],$box[$i3]['service-code'])==0) { $capost[$i2]['base'] += $box[$i3]['base']; $merge=false; break; } } if($merge) $capost[] = array('service-name'=>$box[$i3]['service-name'],'base'=>$box[$i3]['base'],'service-code' => $box[$i3]['service-code'],'expected-delivery-date'=> $box[$i3]['expected-delivery-date']); } } // print_r($aryProducts); return $capost; } //***************************** function _parseResult($xmlResult) { $aryProducts = false; $upstemp = array(); $priceQuotes = $xmlResult->{'price-quotes'}->children('http://www.canadapost.ca/ws/ship/rate'); if ( $priceQuotes->{'price-quote'} ) { $aryProducts=array(); foreach ( $priceQuotes as $priceQuote ) { $title =(string) $priceQuote->{'service-name'}; $code = (string)$priceQuote->{'service-code'}; $charge = (float) $priceQuote->{'price-details'}->{'base'}; $ddate = (string) $priceQuote->{'service-standard'}->{'expected-delivery-date'}; //2011-09-21*/ $aryProducts[] = array('service-name'=>$title,'base'=>$charge,'service-code' => $code,'expected-delivery-date'=> $ddate); } } // print_r($aryProducts); return $aryProducts; } //****************************************************************** function _post($xmlRequest) { $url = $this->protocol."://".$this->host.":".$this->port.$this->path; $curl = curl_init($url); // Create REST Request curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true); curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2); curl_setopt($curl, CURLOPT_CAINFO, realpath(dirname($argv[0])) . '/includes/modules/shipping/canadapost/cacert.pem'); // Signer Certificate in PEM format curl_setopt($curl, CURLOPT_POST, true); curl_setopt($curl, CURLOPT_POSTFIELDS, $xmlRequest); curl_setopt($curl, CURLOPT_TIMEOUT, (int)$this->timeout); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); curl_setopt($curl, CURLOPT_USERPWD, $this->access_username . ':' . $this->access_password); curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type: application/vnd.cpc.ship.rate+xml', 'Accept: application/vnd.cpc.ship.rate+xml')); $curl_response = curl_exec($curl); // Execute REST Request // echo $curl_response; // send email if enabled in the admin section if (curl_errno($curl) && $this->email_errors) { $error_from_curl = sprintf('Error [%d]: %s', curl_errno($curl), curl_error($curl)); error_log("Error from cURL: " . $error_from_curl . " experienced by customer with id " . $_SESSION['customer_id'] . " on " . date('Y-m-d H:i:s'), 1, STORE_OWNER_EMAIL_ADDRESS); } curl_close ($curl); libxml_use_internal_errors(true); $xml = simplexml_load_string('<root>' . preg_replace('/<\?xml.*\?>/','',$curl_response) . '</root>'); if (!$xml) { $error_from_curl = 'Failed loading XML' . "\n". $curl_response . "\n"; if($this->email_errors) error_log("Error from cURL: " . $error_from_curl . " experienced by customer with id " . $_SESSION['customer_id'] . " on " . date('Y-m-d H:i:s'), 1, STORE_OWNER_EMAIL_ADDRESS); } else { if ($xml->{'price-quotes'} ) { return $xml; } if ($xml->{'messages'} ) { $messages = $xml->{'messages'}->children('http://www.canadapost.ca/ws/messages'); $error_from_curl=''; foreach ( $messages as $message ) { $error_from_curl .= 'Error Code: ' . $message->code . "\n"; $error_from_curl .= 'Error Msg: ' . $message->description . "\n\n"; } if($this->email_errors) error_log("Error from cURL: " . $error_from_curl . " experienced by customer with id " . $_SESSION['customer_id'] . " on " . date('Y-m-d H:i:s'), 1, STORE_OWNER_EMAIL_ADDRESS); } } return false; } // *************************** function exclude_choices($type) { if(substr($type,0,4)=='DOM.') $type = 'D.'.substr($type,4); else if(substr($type,0,4)=='USA.') $type = 'U.'.substr($type,4); else if(substr($type,0,4)=='INT.') $type = 'I.'.substr($type,4); $disallowed_types = explode(",", MODULE_SHIPPING_CANADA_POST_TYPES); for ($za = 0; $za < count ($disallowed_types); $za++ ) { // when no disallowed types are present, --none-- is in the db but causes an error because --none-- is // not added as a define if ($disallowed_types[$za] == '--none--' ) continue; if ($type == trim($disallowed_types[$za])) { return true; } // end if ($type_root == constant(trim($disallowed_types[$za]))). } // if the type is not disallowed: return false; } // Next function used for sorting the shipping quotes on rate: low to high is default. function rate_sort_func ($a, $b) { $av = array_values($a); $av = $av[0]; $bv = array_values($b); $bv = $bv[0]; // return ($av == $bv) ? 0 : (($av < $bv) ? 1 : -1); // for having the high rates first return ($av == $bv) ? 0 : (($av > $bv) ? 1 : -1); // low rates first } function _GetRequestXml($index) { //http://www.canadapost.ca/cpo/mc/business/productsservices/developers/services/rating/getrates/default.jsf //The weight of the parcel in kilograms. //Details of the parcel dimensions in centimeters. $weight = $this->item_weight[$index]; $price = round($this->item_price[$index],2); $width = $this->item_weight[$index]; $height = $this->item_height[$index]; $length = $this->item_length[$index]; if($this->unit_weight == 'LBS') { //change to kilograms $weight = round($weight/2.2,3); } if($this->unit_length == 'IN') { //change to centimeters $width = round($width * 2.54,1); $height = round($height * 2.54,1); $length = round($length * 2.54,1); } $xmlRequest ="<?xml version=\"1.0\" encoding=\"UTF-8\"?> <mailing-scenario xmlns=\"http://www.canadapost.ca/ws/ship/rate\"> <customer-number>$this->access_customer_number</customer-number> <quote-type>$this->quotetype</quote-type>"; if($this->contract_id) { $xmlRequest .= "<contract-id>$this->contract_id</contract-id>"; } $xmlRequest .= "<expected-mailing-date>$this->turnaround</expected-mailing-date>"; if (($this->use_insurance) && ($price>0)) { $xmlRequest .= "<options><option> <option-code>COV</option-code> <option-amount>$price</option-amount> </option> </options>"; } $xmlRequest .= " <parcel-characteristics> <weight>$weight</weight>"; if (($this->dimensions_support>0) && ($width>0) && ($height>0) && ($length>0)) { $xmlRequest .= "<dimensions><length>$length</length> <width>$width</width> <height>$height</height> </dimensions>"; } $xmlRequest .= "</parcel-characteristics> <origin-postal-code>$this->_canadaPostOriginPostalCode</origin-postal-code> <destination>"; if($this->_canadaPostDestCountryCode=='CA') { $xmlRequest .="<domestic> <postal-code>$this->_canadaPostDestPostalCode</postal-code> </domestic>"; } else if($this->_canadaPostDestCountryCode=='US') { $xmlRequest .="<united-states> <zip-code>$this->_canadaPostDestPostalCode</zip-code> </united-states>"; } else { $xmlRequest .="<international> <country-code>$this->_canadaPostDestCountryCode</country-code> </international>"; } $xmlRequest .=" </destination> </mailing-scenario>"; //echo $xmlRequest; return $xmlRequest; } //end of function _GetRequestXml } //end of class canadapost function get_multioption_canadapost_xml($values) { if (tep_not_null($values)) { $values_array = explode(',', $values); foreach ($values_array as $key => $_method) { if ($_method == '--none--') { $method = $_method; } else { $method = constant('CANADA_POST_' .get_canada_post_service_code($_method)); } $readable_values_array[] = $method; } $readable_values = implode(', ', $readable_values_array); return $readable_values; } else { return ''; } } function get_canada_post_service_code($key) { $km = str_replace('.','_',trim($key)); if(substr($km,0,2)=='D_') $km = 'DOM_'.substr($km,2); else if(substr($km,0,2)=='U_') $km = 'USA_'.substr($km,2); else if(substr($km,0,2)=='I_') $km = 'INT_'.substr($km,2); return $km; } function canadapost_cfg_select_multioption($select_array, $key_value, $key = '') { for ($i=0; $i<sizeof($select_array); $i++) { $name = (($key) ? 'configuration[' . $key . '][]' : 'configuration_value'); $string .= '<br><input type="checkbox" name="' . $name . '" value="' . $select_array[$i] . '"'; $key_values = explode( ", ", $key_value); if ( in_array($select_array[$i], $key_values) ) $string .= ' CHECKED'; $string .= '> ' . constant('CANADA_POST_' . get_canada_post_service_code($select_array[$i])); } $string .= '<input type="hidden" name="' . $name . '" value="--none--">'; return $string; } ?> Other files are mods to /admin/categories.php Add code for defines....
  11. Dnj1964

    Shipping Add-On Update (Canada)

    Warning gone. But no shipping. Shipping set to Canada only, and testing with a Canadian address Shipping is currently not available for the selected shipping address. Please select or create a new shipping address to use with your purchase.
  12. Dnj1964

    Add Video - Product Info

    I want to add video to the product info description. Using: <div class="embed-responsive embed-responsive-16by9"> <iframe class="embed-responsive-item" src="videos/battery-+-fun-factory.mp4"></iframe> </div> video folder is in /public_html Also tried linking to youtube url instead of server: <div class="embed-responsive embed-responsive-16by9"> <iframe class="embed-responsive-item" src="https://youtu.be/sNPly-u7XMY"></iframe> </div> Both give a 404 error Please contact the web site owner for further assistance. Highly unlikely he will be of any useful help.
  13. Dnj1964

    Add Video - Product Info

    You were right! Thank you! Special character was the problem. Getting rid of the "+" did it. Then putting it in the <iframe> loading from server made the video autoplay. <div class="embed-responsive embed-responsive-16by9"> <iframe width="530" height="298" src="http://www.naughtypleasures.ca/videos/fun-factory/battery-plus-fun-factory-product-video.mp4"></iframe> </div> So changed the code to: <div class="embed-responsive embed-responsive-16by9 hoverable"> <video class="embed-responsive-item" controls> <source src="http://www.naughtypleasures.ca/videos/fun-factory/battery-plus-fun-factory-product-video.mp4" type="video/mp4"> </video> </div> And it adds play controls and by using "hover" the controls disappear while playing unless mouse over video.
  14. Wanting to add images within the product description, not working using simple html
  15. Dnj1964

    Add Video - Product Info

    If I am using outside the tabs I shouldn't need the _VID1... i'll figure it out. Thanks
  16. Dnj1964

    Add Video - Product Info

    I would prefer to the save the video to my server and use that way that way if they are ever removed then it doesn't affect my pages. For some reason uploading and linking locallly doesn't seem to want to work. If I strip the actual URL from the website and add it into an <iframe> it works. <div class="embed-responsive embed-responsive-16by9"> <iframe width="530" height="298" src="https://www.youtube-nocookie.com/embed/sNPly-u7XMY?rel=0&amp;showinfo=0" frameborder="0" allowfullscreen=""></iframe> </a> </div>
  17. Uninstalled Uploaded my changed files again... And it works again. Go figure. Thanks and have a great day. Can't wait until my EV SSL finally arrives... That should be real fun. Stay tuned, I guessing a lot more posts to come...
  18. I did a fresh install 3 times and it doesn't fix it. I will try and upload all the stock files again and then reinstall
  19. I did notice that the categories add-on is broken, no buttons or boxes to change anything. Easy fix was to uninstall and hard code the position and colors.
  20. Ok so it is confirmed... If you look up idiot in the dictionary, you will find my picture front and center. It really was just that simple. I really hate to admit my stupidity, but if you can't laugh at yourself your finished before you started. Thank you very much for the simple suggestion. Clicking those little radio button is almost like a game even if you don't understand the outcome or consequences as it may be!
  21. I just did a full site backup and database backup Will have another look at things but probably just going to start fresh and reload 1 by 1 like you said.
  22. That is about what I thought! Was hoping for a simpler solution but why would anything be simple. Thanks!
  23. BS4 & Categories 1.3 One thing I am good at is taking a prefectly working code and butchering the hell out of it! It shows all categories and has a different cPath=xx for each category. It opens a category page when clicking on each category or sub-category. It does not show any products at all <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <title>For Her | Naughty Pleasures</title> <base href="http://www.naughtypleasures.ca/"> <!-- bs 4.2 --> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous"> <!-- fa 5.6 --> <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css" integrity="sha384-UHRtZLI+pbxtHCWp1t77Bi1L4ZtiqrqD80Kn4Z8NTSRyMA2Fd33n5dQ8lWUE00s/" crossorigin="anonymous"> <link href="custom.css" rel="stylesheet"> <link href="user.css" rel="stylesheet"> <link href="naughty_favicon/favicon.ico" rel="shortcut icon"> <link rel="canonical" href="http://www.naughtypleasures.ca/index.php?view=all&amp;cPath=23" /> </head> <body> <nav class="navbar bg-light navbar-light sticky-top navbar-expand-sm cm-navbar"> <div class="container-fluid"> <div class="navbar-header"> <button type="button" class="navbar-toggler nb-hamburger-button" data-toggle="collapse" data-target="#collapseCoreNav" aria-controls="collapseCoreNav" aria-expanded="false" aria-label="Toggle Navigation"> <span class="navbar-toggler-icon"></span></button> <a class="navbar-brand" href="http://www.naughtypleasures.ca/index.php"><img src="images/np-logo.png" alt="Naughty Pleasures" title="Naughty Pleasures" width="405" height="60" class="img-fluid" /></a> <style> .navbar-header { background-color: #FFFFFF ; background-image: url() !important; color: #B62285 ; } .navbar-light .navbar-nav .nav-link { background-image: url() !important; color: #B62285; } .bg-light { background-color: #FFFFFF !important; background-image: url() !important; color: #B62285 ; } .navbar-light .navbar-brand { color: #B62285 ; } .breadcrumb { background-color: ; color: ; } .alert-info { background-color: #FDE6FD ; color: ; border-color: #FDE6FD; } .card-header { background-color: #F7E4F1 ; background-image: url() !important; color: #B62285 ; } .card-body { background-color: #F7E4F1 ; color: #B62285 ; } .card-footer { background-color: #F7E4F1 ; color: #B62285 ; } .btn-view { background-color: #F7E4F1 ; color: #B62285 ; border-color:#F7E4F1 ; } .btn-view:hover { background-color: #FDE6FD ; color: #B62285 ; border-color:#FDE6FD ; } .btn-success { background-color: #F7E4F1 ; color: #B62285 ; border-color:#F7E4F1 ; } .btn-success:hover { background-color: #dfe3ee ; color: #FDE6FD ; border-color:#dfe3ee ; } .btn-secondary { background-color: #FDE6FD ; color: #B62285 ; border-color:#FDE6FD ; } .btn-secondary:hover { background-color: #FDE6FD ; color: #B62285 ; border-color:#FDE6FD ; } .btn-primary { background-color: #F7E4F1 ; color: #B62285 ; border-color:#F7E4F1 ; } .btn-primary:hover { background-color: #FDE6FD ; color: #B62285 ; border-color:#FDE6FD ; } .btn-danger { background-color: #F7E4F1 ; color: #B62285 ; border-color:#F7E4F1 ; } .btn-danger:hover { background-color: #FDE6FD ; color: #B62285 ; border-color:#FDE6FD ; } .btn-warning { background-color: #F7E4F1 ; color: #B62285 ; border-color:#F7E4F1 ; } .btn-warning:hover { background-color: MODULE_NAVBAR_JCM_COLOR_BRAND_CONTENT_NAVBARB_BUTTONWARNINGRHBC ; color: #B62285 ; border-color:#FDE6FD ; } .btn-info { background-color: #F7E4F1 ; color: #B62285 ; border-color:#F7E4F1 ; } .btn-info:hover { background-color: ; color: #B62285 ; border-color: ; } .bm-categories .list-group-item{ background-color: #B62285 ; color: #FDE6FD; } .bm-categories .list-group-item:hover { background-color:#B62285 ; color: #FDE6FD; } .bm-best-sellers .list-group-item{ background-color: #FFFFFF ; color: #B62285; } .bm-best-sellers .list-group-item:hover { background-color:#B62285 ; color: #FDE6FD; } .jumbotron { background-color: #FFFFFF ; background-image: url() !important; color: #B62285; } .footer a, h4 { color: #B62285; } .footer-extra { background-color: #FFFFFF ; background-image: url() !important; color: #B62285 !important; } </style></div> <div class="collapse navbar-collapse" id="collapseCoreNav"> <ul class="navbar-nav mr-auto"> <li class="nav-item nb-home"> <a class="nav-link" href="http://www.naughtypleasures.ca/index.php"><i class="fa fa-home"></i> Home</a></li> <script type="text/javascript" src="ext/responsivemenu/js/responsivemultimenu-LANGUAGE_CODE.js"></script> <link rel="stylesheet" href="ext/responsivemenu/css/responsivemultimenu.css" type="text/css"/> <li class="rmm style"> <ul> <li> <a href="#"><i class="fa fa-list"></i><b> Products</b></a> <ul id=""><li><a href="http://www.naughtypleasures.ca/index.php?cPath=23">For Her</a> <ul><li><a href="http://www.naughtypleasures.ca/index.php?cPath=23_26">Dildos</a><li><a href="http://www.naughtypleasures.ca/index.php?cPath=23_27">Vibrators</a><li><a href="http://www.naughtypleasures.ca/index.php?cPath=23_28">Eggs/Bullets</a></li> </ul></li> <li><a href="http://www.naughtypleasures.ca/index.php?cPath=24">For Him</a><li><a href="http://www.naughtypleasures.ca/index.php?cPath=25">Couples</a></li> <li><a href="http://www.naughtypleasures.ca/index.php?cPath=21">Lubes</a></li> <li><a href="http://www.naughtypleasures.ca/index.php?cPath=34">Sensual</a><li><a href="http://www.naughtypleasures.ca/index.php?cPath=22">Bondage</a></li> </ul></li> </ul> <!-- menu end --> </li> <style> /* minimal styles for that navi */ .rmm {z-index:900;} .rmm ul {margin: 0; padding:0; list-style: none; position: relative; background: #FDE6FD; z-index:900;} .rmm ul:after {content: ""; clear: both; display: block;} .rmm ul li {float: left;} .rmm ul li:hover {background: #FDE6FD;} .rmm ul li:hover > ul {display: block;} .rmm ul li:hover a{color: #B62285;} .rmm ul li a {color: #B62285; display: block; text-decoration: none;} .rmm ul ul {display: none; margin:0; padding: 0; position: absolute; top: 100%;} .rmm ul ul li {float: none; position: relative;} .rmm ul ul li a{color: #B62285;} .rmm ul ul li a:hover {background: #FDE6FD;} .rmm ul ul ul {position: absolute; left: 100%; top:0; width: 100%;} /* mobile menu header button */ .rmm-toggled {width: 100%; background-color: #FDE6FD; min-height: px; margin: 0 auto; display: none; cursor:pointer;} .rmm-closed ~ .rmm-mobile {display: none!important;} .rmm-toggled-controls{width: 100%;} .rmm-toggled-title{width: 60%; float: left; font-size: 25px; color: #B62285; font-weight:600; display: block; padding: 8px 0; text-decoration: none; text-align: left; padding-left: 35px;} .rmm-toggled-button{width: 20%; float: left; margin-top: 3px; display:block; width: 32px; padding:0 !important; margin:10px 10px 0 0; border:1px solid #FDE6FD; border-radius:3px; float: right; } .rmm-toggled-button span{float: left; display:block; margin: 3px 6px; height: 3px; background:#FDE6FD; width:20px;} /* normalny back button visible only on mobiles */ .rmm .rmm-back{display: none; font-size: 13px;} .rmm .rmm-back:after {display: none;} .rmm .rmm-back a:after { font-family: 'icomoon'; speak: none; -webkit-font-smoothing: antialiased; content: "\e000"; position: relative; display: inline-block; -webkit-transform: rotate(-60deg); transform: rotate(-60deg); top: 1px; right: -2px ; float: left; font-size: 13px; color:#B62285; } .rmm-mobile .rmm-back{display: block;} /* mobile menu list */ .rmm-mobile{width: 10%;} .rmm-mobile .rmm-dropdown:hover ~ ul, .rmm-mobile .rmm-dropdown:hover > ul ,.rmm-mobile .rmm-dropdown:hover + ul {display: none!important;} .rmm-mobile ul{width: 100%; position: inherit!important;} .rmm-mobile li{width: 100%; } /* mobile menu js action */ .rmm-dropdown{display: block!important;} .rmm-mobile .rmm-subview{display: block!important; width: 100%;} .rmm-mobile .rmm-subover-hidden{display: none!important;} .rmm-mobile .rmm-subover-visible{display: block;} .rmm-mobile .rmm-subover-header{display: none!important; padding: 0; margin: 0;} /* mobile menu content */ .rmm-mobile .rmm-submenu { position: relative; left: 0px; } .rmm .rmm-mobile li:hover > ul { display: none; } /* arrow down for wide screen */ .rmm.style { text-align: left; font-family: Helvetica Neue!important; } .rmm.style ul { box-shadow: 0px 0px 0px rgba(0, 0, 0, 0); background: #FFFFFF; text-transform: capitalize; display: inline-table; text-align:left; margin-top: 4px; } /* original #F2F2F2 changed to #E92121*/ .rmm.style ul li { text-align:left; } .rmm.style ul li:hover { background: #FDE6FD; } /* original #DDEBF7 replaced by #ef7070 */ .rmm.style ul ul { display: none; margin:0; background: #FFFFFF; border-radius: 0px; padding: 0; position: absolute; } .rmm.style ul li a { color:#B62285; font-weight:100; display: block; padding: 5px 20px; text-decoration: none; }/* original #4B5668 changed to #ffffff */ .rmm.style ul ul li { border-bottom: 1px solid #FFFFFF; border-top: 1px solid #FFFFFF; } .rmm.style ul ul li a { padding: 2px 50px; color:#B62285;; } .rmm.style ul ul li a:hover { background: #FDE6FD; } /* arrow down for wide screen */ .rmm.style ul li > a:not(:only-child):after { font-family: 'icomoon'; speak: none; -webkit-font-smoothing: antialiased; content: "\e000"; position: relative; display: inline-block; -webkit-transform: rotate(210deg); transform: rotate(210deg); top: -4px; left: 1px; font-size: 10px; } /* arrow left for wide screen submenus */ .rmm.style ul ul li > a:not(:only-child):after {-webkit-transform: rotate(120deg)!important; transform: rotate(120deg)!important; top: 2px; font-size: 12px; float: right; margin-right: -20px;} /* mobile style */ .rmm.style .rmm-mobile li > a:not(:only-child):after { -webkit-transform: rotate(120deg)!important; transform: rotate(120deg)!important; top: 4px!important; font-size: 14px!important; float: right; margin-right: -20px; } .rmm.style .rmm-mobile li{ background: #FDE6FD; border-bottom: 1px solid #FDE6FD!important; border-top: 0!important; } .rmm.style .rmm-mobile li:hover { background:#FDE6FD; } .rmm.style .rmm-mobile ul li a:hover { background: #FDE6FD; } /* like mobile view style .rmm.style2 {text-align: left; font-family: Tahoma;} .rmm.style2 ul {box-shadow: 0px 0px 9px rgba(0, 0, 0, 0.15); background:#990; text-transform: uppercase; display: inline-table; text-align:left; width: 100%;} .rmm.style2 ul li {float: none;} .rmm.style2 ul li:hover {background: #4b545f;} .rmm.style2 ul ul {display: none; margin:0; background: #5f6975; border-radius: 0px; padding: 0; position: relative;} .rmm.style2 ul li a {color: #fff; font-weight:600; display: block; padding: 15px 35px; text-decoration: none; font-weight:600; } .rmm.style2 ul ul li {border-bottom: 1px solid #575F6A; border-top: 1px solid #6B727C;} .rmm.style2 ul ul li a {padding: 12px 35px; color: #fff; } .rmm.style2 ul ul li a:hover {background: #4b545f;} .rmm.style2 ul ul ul {left: 0;} */ /* suhi */ </style> <script> $('ul.nav li.dropdown').hover(function() { $(this).find('.dropdown-menu').stop(true, true).delay(200).fadeIn(500); }, function() { $(this).find('.dropdown-menu').stop(true, true).delay(200).fadeOut(500); }); </script> <li class="nav-item dropdown nb-account"> <a class="nav-link dropdown-toggle" href="#" id="navDropdownAccount" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> <i class="fa fa-fw fa-user"></i> My Account <span class="caret"></span> </a> <div class="dropdown-menu" aria-labelledby="navDropdownAccount"> <a class="dropdown-item" href="http://www.naughtypleasures.ca/login.php"><i class="fas fa-fw fa-sign-in-alt"></i> Log In</a><a class="dropdown-item" href="http://www.naughtypleasures.ca/create_account.php"><i class="fas fa-fw fa-pencil-alt"></i> Register</a> <div class="dropdown-divider"></div> <a class="dropdown-item" href="http://www.naughtypleasures.ca/account.php">My Account</a> <a class="dropdown-item" href="http://www.naughtypleasures.ca/account_history.php">My Orders</a> <a class="dropdown-item" href="http://www.naughtypleasures.ca/address_book.php">My Address Book</a> <a class="dropdown-item" href="http://www.naughtypleasures.ca/account_password.php">My Password</a> </div> </li> </ul> <ul class="navbar-nav ml-auto"> <li class="navbar-search"><form name="quick_find" action="http://www.naughtypleasures.ca/advanced_search_result.php" method="get" class="navbar-form"><div class="input-group"><input type="search" name="keywords" required placeholder="Search" class="form-control" /><span class="input-group-btn"><button type="submit" class="btn btn-info"><i class="fa fa-search"></i></button></span></div></form></li> <li class="nav-item dropdown nb-shopping-cart"> <a class="nav-link dropdown-toggle" href="#" id="navDropdownCart" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> <i class="fa fa-fw fa-shopping-cart"></i> 0 item(s) <span class="caret"></span> </a> <div class="dropdown-menu dropdown-menu-right" aria-labelledby="navDropdownCart"> <a class="dropdown-item" href="http://www.naughtypleasures.ca/shopping_cart.php">0 item(s), $0.00</a> </div> </li> </ul> </div> </div> </nav> <div id="bodyWrapper" class="container-fluid"> <div class="row"> <noscript> <div class="col-sm-12 cm-header-noscript"> <div class="alert alert-danger text-center"> <p><strong>JavaScript seems to be disabled in your browser.</strong></p><p>You must have JavaScript enabled in your browser to utilize the functionality of this website.<br><a class="alert-link" href="https://www.enable-javascript.com/" target="_blank" rel="nofollow">Click here for instructions on enabling javascript in your browser</a>. </div> </div> </noscript> </div> <div class="body-sans-header clearfix"> <div class="row"> <div id="bodyContent" class="col order-xs-1 order-md-6"> <div class="contentContainer"> <div class="row"> <div class="col-sm-12 title cm-ip-title"> <h1 class="display-4">For Her</h1> </div> </div> </div> </div> <!-- bodyContent //--> <div id="columnLeft" class="col-md-2 order-xs-6 order-md-1"> <div class="card bm-manufacturers"> <div class="card-header">Manufacturers</div> <ul class="list-group list-group-flush"> <li class="list-group-item"><form name="manufacturers" action="http://www.naughtypleasures.ca/index.php" method="get"><select name="manufacturers_id" onchange="this.form.submit();" size="1" style="width: 100%" class="form-control"><option value="" selected="selected">Please Select</option><option value="11">Aneros</option><option value="6">Kama Sutra</option><option value="4">Stud 100</option></select></form></li> </ul> </div> <div class="card bm-whats-new"> <div class="card-header"><a href="http://www.naughtypleasures.ca/products_new.php">What's New?</a></div> <div class="card-body text-center"> <a href="http://www.naughtypleasures.ca/product_info.php?products_id=44"><img src="images/helix-200.png" alt="Aneros Helix Trident" title="Aneros Helix Trident" width="200" height="200" class="img-fluid" /></a><br /><a href="http://www.naughtypleasures.ca/product_info.php?products_id=44">Aneros Helix Trident</a><br />$55.99 </div> </div> </div> </div> <!-- row --> </div> <!-- bodyWrapper //--> </div> <footer> <div class="jumbotron jumbotron-fluid jumbotron-footer"> <div class="container-fluid"> <div class="footer"> <div class="row"> <div class="col-sm-6 col-md-3 cm-footer-information-links"> <h4>Information</h4> <ul class="list-unstyled list-tap-target"> <li><a href="http://www.naughtypleasures.ca/privacy.php">Privacy &amp; Cookie Policy</a></li> <li><a href="http://www.naughtypleasures.ca/conditions.php">Terms &amp; Conditions</a></li> <li><a href="http://www.naughtypleasures.ca/shipping.php">Shipping &amp; Returns</a></li> <li><a href="http://www.naughtypleasures.ca/contact_us.php">Contact Us</a></li> </ul> </div> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"> <style> #social { padding-top: 8%; padding-bottom: 1%; margin-top:0%; margin-bottom: 1%; } #social ul{ position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); margin: 0; padding: 0; display: flex; } #social ul li{ list-style: none; margin: 0 40px; } #social ul li .fa{ font-size: 40px; color: #262626; line-height: 80px; transition: .5s; } #social ul li a{ position: relative; display: block; width: 80px; height: 80px; background-color: #fff; text-align: center; transform: perspective(100px) rotate(-30deg) skew(25deg) translate(0,0); transition: .5s; box-shadow: -20px 20px 10px rgb(0, 0, 0, 0.5); } #social ul li a::before{ content: ""; position: absolute; top: 10px; left: -20px; height: 100%; width: 20px; background: #b1b1b1; transition: .5s; transform: rotate(0deg) skewY(-45deg); } #social ul li a::after{ content: ""; position: absolute; top: 80px; left: -11px; height: 20px; width: 100%; background: #b1b1b1; transition: .5s; transform: rotate(0deg) skewX(-45deg); } #social ul li a:hover{ transform: perspective(1000px) rotate(-30deg) skew(25deg) translate(20px, -20px); box-shadow: -50px 50px 50px rgb(0, 0, 0, 0.5); } #social ul li:hover .fa{ color: #fff; } #social ul li a:hover{ transform: perspective(1000px) rotate(-30deg) skew(25deg) translate(20px, -20px); box-shadow: -50px 50px 50px rgb(0, 0, 0, 0.5); } #social ul li:hover:nth-child(1) a{ background: #3b5999; } #social ul li:hover:nth-child(1) a:before{ background: #2e4a86; } #social ul li:hover:nth-child(1) a:after{ background: #4a69ad; } #social ul li:hover:nth-child(2) a{ background: #55acee; } #social ul li:hover:nth-child(2) a:before{ background: #4184b7; } #social ul li:hover:nth-child(2) a:after{ background: #4d9fde; } #social ul li:hover:nth-child(3) a{ background: #dd4b39; } #social ul li:hover:nth-child(3) a:before{ background: #c13929; } #social ul li:hover:nth-child(3) a:after{ background: #e83322; } #social ul li:hover:nth-child(4) a{ background: #0077B5; } #social ul li:hover:nth-child(4) a:before{ background: #036aa0; } #social ul li:hover:nth-child(4) a:after{ background: #0d82bf; } #social ul li:hover:nth-child(5) a{ background: linear-gradient(#400080, transparent), linear-gradient(200deg, #d047d1, #ff0000, #ffff00); } #social ul li:hover:nth-child(5) a:before{ background: linear-gradient(#400080, transparent), linear-gradient(200deg, #d047d1, #ff0000, #ffff00); } #social ul li:hover:nth-child(5) a:after{ background: linear-gradient(#400080, transparent), linear-gradient(200deg, #d047d1, #ff0000, #ffff00); } .sc { position: absolute; left: 50%; top: 50%; top: calc(50% - 50px); transform: translate(-50%, -50%); width: 600px; color: blue; text-align: center; } @media (max-width: 40em) { #social { display: none; } } </style> <div id="social" class="col-sm-12 col-md- cm-footer-social-bookmarks"> <h4 class="sc"></h4> <ul id="social"> <li><a href="https://www.facebook.com" target="_blank" rel="noopener noreferrer"><i class="fa fa-facebook" aria-hidden="true"></i></a></li> <li><a href="#" target="_blank" rel="noopener noreferrer"><i class="fa fa-twitter" aria-hidden="true"></i></a></li> <li><a href="#" target="_blank" rel="noopener noreferrer"><i class="fa fa-google-plus" aria-hidden="true"></i></a></li> <li><a href="https://www.linkedin.com" target="_blank" rel="noopener noreferrer"><i class="fa fa-linkedin" aria-hidden="true"></i></a></li> <li><a href="#" target="_blank" rel="noopener noreferrer"><i class="fa fa-instagram" aria-hidden="true"></i></a></li> </ul> </div> </div> </div> </div> </div> <div class="footer-extra"> <div class="container-fluid"> <div class="row"> <div class="col-sm-6 text-center text-sm-left cm-footer-extra-copyright"> <center><p><b>Copyright &copy; 2019 <a href="http://www.naughtypleasures.ca/index.php">Naughty Pleasures</a></b><br/><img class="img-responsive" src="images/canadian.gif" alt="100% Canadian Owned & Operated"></p></center></div> </div> </div> </div> </footer> <!-- bs 4.2 --> <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.6/umd/popper.min.js" integrity="sha384-wHAiFfRlMFy6i5SRaxvfOCifBUQy1xHdJ/yoi7FRNXMRBu5WHdZYu1hA6ZOblgut" crossorigin="anonymous"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js" integrity="sha384-B0UglyR+jN6CkvvICOB2joaf5I4l3gm9GU6Hc1og6Ls7i6U/mkkaduKaBhlAXv9k" crossorigin="anonymous"></script> <script> var cc = sessionStorage.list_grid; if (cc == 'list') { $('#products .item').removeClass('g-g-i').addClass('l-g-i').addClass('col-sm-12'); }else { $('#products .item').removeClass('l-g-i').addClass('g-g-i').removeClass('col-sm-12'); } $(document).ready(function() { $('#list').click(function(event){ event.preventDefault(); $('#products .item').addClass('l-g-i').removeClass('g-g-i').addClass('col-sm-12'); sessionStorage.setItem('list_grid', 'list'); }); $('#grid').click(function(event){ event.preventDefault(); $('#products .item').removeClass('l-g-i').addClass('g-g-i').removeClass('col-sm-12'); sessionStorage.setItem('list_grid', 'grid'); }); }); </script> <script type="application/ld+json">{"@context":"http:\/\/schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":0,"item":{"@id":"http:\/\/www.naughtypleasures.ca","name":" Home"}},{"@type":"ListItem","position":1,"item":{"@id":"http:\/\/www.naughtypleasures.ca\/index.php","name":"Catalog"}},{"@type":"ListItem","position":2,"item":{"@id":"http:\/\/www.naughtypleasures.ca\/index.php?cPath=23","name":"For Her"}}]}</script> <script> var filter = $('.filter-list'); $('div.alert-filters > ul.nav').append($('<ul>').attr('class','nav ml-auto').append($('<li>').append(filter))); </script> </body> </html>
  24. Dnj1964

    Adding images into product description

    Thanks, I understand simple, about the only thing I do understand.
  25. Dnj1964

    Adding images into product description

    Need to figure out why it wants the image in public_html instead of public_html/images Now that the image is working in the table is it better to use <table> tags or add somthing like this: <div class="divTable"> <div class="divTableBody"> <div class="divTableRow"> <div class="divTableCell"> <ul>Product Specs <li>Tip Width: 0.50&rdquo;</li> <li>Upper Knob: 0.63&rdquo;</li> <li>Lower Knob: 1.75&rdquo;</li> <li>Insertable Length: 3.75&rdquo;</li> </ul> </div> <div class="divTableCell"><img class="img-responsive" src="tempo-specs-image-200.png" alt="Aneros Tempo Sizing" /></div> </div> </div> </div> And add the below to user.css .divTable{ display: table; width: 100%; } .divTableRow { display: table-row; } .divTableHeading { background-color: #FFFFFF; display: table-header-group; } .divTableCell, .divTableHead { border: 1px solid #FFFFFF; display: table-cell; padding: 3px 10px; } .divTableHeading { background-color: #FFFFFF; display: table-header-group; font-weight: bold; } .divTableFoot { background-color: #FFFFFF; display: table-footer-group; font-weight: bold; } .divTableBody { display: table-row-group; }
×