Difference between revisions of "ZenCart data import - admin/custom menu.php"
(New page: ==Navigation== computing: software: ZenCart: importing data: '''admin/custom menu.php''' ==Overview== This file does the actual import. It conta...) |
m (→Source: syntax highlighting) |
||
Line 4: | Line 4: | ||
This file does the actual import. It contains a number of classes which might later be split off into separate PHP files, as they model particular aspects of the ZenCart data. | This file does the actual import. It contains a number of classes which might later be split off into separate PHP files, as they model particular aspects of the ZenCart data. | ||
==Source== | ==Source== | ||
− | < | + | <php><?php |
− | <?php | ||
// | // | ||
// +----------------------------------------------------------------------+ | // +----------------------------------------------------------------------+ | ||
Line 804: | Line 803: | ||
} | } | ||
− | ?> | + | ?></php> |
− | </ |
Revision as of 16:41, 10 March 2007
computing: software: ZenCart: importing data: admin/custom menu.php
Overview
This file does the actual import. It contains a number of classes which might later be split off into separate PHP files, as they model particular aspects of the ZenCart data.
Source
<php><?php // // +----------------------------------------------------------------------+ // |zen-cart Open Source E-commerce | // +----------------------------------------------------------------------+ // | Copyright (c) 2003 The zen-cart developers | // | | // | http://www.zen-cart.com/index.php | // | | // | Portions Copyright (c) 2003 osCommerce | // +----------------------------------------------------------------------+ // | This source file is subject to version 2.0 of the GPL license, | // | that is bundled with this package in the file LICENSE, and is | // | available through the world-wide-web at the following url: | // | http://www.zen-cart.com/license/2_0.txt. | // | If you did not receive a copy of the zen-cart license and are unable | // | to obtain it through the world-wide-web, please send a note to | // | license@zen-cart.com so we can mail you a copy immediately. | // +----------------------------------------------------------------------+ // /*
2006-09-17 (wzl) handlers for "Custom" menu. Used modules.php as model.
SET values:
prod_entry (default): bulk product entry ACTION values: (none): show bulk product entry form check: data is being submitted for preview commit: data is being submitted for final commit (update database)
- /
require('includes/application_top.php');
define('CUSTOM_MODULE_SET_PROD_ENTRY','prod_entry'); define('CUSTOM_MODULE_SAVE_DATA','save'); define('CUSTOM_MODULE_PROD_DATA_NAME','products'); define('CUSTOM_MODULE_ACT_CHECK','check'); define('CUSTOM_MODULE_ACT_COMMIT','commit'); define('CUSTOM_MODULE_BTN_CHECK','Preview Changes'); define('CUSTOM_MODULE_BTN_COMMIT','COMMIT');
define('URL_ISBN_SEARCH','http://www.abebooks.com/servlet/SearchResults?isbn=<<1>>'); define('CUSTOM_DEFAULT_SUPPLIER','Jubilee'); // when import data supplier field is empty define('CUSTOM_DEFAULT_CATEGORY','Unfiled'); // when imported category field is empty
define('TABLE_CUSTOM_IMPORT_PROD',DB_PREFIX.'custom_import_prod'); define('TABLE_CUSTOM_IMPORT_MFGRS',DB_PREFIX.'custom_import_mfgrs');
// new item define('HTML_STATUS_NEW', 'NEW'); // item is saved in list define('HTML_STATUS_NOTED', 'ok'); // item found in database define('HTML_STATUS_EXISTS', 'found');
$set = (isset($_GET['set']) ? $_GET['set'] : ); $button = (isset($_POST['action']) ? $_POST['action'] : ); switch ($button) { case CUSTOM_MODULE_BTN_CHECK: $action=CUSTOM_MODULE_ACT_CHECK; break; case CUSTOM_MODULE_BTN_COMMIT: $action=CUSTOM_MODULE_ACT_COMMIT; break; default: $action=; }
/*
After page has displayed, this handles the user's input
- /
switch ($action) { case CUSTOM_MODULE_SAVE_DATA: $doSave = true;
// new SQL code for updating products: $sqlUpdateProd = "update " . TABLE_PRODUCTS . " set configuration_value = '" . $value . "' where configuration_key = '" . $key ."'";
break; case 'enter': // showing data entry form, so this stage (data processing) does nothing default: }
?> <!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"> >
Previewing entered data:"; ProcessData(false); break; case CUSTOM_MODULE_ACT_COMMIT: echo "Saving entered data:"; $hide_form = 1; ProcessData(true); break; default: } /* DEFAULT: show bulk product entry form check: data is being submitted for preview commit: data is being submitted for final commit (update database) */ // always show data entry form: } if (!$hide_form) { $htmlSep = '<tab>'; echo zen_draw_form('prod_entry', CUSTOM_MENU_MODULE); echo '
';
echo 'Enter product data here: '; echo 'Format is: ' .'ID string'.$htmlSep .'(ignored)'.$htmlSep .'Title'.$htmlSep .'(ignored)'.$htmlSep .'Supplier'.$htmlSep .'Price '; echo ' | |
'; echo ''; echo ''; echo ' | '; echo ''; echo ' |
';
echo '';
}
?>
<?php
require(DIR_WS_INCLUDES . 'application_bottom.php');
function Pluralize($iQty, $iSing=, $iPlur='s') {
if ($iQty == 1) { return $iSing; } else { return $iPlur; }
}
function ProcessData($iCommit) {
$data_raw = $_POST[CUSTOM_MODULE_PROD_DATA_NAME]; $data_lines = explode("\n",$data_raw);
echo '
'; echo ''; echo '';$ctrTitlesNew = 0; $ctrTitlesOld = 0;
foreach ($data_lines as $data_line) {
// create title object for each import line. Title object should do all the lookups and printing and stuff.
if ($data_line) { $objTitle = clsTitles::Import($data_line);
$ctrSuppFnd = clsSuppliers::Count(); // # of suppliers found $ctrSuppNew = clsSuppliers::CountNew(); // # of *new* suppliers $ctrCatgFnd = clsCategories::Count(); // # of new categories $ctrCatgNew = clsCategories::CountNew(); // # of new categoriesecho ''.$objTitle->TableRowCells().''; } } if ($ctrSuppNew) { $htmlSuppList = ': '.clsSuppliers::DoListNew('','',', '); $htmlSuppList .= ' OLD: '.clsSuppliers::DoListOld('','',', '); } if ($ctrCatgNew) { $htmlCatgList = ': '.clsCategories::DoListNew('','',', '); $htmlCatgList .= ' OLD: '.clsCategories::DoListOld('','',', '); } echo '
Data Entry Status | |||||||
---|---|---|---|---|---|---|---|
Catg | ID | Title | Supplier | Price | Supplier | Title | Category |
'; echo 'Processed '.$ctrLines.' lines:
- '
.'
- '.clsTitles::Records()->CountNew().' new titles to add' .'
- '.clsTitles::Records()->CountOld().' titles to update (ignored for now)' .'
- '.$ctrSuppFnd.' supplier'.Pluralize($ctrSuppFnd).' in import, '.$ctrSuppNew.' new'.$htmlSuppList .'
- '.$ctrCatgFnd.' categor'.Pluralize($ctrCatgFnd,'y','ies').' in import, '.$ctrCatgNew.' new'.$htmlCatgList .'
';
echo 'Adding suppliers: '.clsSuppliers::Save($iCommit).'
'; echo 'Adding categories: '.clsCategories::Save($iCommit).'
'; echo 'Adding titles: '.clsTitles::Save($iCommit).'
';
} function MakeKey($iStr) {
return preg_replace('/[ -\.,;]*/',,strtolower($iStr));
} /*
===== CLASSES =====
- /
class clsRecords {
public $List; // actual unique records public $qtyNew; // number of *new* records found during import public $qtyOld;
public function Count() { return Count($this->List); } public function CountOld() { if ($this->qtyOld) { return $this->qtyOld; } else { return 0; } } public function CountNew() { if ($this->qtyNew) { return $this->qtyNew; } else { return 0; } } public function AddObject($iName,$iObj) { if (!$this->List[$iName]) { $this->List[$iName] = $iObj; } if ($iObj->isFound) { $this->qtyOld++; } else { $this->qtyNew++; } } public function Exists($iName) { if (is_array($this->List)) { $isSet = isset($this->List[$iName]); return $isSet; } else { return false; } } public function DoListNew($iPfx,$iSfx,$iSep) { foreach ($this->List as $obj) { if (!$obj->isFound) { if ($out) { $out .= $iSep; } $out .= $iPfx.$obj->Name.$iSfx; } } return $out; } public function DoListOld($iPfx,$iSfx,$iSep) { foreach ($this->List as $obj) { if ($obj->isFound) { if ($out) { $out .= $iSep; } $out .= $iPfx.$obj->Name.$iSfx; } } return $out; }
}
class clsTitles {
private static $objRecords;
public function Records() { self::InitRecords(); return self::$objRecords; }
public function Import($iLine) { $obj = new clsTitle; $obj->ImportLine($iLine); if (!$obj->isCatg) { self::Records()->AddObject($obj->ImportKey,$obj); } return $obj; }
public function Save($iCommit) { global $db;
$result = '
- ';
foreach (self::Records()->List as $obj) {
$result .= $obj->Save($iCommit);
}
$result .= '
';
return $result; } public function Count() { return self::Records()->Count(); } public function CountNew() { return self::Records()->CountNew(); } public function DoListNew($iPfx,$iSfx,$iSep) { return self::Records()->DoListNew($iPfx,$iSfx,$iSep); } protected function InitRecords() { if (!isset(self::$objRecords)) { self::$objRecords = new clsRecords; } }
}
class clsTitle {
public $ImportKey; private $intID; public $Name; public $Price; public $Supplier; public $SuppImp; public $Category; public $CatgImp; public $isCatg;
// calculated fields
public $ISBN; public $ISBN_URL; public $HtmlName;
// status fields
public $Status; public $isFound;
// public static $lstTitles;
public function ID() { if (!isset($this->intID)) { $this->UpdateName(); }
//echo 'TITLE ID='.$this->intID;
return $this->intID; }
public function ImportLine($iLine) { global $db;
list($ImportKeyRaw,$notUsed,$this->Name,$notUsed,$strSupplierName,$notUsed,$this->Price) = explode("\t",$iLine);
//echo 'NAME='.$Name.'
';
// Check to see if the title is actually a category record - price is 0, name is empty or contains "classification"
$this->isCatg = false; if ($this->Price == 0.0) { if ((!MakeKey($this->Name)) || (eregi('classification',$this->Name))) { $this->isCatg = true; } } if ($this->isCatg) {
// for now, we're not really doing anything with category lines
$this->HtmlName = ''.$this->Name.'';
} else {
// ** Supplier
if ($strSupplierName == ) { $strSupplierName = CUSTOM_DEFAULT_SUPPLIER; } $this->SuppImp = clsSuppliers::Import($strSupplierName); $this->Supplier = $this->SuppImp->Supplier;
// Parse out the category and title key
$listTitleParts = array_reverse(split(':',$ImportKeyRaw)); $this->ImportKey = MakeKey(array_shift($listTitleParts)); $strCatg = array_shift($listTitleParts); // for now, assume just one level of category if (!$strCatg) { $strCatg = CUSTOM_DEFAULT_CATEGORY; } $this->CatgImp = clsCategoryImports::Import($strCatg); $this->Category = $this->CatgImp->Category;
//echo 'CATG='.$strCatg.' stored='.$this->Category->Name.'
';
$this->UpdateName();
// ** Title: cross-reference import key to title ID
$sqlFind = 'SELECT * FROM '.TABLE_CUSTOM_IMPORT_PROD.' WHERE import_key="'.$this->ImportKey.'";'; $qryTitle = $db->Execute($sqlFind); if ($qryTitle->RecordCount()) { $this->isFound = true; $this->Status = HTML_STATUS_EXISTS; $this->ID = $qryTitle->fields['prod_key']; } else { $this->isFound = false;
if ($lstTitles[$this->ImportKey]) { $this->Status = HTML_STATUS_NOTED;
} else { $this->Status = HTML_STATUS_NEW;
// $lstTitles[$this->ImportKey] = $this->ID; // may eventually want to save an object, not just a string
} } } }
public function UpdateName() { $subject = $this->Name; $pattern = '/ISBN *[0-9\-]*/'; preg_match($pattern, $subject, $matches, PREG_OFFSET_CAPTURE);
// This operation is unnecessarily complicated, but it is what seems to work:
$this->ISBN = trim(preg_replace('/ISBN/',,$matches[0][0])); if ($this->ISBN) { $this->ISBN_URL = preg_replace('/<<1>>/',$this->ISBN,URL_ISBN_SEARCH); $this->HtmlName = '<a href="'.$this->ISBN_URL.'">'.$this->Name.'</a>'; } else { $this->HtmlName = $this->Name; $this->ISBN_URL = ; } }
public function Save($iCommit) { global $db;
if ($this->isFound) {
// TO DO: write update routine
} else {
// Check for missing manufacturer:
if (!$this->Supplier->ID()) { echo 'MISSING SUPPLIER for title "'.$this->Name.'"
'; } if (!$this->Category->ID()) { echo 'MISSING CATEGORY for title "'.$this->Name.'"
'; }
// only insert items with a numerically valid price
if (is_numeric(trim($this->Price))) {
// Theory: MySQL defaults to using the first index as an auto-increment key. We'll see if this works. // Update main PRODUCTS table:
$sqlAdd = 'INSERT INTO '.TABLE_PRODUCTS.' (products_status,products_price,products_date_added,manufacturers_id,master_categories_id)'
.'VALUES(' .'1,' // products_status (1 = active) .$this->Price.',' // products_price .'NOW(),' // products_date_added .$this->Supplier->ID().',' // manufacturers_id .$this->Category->ID().')'; // master_categories_id
$result .= '
if ($this->isCatg) {$out .= 'category (ignored)';
} else {$out .= '('.$this->Supplier->ID().') '.$this->Supplier->Name.''.$this->Price.''.$this->SuppImp->Status.''.$this->Status.''.$this->CatgImp->Status.'';
} return $out; }
}
class clsSuppliers {
private static $Records;
public function Import($iName) { self::InitRecords(); $objSuppImp = new clsSupplierImport; if (self::$Records->List[$iName]) {
// supplier has already been seen this session
$objSupp = self::$Records->List[$iName]; // retrieve existing supplier record $objSuppImp->ImportOld($objSupp); // attach it to supplier import record for this import } else {
// new supplier for this session
$objSuppImp->ImportNew($iName); self::$Records->AddObject($iName,$objSuppImp->Supplier);
// self::$Records->List[$iName] = $objSuppImp->Supplier;
// if (!$objSuppImp->Supplier->isFound) { // $this->Records->qtyNew++; // } } return $objSuppImp; }
// save list of (new) suppliers to database
public function Save($iCommit) { global $db;$result = '
- ';
foreach (self::$Records->List as $obj) {
if (!$obj->isFound) {
if ($strValues) {
$strValues .= ',';
}
$strValues .= '("'.mysql_real_escape_string($obj->Name).'",NOW())';
}
}
if ($strValues) {
$sqlAdd = 'INSERT INTO '.TABLE_MANUFACTURERS.' (manufacturers_name, date_added) VALUES'.$strValues;
$result .= '
- SQL: '.$sqlAdd; if ($iCommit) { $db->Execute($sqlAdd); $result .= '
- status: '.mysql_info(); } } $result .= '
return $result; } public function Count() { self::InitRecords(); return self::$Records->Count(); } public function CountNew() { self::InitRecords(); return self::$Records->CountNew(); } public function DoListNew($iPfx,$iSfx,$iSep) { self::InitRecords(); return self::$Records->DoListNew($iPfx,$iSfx,$iSep); } public function DoListOld($iPfx,$iSfx,$iSep) { self::InitRecords(); return self::$Records->DoListOld($iPfx,$iSfx,$iSep); } protected function InitRecords() { if (!isset(self::$Records)) { self::$Records = new clsRecords; } }
}
class clsSupplier {
private $intID; public $Name; public $Key; public $isFound;
public function Init($iName) { global $db;
$this->Name = $iName; $this->UpdateName(); } public function Init_fromID($iID) { global $db;
$this->intID = $iID; $sqlFind = 'SELECT * FROM '.TABLE_MANUFACTURERS.' WHERE manufacturers_id="'.$iID.'";'; $qryFind = $db->Execute($sqlFind); $this->isFound = $qryFind->RecordCount(); if ($this->isFound) { $this->Name = $qryFind->fields['manufacturers_name']; } } private function UpdateName() { global $db;
$sqlFind = 'SELECT * FROM '.TABLE_MANUFACTURERS.' WHERE manufacturers_name="'.$this->Name.'";'; $qryFind = $db->Execute($sqlFind); $this->isFound = $qryFind->RecordCount(); if ($this->isFound) { $this->intID = $qryFind->fields['manufacturers_id']; } else {
// not found in main list, so check aliases
$sqlFind = 'SELECT * FROM '.TABLE_CUSTOM_IMPORT_MFGRS.' WHERE LCASE(import_alias)="'.mysql_real_escape_string(strtolower($this->Name)).'";'; $qryFind = $db->Execute($sqlFind); $this->isFound = $qryFind->RecordCount(); if ($this->isFound) { $this->Init_fromID($qryFind->fields['id_mfgr']); } } } public function ID() { if ($this->intID) { $this->UpdateName(); } return $this->intID; }
}
class clsSupplierImport {
public $Supplier; // points to supplier data public $Status; // indicates status of this particular import of that data
// Supplier record has already been created, so use it:
public function ImportOld($iObj) { $this->Supplier = $iObj; $this->Status = HTML_STATUS_NOTED; }
// Supplier record needs to be created:
public function ImportNew($iName) { global $db;
$this->Supplier = new clsSupplier; $this->Supplier->Init($iName); if ($this->Supplier->isFound) { $this->Status = HTML_STATUS_EXISTS; } else { $this->Status = HTML_STATUS_NEW; } }
}
/*
===== CATEGORIES =====
- /
class clsCategories {
private static $Records;
public function Create($iName) {
// This function is only called if category has not been seen before in this run
global $db;
$objNew = new clsCategory; self::InitRecords(); $objNew->Init($iName); self::$Records->AddObject($iName,$objNew);
/* self::$Records->List[$iName] = $objNew;
if (!$objNew->isFound) { self::$Records->qtyNew++; }
- /
return $objNew; }
// add any new categories to database
public function Save($iCommit) { foreach (self::$Records->List as $obj) { if (!$obj->isFound) { $sqlOut .= $obj->Save($iCommit); } } return $sqlOut; } public function GetObject($ID) { self::InitRecords(); return self::$Records->List[$ID]; } public function Count() { self::InitRecords(); return self::$Records->Count(); } public function CountNew() { self::InitRecords(); return self::$Records->CountNew(); } public function Exists($iName) { self::InitRecords(); return self::$Records->Exists($iName); } public function DoListNew($iPfx,$iSfx,$iSep) { self::InitRecords(); return self::$Records->DoListNew($iPfx,$iSfx,$iSep); } public function DoListOld($iPfx,$iSfx,$iSep) { self::InitRecords(); return self::$Records->DoListOld($iPfx,$iSfx,$iSep); } protected function InitRecords() { if (!isset(self::$Records)) { self::$Records = new clsRecords; } }
} class clsCategory {
private $intID; public $Name; public $ImportKey;
// status
public $isFound;
public function Init($iName) { global $db;
//echo 'storing 2:'.$iName.' ';
$this->Name = $iName; $this->ImportKey = MakeKey($iName); $this->UpdateName(); } private function UpdateName() { global $db;
$sqlFind = 'SELECT * FROM '.TABLE_CATEGORIES_DESCRIPTION.' WHERE categories_name="'.$this->Name.'"'; $qryFind = $db->Execute($sqlFind); $this->isFound = $qryFind->RecordCount(); $this->intID = $qryFind->fields['categories_id']; } public function ID() { if (!$this->intID) { $this->UpdateName(); } return $this->intID; } public function Save($iCommit) { global $db;$result = '
- ';
$sqlAdd = 'INSERT INTO '.TABLE_CATEGORIES.' (date_added) VALUES(NOW())';
$result .= '
- SQL: '.$sqlAdd; if ($iCommit) { $db->Execute($sqlAdd); $result .= '
- status: '.mysql_info(); $idNew = mysql_insert_id(); $result .= '
- ID: '.$idNew; } else { $idNew = '?'; } $sqlAdd = 'INSERT INTO '.TABLE_CATEGORIES_DESCRIPTION.' (categories_id,categories_name) VALUES(' .$idNew.',"'.mysql_real_escape_string($this->Name).'");'; $result .= '
- SQL: '.$sqlAdd; if ($iCommit) { $db->Execute($sqlAdd); $result .= '
- status: '.mysql_info(); } $result .= '
return $result; }
}
class clsCategoryImports {
public function Import($iName) { $objImport = new clsCategoryImport; $objImport->Import($iName); return $objImport; }
}
class clsCategoryImport {
public $Category; public $Status;
public function Import($iName) {
// echo 'storing 1:'.$iName.' ';
if (clsCategories::Exists($iName)) {
//echo 'EXISTS ';
$this->Category = clsCategories::GetObject($iName); $this->Status = HTML_STATUS_NOTED; } else {
//echo '*NEW* ';
$this->Category = clsCategories::Create($iName); if ($this->Category->isFound) { $this->Status = HTML_STATUS_EXISTS; } else { $this->Status = HTML_STATUS_NEW; } } }
}
?></php>