ZenCart data import - admin/custom menu.php

from HTYP, the free directory anyone can edit if they can prove to me that they're not a spambot
Jump to: navigation, search

Navigation

computing: software: ZenCart: importing data: $zc/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_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_ACT_UPLOAD','upload');
 define('CUSTOM_MODULE_ACT_DELETE','delete');
 define('CUSTOM_MODULE_ACT_ASSIGN','assign');
 define('CUSTOM_MODULE_ACT_VIEW','view');
 define('CUSTOM_MODULE_ACT_LOOSE_DEL','loose_del');
 define('CUSTOM_MODULE_ACT_LOOSE_EXT','loose_unzip');
 define('CUSTOM_MODULE_ACT_LOOSE_VIEW','loose_view');
 define('CUSTOM_MODULE_BTN_CHECK','Preview Changes');
 define('CUSTOM_MODULE_BTN_COMMIT','COMMIT');
 define('CUSTOM_MODULE_BTN_UPLOAD','Upload File');
 define('CUSTOM_MODULE_BTN_DELETE_FILE','Delete File');
 define('CUSTOM_MODULE_BTN_ASSIGN_IMG','Assign Image');
 define('CUSTOM_MODULE_BTN_VIEW_PROD','View Product');
 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');
 define('TABLE_CUSTOM_UPLOADS',DB_PREFIX.'custom_uploads');
 define('TABLE_CUSTOM_UPLOAD_FILES',DB_PREFIX.'custom_upload_files');
 define('TABLE_CUSTOM_UPLOAD_THUMBS',DB_PREFIX.'custom_upload_thumbs');
 // 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');
 $intOpt_MaxThumbs = 50;	// default

// Get any expected parameters

 if (count($_POST)) {
   $button = (isset($_POST['action']) ? $_POST['action'] : );
   $idProd = $_POST['prod-id'];
   $idImg = $_POST['img-id'];
 } else {
   $set = (isset($_GET['set']) ? $_GET['set'] : );
   $idImg = $_GET['img-id'];
   $strFileName = $_GET['file'];
 }
 switch ($button) {
   case CUSTOM_MODULE_BTN_CHECK: $action=CUSTOM_MODULE_ACT_CHECK; break;
   case CUSTOM_MODULE_BTN_COMMIT: $action=CUSTOM_MODULE_ACT_COMMIT; break;
   case CUSTOM_MODULE_BTN_UPLOAD: $action=CUSTOM_MODULE_ACT_UPLOAD; break;
   case CUSTOM_MODULE_BTN_DELETE_FILE: $action=CUSTOM_MODULE_ACT_DELETE; break;
   case CUSTOM_MODULE_BTN_ASSIGN_IMG: $action=CUSTOM_MODULE_ACT_ASSIGN; break;
   case CUSTOM_MODULE_BTN_VIEW_PROD: $action=CUSTOM_MODULE_ACT_VIEW; break;
   default: $action=$_GET['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"> <html <?php echo HTML_PARAMS; ?>> <head> <meta http-equiv="Content-Type" content="text/html; charset=<?php echo CHARSET; ?>"> <title><?php echo TITLE; ?></title> <link rel="stylesheet" type="text/css" href="includes/stylesheet.css"> <link rel="stylesheet" type="text/css" href="includes/cssjsmenuhover.css" media="all" id="hoverJS"> <script language="javascript" src="includes/menu.js"></script> <script language="javascript" src="includes/general.js"></script> <script type="text/javascript"> </script> </head> <body onload="init()"> <?php require(DIR_WS_INCLUDES . 'header.php'); ?>


<?php /* Apparently the $set is only sent on the initial stage of each operation.

 So first we check for an $action; if no $action, then look for a $set.
  • /
 $show_data_entry_form = 0;
 $idAdmin = $_SESSION['admin_id'];
 $doSet = false;
 switch ($action) {
 case CUSTOM_MODULE_ACT_CHECK:
   $show_data_entry_form = 1;
   echo "Previewing entered data:";
   ProcessData(false);
 break;
 case CUSTOM_MODULE_ACT_COMMIT:
   $show_data_entry_form = 1;
   echo "Saving entered data:";
   $hide_form = 1;
   ProcessData(true);
 break;
 case CUSTOM_MODULE_ACT_UPLOAD: // we've got the zipfile, so unpack it etc.
   $objUpload = clsUploads::AddNew();	// log the start of the upload processing

// process the upload

   $objUpload->UnzipUpload();

// log upload completion

   $objUpload->Finish();

// ** image-editing actions

   case CUSTOM_MODULE_ACT_DELETE:
     $show_img_assign_form = true;
     $objFile = clsUploadFiles::File_fromID($idImg);
     echo 'Deleting image ['.$objFile->filespec.'] (ID='.$idImg.')...';
     $objFile->Delete();

echo '


';

// clear image so we go back to the list of unassigned images:

     unset($idImg);
     $doSet = true;
   break;
   case CUSTOM_MODULE_ACT_ASSIGN:

echo 'Assigning displayed image to the displayed product

'; $objProd = clsTitles::Item($idProd); $objFile = clsUploadFiles::File_fromID($idImg); echo 'Assigning image ['.$objFile->filespec.'] to product ID='.$idProd.' ['.$objProd->DescrObj()->name.'] '.$objProd->HTML_Links().'
'; $objProd->image = 'bulk/'.$objFile->filespec; $objFile->ID_Prod = $idProd; $objProd->Save(); $objFile->Save(); // clear image so we go back to the list of unassigned images and display the updated product: unset($idImg); $show_img_assign_form = true; break; case CUSTOM_MODULE_ACT_VIEW: echo 'Viewing image, with unassigned product information

'; $objProd = clsTitles::Item($idProd); echo $objProd->HTML(); echo '


';

     $show_img_assign_form = true;
   break;
   case CUSTOM_MODULE_ACT_LOOSE_DEL:
     $strFileName = $_GET['file'];
     $strFileSpec = clsUploads::PathToBulkUpload().$strFileName;
     if (strstr($strFileName,'../')) {
       echo 'Ignoring dangerous filename ['.$strFileName.'].';
     } else {
       echo 'Deleting ['.$strFileSpec.']...';
       if (unlink($strFileSpec)) {
         echo 'ok';
       } else {
         echo 'error!';
       }

echo '


';

     }
     $doSet = true;
   break;
   case CUSTOM_MODULE_ACT_LOOSE_EXT:
     echo 'Unzipping the file ['.$strFileName.']...';
     $objUpload = new clsUpload;
     $objUpload->Start_fromLoose($strFileName,'FTP upload');
     $objUpload->UnzipArchive();
     $objUpload->Finish();
   break;
   case CUSTOM_MODULE_ACT_LOOSE_VIEW:
     echo 'Viewing '.$strFileName.':
'; echo '<img src="'.clsUploads::URLToBulkUpload().$strFileName.'">'; $doSet = true; break; default: $doSet = true; } if ($doSet) { switch ($set) { case CUSTOM_MODULE_SET_PROD_ENTRY:

/*

SET: show bulk product entry form
check: data is being submitted for preview
commit: data is being submitted for final commit (update database)
  • /
       $show_data_entry_form = true;
     break;
     case CUSTOM_MODULE_SET_BULK_UPLOAD:
       $show_img_upload_form = true;
     break;
     case CUSTOM_MODULE_SET_BULK_ASSIGN:

$show_img_assign_form = true;

     break;
     default:

if ($set) { echo "Sorry, this function ($set) is not implemented yet!"; if ($action) { echo "
action=[$action]"; } } else { // The action for the top level of the custom menu goes here. // This seemed like a good place to have an explanation of what the menu choices do. // You could put in just an "echo" and the text, but the following code extracts it // from a wiki page: // error_reporting(E_ALL ^ E_NOTICE ^ E_WARNING); // turn off the session warning

	  require_once('../../w/extract.php');

echo getWikiPage('Embed:menu:Import');

       }
   break;
 }

}

 if ($show_data_entry_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 zen_draw_textarea_field(CUSTOM_MODULE_PROD_DATA_NAME, , '100', '20');

// later on this can use Zen functions for more slickness, but for now this should work:

echo '
';
   echo '<input type="submit" name="action" value="'.CUSTOM_MODULE_BTN_CHECK.'">';
   echo '<input type="submit" name="action" value="'.CUSTOM_MODULE_BTN_COMMIT.'">';
echo '
';
   echo '<input type="reset" value="Undo all edits">';
echo '

';

   echo '</form>';
 }
 if ($show_img_upload_form) {
   require_once('../../w/extract.php');
   // display the help text
   echo getWikiPage('Embed:menu:Upload');
   // check to see if there are any files already uploaded
   clsUploads::ListUnrecorded();
   // display the upload form
   echo zen_draw_form('img_bulk_upload',CUSTOM_MENU_MODULE,,'post','enctype="multipart/form-data"');

echo '

'; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo '
Image zipfile:'.zen_draw_file_field('upload_file',true).'
Make a note of what the upload is for:
Description:'.zen_draw_input_field('upload_descr').'
<input type="submit" name="action" value="'.CUSTOM_MODULE_BTN_UPLOAD.'"> (Please be patient...)

';

   echo '</form>';
 }
 if ($show_img_assign_form) {
   require_once('../../w/extract.php');
   if ($idImg) {
     // show single-image edit form
     $objImg = clsUploadFiles::File_fromID($idImg);
     echo $objImg->HTML('align=left');

echo '

';
     echo $objImg->AutoDescrHTML('
'); echo zen_draw_form('img_edit', CUSTOM_MENU_MODULE);
echo '
<input type="submit" name="action" value="'.CUSTOM_MODULE_BTN_DELETE_FILE.'">';
     $sql = 'select p.products_id, pd.products_name from products AS p LEFT JOIN products_description AS pd ON pd.products_id=p.products_id WHERE (p.products_image IS NULL) AND (pd.products_name IS NOT NULL) ORDER BY pd.products_name';
     $qry = $db->Execute($sql);
     $idx = 0;
     if ($qry->RecordCount()) {
       while (!$qry->EOF) {
         $arrProd[$idx]['id'] = $qry->fields['products_id'];
         $arrProd[$idx]['text'] = $qry->fields['products_name'];
         $qry->MoveNext();
         $idx++;
       }
echo '
';
       echo zen_draw_hidden_field('img-id',$idImg);
       echo zen_draw_pull_down_menu('prod-id',$arrProd,$idProd);
       echo '
' .'<input type="submit" name="action" value="'.CUSTOM_MODULE_BTN_ASSIGN_IMG.'">' .'<input type="submit" name="action" value="'.CUSTOM_MODULE_BTN_VIEW_PROD.'">';

// echo zen_draw_checkbox_field('in-new-window',,true); // echo 'open product in new window';

echo '

';

     } else {
       echo 'There are currently no unassigned products.';
     }
   } else {
     echo getWikiPage('Embed:menu:Import.assign');
     // show gallery of unassigned thumbnails
     clsUploads::ListAvail();
   }
 }

?>

<?php require(DIR_WS_INCLUDES . 'footer.php'); ?>
</body> </html> <?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 categories
echo ''.$objTitle->TableRowCells().''; } } if ($ctrSuppNew) { $htmlSuppList = ': '.clsSuppliers::DoListNew('','',', '); $htmlSuppList .= ' OLD: '.clsSuppliers::DoListOld('','',', '); } if ($ctrCatgNew) { $htmlCatgList = ': '.clsCategories::DoListNew('','',', '); $htmlCatgList .= ' OLD: '.clsCategories::DoListOld('','',', '); } echo '
Data Entry Status
CatgIDTitleSupplierPriceSupplierTitleCategory

'; 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::SaveImport($iCommit).'
'; echo 'Adding categories: '.clsCategories::SaveImport($iCommit).'
'; echo 'Adding titles: '.clsTitles::SaveImport($iCommit).'
';

} function MakeKey($iStr) {

 return preg_replace('/[ -\.,;]*/',,strtolower($iStr));

} function FieldDate() { // ACTION: Returns a date formatted suitably for a datetime field in a database

 return '"'.date('Y-m-d H:i:s').'"';

} /*

===== CLASSES =====
  • /

class clsUploads {

 public function AddNew() {
   $obj = new clsUpload;
   $obj->Start();
   return $obj;
 }
 public function ListUnrecorded() {

// PURPOSE: Display a list of uploaded files not yet registered // This would happen either when a web-based upload got interrupted, // or if we had to FTP a file because the web-based upload takes too long

// get a listing of all files in the bulk-upload area:

   $fpBulkUpload = clsUploads::PathToBulkUpload();

// $fpBulkUpload = '/hsphere/local/home/hypertwi/thejubileestore.com/shop/images/bulk';

   $lstFiles = dirlist($fpBulkUpload);
   $cntKnown = 0; $cntNew = 0;
   if (count($lstFiles)) {

$out = 'Loose files found in bulk upload area:

    '; foreach ($lstFiles as $objFile) { // $objFile = new clsUploadFile; // $objFile->MakeSpec($this,$strFSpec); if (clsUploadFiles::File_isKnown($objFile->SpecRel())) { $cntKnown++; } else { $cntNew++; if ($objFile->pathRel) { $strSpec = $objFile->pathRel.'/'; } else { $strSpec = ; } $strSpec .= $objFile->name; $strParam = '?set='.CUSTOM_MODULE_SET_BULK_UPLOAD.'&file='.urlencode($strSpec).'&action='; $out .= '
  • '.$strSpec; $out .= ' ' .'[<a href="'.$strParam.CUSTOM_MODULE_ACT_LOOSE_DEL.'">delete</a>]' .'[<a href="'.$strParam.CUSTOM_MODULE_ACT_LOOSE_EXT.'">extract</a>]' .'[<a href="'.$strParam.CUSTOM_MODULE_ACT_LOOSE_VIEW.'">view</a>]'; } } if ($cntKnown) { if ($cntKnown == 1) { $out .= '
  • '.$objFile->name; if ($objFile->pathRel != ) { $out .= ' in ['.$objFile->pathRel.']'; } $out .= ' (previously extracted)'; } else { $out .= '
  • '.$cntKnown.' previously extracted files'; } } $out .= '

';

     if ($cntNew) {
       echo $out;
     }
   }
 }
 public function ListAvail() {

// PURPOSE: Display a list of unassigned images

   global $db;
   global $intOpt_MaxThumbs;
   $sql = 'SELECT * FROM '.TABLE_CUSTOM_UPLOAD_FILES.' WHERE (when_deleted IS NULL) AND (id_prod IS NULL)';
   $qry = $db->Execute($sql);
   $intCount = $qry->RecordCount();
   if ($intCount) {
     echo 'There are '.$intCount.' image'.Pluralize($intCount).' currently unassigned';
     if ($intOpt_MaxThumbs < $intCount) {
       $sql .= ' LIMIT '.$intOpt_MaxThumbs;
       $qry = $db->Execute($sql);
       echo '; showing the first '.$intOpt_MaxThumbs.'';
     }
     echo ':
';
     while (!$qry->EOF) {

$objImg = new clsUploadFile();

       $objImg->LoadFields($qry);
       $objThumb = new clsUploadThumb();
       $objThumb->Make($objImg, 0, 100);
       if ($objThumb->error) {
         echo $objThumb->status;
       } else {
         $strHTML = $objThumb->HTML();
         echo $strHTML;
       }
       $qry->MoveNext();
     }

// echo '';

   } else {
     require_once('../../w/extract.php');
     echo getWikiPage('Embed:menu:Import.assign.no-files');

// echo 'No unassigned files to show.';

   }
 }
 public function PathToBulkUpload() {
   return DIR_FS_CATALOG_IMAGES.'bulk/';

// return '../images/bulk/';

 }
 public function URLToBulkUpload() {
   return DIR_WS_CATALOG_IMAGES.'bulk/';
 }

}

class clsUpload {

 public $ID;
 public $idAdmin;	// ID of admin doing the upload
 public $filename;	// name of bulk upload file (zipfile or tarball)
 public $tempname;	// local temporary filename
 public $comment;	// admin comment for this upload
 public $status;	// status string (not stored)

/* NOT USED

 public function LoadRecord($iData) {
   $this->ID = $iData->fields['id'];
   $this->idAdmin = $iData->fields['id_admin'];
   $this->filename = $iData->fields['filename'];
   $this->comment = $iData->fields['comment'];
 }
  • /
 public function Start() {
   global $db;

// fetch values from global arrays

   $this->filename = $_FILES['upload_file']['name'];
   $this->comment = $_POST['upload_descr'];
   $this->tempname = $_FILES['upload_file']['tmp_name'];
   echo 'Uploading file ['.$this->filename.'], description ['.$this->comment.']...';

// echo '_FILES:'; // var_dump($_FILES); // echo '_POST:'; // var_dump($_POST); // echo 'TEST=['.$_FILES['upload_file']['tmp_name'].']';

   $this->DoRecord();
 }
 public function Start_fromLoose($iFileName,$iComment) {
   $this->filename = $iFileName;
   $this->comment = $iComment;
   $this->tempname = ; // not applicable
   $this->DoRecord();
 }
 private function DoRecord() {
   global $db;
   $this->idAdmin = $_SESSION['admin_id'];
   $sqlComment = mysql_real_escape_string($this->comment);
   $sqlFilename = mysql_real_escape_string($this->filename);
   $sqlTempname = mysql_real_escape_string($this->tempname);

// log beginning of the upload

   $sqlAdd = 'INSERT INTO '.TABLE_CUSTOM_UPLOADS.' (id_admin,when_started,filename,comment) '

.'VALUES(' .$this->idAdmin.',' // ID of current administrator .FieldDate().',' // current timestamp .'"'.$sqlFilename.'",' .'"'.$sqlComment.'");';

   $db->Execute($sqlAdd);
   $this->ID = mysql_insert_id();
   $this->status = mysql_info();
 }
 public function UnzipUpload() {

// ACTION: // * Moves a PHP-uploaded file into the bulk upload area, with a unique name // * Calls UnzipArchive() to unzip the file // USAGE: PHP bulk upload function should call: // * Start() to set up values and log the new upload (clsUploads::AddNew() also creates the object for you) // * UnzipUpload() to move the temp file into a normal folder, and extract the files // * Finish() to record the timestamp when extraction completed // To properly record non-PHP-uploaded archives: // * Start_fromLoose() to set up values and log the new archive // * UnzipArchive() to extract the files // * Finish() same as above

// * Move the temporary upload file over to the bulk uploads area:

   global $db;
   //$fpBulkUpload = DIR_FS_CATALOG_IMAGES.'bulk/';
   $fpBulkUpload = clsUploads::PathToBulkUpload();
   $fnBulkUpload = 'upload-'.$this->idAdmin.'.zip';	// unique filename for each admin
   $fsBulkUpload = $fpBulkUpload.$fnBulkUpload;
   echo '
Moving ['.$this->tempname.'] to ['.$fsBulkUpload.']...';

// do the actual move

   move_uploaded_file($this->tempname,$fsBulkUpload);
   echo ' copied.
Unpacking...
';

// unzip the file and save results in permanent location:

   $this->UnzipArchive($fnBulkUpload);
 }
 public function UnzipArchive() {
   $fpBulkUpload = clsUploads::PathToBulkUpload();
   $fnBulkUpload = $this->filename;

echo '

';
    system('cd "'.$fpBulkUpload.'";tar -xvvzf "'.$fnBulkUpload.'"',$intErr);
    echo '

';

   if ($intErr) {
     echo 'Some kind of error was encountered while extracting the files. (code='.$intErr.')
'; } else { unlink($fsBulkUpload); // delete the zipfile, now that everything is extracted

echo '
Changing file permissions...

';
      system('chmod -vR 777 '.$fpBulkUpload.'*');
      echo '


Files found in bulk upload area:

    ';

    // get a listing of all bulk-uploaded files:

         $lstFiles = dirlist($fpBulkUpload);
         foreach ($lstFiles as $objFile) {
           $objFileUp = new clsUploadFile;
    

    $objFileUp->MakeSpec($this,$objFile->SpecRel());

         }
    
    echo '

';

   }
 }
 public function Finish() {
   global $db;
   $sqlDone = 'UPDATE '.TABLE_CUSTOM_UPLOADS.' SET when_finished='.FieldDate().' WHERE id="'.$this->ID.'"';
   $db->Execute($sqlDone);
   $this->status = mysql_info();
 }
 public function FileSpec() {
   return clsUploads::PathToBulkUpload().$this->filename;
 }

}

class clsUploadFiles {

 public function File_fromID($iID) {
   global $db;
   $idSafe = sprintf('%u',$iID);
   $sql = 'SELECT * FROM '.TABLE_CUSTOM_UPLOAD_FILES.' WHERE id='.$idSafe;
   $qry = $db->Execute($sql);
   if ($qry->RecordCount()) {
     $obj = new clsUploadFile;
     $obj->LoadFields($qry);
     return $obj;
   }
 }
 public function File_isKnown($iName) {
   global $db;
   $sql = 'SELECT * FROM '.TABLE_CUSTOM_UPLOAD_FILES.' WHERE filespec="'.$iName.'"';
   $qry = $db->Execute($sql);
   return ($qry->RecordCount());
 }

}

class clsUploadFile {

 public $ID;
 public $ID_Upload;
 public $filespec;
 public $ID_Prod;
 private $strAutoDescr;
 public $width, $height;
 public $status;
 private $objUpload;
 public function MakeSpec($iUpload,$iSpec) {
   global $db;
   $this->objUpload = $iUpload;
   $this->filespec = $iSpec;
   $strFileSpec = $this->FileSpec();

// echo 'ISPEC='.$iSpec.' FULL SPEC='.$strFileSpec.'
';

   $imgArr = getimagesize($strFileSpec);
   $sqlFSpec = mysql_real_escape_string($this->filespec);
   $this->width = $imgArr[0];
   $this->height = $imgArr[1];

echo '

  • '.$this->filespec; if ($this->width && $this->height) { $sql = 'SELECT * FROM '.TABLE_CUSTOM_UPLOAD_FILES.' WHERE filespec="'.$sqlFSpec.'"'; $qryFile = $db->Execute($sql); if ($qryFile->RecordCount()) { // existing record found; is it a deleted file? if ($qryFile->fields['when_deleted']) { // previously deleted file has just been uploaded again; un-delete it from the table: $sql = 'UPDATE '.TABLE_CUSTOM_UPLOAD_FILES.' SET ' .'when_deleted=NULL,' .'size_x='.$this->width.',' .'size_y='.$this->height.' WHERE id='.$qryFile->id; $db->Execute($sql); $this->status = mysql_info(); echo ' ...re-uploaded; was previously deleted by admin #'.$qryFile->fields['who_deleted'].' at '.$qryFile->fields['when_deleted']; } else { // existing record has not been deleted, so just report the duplication // Later: should probably update the record as above, since the existing file gets overwritten echo ' ...duplicate; ID='.$qryFile->fields['id']; } } else { // existing record not found; create it: $sql = 'INSERT INTO '.TABLE_CUSTOM_UPLOAD_FILES.' (id_upload,filespec,size_x,size_y) VALUES(' .$this->objUpload->ID.',' .'"'.$sqlFSpec.'",' .$this->width.',' .$this->height.');'; $db->Execute($sql); $this->status = mysql_info(); if ($this->status) { echo ' ...ID='.mysql_insert_id().' status='.$this->status.''; } else { echo ' ...ID='.mysql_insert_id().' (ok)'; } } } else { // imagesize returned zero pixels for width or height, so file is not an image echo ' ...not an image'; } } public function LoadFields($iData) { $this->ID = $iData->fields['id']; $this->ID_Upload = $iData->fields['id_upload']; $this->filespec = $iData->fields['filespec']; $this->ID_Prod = $iData->fields['id_prod']; } public function Save() { global $db; $sql = 'UPDATE '.TABLE_CUSTOM_UPLOAD_FILES.' SET ' .'when_deleted=NULL,' .'filespec="'.mysql_real_escape_string($this->filespec).'",' .'size_x='.(int)$this->width.',' .'size_y='.(int)$this->height.',' .'id_prod='.(int)$this->ID_Prod .' WHERE id='.$this->ID; $db->Execute($sql); } public function FileSpec() { return clsUploads::PathToBulkUpload().$this->filespec; } public function FileExt() { $path_parts = pathinfo($this->filespec); return $path_parts['extension']; } public function MakeThumb($iWidth,$iHeight) { $objThumb = new clsUploadThumb; $objThumb->Create($this, $iWidth,$iHeight); return $objThumb; } public function AutoDescr() { if ($strAutoDescr == ) { $strFileSpec = wfEscapeShellArg($this->FileSpec()); $cmd = 'identify -format "%f ... %ww x %hh (x %q bits) ... %b" '.$strFileSpec; $strAutoDescr = exec($cmd); } return $strAutoDescr; } public function AutoDescrHTML($iSep) { $strFileSpec = wfEscapeShellArg($this->FileSpec()); $cmd = 'identify -format "file: %f'.$iSep.'%ww x %hh (x %q bits)'.$iSep.'%b" '.$strFileSpec; $strDescr = exec($cmd); return $strDescr; } public function URL() { return clsUploads::URLToBulkUpload().$this->filespec; } public function HTML($iHTMLAttr) { return '<img '.$iHTMLAttr.' src="'.$this->URL().'" title="'.$this->AutoDescr().'">'; } public function Delete() { // ACTION: Deletes the current image file and all associated thumbnails global $db; $fn = $this->filespec; $fs = $this->FileSpec(); echo '
    Deleting thumbnails for ['.$fn.']'; // Delete the thumbnails: clsUploadThumbs::DelImgThumbs($this->ID); // Delete the master image file: echo '
    Deleting file ['.$fn.']'; if (is_file($fs)) { unlink($fs); echo '...ok'; } else { echo '...FILE NOT FOUND'; } // Mark the file as deleted: $sql = 'UPDATE '.TABLE_CUSTOM_UPLOAD_FILES.' SET' .' when_deleted='.FieldDate() .',who_deleted='.$_SESSION['admin_id'] .' WHERE id='.$this->ID; $db->Execute($sql); } } class clsFile { public $name; public $path; public $pathRel; public function Init($iPath,$iName) { $this->name = $iName; $this->path = $iPath; $this->pathRel = $iPathRel; } public function InitSpec($iSpec,$iPathRel) { $arrPath = pathinfo($iSpec); $this->name = $arrPath['basename']; $this->path = $arrPath['dirname']; $this->pathRel = $iPathRel; } public function Spec() { return $this->path.$this->name; } public function SpecRel() { if ($this->pathRel) { $strPath = $this->pathRel.'/'; } return $strPath.$this->name; } } function dirlist($iDir,$iPathRel=) { // foreach(scandir($dir) as $entry) { $d = dir($iDir); while (false !== ($entry = $d->read())) { if($entry != '.' && $entry != '..') { $entry = $iDir.'/'.$entry; if(is_dir($entry)) { $path = pathinfo($entry); $subDir = dirlist($entry,$iPathRel.$path['basename']); if (is_array($listarray)) { if (is_array($subDir)) { $listarray = array_merge($listarray,$subDir); } } else { $listarray = $subDir; } } else { $path = pathinfo($entry); $objFile = new clsFile; // $objFile->Init($path['basename'],$entry); $objFile->InitSpec($entry,$iPathRel); // $listarray[] = $ipath.'/'.$path['basename']; $listarray[] = $objFile; } } } $d->close(); return($listarray); } class clsUploadThumbs { public function Path() { return DIR_FS_CATALOG_IMAGES.'thumbs/'; // return '../images/thumbs/'; } public function URL() { return DIR_WS_CATALOG_IMAGES.'thumbs/'; } public function ImgThumbs($iImgID) { global $db; $sql = 'SELECT * FROM '.TABLE_CUSTOM_UPLOAD_THUMBS.' WHERE id_file='.$iImgID; $qry = $db->Execute($sql); if ($qry->RecordCount()) { while (!$qry->EOF) { $obj = new clsUploadThumb; $obj->LoadFields($qry); $arr[$obj->ID]=$obj; // $arr[]=$obj; $qry->MoveNext(); } return $arr; } } public function DelImgThumbs($iImgID) { $arrThumbs = self::ImgThumbs($iImgID); if (is_array($arrThumbs)) { foreach ($arrThumbs as $objThumb) { $fn = $objThumb->filename; $fs = $objThumb->FileSpec(); echo '
    - deleting thumbnail ['.$fn.']'; if (is_file($fs)) { $objThumb->Delete(); if ($objThumb->status) { echo '...ok'; } else { echo '...ERROR'; } } else { echo '...FILE NOT FOUND'; } } } else { echo '
    No thumbnails to delete.'; } } } class clsUploadThumb { public $ID; public $ID_File; public $error; public $filename; public $width; public $height; public $request; public $status; public $when_made; private $objFile; private $pxReqX,$pxReqY; public function LoadFields($iData) { $this->ID = $iData->fields['id']; $this->ID_file = $iData->fields['id_file']; $this->filename = $iData->fields['filename']; $this->width = $iData->fields['size_x']; $this->height = $iData->fields['size_y']; $this->request = $iData->fields['request']; $this->when_made = $iData->fields['when_made']; } public function Make($iFile, $iWidth, $iHeight) { // ACTION: Initializes the object and, if necessary, creates the thumb file global $db; global $wgImageMagickConvertCommand; $kTempFile = clsUploadThumbs::Path().'temp.tmp'; $this->objFile = $iFile; $this->filename = $this->FileName(); $this->pxReqX = $iWidth; $this->pxReqY = $iHeight; // check database for a matching thumbnail // $sql = 'SELECT * FROM '.TABLE_CUSTOM_UPLOAD_THUMBS.' WHERE filename="'.$this->FileName().'"'; $sql = 'SELECT * FROM '.TABLE_CUSTOM_UPLOAD_THUMBS.' WHERE request="'.$this->MatchStr().'"'; //echo 'SQL=['.$sql.']
    '; $qry = $db->Execute($sql); if ($qry->RecordCount()) { // found; load record $this->status = 'found'; $this->LoadFields($qry); //echo " - FOUND"; } else { // not found; create record and thumbnail $strFileSpec = wfEscapeShellArg($this->objFile->FileSpec()); $strThumbSpec = wfEscapeShellArg($this->FileSpec()); // $cmd = $wgImageMagickConvertCommand.' '.$strFileSpec.' -quality 80 -thumbnail "'.$iOption.'" -depth 8 '.$strThumbSpec; $cmd = 'convert '.$strFileSpec.' -quality 80 -thumbnail "'.$this->GeomStrReq().'>" -depth 8 '.$kTempFile; system ( $cmd,$retval ); $this->error = $retval; if ($retval) { $this->status = '
    Command ['.$cmd.'] failed; error code = '.$retval; } else { $imgArr = getimagesize($kTempFile); //echo 'Getting size of ['.$this->FileSpec().']'; $this->width = $imgArr[0]; $this->height = $imgArr[1]; $this->filename = $this->FileName(); rename($kTempFile,$this->FileSpec()); $sql = 'INSERT INTO '.TABLE_CUSTOM_UPLOAD_THUMBS.' (id_file,filename,size_x,size_y,request,when_made) VALUES(' .$this->objFile->ID.', ' .'"'.$this->filename.'", ' .$this->width.', ' .$this->height.', ' .'"'.$this->MatchStr().'", ' .FieldDate().')'; $qry = $db->Execute($sql); $this->ID = mysql_insert_id(); $this->status = 'ok'; } } return $retval; } public function HTML() { return '<a href="?set='.CUSTOM_MODULE_SET_BULK_ASSIGN.'&img-id='.$this->objFile->ID.'"><img src="'.$this->FileURL($iAffix).'" title="'.$this->objFile->AutoDescr().'"></a>'; } public function FileName() { return $this->objFile->ID.'-'.$this->GeomStrReal().'.'.$this->objFile->FileExt(); } public function FileSpec() { return clsUploadThumbs::Path().$this->filename; } public function FileURL() { return clsUploadThumbs::URL().$this->filename; } private function GeomStrReal() { return GeomStr($this->width,$this->height); } private function GeomStrReq() { return GeomStr($this->pxReqX,$this->pxReqY); } private function MatchStr() { return $this->objFile->ID.'-'.$this->pxReqX.'x'.$this->pxReqY; } public function Delete() { // ACTION: Deletes the thumbnail file and the associated record global $db; // remove the record $sql = 'DELETE FROM '.TABLE_CUSTOM_UPLOAD_THUMBS.' WHERE id='.$this->ID; $db->Execute($sql); // delete the file $this->status = unlink($this->FileSpec()); } } function GeomStr($iWidth,$iHeight) { if ($iWidth) { $strOut = $iWidth; } $strOut .= 'x'; if ($iHeight) { $strOut .= $iHeight; } return $strOut; } 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 SaveImport($iCommit) { global $db; $result = '
      '; foreach (self::Records()->List as $obj) { $result .= $obj->SaveImport($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;
       }
     }
     public function Item($iID) {
       global $db;
    
       $sql = 'SELECT * FROM '.TABLE_PRODUCTS.' WHERE products_id='.(int)$iID;
       $qry = $db->Execute($sql);
       if ($qry->RecordCount()) {
         $objItem = new clsTitle();
         $objItem->LoadFields($qry);
         return $objItem;
       }
     }
    

    }

    class clsTitle {

     private $intID;
     public $price;
     public $supplier;
     public $category;	// master category
    

    // import fields

     public $ImportKey;
     public $Name;
     public $SuppImp;
     public $CatgImp;
     public $isCatg;
    

    // -- calculated fields

     public $ISBN;
     public $ISBN_URL;
     public $HtmlName;
    

    // -- status fields

     public $Status;
     public $isFound;
    

    // stuff for catalog viewing:

     public $model;
     public $image;
    

    // -- object cache

     private $objDescr;
    
     public function ID() {
       if (!isset($this->intID)) {
         $this->UpdateName();
       }
    

    //echo 'TITLE ID='.$this->intID;

       return $this->intID;
     }
    

    // == DISPLAY FUNCTIONS

     public function Load() {
       global $db;
    
       $sql = 'SELECT * FROM '.TABLE_PRODUCTS.' WHERE products_id='.$this->intID;
       $qry = $db->Execute($sql);
       if ($qry->RecordCount()) {
         $this->LoadFields($qry);
       }
     }
     public function Save() {
       global $db;
    
       $sql = 'UPDATE '.TABLE_PRODUCTS.' SET '
         .'products_model="'.mysql_real_escape_string($this->model).'"'
         .',products_image="'.mysql_real_escape_string($this->image).'"'
         .',products_price="'.mysql_real_escape_string($this->price).'"'
         .',manufacturers_id='.(int)$this->supplier
         .',master_categories_id='.(int)$this->category
         .' WHERE products_id='.(int)$this->intID;
       $db->Execute($sql);
    

    //echo 'SQL=['.$sql.']';

     }
     public function LoadFields($iData) {
       $this->isFound = true;
       $this->intID = $iData->fields['products_id'];
       $this->model = $iData->fields['products_model'];
       $this->image = $iData->fields['products_image'];
       $this->price = $iData->fields['products_price'];
       $this->supplier = $iData->fields['manufacturers_id'];;
       $this->category = $iData->fields['master_categories_id'];
    

    echo 'LOADING: Price='.$this->price;

     }
     public function DescrObj() {
       if (is_null($objDescr)) {
         $objDescr = clsProdDescrs::Item($this->intID);
       }
       return $objDescr;
     }
     public function HTML_Links() {
       $id = $this->intID;
       $out = '[<a href="/shop/admin/product.php?read=only&action=new_product_preview&pID='.$id.'">preview</a>]';
       $out .= ' [<a href="/shop/admin/product.php?action=new_product&pID='.$id.'">edit</a>]';
       $out .= ' [<a href="/shop/index.php?main_page=product_info&products_id='.$id.'">shop</a>]';
       return $out;
     }
     public function HTML() {
       global $db;
    

    // make HTML for basic product info:

       if ($this->image) {
         $out = '<img src="'.DIR_WS_CATALOG_IMAGES.$this->image.'" align=left>';
       }
       $id = $this->intID;
       $out = 'Product ID: '.$id;
       $out .= ' '.$this->HTML_Links();
       $out .= '
    ';

    // add HTML for current language-description:

       $objDescr = clsProdDescrs::Item($this->intID);
       $out .= $objDescr->HTML();
       return $out;
     }
    

    // == IMPORT FUNCTIONS

     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 SaveImport($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 .= '
  • SQL: '.$sqlAdd; if ($iCommit) { $db->Execute($sqlAdd); $result .= '
  • main products table status: '.mysql_info(); $this->intID = mysql_insert_id(); $result .= '
  • ID: '.$this->intID; } else { $this->intID = 0; } // Update product import table: $sqlAdd = 'INSERT INTO '.TABLE_CUSTOM_IMPORT_PROD.' (import_key,prod_key) VALUES("'.mysql_real_escape_string($this->ImportKey).'",'.$this->ID().')'; $result .= '
  • SQL: '.$sqlAdd; if ($iCommit) { $db->Execute($sqlAdd); $result .= '
  • products import table status: '.mysql_info(); } // Update PRODUCTS_DESCRIPTION: $sqlAdd = 'INSERT INTO '.TABLE_PRODUCTS_DESCRIPTION.' (products_id,products_name) VALUES('.$this->ID().',"'.mysql_real_escape_string($this->Name).'")'; $result .= '
  • SQL: '.$sqlAdd; if ($iCommit) { $db->Execute($sqlAdd); $result .= '
  • products description status: '.mysql_info(); } // Update PRODUCT CATEGORIES: $sqlAdd = 'INSERT INTO '.TABLE_PRODUCTS_TO_CATEGORIES.' (products_id,categories_id) VALUES('.$this->ID().','.$this->category->ID().')'; $result .= '
  • SQL: '.$sqlAdd; if ($iCommit) { $db->Execute($sqlAdd); $result .= '
  • products description status: '.mysql_info(); } } else { $result = '
  • Warning: product ['.$this->Name.'] has no price set ('.$this->price.'); skipping.'; } return $result; } } public function TableRowCells() { $out = ''.$this->category->Name.''.$this->ImportKey.''.$this->HtmlName.'';
       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 clsProdDescrs {

     public function Item($iProd) {
       global $db;
    
       $idLang = clsLanguages::Current()->id;
       $sql = 'SELECT * FROM '.TABLE_PRODUCTS_DESCRIPTION.' WHERE products_id='.(int)$iProd.' AND language_id='.(int)$idLang;
       $qry = $db->Execute($sql);
       if ($qry->RecordCount()) {
         $objItem = new clsProdDescr();
         $objItem->LoadFields($qry);
         return $objItem;
       }
     }
    

    }

    class clsProdDescr {

     public $id_prod;
     private $objProd;
     public $id_lang;
     public $name;
     public $descr;
     public $URL;
     
     public function LoadFields($iData) {
       $this->id_prod = $iData->fields['products_id'];
       $this->id_lang = $iData->fields['language_id'];
       $this->name = $iData->fields['products_name'];
       $this->descr = $iData->fields['products_description'];
       $this->URL = $iData->fields['products_url'];
     }
     public function HTML() {
       $out = 'Name: '.$this->name.'
    '; if ($this->descr) { $out .= 'Description: '.$this->descr.'
    '; } else { $out .= 'No description
    '; } return $out; }

    }

    class clsLanguages {

     public function Current() {
       global $db;
    
       $strLang = $_SESSION['language'];
       $sql = 'SELECT * FROM '.TABLE_LANGUAGES.' WHERE directory="'.$strLang.'"';
       $qry = $db->Execute($sql);
       if ($qry->RecordCount()) {
         $obj = new clsLanguage;
         $obj->LoadFields($qry);
         return $obj;
       }
     }
    

    }

    class clsLanguage {

     public $id;
     public $name;
    
     public function LoadFields($iData) {
       $this->id = $iData->fields['languages_id'];
       $this->name = $iData->fields['name'];
     }
    

    }

    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 SaveImport($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 SaveImport($iCommit) {
       foreach (self::$Records->List as $obj) {
         if (!$obj->isFound) {
           $sqlOut .= $obj->SaveImport($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 SaveImport($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>