Jump to content
  • Checkout
  • Login
  • Get in touch

osCommerce

The e-commerce.

product notifications content module


Recommended Posts

Working on a small addon today - to move the product notification box module into a product info content module... but for some reason I cannot get this thing to enable... Any ideas?

class cm_pi_product_notifications {
var $code;
var $group;
var $title;
var $description;
var $sort_order;
var $enabled = false;

function cm_pi_product_notifications() {
$this->code = get_class($this);
$this->group = basename(dirname(__FILE__));
    
$this->title = MODULE_CONTENT_PRODUCT_INFO_NOTIFICATIONS_TITLE;
$this->description = MODULE_CONTENT_PRODUCT_INFO_NOTIFICATIONS_DESCRIPTION;

if ( defined('MODULE_CONTENT_PRODUCT_INFO_NOTIFICATIONS_STATUS') ) {
$this->sort_order = MODULE_CONTENT_PRODUCT_INFO_NOTIFICATIONS_SORT_ORDER;
$this->enabled = (MODULE_CONTENT_PRODUCT_INFO_NOTIFICATIONS_STATUS == 'True');
}
}

function execute() {
global $HTTP_GET_VARS, $_GET, $customer_id, $PHP_SELF, $request_type, $oscTemplate;
    
$content_width = (int)MODULE_CONTENT_PRODUCT_INFO_NOTIFICATIONS_TITLE_CONTENT_WIDTH;    

if (isset($HTTP_GET_VARS['products_id'])) {
if (tep_session_is_registered('customer_id')) {
$check_query = tep_db_query("select count(*) as count from " . TABLE_PRODUCTS_NOTIFICATIONS . " where products_id = '" . (int)$HTTP_GET_VARS['products_id'] . "' and customers_id = '" . (int)$customer_id . "'");
$check = tep_db_fetch_array($check_query);

$notification_exists = (($check['count'] > 0) ? true : false);
} else {
$notification_exists = false;
}

$notif_contents = '';

if ($notification_exists == true) {
$notif_contents = '<a href="' . tep_href_link($PHP_SELF, tep_get_all_get_params(array('action')) . 'action=notify_remove', $request_type) . '"><span class="glyphicon glyphicon-remove"></span> ' . sprintf(MODULE_CONTENT_PRODUCT_INFO_NOTIFICATIONS_BOX_NOTIFY_REMOVE, tep_get_products_name($HTTP_GET_VARS['products_id'])) .'</a>';
} else {
$notif_contents = '<a href="' . tep_href_link($PHP_SELF, tep_get_all_get_params(array('action')) . 'action=notify', $request_type) . '"><span class="glyphicon glyphicon-envelope"></span> ' . sprintf(MODULE_CONTENT_PRODUCT_INFO_NOTIFICATIONS_BOX_NOTIFY, tep_get_products_name($HTTP_GET_VARS['products_id'])) .'</a>';
}

ob_start();
include(DIR_WS_MODULES . 'content/' . $this->group . '/templates/product_notifications.php');
$data = ob_get_clean();

$oscTemplate->addBlock($data, $this->group);
}
}

function isEnabled() {
return $this->enabled;
}

function check() {
return defined('MODULE_CONTENT_PRODUCT_INFO_NOTIFICATIONS_STATUS');
}

function install() {
tep_db_query("insert into configuration (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, date_added) values ('Enable Social Bookmark Product Info Module', 'MODULE_CONTENT_PRODUCT_INFO_NOTIFICATIONS_STATUS', 'True', 'Should the social block be shown on the product info page?', '6', '1', 'tep_cfg_select_option(array(\'True\', \'False\'), ', now())");
tep_db_query("insert into configuration (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, date_added) values ('Content Width', 'MODULE_CONTENT_PRODUCT_INFO_NOTIFICATIONS_CONTENT_WIDTH', '6', 'What width container should the content be shown in?', '6', '1', 'tep_cfg_select_option(array(\'12\', \'11\', \'10\', \'9\', \'8\', \'7\', \'6\', \'5\', \'4\', \'3\', \'2\', \'1\'), ', now())");
tep_db_query("insert into configuration (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Sort Order', 'MODULE_CONTENT_PRODUCT_INFO_NOTIFICATIONS_SORT_ORDER', '0', 'Sort order of display. Lowest is displayed first.', '6', '0', now())");
}

function remove() {
tep_db_query("delete from configuration where configuration_key in ('" . implode("', '", $this->keys()) . "')");
}

function keys() {
return array('MODULE_CONTENT_PRODUCT_INFO_NOTIFICATIONS_STATUS', 'MODULE_CONTENT_PRODUCT_INFO_NOTIFICATIONS_CONTENT_WIDTH', 'MODULE_CONTENT_PRODUCT_INFO_NOTIFICATIONS_SORT_ORDER');
}
}

And for a template I have

<div class="col-sm-<?php echo $content_width; ?> product_notifications">
<div class="panel panel-default">
  <div class="panel-heading"><a href="<?php echo tep_href_link('account_notifications.php', '', 'SSL'); ?>"><?php echo MODULE_CONTENT_PRODUCT_INFO_NOTIFICATIONS_BOX_TITLE; ?></a></div>
  <div class="panel-body"><?php echo $notif_contents; ?></div>
</div>
</div>
Link to comment
Share on other sites

@@greasemonkey 

 

Hi Scott,

 

One thing I noticed is you've got

$oscTemplate->addBlock($data, $this->group);

instead of

$oscTemplate->addContent($data, $this->group);

cheers

My Add-ons
Advanced Cache Control Tool for osCommerce 2.3.x (non-bootstrap) Download Support
Ajax Product Listing for osC 2.3.4 (bootstrap) Download Support
Category New Products Carousel for osC 2.3.4 (bootstrap) Download Support
Category Popular Products Carousel for osC 2.3.4 (bootstrap) Download Support
Customer Testimonials for osCommerce 2.3.4 (bootstrap and non-bootstrap) Download Support
Front Page New Products Carousel for osC 2.3.4 (bootstrap) Download Support

Index Nested - Product Listing for osC 2.3.4 (bootstrapDownload Support
Match Categories in Search Results for osCommerce versions 2.3.x (non-bootstrap) Download Support
Modular Category Page for osC 2.3.4 (bootstrap)
Download Support

NEW Australia Post Shipping Modules for osCommerce 2.3.x (non-bootstrap) Download Support
NEW Equal Height Module for osC 2.3.4 (bootstrapDownload Support
Products Low Stock Report for osC 2.3.x (bootstrap and non-bootstrap) Download Support
Twitter Typeahead Autocomplete Search for osCommerce 2.3.4 (bootstrap and non-bootstrap)
Download Support

Upcoming Products Modules for osC 2.3.4 (bootstrap) Download Support

 
Assisted Add-ons
Scroll Boxes for osCommerce 2.3.x (bootstrap and non-bootstrap) Download Support
 
Bootstrap Add-ons created by other members
osCommerce Bootstrap Addons and Code

Link to comment
Share on other sites

Not perfect, but it seems to work.

 

cm_pi_notifications.php

<?php
/*
  $Id$

  osCommerce, Open Source E-Commerce Solutions
  http://www.oscommerce.com

  Copyright (c) 2014 osCommerce

  Released under the GNU General Public License
*/

  class cm_pi_notifications {
    var $code;
    var $group;
    var $title;
    var $description;
    var $sort_order;
    var $enabled = false;

    function cm_pi_notifications() {
      $this->code = get_class($this);
      $this->group = basename(dirname(__FILE__));

      $this->title = MODULE_CONTENT_PRODUCT_INFO_NOTIFICATIONS_TITLE;
      $this->description = MODULE_CONTENT_PRODUCT_INFO_NOTIFICATIONS_DESCRIPTION;

      if ( defined('MODULE_CONTENT_PRODUCT_INFO_NOTIFICATIONS_STATUS') ) {
        $this->sort_order = MODULE_CONTENT_PRODUCT_INFO_NOTIFICATIONS_SORT_ORDER;
        $this->enabled = (MODULE_CONTENT_PRODUCT_INFO_NOTIFICATIONS_STATUS == 'True');
      }
    }

    function execute() {
      global $HTTP_GET_VARS, $customer_id, $PHP_SELF, $request_type, $oscTemplate;
      
      $content_width = (int)MODULE_CONTENT_PRODUCT_INFO_NOTIFICATIONS_CONTENT_WIDTH;
	  
	  if (isset($HTTP_GET_VARS['products_id'])) {
        if (tep_session_is_registered('customer_id')) {
          $check_query = tep_db_query("select count(*) as count from " . TABLE_PRODUCTS_NOTIFICATIONS . " where products_id = '" . (int)$HTTP_GET_VARS['products_id'] . "' and customers_id = '" . (int)$customer_id . "'");
          $check = tep_db_fetch_array($check_query);

          $notification_exists = (($check['count'] > 0) ? true : false);
        } else {
          $notification_exists = false;
        }

        $notif_contents = '';

        if ($notification_exists == true) {
          $notif_contents = '<a href="' . tep_href_link($PHP_SELF, tep_get_all_get_params(array('action')) . 'action=notify_remove', $request_type) . '"><span class="glyphicon glyphicon-remove"></span> ' . sprintf(MODULE_BOXES_PRODUCT_NOTIFICATIONS_BOX_NOTIFY_REMOVE, tep_get_products_name($HTTP_GET_VARS['products_id'])) .'</a>';
        } else {
          $notif_contents = '<a href="' . tep_href_link($PHP_SELF, tep_get_all_get_params(array('action')) . 'action=notify', $request_type) . '"><span class="glyphicon glyphicon-envelope"></span> ' . sprintf(MODULE_BOXES_PRODUCT_NOTIFICATIONS_BOX_NOTIFY, tep_get_products_name($HTTP_GET_VARS['products_id'])) .'</a>';
        }
        
        ob_start();
        include(DIR_WS_MODULES . 'content/' . $this->group . '/templates/notifications.php');
        $template = ob_get_clean();

        $oscTemplate->addContent($template, $this->group);
      }
    }

    function isEnabled() {
      return $this->enabled;
    }

    function check() {
      return defined('MODULE_CONTENT_PRODUCT_INFO_NOTIFICATIONS_STATUS');
    }

    function install() {
      tep_db_query("insert into configuration (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, date_added) values ('Enable Notifications Module', 'MODULE_CONTENT_PRODUCT_INFO_NOTIFICATIONS_STATUS', 'True', 'Should the notifications block be shown on the product info page?', '6', '1', 'tep_cfg_select_option(array(\'True\', \'False\'), ', now())");
      tep_db_query("insert into configuration (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, date_added) values ('Content Width', 'MODULE_CONTENT_PRODUCT_INFO_NOTIFICATIONS_CONTENT_WIDTH', '6', 'What width container should the content be shown in?', '6', '1', 'tep_cfg_select_option(array(\'12\', \'11\', \'10\', \'9\', \'8\', \'7\', \'6\', \'5\', \'4\', \'3\', \'2\', \'1\'), ', now())");
      tep_db_query("insert into configuration (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Sort Order', 'MODULE_CONTENT_PRODUCT_INFO_NOTIFICATIONS_SORT_ORDER', '0', 'Sort order of display. Lowest is displayed first.', '6', '0', now())");
    }

    function remove() {
      tep_db_query("delete from configuration where configuration_key in ('" . implode("', '", $this->keys()) . "')");
    }

    function keys() {
      return array('MODULE_CONTENT_PRODUCT_INFO_NOTIFICATIONS_STATUS', 'MODULE_CONTENT_PRODUCT_INFO_NOTIFICATIONS_CONTENT_WIDTH', 'MODULE_CONTENT_PRODUCT_INFO_NOTIFICATIONS_SORT_ORDER');
    }
  }
?>

cm_pi_notifications.php

<?php
/*
  $Id$

  osCommerce, Open Source E-Commerce Solutions
  http://www.oscommerce.com

  Copyright (c) 2014 osCommerce

  Released under the GNU General Public License
*/

  define('MODULE_CONTENT_PRODUCT_INFO_NOTIFICATIONS_TITLE', 'Product Notifications');
  define('MODULE_CONTENT_PRODUCT_INFO_NOTIFICATIONS_DESCRIPTION', 'Show notifications block on the product info page.');
  define('MODULE_BOXES_PRODUCT_NOTIFICATIONS_BOX_TITLE', 'Notifications');
  define('MODULE_BOXES_PRODUCT_NOTIFICATIONS_BOX_NOTIFY', 'Notify me of updates to <strong>%s</strong>');
?>

notifications.php

<div class="col-sm-<?php echo $content_width; ?> notifications">
<div class="panel panel-default">
  <div class="panel-heading"><a href="<?php echo tep_href_link('account_notifications.php', '', 'SSL'); ?>"><?php echo MODULE_BOXES_PRODUCT_NOTIFICATIONS_BOX_TITLE; ?></a></div>
  <div class="panel-body"><?php echo $notif_contents; ?></div>
</div>
</div>
Link to comment
Share on other sites

@@greasemonkey

 

Scott,

 

Not sure why you want to disable when zero stock? Wouldn't you still want to allow customers to choose whether or not to be notified when it's back in stock or any other info about the product ie not longer available etc..

 

But anyway, try this....

 

 (taken from your code above)

    function cm_pi_product_notifications() {
      global $product_info;
      
      $this->code = get_class($this);
      $this->group = basename(dirname(__FILE__));

      $this->title = MODULE_CONTENT_PRODUCT_INFO_NOTIFICATIONS_TITLE;
      $this->description = MODULE_CONTENT_PRODUCT_INFO_NOTIFICATIONS_DESCRIPTION;

      if ( defined('MODULE_CONTENT_PRODUCT_INFO_NOTIFICATIONS_STATUS') ) {
        $this->sort_order = MODULE_CONTENT_PRODUCT_INFO_NOTIFICATIONS_SORT_ORDER;
        $this->enabled = (MODULE_CONTENT_PRODUCT_INFO_NOTIFICATIONS_STATUS == 'True');
      }

      if($this->enabled && $product_info['products_quantity'] < 1) {
        $this->enabled = false;
      }
    }

My Add-ons
Advanced Cache Control Tool for osCommerce 2.3.x (non-bootstrap) Download Support
Ajax Product Listing for osC 2.3.4 (bootstrap) Download Support
Category New Products Carousel for osC 2.3.4 (bootstrap) Download Support
Category Popular Products Carousel for osC 2.3.4 (bootstrap) Download Support
Customer Testimonials for osCommerce 2.3.4 (bootstrap and non-bootstrap) Download Support
Front Page New Products Carousel for osC 2.3.4 (bootstrap) Download Support

Index Nested - Product Listing for osC 2.3.4 (bootstrapDownload Support
Match Categories in Search Results for osCommerce versions 2.3.x (non-bootstrap) Download Support
Modular Category Page for osC 2.3.4 (bootstrap)
Download Support

NEW Australia Post Shipping Modules for osCommerce 2.3.x (non-bootstrap) Download Support
NEW Equal Height Module for osC 2.3.4 (bootstrapDownload Support
Products Low Stock Report for osC 2.3.x (bootstrap and non-bootstrap) Download Support
Twitter Typeahead Autocomplete Search for osCommerce 2.3.4 (bootstrap and non-bootstrap)
Download Support

Upcoming Products Modules for osC 2.3.4 (bootstrap) Download Support

 
Assisted Add-ons
Scroll Boxes for osCommerce 2.3.x (bootstrap and non-bootstrap) Download Support
 
Bootstrap Add-ons created by other members
osCommerce Bootstrap Addons and Code

Link to comment
Share on other sites

Hello Scott @@greasemonkey,

 

I'm using this code for similar purpose:

    function isEnabled() {
    	global $product_info;
    	if($product_info['products_quantity'] < 1) {
    		$this->enabled = false;
    	} else {
    		return $this->enabled;
    	}
    }

regards

Rainer

Link to comment
Share on other sites

@@raiwa @@auzStar @@Hotclutch thanks again all of you - I believe this makes much more sense as a product info content module. My final code is below.... It was the addBlock carried over from the box module preventing the display - should have been.... addContent.

 

Here is cm_pi_notifications.php

<?php
/*
  $Id$

  osCommerce, Open Source E-Commerce Solutions
  http://www.oscommerce.com

  Copyright (c) 2014 osCommerce

  Released under the GNU General Public License
*/

  class cm_pi_notifications {
    var $code;
    var $group;
    var $title;
    var $description;
    var $sort_order;
    var $enabled = false;

    function cm_pi_notifications() {
      $this->code = get_class($this);
      $this->group = basename(dirname(__FILE__));

      $this->title = MODULE_CONTENT_PRODUCT_INFO_NOTIFICATIONS_TITLE;
      $this->description = MODULE_CONTENT_PRODUCT_INFO_NOTIFICATIONS_DESCRIPTION;

      if ( defined('MODULE_CONTENT_PRODUCT_INFO_NOTIFICATIONS_STATUS') ) {
        $this->sort_order = MODULE_CONTENT_PRODUCT_INFO_NOTIFICATIONS_SORT_ORDER;
        $this->enabled = (MODULE_CONTENT_PRODUCT_INFO_NOTIFICATIONS_STATUS == 'True');
      }
    }

    function execute() {
      global $HTTP_GET_VARS, $customer_id, $PHP_SELF, $request_type, $oscTemplate;
      
      $content_width = (int)MODULE_CONTENT_PRODUCT_INFO_NOTIFICATIONS_CONTENT_WIDTH;
	  
	  if (isset($HTTP_GET_VARS['products_id'])) {
        if (tep_session_is_registered('customer_id')) {
          $check_query = tep_db_query("select count(*) as count from " . TABLE_PRODUCTS_NOTIFICATIONS . " where products_id = '" . (int)$HTTP_GET_VARS['products_id'] . "' and customers_id = '" . (int)$customer_id . "'");
          $check = tep_db_fetch_array($check_query);

          $notification_exists = (($check['count'] > 0) ? true : false);
        } else {
          $notification_exists = false;
        }

        $notif_contents = '';

        if ($notification_exists == true) {
          $notif_contents = '<a href="' . tep_href_link($PHP_SELF, tep_get_all_get_params(array('action')) . 'action=notify_remove', $request_type) . '"><span class="glyphicon glyphicon-remove"></span> ' . sprintf(MODULE_CONTENT_PRODUCT_NOTIFICATIONS_BOX_NOTIFY_REMOVE, tep_get_products_name($HTTP_GET_VARS['products_id'])) .'</a>';
        } else {
          $notif_contents = '<a href="' . tep_href_link($PHP_SELF, tep_get_all_get_params(array('action')) . 'action=notify', $request_type) . '"><span class="glyphicon glyphicon-envelope"></span> ' . sprintf(MODULE_CONTENT_PRODUCT_NOTIFICATIONS_BOX_NOTIFY, tep_get_products_name($HTTP_GET_VARS['products_id'])) .'</a>';
        }
        
        ob_start();
        include(DIR_WS_MODULES . 'content/' . $this->group . '/templates/notifications.php');
        $template = ob_get_clean();

        $oscTemplate->addContent($template, $this->group);
      }
    }

    function isEnabled() {
      return $this->enabled;
    }

    function check() {
      return defined('MODULE_CONTENT_PRODUCT_INFO_NOTIFICATIONS_STATUS');
    }

    function install() {
      tep_db_query("insert into configuration (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, date_added) values ('Enable Notifications Module', 'MODULE_CONTENT_PRODUCT_INFO_NOTIFICATIONS_STATUS', 'True', 'Should the notifications block be shown on the product info page?', '6', '1', 'tep_cfg_select_option(array(\'True\', \'False\'), ', now())");
      tep_db_query("insert into configuration (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, date_added) values ('Content Width', 'MODULE_CONTENT_PRODUCT_INFO_NOTIFICATIONS_CONTENT_WIDTH', '6', 'What width container should the content be shown in?', '6', '1', 'tep_cfg_select_option(array(\'12\', \'11\', \'10\', \'9\', \'8\', \'7\', \'6\', \'5\', \'4\', \'3\', \'2\', \'1\'), ', now())");
      tep_db_query("insert into configuration (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Sort Order', 'MODULE_CONTENT_PRODUCT_INFO_NOTIFICATIONS_SORT_ORDER', '0', 'Sort order of display. Lowest is displayed first.', '6', '0', now())");
    }

    function remove() {
      tep_db_query("delete from configuration where configuration_key in ('" . implode("', '", $this->keys()) . "')");
    }

    function keys() {
      return array('MODULE_CONTENT_PRODUCT_INFO_NOTIFICATIONS_STATUS', 'MODULE_CONTENT_PRODUCT_INFO_NOTIFICATIONS_CONTENT_WIDTH', 'MODULE_CONTENT_PRODUCT_INFO_NOTIFICATIONS_SORT_ORDER');
    }
  }
?>

And the template notifications.php

<div class="col-sm-<?php echo $content_width; ?> notifications">
<div class="panel panel-default">
  <div class="panel-heading"><a href="<?php echo tep_href_link('account_notifications.php', '', 'SSL'); ?>"><?php echo MODULE_CONTENT_PRODUCT_NOTIFICATIONS_BOX_TITLE; ?></a></div>
  <div class="panel-body"><?php echo $notif_contents; ?></div>
</div>
</div>

And the language file cm_pi_notifications.php

<?php
/*
  $Id$

  osCommerce, Open Source E-Commerce Solutions
  http://www.oscommerce.com

  Copyright (c) 2014 osCommerce

  Released under the GNU General Public License
*/

  define('MODULE_CONTENT_PRODUCT_INFO_NOTIFICATIONS_TITLE', 'Product Notifications');
  define('MODULE_CONTENT_PRODUCT_INFO_NOTIFICATIONS_DESCRIPTION', 'Show notifications block on the product info page.');
  define('MODULE_CONTENT_PRODUCT_NOTIFICATIONS_BOX_TITLE', 'Notifications');
  define('MODULE_CONTENT_PRODUCT_NOTIFICATIONS_BOX_NOTIFY', 'Notify when <strong>%s</strong> comes back in stock');
?>

Rainer, thanks again... I've edited your code snippet for my intended use.

 

Dominic, the I plan to display this content module only when stock is 0 or less. (notice the language file).

    function isEnabled() {
    	global $product_info;
    	if($product_info['products_quantity'] > 0) {
    		$this->enabled = false;
    	} else {
    		return $this->enabled;
    	}
    }
Link to comment
Share on other sites

@@raiwa @@auzStar @@Hotclutch thanks again all of you - I believe this makes much more sense as a product info content module. My final code is below.... It was the addBlock carried over from the box module preventing the display - should have been.... addContent.

 

Dominic, the I plan to display this content module only when stock is 0 or less. (notice the language file).

 

@@greasemonkey

 

I see now. That sounds like a better idea.

No worries. Glad to help.

 

cheers

My Add-ons
Advanced Cache Control Tool for osCommerce 2.3.x (non-bootstrap) Download Support
Ajax Product Listing for osC 2.3.4 (bootstrap) Download Support
Category New Products Carousel for osC 2.3.4 (bootstrap) Download Support
Category Popular Products Carousel for osC 2.3.4 (bootstrap) Download Support
Customer Testimonials for osCommerce 2.3.4 (bootstrap and non-bootstrap) Download Support
Front Page New Products Carousel for osC 2.3.4 (bootstrap) Download Support

Index Nested - Product Listing for osC 2.3.4 (bootstrapDownload Support
Match Categories in Search Results for osCommerce versions 2.3.x (non-bootstrap) Download Support
Modular Category Page for osC 2.3.4 (bootstrap)
Download Support

NEW Australia Post Shipping Modules for osCommerce 2.3.x (non-bootstrap) Download Support
NEW Equal Height Module for osC 2.3.4 (bootstrapDownload Support
Products Low Stock Report for osC 2.3.x (bootstrap and non-bootstrap) Download Support
Twitter Typeahead Autocomplete Search for osCommerce 2.3.4 (bootstrap and non-bootstrap)
Download Support

Upcoming Products Modules for osC 2.3.4 (bootstrap) Download Support

 
Assisted Add-ons
Scroll Boxes for osCommerce 2.3.x (bootstrap and non-bootstrap) Download Support
 
Bootstrap Add-ons created by other members
osCommerce Bootstrap Addons and Code

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...