OsCommerce architecture

Uit DeVliegendeWiki

Ga naar: navigatie, zoeken

PHP, HTML & MySQL: The bulk of osCommerce consists of PHP code with embedded HTML. Further, osCommerce makes use of a MySQL database and is webserver-independent. This means, that when you have an osCommerce instance, and you copy the PHP code and the contents of the MySQL (through e.g. a MySQL dump) to another computer, you could just recreate the whole shop.

Three-tier application: To look at osCommerce from a three-tier architecture view: MySQL forms the data-storage layer; PHP makes up the business logic layer, and HTML the presentation layer. Further, there is as well a bit of JavaScript present in the HTML-code. Since PHP, JavaScript and HTML are intertwined in the same files, the presentation and business logic layers are closely coupled.

Two separate applications: osCommerce (that is loosely spoken, the PHP code) is divided in two parts: the online shop, and the administrative tool. These are two almost completely separated applications, with a duplicated file structure. This division may help a lot in reducing the complexity of managing osCommerce to reasonable levels.

Content separated from code: Content (text) is not stored in the database, nor directly embedded in PHP code. It is stored is designated PHP files, grouped per language, where the text is assigned to strings. As an example, here's /includes/languages/english/account.php:

<?php
/*
  $Id: account.php 1739 2007-12-20 00:52:16Z hpdl $

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

  Copyright (c) 2003 osCommerce

  Released under the GNU General Public License
*/

define('NAVBAR_TITLE', 'My Account');
define('HEADING_TITLE', 'My Account Information');

define('OVERVIEW_TITLE', 'Overview');
define('OVERVIEW_SHOW_ALL_ORDERS', '(show all orders)');
define('OVERVIEW_PREVIOUS_ORDERS', 'Previous Orders');

define('MY_ACCOUNT_TITLE', 'My Account');
define('MY_ACCOUNT_INFORMATION', 'View or change my account information.');
define('MY_ACCOUNT_ADDRESS_BOOK', 'View or change entries in my address book.');
define('MY_ACCOUNT_PASSWORD', 'Change my account password.');

define('MY_ORDERS_TITLE', 'My Orders');
define('MY_ORDERS_VIEW', 'View the orders I have made.');

define('EMAIL_NOTIFICATIONS_TITLE', 'E-Mail Notifications');
define('EMAIL_NOTIFICATIONS_NEWSLETTERS', 'Subscribe or unsubscribe from newsletters.');
define('EMAIL_NOTIFICATIONS_PRODUCTS', 'View or change my product notification list.');
?>

layout of the main page. The file /index.php refers to the following files, that make up the body of the main page:

+--------------------------------------------------------------+
|                        header.php                            |
+--------------------------------------------------------------+
|column_left.php:   |                 |column_right.php:       |
|                   |                 |                        | 
|* categories.php   |                 |* shopping_cart.php     |
|* manufacturers.php|                 |* manufacturers_info.php|
|* whats_new.php    |                 |* best_sellers.php      |  
|* search.php       |                 |* tell_a_friend.php     |
|* information.php  |                 |* specials.php          |
|                   |                 |* reviews.php           |
|                   |                 |* languages.php         |
|                   |                 |* currencies.php        |
+--------------------------------------------------------------+
|                        footer.php                            |
+--------------------------------------------------------------+

Inhoud

Other

Startup sequence

index.php

  • includes/application_top.php
    • includes/configure.php, which defines values for the following constants (given with typical values, where applicable)
      • HTTP_SERVER, http://localhost
      • HTTPS_SERVER , http://localhost
      • ENABLE_SSL, false
      • HTTP_COOKIE_DOMAIN, localhost
      • HTTPS_COOKIE_DOMAIN, localhost
      • HTTP_COOKIE_PATH, /
      • HTTPS_COOKIE_PATH, /
      • DIR_WS_HTTP_CATALOG, /
      • DIR_WS_HTTPS_CATALOG, /
      • DIR_WS_IMAGES, images/
      • DIR_WS_ICONS, DIR_WS_IMAGES . icons/
      • DIR_WS_INCLUDES, includes/
      • DIR_WS_BOXES, DIR_WS_INCLUDES . boxes/
      • DIR_WS_FUNCTIONS, DIR_WS_INCLUDES . functions/
      • DIR_WS_CLASSES, DIR_WS_INCLUDES . classes/
      • DIR_WS_MODULES, DIR_WS_INCLUDES . modules/
      • DIR_WS_LANGUAGES, DIR_WS_INCLUDES . languages/
      • DIR_WS_DOWNLOAD_PUBLIC, pub/
      • DIR_FS_CATALOG, /var/www/
      • DIR_FS_DOWNLOAD, DIR_FS_CATALOG . download/
      • DIR_FS_DOWNLOAD_PUBLIC, DIR_FS_CATALOG . pub/
      • DB_SERVER, localhost
      • DB_SERVER_USERNAME, root
      • DB_SERVER_PASSWORD,
      • DB_DATABASE, borenbase
      • USE_PCONNECT, false
      • STORE_SESSIONS, mysql
    • DIR_WS_FUNCTIONS.compatibility.php
    • DIR_WS_INCLUDES.filenames.php
    • DIR_WS_INCLUDES.database_tables.php
    • BOX_WIDTH set at 125
    • DIR_WS_FUNCTIONS.database.php Defines the following functions:
        • tep_db_connect
        • tep_db_close
        • tep_db_error
        • tep_db_query: Execute a query. The function returns a resource handle to the query. This resource handle can be used by tep_db_fetch_array and probably some other functions.
        • tep_db_perform
        • tep_db_fetch_array: Fetches a row, like through $row=tep_db_array($resource_handle). The returned $row is an array with associative indices. Here's a complete example:
$resource_handle=tep_db_query("select * from ".TABLE_PRODUCTS);
$row=tep_db_fetch_array($resource_handle);
print $row['products_id']
        • tep_db_num_rows
        • tep_db_data_seek places the record pointer in the collection of records. The following example is from the function tep_random_select (mentioned further on)
$handle = tep_db_query($query); // Create handle
$num_rows = tep_db_num_rows($handle); // Retrieve number of rows in query
$random_row = tep_rand(0, ($num_rows - 1)); // Get a random number in the range [0;$num_rows-1]
tep_db_data_seek($handle, $random_row); // Place record pointer at random record
$random_product = tep_db_fetch_array($handle); // Fetch record
        • tep_db_insert_id
        • tep_db_free_result
        • tep_db_fetch_fields
        • tep_db_output
        • tep_db_input
        • tep_db_prepare_input
    • includes/application_top.php makes a database connection for the first time and sets some parameters
    • DIR_WS_FUNCTIONS.gzip_compression.php
    • includes/application_top.phpinvokes DIR_WS_FUNCTIONS.general.php
      • DIR_WS_FUNCTIONS.general.php defines the following functions:
        • tep_exit
        • tep_redirect
        • tep_parse_input_field_data
        • tep_output_string
        • tep_output_string_protected
        • tep_sanitize_string
        • tep_random_select: Return a random row from a database query
        • tep_get_products_name: Return a product's name
        • tep_get_products_special_price($product_id): Return a product's special price (returns nothing if there is no offer)
        • tep_get_products_stock: Return a product's stock
        • tep_check_stock: Check if the required stock is available. If insufficent stock is available return an out of stock message
        • tep_break_string
        • tep_get_all_get_params
        • tep_get_countries
        • tep_get_countries_with_iso_codes
        • tep_get_path
        • tep_browser_detect
        • tep_get_country_name
        • tep_get_zone_name
        • tep_get_zone_code
        • tep_round
        • tep_get_tax_rate
        • tep_db_query
        • tep_get_tax_description
        • tep_add_tax
        • tep_calculate_tax
        • tep_get_tax_description($class_id, $country_id, $zone_id)
        • tep_add_tax($price, $tax)
        • tep_calculate_tax($price, $tax)
        • tep_count_products_in_category($category_id, $include_inactive = false)
        • tep_has_category_subcategories($category_id)
        • tep_get_address_format_id($country_id)
        • tep_address_format($address_format_id, $address, $html, $boln, $eoln)
        • tep_address_label($customers_id, $address_id = 1, $html = false, $boln = , $eoln = "\n")
        • tep_row_number_format($number)
        • tep_get_categories($categories_array = , $parent_id = '0', $indent = )
        • tep_get_manufacturers($manufacturers_array = )
        • tep_get_subcategories(&$subcategories_array, $parent_id = 0)
        • tep_date_long($raw_date)
        • tep_date_short($raw_date)
        • tep_parse_search_string($search_str = , &$objects)
        • tep_checkdate($date_to_check, $format_string, &$date_array)
        • tep_is_leap_year($year)
        • tep_create_sort_heading($sortby, $colnum, $heading)
        • tep_get_parent_categories(&$categories, $categories_id)
        • tep_get_product_path($products_id)
        • tep_get_uprid($prid, $params)
        • tep_get_prid($uprid)
        • tep_customer_greeting()
        • tep_mail($to_name, $to_email_address, $email_subject, $email_text, $from_email_name, $from_email_address)
        • tep_has_product_attributes($products_id)
        • tep_word_count($string, $needle)
        • tep_count_modules($modules = )
        • tep_count_payment_modules()
        • tep_count_shipping_modules()
        • tep_create_random_value($length, $type = 'mixed')
        • tep_array_to_string($array, $exclude = , $equals = '=', $separator = '&')
        • tep_not_null($value)
        • tep_display_tax_value($value, $padding = TAX_DECIMAL_PLACES)
        • tep_currency_exists($code)
        • tep_parse_category_path($cPath)
        • tep_rand($min = null, $max = null)
        • tep_setcookie($name, $value = , $expire = 0, $path = '/', $domain = , $secure = 0)
        • tep_get_ip_address()
        • tep_count_customer_orders($id = , $check_session = true)
        • tep_count_customer_address_book_entries($id = , $check_session = true)
        • tep_convert_linefeeds($from, $to, $string)
    • DIR_WS_FUNCTIONS.html_output.php
      • tep_href_link
      • tep_image
      • tep_image_submit
      • tep_image_button
      • tep_draw_separator
      • tep_draw_form
      • tep_draw_input_field
      • tep_draw_password_field
      • tep_draw_selection_field
      • tep_draw_checkbox_field
      • tep_draw_radio_field
      • tep_draw_textarea_field
      • tep_draw_hidden_field
      • tep_hide_session_id
      • tep_draw_pull_down_menu
      • tep_get_country_list
    • DIR_WS_FUNCTIONS.cache.php (conditionally)
    • DIR_WS_CLASSES.shopping_cart.php
    • DIR_WS_CLASSES.navigation_history.php
    • If sessions are not supported, use the php3 compatible session class through defining the following constants:
      • PHP_SESSION_NAME, osCsid
      • PHP_SESSION_PATH, $cookie_path
      • PHP_SESSION_DOMAIN, $cookie_domain
      • PHP_SESSIONS_SAVE_PATH,SESSION_WRITE_DIRECTORYi
    • DIR_WS_CLASSES.sessions.php
    • Set session cookies parameters
    • Set the session ID if it exists
    • Start the session
    • Create shopping cart & fix the cart if necessary
    • DIR_WS_CLASSES.currencies.php
    • Create instance $currencies
    • DIR_WS_CLASSES.mime.php
    • DIR_WS_CLASSES.email.php
    • Set the language
    • DIR_WS_CLASSES.language.php
    • DIR_WS_CLASSES.$language.php
    • Some extensive code for processing various buying-related actions
    • DIR_WS_FUNCTIONS.whos_online.php
    • DIR_WS_FUNCTIONS.password.funcs.php
    • DIR_WS_FUNCTIONS.validations.php
    • DIR_WS_FUNCTIONS.split_page_results.php
    • DIR_WS_CLASSES.boxes.php
    • DIR_WS_CLASSES.banner.php
    • Activate banners
    • DIR_WS_FUNCTIONS.specials.php
    • Calculate category path
    • DIR_WS_CLASSES.breadcrumb.php
    • Start breadcrumb path
    • DIR_WS_CLASSES.message_stack.php
      • define

Data model

Use phpMyAdmin or just the mysql client for inspecting the data model. Here's an impression of some tables:

  • products
    • products_id
    • products_quantity
    • products_model
    • products_image
    • products_price
    • products_date_added
    • products_last_modified
    • products_date_available
    • products_weight
    • products_status
    • products_tax_class_id
    • manufacturers_id
    • products_ordered

Price calculations

  • Normally, prices are stored in table products as field products_price.
  • Special prices are stored in table specials. Maybe this is handy for promotional activities or so. I don't seem to use it.
  • /includes/classes/currencies.php defines a class currencies. There seems to be a global variable $currencies that is being used constantly for dealing with prices. As an example,here is some simplified code from the box whats_new.php:
if (tep_not_null($random_product['specials_new_products_price'])) 
 { // This code is executed when a special price has been found
  $whats_new_price = $currencies->display_price
   (
     $random_product['products_price'],
     tep_get_tax_rate($random_product['products_tax_class_id'])
   ) ;
 } 
else 
 { // This code is executed when no special prices is found.
   // Normal prices will be used instead
   $whats_new_price = $currencies->display_price
   (
     $random_product['products_price'],
     tep_get_tax_rate($random_product['products_tax_class_id'])
   );
  }

Order process

The basic order process seems to proceed through schreens products_new.php --> shopping_cart.php --> checkout_shipping.php

Code in products_new.php

The following code is behind the put in cart-button in file products_new.php. It may help to understand the first part of the order process. Function tep_href_link adds a osCsid (osCommerce Session ID) at the end of the link:

echo '<a href="' .

 tep_href_link(FILENAME_PRODUCTS_NEW, tep_get_all_get_params(array('action')) . 
 'action=buy_now&products_id=' . $products_new['products_id']) . '">' . 

 tep_image_button('button_in_cart.gif', 
 IMAGE_BUTTON_IN_CART) . '</a>';

Code in shopping_cart.php The shopping cart is an infoBox, just as more objects in osCommerce. Here is a bit of the code that is used for assembling its contents:

$info_box_contents[$cur_row][] = array
(
  'align' => 'center',
  'params' => 'class="productListing-data" valign="top"',
  'text' => tep_draw_checkbox_field
  (
    'cart_delete[]', 
    $products[$i]['id']
  )
);
Persoonlijke instellingen