Mail Manager for OSCommerce:
Installation Instructions

Files required for installation can be downloaded from:
The OSCommerce site.

Mail Manager Description

installation:

  • open catalog/includes/languages/english/checkout_process.php, add:define('EMAIL_TEXT_CONFIRM', 'has recommended');
    define('TEXT_FROM', 'from');
  • open/admin/includes/languages/english.php add://mail manager
    define('BOX_HEADING_MAIL_MANAGER', 'Mail Manager');
    define('BOX_MM_BULKMAIL', 'BulkMail Manager');
    define('BOX_MM_TEMPLATES', 'Template Manager');
    define('BOX_MM_EMAIL', 'Send Email');
    define('BOX_MM_RESPONSEMAIL', 'Response Mail');
  • open admin/includes/filenames.php
    add://MAIL MANAGER
    define('FILENAME_MM_RESPONSEMAIL', 'mm_responsemail.php');
    define('FILENAME_MM_TEMPLATES', 'mm_templates.php');
    define('FILENAME_MM_BULKMAIL', 'mm_bulkmail.php');
    define('FILENAME_MM_EMAIL', 'mm_email.php');
  • open admin/includes/database_tables.php
    add:///Mail Manager
    define('TABLE_MM_RESPONSEMAIL', 'mm_responsemail');
    define('TABLE_MM_RESPONSEMAIL_RESTORE', 'mm_responsemail_backup');
    define('TABLE_MM_RESPONSEMAIL_RESET', 'mm_responsemail_reset');
    define('TABLE_MM_TEMPLATES', 'mm_templates');
    define('TABLE_MM_NEWSLETTERS', 'mm_newsletters');
  • open admin/includes/column_left.php add:
    include(DIR_WS_BOXES . 'mail_manager.php');
    just below include(DIR_WS_BOXES . 'modules.php');
  • open admin/includes/classes/email.php, add at the bottom before the closing ?> tag:// eliminate line feeds as <br>
    class emailMailManager extends email {
    function add_html($html, $text = NULL, $images_dir = NULL) {
    $this->html = $html; //tep_convert_linefeeds(array("\r\n", "\n", "\r"), '<br>', $html);
    $this->html_text = tep_convert_linefeeds(array("\r\n", "\n", "\r"), $this->lf, $text);
    if (isset($images_dir)) $this->find_html_images($images_dir);
    }
    }
  • open admin/includes/functions/general.php
    just above the closing ?> tag at the bottom of the page add:///////////////////start mail manager////////////////////////////////////////start mail manager////////////////////////////////////////start mail manager/////////////////////
    function tep_mm_set_mailstatus($mail_id, $status) {
    if ($status == '1') {
    return tep_db_query("update " . TABLE_MM_RESPONSEMAIL . " set status = '1' where mail_id = '" . (int)$mail_id . "'");
    } elseif ($status == '0') {
    return tep_db_query("update " . TABLE_MM_RESPONSEMAIL . " set status = '0' where mail_id = '" . (int)$mail_id . "'");
    } else {
    return -1;
    }
    }

    //mail it
    function tep_mm_sendmail($mail, $email_address, $sender_name, $sender, $output_subject, $output_content_html, $output_content_txt) {
    $mimemessage = new emailMailManager(array('X-Mailer: cat/mail_manager.com'));
    // add html and alternative text version
    $mimemessage->add_html($output_content_html, $output_content_txt);
    $mimemessage->build_message(); // encoding -> 76 character linebreak, replacements must be done before
    $mimemessage->send($mail, $email_address, $sender_name, $sender, $output_subject, $output_content_html, $output_content_txt);
    }///////////////////end mail manager////////////////////////////////////////end mail manager////////////////////////////////////////end mail manager/////////////////////

  • open catalog/includes/classes/email.php, add at the bottom before the closing ?> tag:// eliminate line feeds as <br>
    class emailMailManager extends email {
    function add_html($html, $text = NULL, $images_dir = NULL) {
    $this->html = $html; //tep_convert_linefeeds(array("\r\n", "\n", "\r"), '<br>', $html);
    $this->html_text = tep_convert_linefeeds(array("\r\n", "\n", "\r"), $this->lf, $text);
    if (isset($images_dir)) $this->find_html_images($images_dir);
    }
    }
  • open catalog/includes/database_tables.php
    add:///Mail Manager
    define('TABLE_MM_RESPONSEMAIL', 'mm_responsemail');
    define('TABLE_MM_RESPONSEMAIL_RESTORE', 'mm_responsemail_backup');
    define('TABLE_MM_RESPONSEMAIL_RESET', 'mm_responsemail_reset');
    define('TABLE_MM_TEMPLATES', 'mm_templates');
    define('TABLE_MM_BULKMAIL', 'mm_bulkmail');
  • open admin/includes/column_left.php add:
    include(DIR_WS_BOXES . 'mail_manager.php');
    just below include(DIR_WS_BOXES . 'modules.php');
  • open catalog/includes/functions/general.php
    just above the closing ?> tag at the bottom of the page add:///////////////////start mail manager////////////////////////////////////////start mail manager////////////////////////////////////////start mail manager/////////////////////
    //
    // Sets the status of a mail item
    function tep_mm_set_mailstatus($mail_id, $status) {
    if ($status == '1') {
    return tep_db_query("update " . TABLE_MM_RESPONSEMAIL . " set status = '1' where mail_id = '" . (int)$mail_id . "'");
    } elseif ($status == '0') {
    return tep_db_query("update " . TABLE_MM_RESPONSEMAIL . " set status = '0' where mail_id = '" . (int)$mail_id . "'");
    } else {
    return -1;
    }
    }
    //sends it
    function tep_mm_sendmail($mail, $email_address, $sender_name, $sender, $output_subject, $output_content_html, $output_content_txt) {
    $mimemessage = new emailMailManager(array('X-Mailer: ad/mail_manager.com'));
    // add html and alternative text version
    $mimemessage->add_html($output_content_html, $output_content_txt);
    $mimemessage->build_message(); // encoding -> 76 character linebreak, replacements must be done before
    $mimemessage->send($mail, $email_address, $sender_name, $sender, $output_subject, '');
    }
    ///////////////////end mail manager////////////////////////////////////////end mail manager////////////////////////////////////////end mail manager/////////////////////
  • open catalog/tell_a_friend.php.
    1. About line 35 change:
      $product_info_query = tep_db_query("select pd.products_name from " . TABLE_PRODUCTS . " p, " . TABLE_PRODUCTS_DESCRIPTION . " pd where p.products_status = '1' and p.products_id = '" . (int)$HTTP_GET_VARS['products_id'] . "' and p.products_id = pd.products_id and pd.language_id = '" . (int)$languages_id . "'");

      to:
      $product_info_query = tep_db_query("select p.products_image, pd.products_name from " . TABLE_PRODUCTS . " p, " . TABLE_PRODUCTS_DESCRIPTION . " pd where p.products_status = '1' and p.products_id = '" . (int)$HTTP_GET_VARS['products_id'] . "' and p.products_id = pd.products_id and pd.language_id = '" . (int)$languages_id . "'");

      ( or simply add p.products_image to the query)
    2. About line 100 change:
      tep_mail($to_name, $to_email_address, $email_subject, $email_body, $from_name, $from_email_address);

      to//*******start mail manager***************//
      if (file_exists(DIR_WS_MODULES.'mail_manager/tell_a_friend.php')){
      include(DIR_WS_MODULES.'mail_manager/tell_a_friend.php');
      }else{
      tep_mail($to_name, $to_email_address, $email_subject, $email_body, $from_name, $from_email_address);
      }
      //*******end mail manager*****************//
  • open admin/orders.php. About line 85 change:
    tep_mail($check_status['customers_name'], $check_status['customers_email_address'], EMAIL_TEXT_SUBJECT, $email, STORE_OWNER, STORE_OWNER_EMAIL_ADDRESS);

    to:
    //*******start mail manager****************//
    if (file_exists(DIR_FS_CATALOG_MODULES.'mail_manager/status_update.php')){
    include(DIR_FS_CATALOG_MODULES.'mail_manager/status_update.php');
    }else{
    tep_mail($check_status['customers_name'], $check_status['customers_email_address'], EMAIL_TEXT_SUBJECT, $email, STORE_OWNER, STORE_OWNER_EMAIL_ADDRESS);
    }
    //********end mail manager****************//
  • open catalog/create_account.php. About line 210 change: tep_mail($name, $email_address, EMAIL_SUBJECT, $email_text, STORE_OWNER, STORE_OWNER_EMAIL_ADDRESS);

    to:
    //*******start mail manager**************//
    if (file_exists(DIR_WS_MODULES.'mail_manager/create_account.php')){
    include(DIR_WS_MODULES.'mail_manager/create_account.php');
    }else{
    tep_mail($name, $email_address, EMAIL_SUBJECT, $email_text, STORE_OWNER, STORE_OWNER_EMAIL_ADDRESS);
    }
    //*******end mail manager****************//
  • open catalog/checkout_process.php
    1. about line 350 change:
      tep_mail($order->customer['firstname'] . ' ' . $order->customer['lastname'], $order->customer['email_address'], EMAIL_TEXT_SUBJECT, $email_order, STORE_OWNER, STORE_OWNER_EMAIL_ADDRESS);

      to:
      //*******start mail manager****************//
      if (file_exists(DIR_WS_MODULES.'mail_manager/order_confirm.php')){
      include(DIR_WS_MODULES.'mail_manager/order_confirm.php');
      }else{
      tep_mail($order->customer['firstname'] . ' ' . $order->customer['lastname'], $order->customer['email_address'], EMAIL_TEXT_SUBJECT, $email_order, STORE_OWNER, STORE_OWNER_EMAIL_ADDRESS);
      }
      //*******end mail manager*****************//
    2. about line 245 change
      $products_ordered .= $order->products[$i]['qty'] . ' x ' . $order->products[$i]['name'] . ' (' . $order->products[$i]['model'] . ') = ' . $currencies->display_price($order->products[$i]['final_price'], $order->products[$i]['tax'], $order->products[$i]['qty']) . $products_ordered_attributes . "\n";


      to
      $products_ordered .= $order->products[$i]['qty'] . ' x ' . $order->products[$i]['name'] . ' (' . $order->products[$i]['model'] . ') = ' . $currencies->display_price($order->products[$i]['final_price'], $order->products[$i]['tax'], $order->products[$i]['qty']) . $products_ordered_attributes . "\n".'<br />';
      (add a break tag)
  • open catalog/password_forgotten change
    tep_mail($check_customer['customers_firstname'] . ' ' . $check_customer['customers_lastname'], $email_address, EMAIL_PASSWORD_REMINDER_SUBJECT, sprintf(EMAIL_PASSWORD_REMINDER_BODY, $new_password), STORE_OWNER, STORE_OWNER_EMAIL_ADDRESS);

    to //*******start mail manager
    if (file_exists(DIR_WS_MODULES.'mail_manager/password_forgotten.php')){
    include(DIR_WS_MODULES.'mail_manager/password_forgotten.php');
    }else{
    tep_mail($check_customer['customers_firstname'] . ' ' . $check_customer['customers_lastname'], $email_address, EMAIL_PASSWORD_REMINDER_SUBJECT, sprintf(EMAIL_PASSWORD_REMINDER_BODY, $new_password), STORE_OWNER, STORE_OWNER_EMAIL_ADDRESS);
    }
    //*******end mail manager
  • Upload the files and folders in the folder mail_managers folder. All folders and files are new.
  • Import the sql database file. It adds 5 tables to your database, and does not change any existing tables or configuration. It also loads several sample templates.
  • Create a new field, mmstatus, in the Database in the customers table. The mmstatus.sql file contains command to use in phpmyadmin to create this. This command is posted below:ALTER TABLE `customers` ADD `mmstatus` CHAR( 2 ) NOT NULL AFTER `customers_newsletter`

Recently Viewed Products Infobox for OSCommerce

for: OSC 2 CSS.

The following code yields a new infobox that displays the last four items viewed. Adapted from this OSCommerce Contribution to fit OSC 2 CSS. Caveat: I have had mixed success with rendering product urls but you can see a successful demo at www.niora.com. View some products and they start showing up in a box in the right hand column. What is unique about this code is that does not use database queries to display the products.

Installation:

2) Add the following command to the left or right column where you want the box to appear.

require(DIR_WS_BOXES . 'recently_viewed.php');

1) create a new file, recently_viewed.php. Paste the following code into this file and upload the file to the includes/boxes folder.

<?php
// Lets set the number of history items to display
$display_count = 4;
$action = (isset($_GET&#91;'action'&#93;) ? $_GET&#91;'action'&#93; : '');
if ($action == 'clear_history') {
unset($_SESSION&#91;'last_product_views'&#93;);
}
// Build history string
$last_product_views = $_SESSION&#91;'last_product_views'&#93;;
if ($last_product_views != "") {
$visited_array = explode('|', $_SESSION&#91;'last_product_views'&#93;);
$output_count = 1; 
foreach ($visited_array as $visited_array_item) {
$visited_item = trim($visited_array_item);
if ( ($visited_item != "") && ($output_count <= $display_count) ) {
$item_pieces = explode("^", $visited_item);
$item_image = trim($item_pieces&#91;0&#93;);
$item_name = trim($item_pieces&#91;1&#93;);
$item_url = trim($item_pieces&#91;2&#93;);
$visited_output .= '';
$last_visited_thumb = tep_image(DIR_WS_IMAGES . $item_image, $item_name, '75', '75');
$visited_output .= '<div class="pl-image"><a href="http://' . $item_url . '">' . $last_visited_thumb . '</a></div><div class="pl-name"><a href="http://' . $item_url . '">' . $item_name.'</a><br></div>';
$visited_output .= '';
$output_count++;
}
}
}
// Now look at the current page
if (basename($_SERVER['SCRIPT_NAME']) == "product_info.php") {
// First remove the action=clear_history from the url
$current_product_path = str_replace('&action=clear_history', '', $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
//$pieces = explode("?osCsid", $current_product_path);
//$current_product_path = $pieces[0];
$new_array_item = $product_info['products_image'] . '^' . $product_info['products_name']. '^' . $current_product_path;
// and add it to the $_SESSION variable
$last_product_views = $_SESSION['last_product_views'];
if ($last_product_views == "") {
$_SESSION['last_product_views'] = trim($new_array_item);
} else {
$items_array = explode('|', $_SESSION['last_product_views']); 
$count = 1;
$new_array_string = '';
foreach ($items_array as $array_item) {
if ($count <= $display_count) {
$array_item = trim($array_item);
if ($array_item != "") {
if ($array_item != $new_array_item) {
$new_array_string .= "|" . $array_item;
$count++;
} 
}
}
}
$_SESSION&#91;'last_product_views'&#93; = $new_array_item . '|' . $new_array_string;
}
}
// Display history string to browser
if ($last_product_views != "") {
$info_box_contents = array();
$info_box_contents&#91;&#93; = array('text' => '<hr><div class="align_left"><strong>Last Viewed</strong></div>');
new cssinfoBoxHeading($info_box_contents, 'true', 'true', tep_href_link($_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'], tep_get_all_get_params(array('action')) . 'action=clear_history'));

$info_box_contents = array();
$info_box_contents[] = array('text' => $visited_output);
// new plcontentBox($info_box_contents);
new cssinfoBox($info_box_contents);
} // end if ($last_product_views != "")
?>

Account Tabs for OSC to CSSv2

On OCS to CSS this combines the files address_book.php, account_edit.php, account_history.php and account_password.php into one file, account.php. The information is accessed with JQuery tabs for really intuitive and easy navigation. Download this file, account.php and the required CSS file from google.code

Requires the main JQuery file and the JQuery UI file. You will need to be prepared to make adjustments to the html.

Screenshots:

Address Book Tab
Click to enlarge


Address Book Tab
Edit Account Tab
Click to enlarge


Edit Account Tab
Password Tab
Click to enlarge


Password Tab
Order History Tab
Click to enlarge


Order History Tab

Download the Files

OSCommerce: 3.0 vs 2.3 vs OSC to CSS

What version to use?

  • V3.0

    OSCommerce 3.0 represents an entirely new modular structure. It has updated security features, and a nicer admin and much more. However, it is virtually featureless, a bare bones core, that is not ready for non-developers to use. Many people will find that their web hosts do not have the latest version of php, which 3.0 requires. The thousands of great contributions available for 2.2RC2a will not work on 3.0

  • V2.3

    OSCommerce 2.3 is the first version to get rid of the outmoded OSCommerce table structure, and it incorporates important security features. It has an improved admin. It is different enough from 2.2RC2a that many of the contributions available for 2.2RC2a will not work. Plus the incorporation of the tableless CSS structure is not complete, and awkwardly implemented. For example, it is difficult to add javascript or unique stylesheets to individual pages.

  • OSC to CSS

    OSC to CSS has all the advantages of 2.2RC2a, has the table structure replaced with a superior incorporation of CSS. It some nice JQuery features installed to include a horizontal category menu, pretty photo, and a Json coded ‘add to cart’ feature. The admin and database structure are unchanged from 2.2RC2a so nearly all the contributions available for 2.2RC2a work on OSC to CSS. It just takes a bit of creative html work on the catalog side. An it is not difficult to install the 2.3 security features. This link explains how: update 2.2RC2a security

In summary, OSC to CSS is fast and simple with thousands of contributions available, uses a great tableless structure, has an updated modern look as downloaded, and the security features for 2.3 can easily be incorporated.

Quantity Box

Add a quantity text box before the ‘add to cart’ button on the product page to allow a quantity to be posted to the shopping cart.

Demo:

Step 1:
in includes/application_top.php
find:
$cart->add_cart($HTTP_POST_VARS['products_id'], $cart->get_quantity(tep_get_uprid($HTTP_POST_VARS['products_id'], $HTTP_POST_VARS['id']))+1, $HTTP_POST_VARS['id']);

change to:
$cart->add_cart($HTTP_POST_VARS['products_id'], $cart->get_quantity(tep_get_uprid($HTTP_POST_VARS['products_id'], $HTTP_POST_VARS['id']))+$HTTP_POST_VARS['cart_quantity'], $HTTP_POST_VARS['id']);


( This changes the +1 to
$HTTP_POST_VARS[‘cart_quantity’] )

Step 2:
in product_info.php
find:
<?php echo tep_draw_hidden_field('products_id', $product_info['products_id']) . tep_image_submit('button_in_cart.gif', IMAGE_BUTTON_IN_CART); ?>

just in front of that add:
<input type="text" name="cart_quantity" value="1" maxlength="2" size="2">

(this is also posted on ‘Tips and Tricks’ section of the OSCommerce Forum)
Add a Quantity box

Product MiniDescriptions for OSCommerce 2.3

Product MiniDescriptions for OSCommerce 2.3

Adding minidescription to your product listing in OSCommerce 2.3 is easy:

  1. Create a new field in products_description. (use the following in phpMyAdmin)
    ALTER TABLE `products_description` ADD `products_minidescp` TEXT NOT NULL

    Then type the product mini-descriptions directly into the database.

  2. On about line 121 in index.php
    change:

    case 'PRODUCT_LIST_NAME':
    $select_column_list .= 'pd.products_name, ';
    break;

    to this:
    case 'PRODUCT_LIST_NAME':
    $select_column_list .= 'pd.products_name, pd.products_minidescp, ';
    break;

  3. In includes/modules/product_listing.php
    change this:
    case 'PRODUCT_LIST_NAME':
    if (isset($HTTP_GET_VARS['manufacturers_id']) && tep_not_null($HTTP_GET_VARS['manufacturers_id'])) {
    $prod_list_contents .= ' <td><a href="' . tep_href_link(FILENAME_PRODUCT_INFO, 'manufacturers_id=' . $HTTP_GET_VARS['manufacturers_id'] . '&products_id=' . $listing['products_id']) . '">' . $listing['products_name'] . '</a></td>';
    } else {
    $prod_list_contents .= ' <td><a href="' . tep_href_link(FILENAME_PRODUCT_INFO, ($cPath ? 'cPath=' . $cPath . '&' : '') . 'products_id=' . $listing['products_id']) . '">' . $listing['products_name'] . '</a></td>';
    }

    to this:

    case 'PRODUCT_LIST_NAME':
    if (isset($HTTP_GET_VARS['manufacturers_id']) && tep_not_null($HTTP_GET_VARS['manufacturers_id'])) {
    $prod_list_contents .= ' <td><a href="' . tep_href_link(FILENAME_PRODUCT_INFO, 'manufacturers_id=' . $HTTP_GET_VARS['manufacturers_id'] . '&products_id=' . $listing['products_id']) . '">' . $listing['products_name'] . '</a><br/>'. $listing['products_minidescp'].'</td>';
    } else {
    $prod_list_contents .= ' <td><a href="' . tep_href_link(FILENAME_PRODUCT_INFO, ($cPath ? 'cPath=' . $cPath . '&' : '') . 'products_id=' . $listing['products_id']) . '">' . $listing['products_name'] . '</a><br/>'. $listing['products_minidescp'].'</td>';
    }

That’s it!

In OSCommerce 2.2RC2a step three above is different:
3. In includes/modules/product_listing.php
change this:
$lc_text = ' <a href="' . tep_href_link(FILENAME_PRODUCT_INFO, ($cPath ? 'cPath=' . $cPath . '&' : '') . 'products_id=' . $listing['products_id']) . '">' . $listing['products_name'] . '</a>';

To this:

$lc_text = '<a href="' . tep_href_link(FILENAME_PRODUCT_INFO, ($cPath ? 'cPath=' . $cPath . '&' : '') . 'products_id=' . $listing['products_id']) . '">' . $listing['products_name'] . '</a><br/>'. $listing['products_minidescp'];

An Easier Way to Create an Account

Make it a bit less challenging to create an account. This adds an email entry field adjacent to the ‘create account’ button. When the user fills in an email and clicks the submit button, they go as usual to create_account.php, but the email field is filled in. If they enter nothing on login.php, they still proceed to create_account.php and fill in the form as normal. It’s kind of like Amazon, sort of.

  1. Place the following on login.php : (replaces the submit button)

    <?php
    echo tep_draw_form('email_login', tep_href_link(FILENAME_CREATE_ACCOUNT, 'action=post', 'SSL'));
    echo '<p class="right">'.tep_draw_input_field('email_login', 'enter email address'). tep_draw_separator('pixel_trans.gif', '10', '10').tep_image_submit('', '', 'value="Create Account"');
    echo '</p></form>';
    ?>

  2. Place the following on create_account.php (replaces the email field)

    <?php
    $email_login = $HTTP_POST_VARS['email_login'];
    echo '<p>'.ENTRY_EMAIL_ADDRESS.'<br/>'.tep_draw_input_field('email_address', $email_login) . '&nbsp;' . (tep_not_null(ENTRY_EMAIL_ADDRESS_TEXT) ? '<span class="inputRequirement">' . ENTRY_EMAIL_ADDRESS_TEXT . '</span>': '');
    ?>

posted on the OSCommerce forum under ‘Tips and Tricks’:
Create Account Variation

Search Box Anywhere

This code can be used to install a CSS style search box anywhere on a OSCommerce shopping cart. It uses OSCommerce functions and clears when clicked on.

Paste this code where you would like to have the search box:
<div class="search-box">
<?php echo tep_draw_form('quick_find', tep_href_link(FILENAME_ADVANCED_SEARCH_RESULT, '', 'SSL', false), 'get'); ?>
<input type=text name="keywords" size="10" maxlength="25" class="search-field" value="Search..." onclick="this.value='';" onblur="if(!this.value) {this.value='Search...'; }">
<input type="hidden" name="search_in_description" value="1" />
<input type="hidden" name="inc_subcat" value="1" />
<?php echo tep_hide_session_id() .'<input type="submit" name="search" value="" class="search-go" border="0" width="79" height="25">';?>
</form>
</div>

Add this to your style sheet:
.search-box{ /*outer background*/float:right; height: 26px; padding: 10px 10px 0px 10px; }
input.search-field{ /*input field */ color:#999999; float: left; border:1px dotted #CCCCCC; border-width: 1px 0px 1px 1px; margin:0; padding: 3px 0px 0px 4px; height:16px; width: 92px; }
input.search-go { /*search icon */ float:left; border:1px solid #CCCCCC; border-width: 1px 1px 1px 0px; margin:0; padding:0; margin-left: 0px; height: 21px; width: 21px; background: #F2F2F2 url(img/icon-search.png) no-repeat top left; cursor: pointer; }
input.search-go:hover{ /*search icon hover "Does Not work in ie6" */ background:url(images/icon-search.png) no-repeat bottom left; }

Now upload this icon,
search icon
to the ‘images’ folder on your site.