Jump to content

ecartz

♥Ambassador
  • Content count

    3,088
  • Joined

  • Last visited

  • Days Won

    30

Reputation Activity

  1. Thanks
    ecartz got a reaction from ce7 in foreach error   
    It's telling you that that function is not returning an array.  It would need to consistently return an array to be used that way. 
  2. Thanks
    ecartz got a reaction from ce7 in Insert / Update / Delete Categories Images   
    No, the DB update would stay the same.  The only change you'd need to make is " . TABLE_CATEGORIES . " to categories.  Otherwise , the code that you posted should be correct.  Except that it's missing the confirmation step.  You have the button and you have the code that processes the confirmation.  But I don't see the actual step for confirming the deletion. 
  3. Thanks
    ecartz got a reaction from domiosc in problem with .mx files generated as copies of all .php files   
    If you can run executable code in .ico files, that is a security hole. 
    Similarly, X-Frame-Options is generally set by Apache, not by individual applications.  https://geekflare.com/secure-apache-from-clickjacking-with-x-frame-options/
    Allowing image uploads should only be available to the admin, which should be secured by Apache's Basic Authentication (htpasswd).  Writing image files to anywhere other than images/ admin/backups and a few more locations should be blocked by directory file permissions. 
    You can disable osCommerce from allowing .ico uploads.  Look for set_extensions or I seem to recall that older versions had a default set somewhere. 
    Only the last of those is settable in application.  Some of the third is configuring for use by the application.  Some is host configuration (who owns the site files and directories; what are the permissions).  The first two are purely host configuration.  Although perhaps the .ico file is being included by something else (what?). 
    In general, clickjacking only works if you use the same browser instance to both log into your osCommerce admin and view other pages.  If you only ever use the browser instance for looking at the osCommerce admin, clickjacking won't work.  Keep one browser only for osCommerce.  This could be Chrome, Edge, Firefox, Safari, Opera, etc.  And use a different browser for regular web browsing.  Chrome and Firefox also support multiple profiles (Chrome will let you have multiple profiles open at the same time). 
  4. Thanks
    ecartz got a reaction from ce7 in Insert / Update / Delete Categories Images   
    The image URLs are made by appending the image name to the image directory URL.  So you only want the portion of the path after the images directory.  In your example, that would be cat2/cat-test-01.jpg
  5. Thanks
    ecartz got a reaction from ce7 in Insert / Update / Delete Categories Images   
    The image URLs are made by appending the image name to the image directory URL.  So you only want the portion of the path after the images directory.  In your example, that would be cat2/cat-test-01.jpg
  6. Thanks
    ecartz got a reaction from ralgiere in Phoenix easy populate addon v1.0.6.0   
    I realize that the Apps Marketplace search often sucks.  But https://apps.oscommerce.com/v=cephoenix10&q=Easy Populate shows three things claiming to be Easy Populate for Phoenix. 
  7. Like
    ecartz got a reaction from Demitry in problem with .mx files generated as copies of all .php files   
    Perhaps to lull you into a false sense of security.  Or because they didn't need it.  Corrupt the 2.2 site directly.  And use those permissions to try to corrupt the Edge site.  This works if both subdomains use the same user behind the scenes.  So corrupting the 2.2 site allows them to make changes to the Edge site.  Or almost make changes.  Perhaps they were unable to complete the hack.  Perhaps adding the .mx files was only the first step.  If they had completed the hack, you might never have known because they would have cleaned up after themselves. 
  8. Thanks
    ecartz got a reaction from ralgiere in Google is not indexing my website   
    admin > Modules > Header tags > Robot NoIndex
    Note though that that is only on specific pages by default and there are reasons why you might not want to have those particular pages indexed.  So rather than turning it off, just make sure that it does not have either All or the specific page that you want indexed checked. 
  9. Thanks
    ecartz got a reaction from ralgiere in Google is not indexing my website   
    Have you signed up for Google Search Console?  https://www.google.com/webmasters/tools/submit-url?pli=1
    https://support.google.com/webmasters/answer/6065812
  10. Like
    ecartz got a reaction from DivebombInc in Installation issues   
    My guess would be that something went wrong with the FTP upload.  Try it again. 
    You could also upload just the install.php file.  But usually it's not just one file that goes missing.  So either do the whole thing or at least the install directory (and all contents). 
    You might check that you aren't out of filesystem quota.  Some hosts have limits. 
  11. Like
    ecartz got a reaction from DivebombInc in Installation issues   
    Download page:  yellow button. 
  12. Like
    ecartz got a reaction from DivebombInc in Installation issues   
    What is the part of the the URL after the catalog directory?  E.g. if I go to https://template.me.uk/phoenix/index.php , then the catalog directory is https://template.me.uk/phoenix/ and the part of the URL after it is index.php
    When you click Start, to what URL does it try to go, relative to the catalog directory? 
  13. Like
    ecartz got a reaction from peterpil19 in Free Shipping Per Product for v2.3   
    I made a mistake in the second line. 
    public function listen_injectRedirects() { $products_ship_free = false; if (!GLOBALS['free_shipping']) { define('TEXT_CHOOSE_SHIPPING_METHOD', TEXT_CHOOSE_SHIPPING_METHOD_NO_PFS); define('TEXT_ENTER_SHIPPING_INFORMATION', TEXT_ENTER_SHIPPING_INFORMATION_NO_PFS); return; } foreach ($_SESSION['cart']->get_products() as $product) { if (1 == $product['ship_free']) { $ship_free_count += $product['quantity']; } } if (($GLOBALS['total_weight'] == 0) && ($GLOBALS['total_count'] == 0)) { $products_ship_free = true; $GLOBALS['free_shipping'] = true; if (!defined('FREE_SHIPPING_TITLE')) { include 'includes/languages/' . $_SESSION['language'] . '/modules/order_total/ot_shipping.php'; } } define('TEXT_CHOOSE_SHIPPING_METHOD', ($products_ship_free ? sprintf(PRODUCTS_SHIP_FREE_COUNT, $ship_free_count); : TEXT_CHOOSE_SHIPPING_METHOD_NO_PFS)); define('TEXT_ENTER_SHIPPING_INFORMATION', ((!$products_ship_free && ($ship_free_count > 0)) ? sprintf(PRODUCTS_SHIP_FREE_COUNT_ONLY, $ship_free_count) : TEXT_ENTER_SHIPPING_INFORMATION_NO_PFS)); } Note that this assumes that you've modified the shoppingCart->get_products method to return the 'ship_free' column. 
  14. Like
    ecartz got a reaction from cdetdi in When is /ext/.../standard_ipn used?   
    Just to highlight something that others have noted in passing but may not have stated explicitly enough.  If you want to test the IPN path, then don't go back to your site after making the payment.  Because if you just click quickly through everything, chances are that you get back to the site before PayPal sends the IPN.  So act like a customer.  When you get to the screen that says something like "Click here to return to the merchant", close the browser window.  Then your test will work like their order.  Because some customers do exactly that. 
    Note that both the IPN and the click through flow use the paypal_standard file.  The IPN file also has some logic of its own.  This contrasts to the logic triggered from the checkout_process file. 
  15. Like
    ecartz got a reaction from cdetdi in When is /ext/.../standard_ipn used?   
    Just to highlight something that others have noted in passing but may not have stated explicitly enough.  If you want to test the IPN path, then don't go back to your site after making the payment.  Because if you just click quickly through everything, chances are that you get back to the site before PayPal sends the IPN.  So act like a customer.  When you get to the screen that says something like "Click here to return to the merchant", close the browser window.  Then your test will work like their order.  Because some customers do exactly that. 
    Note that both the IPN and the click through flow use the paypal_standard file.  The IPN file also has some logic of its own.  This contrasts to the logic triggered from the checkout_process file. 
  16. Like
    ecartz got a reaction from sickaporean in 1064 error and worse ...   
    The one and only important difference is in includes/modules/product_listing.php , so you can just copy that file from the download (either the second link that I posted or it's on the downloads page now).  Or use the first link and delete the single line that it shows to delete. 
    The only other file that has changed is the includes/version.php file.  If you want, you can copy that over too. 
    I don't know that update instructions have been posted yet, but they would essentially be to copy those two files. 
  17. Like
    ecartz got a reaction from sickaporean in 1064 error and worse ...   
    Unfortunately, 1.0.7.0 is the version on the download page. 
    The line to remove to fix that is at https://github.com/gburton/CE-Phoenix/commit/82d528731f600565d113614e0733a831c5a27f8a
    Alternately, download the entire https://github.com/gburton/CE-Phoenix/archive/master.zip and extract includes/modules/product_listing.php and copy it over. 
  18. Like
    ecartz got a reaction from sickaporean in 1064 error and worse ...   
    If you use phpMyAdmin to run
    select p.*, pd.*, m.*, IF(s.status, s.specials_new_products_price, NULL) as specials_new_products_price, IF(s.status, s.specials_new_products_price, p.products_price) as final_price, p.products_quantity as in_stock, if(s.status, 1, 0) as is_special from products_description pd, products p left join manufacturers m on p.manufacturers_id = m.manufacturers_id left join specials s on p.products_id = s.products_id, products_to_categories p2c where p.products_status = '1' and p.products_id = p2c.products_id and pd.products_id = p2c.products_id and pd.language_id = '1' and p2c.categories_id = '2' order by pd.products_name what does it say? 
  19. Thanks
    ecartz got a reaction from ce7 in admin Define Languages produces double blank lines   
    I would do it right before the return rather than where you're doing it, for efficiency's sake and to make sure you sort every file. 
    I think that you are implicitly sorting by path most of the time but not always.  Try
    usort($result, function ($a, $b) { return strcmp($a['name'], $b['name']); }); return $result; That explicitly sorts by path. 
    Or even better might be to move it outside the function entirely. 
    foreach (tep_opendir(DIR_FS_CATALOG_LANGUAGES . $_GET['lngdir']) as $file) { to
    $files = tep_opendir(DIR_FS_CATALOG_LANGUAGES . $_GET['lngdir']); usort($result, function ($a, $b) { return strcmp($a['name'], $b['name']); }); foreach ($files as $file) {  
  20. Thanks
    ecartz got a reaction from Philo2005 in Product Listing - Picture width   
    https://github.com/gburton/CE-Phoenix/commit/8f4c98ab496f47b58bcc8accf81b183fab013013
    Or just update to 1.0.6.0. 
  21. Like
    ecartz got a reaction from ce7 in Products Image Verify   
    Try replacing every instance of
    $HTTP_GET_VARS with
    $_GET I.e.
    <?php require 'includes/application_top.php'; if (!function_exists('file_put_contents')) { function file_put_contents($filename, $data, $file_append = false) { $fp = fopen($filename, ($file_append ? 'a+' : 'w+')); if (!$fp) { trigger_error('file_put_contents cannot write in file.', E_USER_ERROR); return; } fputs($fp, $data); fclose($fp); } } require 'includes/template_top.php'; ?> <!-- body_text //--> <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> </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_PRODUCTS; ?></td> <td class="dataTableHeadingContent" align="left"><?php echo TABLE_HEADING_IMAGE_SIZE; ?></td> <td class="dataTableHeadingContent" align="right"><?php echo TABLE_HEADING_ACTION; ?>&nbsp;</td> </tr> <?php if ($sID !="" && file_exists(DIR_FS_CACHE . 'image_verify.cache')) { $fd = fopen (DIR_FS_CACHE . 'image_verify.cache', "r"); $iv_cache_contents = fread ($fd,filesize (DIR_FS_CACHE . 'image_verify.cache')); fclose ($fd); $verify_query_raw = "select p.products_id, p.products_image, pd.products_name from products p, products_description pd where p.products_id = pd.products_id and (" . $iv_cache_contents .") order by pd.products_name"; } else { if (file_exists(DIR_FS_CACHE . 'image_verify.cache')) { unlink(DIR_FS_CACHE . 'image_verify.cache'); } $verify_query_raw = "select p.products_id, p.products_image, pd.products_name from products p, products_description pd where p.products_id = pd.products_id order by pd.products_name"; } $verify_query = tep_db_query($verify_query_raw); while ($verify = tep_db_fetch_array($verify_query)) { if ( !isset($sInfo) && (!isset($_GET['sID']) || ($_GET['sID'] == $verify['products_id'])) ) { $sInfo = new objectInfo($verify); } //Checks Status of all 3 image sizes to make sure it is not blank, null or if file exists so we only print out products with missing images only. $image_status = 0; if ($verify['products_image'] != "" && $verify['products_image'] != "NULL") { if (file_exists(DIR_FS_CATALOG . 'images/' . $verify['products_image'])) { $image_status = 1; } else { $image_status = 0; } } else { $image_status = 2; } if ($image_status != 1) { if (file_exists(DIR_FS_CACHE . 'image_verify.cache')) { file_put_contents(DIR_FS_CACHE . 'image_verify.cache', " or pd.products_id = " . $verify['products_id'], 'append.php'); } else { file_put_contents(DIR_FS_CACHE . 'image_verify.cache', "pd.products_id = " . $verify['products_id']); } } if ( (is_object($sInfo ?? null)) && ($verify['products_id'] == $sInfo->products_id) && ($image_status != 1)) { echo ' <tr class="dataTableRowSelected" onmouseover="this.style.cursor=\'hand\'" onclick="document.location.href=\'' . tep_href_link('image_verify.php', '&sID=' . $sInfo->products_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('image_verify.php', '&sID=' . $verify['products_id']) . '\'">' . "\n"; } if ($image_status != 1) { ?> <td class="dataTableContent"><?php echo $verify['products_name']; ?></td> <td class="dataTableContent" align="left"><?php } switch ($image_status) { case 0: echo tep_image('images/icons/ms_error.png', KEY_OK, 20, 20); break; case 2: echo tep_image('images/icons/ms_warning.png', KEY_ERROR, 20, 20); break; } if ($image_status != 1) { ?></td> <td class="dataTableContent" align="right"> <?php if ( (is_object($sInfo)) && ($verify['products_id'] == $sInfo->products_id) ) { echo tep_image('images/icon_arrow_right.gif', ''); } else { echo '<a href="' . tep_href_link('image_verify.php', 'page=' . $_GET['page'] . '&sID=' . $verify['products_id']) . '">' . tep_image('images/icon_info.gif', IMAGE_ICON_INFO) . '</a>'; } ?>&nbsp;</td> </tr> <?php } } ?> </table></td> <?php $heading = []; $contents = []; if ($sID =="") { $heading[] = ['text' => '<b><center>PLEASE CLICK ON PRODUCT ROW<BR>FOR MORE OPTIONS</center></b>']; } else { $heading[] = ['text' => '<b><center>' . $sInfo->products_name. '</center></b>']; } $contents[] = ['text' => '' . tep_image('images/pixel_black.gif', '', '100%', 3)]; $contents[] = [ 'align' => 'center', 'text' => '<a href="' . tep_href_link('categories.php', '&pID=' . $sInfo->products_id . '&action=new_product') . '">' . tep_image_button('button_edit.gif', IMAGE_EDIT) . '</a> <a href="' . tep_href_link('categories.php', '&pID=' . $sInfo->products_id . '&action=delete_product') . '">' . tep_image_button('button_delete.gif', IMAGE_DELETE) . '</a>', ]; $contents[] = ['text' => '' . tep_image('images/pixel_black.gif', '', '100%', 3)]; $contents[] = ['text' => '' . tep_image('images/icons/ms_error.png', '', 20, 20) . KEY_ERROR]; $contents[] = ['text' => '' . tep_image('images/icons/ms_warning.png', '', 20, 20) . KEY_NOT_USED]; $contents[] = ['text' => '' . tep_image('images/pixel_black.gif', '', '100%', 3)]; $contents[] = ['text' => DELETE_WARNING]; $contents[] = ['text' => '' . tep_image('images/pixel_black.gif', '', '100%', 3)]; $contents[] = ['text' => EDIT_WARNING]; $contents[] = ['text' => '' . tep_image('images/pixel_black.gif', '', '100%', 3)]; 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></td> <!-- body_text_eof //--> </tr> </table> <!-- body_eof //--> </body> </html> <?php require 'includes/template_bottom.php'; ?> <?php require 'includes/application_bottom.php'; ?> Also changed the location of the cache file.  The previous version required the admin directory to be writable, which should not be necessary. 
  22. Like
    ecartz got a reaction from raiwa in Purchase without account for 2.3.4 and BS2334   
    Nothing to do with this App (PWA), but this suggests that the class name and file of manualCart do not match or are not in includes/classes or includes/modules.  I would expect a class name of ManualCart and a file name of manual_cart.php -- it's possible that just changing those to match expectations would work.  You might want to post in that App's support thread for more help. 
  23. Like
    ecartz got a reaction from GetSirius in Categories Navbar Module - Phoenix v1.0.6.0   
    You might want to change lines 67-71 to
    $tpl_data = ['group' => $this->group, 'file' => __FILE__]; include 'includes/modules/block_template.php'; Which happens to be robust in the face of name changes as well as forwardly compatible with switchable templates.  See https://github.com/gburton/CE-Phoenix/commit/e8280d9fdf6364c01484fb5f292adf2511bcefbb#diff-da2a69f7f229fdc1ad483c93b286d7f2 for examples. 
  24. Like
    ecartz got a reaction from Omar_one in Free Shipping Per Product for v2.3   
    Create a checkout_shipping, injectRedirects hook. 
    public function listen_injectRedirects() { $GLOBALS['products_ship_free'] = false; if (!GLOBALS['free_shipping']) { define('TEXT_CHOOSE_SHIPPING_METHOD', TEXT_CHOOSE_SHIPPING_METHOD_NO_PFS); define('TEXT_ENTER_SHIPPING_INFORMATION', TEXT_ENTER_SHIPPING_INFORMATION_NO_PFS); return; } foreach ($_SESSION['cart']->get_products() as $product) { if (1 == $product['ship_free']) { $ship_free_count += $product['quantity']; } } if (($GLOBALS['total_weight'] == 0) && ($GLOBALS['total_count'] == 0)) { $products_ship_free = true; $GLOBALS['free_shipping'] = true; if (!defined('FREE_SHIPPING_TITLE')) { include 'includes/languages/' . $_SESSION['language'] . '/modules/order_total/ot_shipping.php'; } } define('TEXT_CHOOSE_SHIPPING_METHOD', ($products_ship_free ? sprintf(PRODUCTS_SHIP_FREE_COUNT, $ship_free_count); : TEXT_CHOOSE_SHIPPING_METHOD_NO_PFS)); define('TEXT_ENTER_SHIPPING_INFORMATION', ((!$products_ship_free && ($ship_free_count > 0)) ? sprintf(PRODUCTS_SHIP_FREE_COUNT_ONLY, $ship_free_count) : TEXT_ENTER_SHIPPING_INFORMATION_NO_PFS)); } or similar.  In the language files for that page, for each language, change TEXT_CHOOSE_SHIPPING_METHOD to TEXT_CHOOSE_SHIPPING_METHOD_NO_PFS and TEXT_ENTER_SHIPPING_INFORMATION to TEXT_ENTER_SHIPPING_INFORMATION_NO_PFS. 
    In your overridden shopping_cart class, also change
    function count_contents() { $total_items = 0; if (is_array($this->contents)) { foreach (array_keys($this->contents) as $products_id) { $total_items += $this->get_quantity($products_id); } } return $total_items; } to
    function count_contents() { $total_items = 0; if (is_array($this->contents)) { foreach ($this->contents as $products_id => $product) { if (1 != $product['ship_free']) { $total_items += $this->get_quantity($products_id); } } } return $total_items; } and change in the calculate function
    $this->weight += ($qty * $products_weight); to
    if (1 != $this->contents[$products_id]['ship_free']) { $this->weight += ($qty * $products_weight); } That should cover the checkout_shipping instructions Lambros posted.  There may be other changes necessary to other files that are not included here.  For example, there are other changes to the shopping_cart class posted in the instructions.  And the catalog/shopping_cart.php change would now be made in includes/modules/content/shopping_cart/templates/tpl_cm_sc_product_listing.php
    Replace
    echo '<th><a href="' . tep_href_link('product_info.php', 'products_id=' . $product['id']) . '">' . $product['name'] . '</a>'; foreach (($product['attributes'] ?? []) as $option => $value) { with
    echo '<th><a href="' . tep_href_link('product_info.php', 'products_id=' . $product['id']) . '">' . $product['name'] . '</a>'; if (1 == $product['ship_free']) { echo '<br /><span class="smallText">(' . TEXT_PRODUCT_SHIPS_FREE . ')</span>'; } foreach (($product['attributes'] ?? []) as $option => $value) { That's three lines added between two existing lines. 
    Hopefully that will be enough to get you going.  @Omar_one
  25. Like
    ecartz got a reaction from GetSirius in Categories Navbar Module - Phoenix v1.0.6.0   
    Also, this usually means that there is an error.  This error might be logged somewhere.  And knowing what the error was would be helpful. 
    You'd have to put the files in navbar not navbar_modules. 
×