Difference between revisions of "ZenCart data import - admin/custom menu.php"
m (→Navigation: it's actually an underline) |
(→Source: update: image assignment now working) |
||
| (One intermediate revision by the same user not shown) | |||
| Line 1: | Line 1: | ||
==Navigation== | ==Navigation== | ||
| − | [[computing]]: [[software]]: [[ZenCart]]: [[importing data into ZenCart|importing data]]: '''admin/custom_menu.php''' | + | [[computing]]: [[software]]: [[ZenCart]]: [[importing data into ZenCart|importing data]]: '''{{faint|$zc}}/admin/custom_menu.php''' |
==Overview== | ==Overview== | ||
| Line 38: | Line 38: | ||
require('includes/application_top.php'); | require('includes/application_top.php'); | ||
| − | |||
define('CUSTOM_MODULE_SAVE_DATA','save'); | define('CUSTOM_MODULE_SAVE_DATA','save'); | ||
define('CUSTOM_MODULE_PROD_DATA_NAME','products'); | define('CUSTOM_MODULE_PROD_DATA_NAME','products'); | ||
define('CUSTOM_MODULE_ACT_CHECK','check'); | define('CUSTOM_MODULE_ACT_CHECK','check'); | ||
define('CUSTOM_MODULE_ACT_COMMIT','commit'); | 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_CHECK','Preview Changes'); | ||
define('CUSTOM_MODULE_BTN_COMMIT','COMMIT'); | 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('URL_ISBN_SEARCH','http://www.abebooks.com/servlet/SearchResults?isbn=<<1>>'); | ||
| Line 52: | Line 62: | ||
define('TABLE_CUSTOM_IMPORT_PROD',DB_PREFIX.'custom_import_prod'); | define('TABLE_CUSTOM_IMPORT_PROD',DB_PREFIX.'custom_import_prod'); | ||
define('TABLE_CUSTOM_IMPORT_MFGRS',DB_PREFIX.'custom_import_mfgrs'); | 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 | // new item | ||
| Line 60: | Line 73: | ||
define('HTML_STATUS_EXISTS', '<font color="#006600">found</font>'); | define('HTML_STATUS_EXISTS', '<font color="#006600">found</font>'); | ||
| + | $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) { | switch ($button) { | ||
case CUSTOM_MODULE_BTN_CHECK: $action=CUSTOM_MODULE_ACT_CHECK; break; | 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_COMMIT: $action=CUSTOM_MODULE_ACT_COMMIT; break; | ||
| − | default: $action=''; | + | 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']; | ||
} | } | ||
| Line 113: | Line 140: | ||
<!-- body //--> | <!-- body //--> | ||
| − | |||
| − | |||
<!-- SET=<?php echo $set?> ACTION=<?php echo $action?> --> | <!-- SET=<?php echo $set?> ACTION=<?php echo $action?> --> | ||
<?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 "<b>Previewing entered data:</b>"; | |
| − | + | ProcessData(false); | |
| − | + | break; | |
| − | + | case CUSTOM_MODULE_ACT_COMMIT: | |
| − | + | $show_data_entry_form = 1; | |
| + | echo "<b>Saving entered data:</b>"; | ||
| + | $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 '<b>Deleting image</b> ['.$objFile->filespec.'] (ID='.$idImg.')...'; | ||
| + | $objFile->Delete(); | ||
| + | echo '<hr>'; | ||
| + | // clear image so we go back to the list of unassigned images: | ||
| + | unset($idImg); | ||
| + | $doSet = true; | ||
| + | break; | ||
| + | case CUSTOM_MODULE_ACT_ASSIGN: | ||
| + | echo '<span class="pageHeading">Assigning displayed image to the displayed product</span><p>'; | ||
| + | $objProd = clsTitles::Item($idProd); | ||
| + | $objFile = clsUploadFiles::File_fromID($idImg); | ||
| + | echo 'Assigning image [<b>'.$objFile->filespec.'</b>] to product ID='.$idProd.' [<b>'.$objProd->DescrObj()->name.'</b>] '.$objProd->HTML_Links().'<br>'; | ||
| + | $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 '<span class="pageHeading">Viewing image, with unassigned product information</span><p>'; | ||
| + | $objProd = clsTitles::Item($idProd); | ||
| + | echo $objProd->HTML(); | ||
| + | echo '<hr>'; | ||
| + | $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 [<b>'.$strFileSpec.'</b>]...'; | ||
| + | if (unlink($strFileSpec)) { | ||
| + | echo 'ok'; | ||
| + | } else { | ||
| + | echo '<font color=red>error!</font>'; | ||
| + | } | ||
| + | echo '<hr>'; | ||
} | } | ||
| + | $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 '<big>Viewing <b>'.$strFileName.'</b>:</big><br>'; | ||
| + | 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 | check: data is being submitted for preview | ||
commit: data is being submitted for final commit (update database) | 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 "<b>Sorry, this function ($set) is not implemented yet!</b>"; | ||
| + | if ($action) { | ||
| + | echo "<br>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) { | |
| − | |||
| − | if ( | ||
$htmlSep = '<font color="#7f7f7f"><tab></font>'; | $htmlSep = '<font color="#7f7f7f"><tab></font>'; | ||
echo zen_draw_form('prod_entry', CUSTOM_MENU_MODULE); | echo zen_draw_form('prod_entry', CUSTOM_MENU_MODULE); | ||
| Line 164: | Line 288: | ||
echo '</td></tr></table></center>'; | echo '</td></tr></table></center>'; | ||
echo '</form>'; | 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 '<center><table>'; | ||
| + | echo '<tr>'; | ||
| + | echo '<td align=right>Image zipfile:</td>'; | ||
| + | echo '<td>'.zen_draw_file_field('upload_file',true).'</td>'; | ||
| + | echo '</tr>'; | ||
| + | echo '<tr>'; | ||
| + | echo '<tr><td colspan=2><small>Make a note of what the upload is for:</small></td></tr>'; | ||
| + | echo '<td align=right>Description:</td>'; | ||
| + | echo '<td>'.zen_draw_input_field('upload_descr').'</td>'; | ||
| + | echo '</tr>'; | ||
| + | echo '<tr><td><input type="submit" name="action" value="'.CUSTOM_MODULE_BTN_UPLOAD.'"></td><td> (Please be patient...)</td></tr>'; | ||
| + | echo '</table></center>'; | ||
| + | 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 '<table><tr><td>'; | ||
| + | echo $objImg->AutoDescrHTML('<br>'); | ||
| + | echo zen_draw_form('img_edit', CUSTOM_MENU_MODULE); | ||
| + | echo '<hr><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 '<hr>'; | ||
| + | echo zen_draw_hidden_field('img-id',$idImg); | ||
| + | echo zen_draw_pull_down_menu('prod-id',$arrProd,$idProd); | ||
| + | echo '<br>' | ||
| + | .'<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 '</td></tr></table>'; | ||
| + | } else { | ||
| + | echo 'There are currently no unassigned products.'; | ||
| + | } | ||
| + | } else { | ||
| + | echo getWikiPage('Embed:menu:Import.assign'); | ||
| + | // show gallery of unassigned thumbnails | ||
| + | clsUploads::ListAvail(); | ||
| + | } | ||
} | } | ||
?> | ?> | ||
| Line 226: | Line 410: | ||
.'<li><b>'.$ctrCatgFnd.'</b> categor'.Pluralize($ctrCatgFnd,'y','ies').' in import, <b>'.$ctrCatgNew.'</b> new'.$htmlCatgList | .'<li><b>'.$ctrCatgFnd.'</b> categor'.Pluralize($ctrCatgFnd,'y','ies').' in import, <b>'.$ctrCatgNew.'</b> new'.$htmlCatgList | ||
.'</ul>'; | .'</ul>'; | ||
| − | echo '<b>Adding suppliers</b>: '.clsSuppliers:: | + | echo '<b>Adding suppliers</b>: '.clsSuppliers::SaveImport($iCommit).'<br>'; |
| − | echo '<b>Adding categories</b>: '.clsCategories:: | + | echo '<b>Adding categories</b>: '.clsCategories::SaveImport($iCommit).'<br>'; |
| − | echo '<b>Adding titles</b>: '.clsTitles:: | + | echo '<b>Adding titles</b>: '.clsTitles::SaveImport($iCommit).'<br>'; |
} | } | ||
function MakeKey($iStr) { | function MakeKey($iStr) { | ||
return preg_replace('/[ -\.,;]*/','',strtolower($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 ===== | ===== 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:<ul>'; | ||
| + | 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 .= '<li>'.$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 .= '<li>'.$objFile->name; | ||
| + | if ($objFile->pathRel != '') { | ||
| + | $out .= ' in ['.$objFile->pathRel.']'; | ||
| + | } | ||
| + | $out .= ' (previously extracted)'; | ||
| + | } else { | ||
| + | $out .= '<li>'.$cntKnown.' previously extracted files'; | ||
| + | } | ||
| + | } | ||
| + | $out .= '</ul><hr>'; | ||
| + | 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 <b>'.$intCount.'</b> image'.Pluralize($intCount).' currently unassigned'; | ||
| + | if ($intOpt_MaxThumbs < $intCount) { | ||
| + | $sql .= ' LIMIT '.$intOpt_MaxThumbs; | ||
| + | $qry = $db->Execute($sql); | ||
| + | echo '; showing the first <b>'.$intOpt_MaxThumbs.'</b>'; | ||
| + | } | ||
| + | echo ':<br>'; | ||
| + | |||
| + | 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 '</ul>'; | ||
| + | } 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 '<br>Moving ['.$this->tempname.'] to ['.$fsBulkUpload.']...'; | ||
| + | // do the actual move | ||
| + | move_uploaded_file($this->tempname,$fsBulkUpload); | ||
| + | echo ' copied.<br>Unpacking...<br>'; | ||
| + | // unzip the file and save results in permanent location: | ||
| + | $this->UnzipArchive($fnBulkUpload); | ||
| + | } | ||
| + | public function UnzipArchive() { | ||
| + | $fpBulkUpload = clsUploads::PathToBulkUpload(); | ||
| + | $fnBulkUpload = $this->filename; | ||
| + | |||
| + | echo '<pre>'; | ||
| + | system('cd "'.$fpBulkUpload.'";tar -xvvzf "'.$fnBulkUpload.'"',$intErr); | ||
| + | echo '</pre>'; | ||
| + | if ($intErr) { | ||
| + | echo 'Some kind of error was encountered while extracting the files. (code='.$intErr.')<br>'; | ||
| + | } else { | ||
| + | unlink($fsBulkUpload); // delete the zipfile, now that everything is extracted | ||
| + | echo '<br>Changing file permissions...<br><pre>'; | ||
| + | system('chmod -vR 777 '.$fpBulkUpload.'*'); | ||
| + | echo '</pre><br>Files found in bulk upload area:<br><ul>'; | ||
| + | // get a listing of all bulk-uploaded files: | ||
| + | $lstFiles = dirlist($fpBulkUpload); | ||
| + | foreach ($lstFiles as $objFile) { | ||
| + | $objFileUp = new clsUploadFile; | ||
| + | $objFileUp->MakeSpec($this,$objFile->SpecRel()); | ||
| + | } | ||
| + | echo '</ul>'; | ||
| + | } | ||
| + | } | ||
| + | |||
| + | 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.'<br>'; | ||
| + | |||
| + | $imgArr = getimagesize($strFileSpec); | ||
| + | $sqlFSpec = mysql_real_escape_string($this->filespec); | ||
| + | $this->width = $imgArr[0]; | ||
| + | $this->height = $imgArr[1]; | ||
| + | echo '<li>'.$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 ' ...<b>re-uploaded</b>; 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().' <b>status='.$this->status.'</b>'; | ||
| + | } else { | ||
| + | echo ' ...ID='.mysql_insert_id().' (ok)'; | ||
| + | } | ||
| + | } | ||
| + | } else { | ||
| + | // imagesize returned zero pixels for width or height, so file is not an image | ||
| + | echo ' ...<b>not an image</b>'; | ||
| + | } | ||
| + | } | ||
| + | |||
| + | 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 "<b>file:</b> %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 '<br>Deleting thumbnails for ['.$fn.']'; | ||
| + | // Delete the thumbnails: | ||
| + | clsUploadThumbs::DelImgThumbs($this->ID); | ||
| + | // Delete the master image file: | ||
| + | echo '<br>Deleting file ['.$fn.']'; | ||
| + | if (is_file($fs)) { | ||
| + | unlink($fs); | ||
| + | echo '...ok'; | ||
| + | } else { | ||
| + | echo '...<font color=red>FILE NOT FOUND</font>'; | ||
| + | } | ||
| + | // 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 '<br> - deleting thumbnail ['.$fn.']'; | ||
| + | if (is_file($fs)) { | ||
| + | $objThumb->Delete(); | ||
| + | if ($objThumb->status) { | ||
| + | echo '...ok'; | ||
| + | } else { | ||
| + | echo '...<font color=red>ERROR</font>'; | ||
| + | } | ||
| + | } else { | ||
| + | echo '...<font color=red>FILE NOT FOUND</font>'; | ||
| + | } | ||
| + | } | ||
| + | } else { | ||
| + | echo '<br>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.']<br>'; | ||
| + | $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 = '<br>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 { | class clsRecords { | ||
| Line 318: | Line 1,121: | ||
} | } | ||
| − | public function | + | public function SaveImport($iCommit) { |
global $db; | global $db; | ||
$result = '<ul>'; | $result = '<ul>'; | ||
foreach (self::Records()->List as $obj) { | foreach (self::Records()->List as $obj) { | ||
| − | $result .= $obj-> | + | $result .= $obj->SaveImport($iCommit); |
} | } | ||
$result .= '</ul>'; | $result .= '</ul>'; | ||
| Line 339: | Line 1,142: | ||
if (!isset(self::$objRecords)) { | if (!isset(self::$objRecords)) { | ||
self::$objRecords = new clsRecords; | 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; | ||
} | } | ||
} | } | ||
| Line 344: | Line 1,158: | ||
class clsTitle { | class clsTitle { | ||
| + | private $intID; | ||
| + | public $price; | ||
| + | public $supplier; | ||
| + | public $category; // master category | ||
| + | // import fields | ||
public $ImportKey; | public $ImportKey; | ||
| − | |||
public $Name; | public $Name; | ||
| − | |||
| − | |||
public $SuppImp; | public $SuppImp; | ||
| − | |||
public $CatgImp; | public $CatgImp; | ||
public $isCatg; | public $isCatg; | ||
| − | // calculated fields | + | // -- calculated fields |
public $ISBN; | public $ISBN; | ||
public $ISBN_URL; | public $ISBN_URL; | ||
public $HtmlName; | public $HtmlName; | ||
| − | // status fields | + | // -- status fields |
public $Status; | public $Status; | ||
public $isFound; | public $isFound; | ||
| − | // | + | // stuff for catalog viewing: |
| + | public $model; | ||
| + | public $image; | ||
| + | // -- object cache | ||
| + | private $objDescr; | ||
public function ID() { | public function ID() { | ||
| Line 369: | Line 1,188: | ||
return $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=[<b>'.$sql.'</b>]'; | ||
| + | } | ||
| + | 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 = '<b>Product ID</b>: '.$id; | ||
| + | $out .= ' '.$this->HTML_Links(); | ||
| + | $out .= '<br>'; | ||
| + | |||
| + | // add HTML for current language-description: | ||
| + | $objDescr = clsProdDescrs::Item($this->intID); | ||
| + | $out .= $objDescr->HTML(); | ||
| + | return $out; | ||
| + | } | ||
| + | // == IMPORT FUNCTIONS | ||
public function ImportLine($iLine) { | public function ImportLine($iLine) { | ||
global $db; | global $db; | ||
| − | list($ImportKeyRaw,$notUsed,$this->Name,$notUsed,$strSupplierName,$notUsed,$this-> | + | list($ImportKeyRaw,$notUsed,$this->Name,$notUsed,$strSupplierName,$notUsed,$this->price) = explode("\t",$iLine); |
//echo 'NAME='.$Name.'<br>'; | //echo 'NAME='.$Name.'<br>'; | ||
// Check to see if the title is actually a category record - price is 0, name is empty or contains "classification" | // Check to see if the title is actually a category record - price is 0, name is empty or contains "classification" | ||
$this->isCatg = false; | $this->isCatg = false; | ||
| − | if ($this-> | + | if ($this->price == 0.0) { |
if ((!MakeKey($this->Name)) || (eregi('classification',$this->Name))) { | if ((!MakeKey($this->Name)) || (eregi('classification',$this->Name))) { | ||
$this->isCatg = true; | $this->isCatg = true; | ||
| Line 391: | Line 1,273: | ||
} | } | ||
$this->SuppImp = clsSuppliers::Import($strSupplierName); | $this->SuppImp = clsSuppliers::Import($strSupplierName); | ||
| − | $this-> | + | $this->supplier = $this->SuppImp->supplier; |
// Parse out the category and title key | // Parse out the category and title key | ||
| Line 401: | Line 1,283: | ||
} | } | ||
$this->CatgImp = clsCategoryImports::Import($strCatg); | $this->CatgImp = clsCategoryImports::Import($strCatg); | ||
| − | $this-> | + | $this->category = $this->CatgImp->category; |
//echo 'CATG='.$strCatg.' stored='.$this->Category->Name.'<br>'; | //echo 'CATG='.$strCatg.' stored='.$this->Category->Name.'<br>'; | ||
| Line 440: | Line 1,322: | ||
} | } | ||
| − | public function | + | public function SaveImport($iCommit) { |
global $db; | global $db; | ||
| Line 447: | Line 1,329: | ||
} else { | } else { | ||
// Check for missing manufacturer: | // Check for missing manufacturer: | ||
| − | if (!$this-> | + | if (!$this->supplier->ID()) { |
echo '<b>MISSING SUPPLIER</b> for title "'.$this->Name.'"<br>'; | echo '<b>MISSING SUPPLIER</b> for title "'.$this->Name.'"<br>'; | ||
} | } | ||
| − | if (!$this-> | + | if (!$this->category->ID()) { |
echo '<b>MISSING CATEGORY</b> for title "'.$this->Name.'"<br>'; | echo '<b>MISSING CATEGORY</b> for title "'.$this->Name.'"<br>'; | ||
} | } | ||
// only insert items with a numerically valid price | // only insert items with a numerically valid price | ||
| − | if (is_numeric(trim($this-> | + | 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. | // Theory: MySQL defaults to using the first index as an auto-increment key. We'll see if this works. | ||
// Update main PRODUCTS table: | // Update main PRODUCTS table: | ||
| Line 461: | Line 1,343: | ||
.'VALUES(' | .'VALUES(' | ||
.'1,' // products_status (1 = active) | .'1,' // products_status (1 = active) | ||
| − | .$this-> | + | .$this->price.',' // products_price |
.'NOW(),' // products_date_added | .'NOW(),' // products_date_added | ||
| − | .$this-> | + | .$this->supplier->ID().',' // manufacturers_id |
| − | .$this-> | + | .$this->category->ID().')'; // master_categories_id |
$result .= '<li><b>SQL</b>: '.$sqlAdd; | $result .= '<li><b>SQL</b>: '.$sqlAdd; | ||
if ($iCommit) { | if ($iCommit) { | ||
| Line 490: | Line 1,372: | ||
} | } | ||
// Update PRODUCT CATEGORIES: | // Update PRODUCT CATEGORIES: | ||
| − | $sqlAdd = 'INSERT INTO '.TABLE_PRODUCTS_TO_CATEGORIES.' (products_id,categories_id) VALUES('.$this->ID().','.$this-> | + | $sqlAdd = 'INSERT INTO '.TABLE_PRODUCTS_TO_CATEGORIES.' (products_id,categories_id) VALUES('.$this->ID().','.$this->category->ID().')'; |
$result .= '<li><b>SQL</b>: '.$sqlAdd; | $result .= '<li><b>SQL</b>: '.$sqlAdd; | ||
if ($iCommit) { | if ($iCommit) { | ||
| Line 497: | Line 1,379: | ||
} | } | ||
} else { | } else { | ||
| − | $result = '<li><b>Warning</b>: product ['.$this->Name.'] has no price set ('.$this-> | + | $result = '<li><b>Warning</b>: product ['.$this->Name.'] has no price set ('.$this->price.'); skipping.'; |
} | } | ||
return $result; | return $result; | ||
| Line 504: | Line 1,386: | ||
public function TableRowCells() { | public function TableRowCells() { | ||
| − | $out = '<td>'.$this-> | + | $out = '<td>'.$this->category->Name.'</td><td>'.$this->ImportKey.'</td><td>'.$this->HtmlName.'</td>'; |
if ($this->isCatg) { | if ($this->isCatg) { | ||
$out .= '<td colspan=5 align=center bgcolor="#eeeeff"><b>category</b> (ignored)</td>'; | $out .= '<td colspan=5 align=center bgcolor="#eeeeff"><b>category</b> (ignored)</td>'; | ||
} else { | } else { | ||
| − | $out .= '<td>(<b>'.$this-> | + | $out .= '<td>(<b>'.$this->supplier->ID().'</b>) '.$this->supplier->Name.'</td><td>'.$this->price.'</td><td align=center>'.$this->SuppImp->status.'</td><td align=center>'.$this->Status.'</td><td>'.$this->CatgImp->Status.'</td>'; |
} | } | ||
return $out; | 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 = '<b>Name</b>: '.$this->name.'<br>'; | ||
| + | if ($this->descr) { | ||
| + | $out .= '<b>Description</b>: '.$this->descr.'<br>'; | ||
| + | } else { | ||
| + | $out .= '<b><font color=#6f6f6f>No description</font></b><br>'; | ||
| + | } | ||
| + | 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']; | ||
} | } | ||
} | } | ||
| Line 527: | Line 1,476: | ||
// new supplier for this session | // new supplier for this session | ||
$objSuppImp->ImportNew($iName); | $objSuppImp->ImportNew($iName); | ||
| − | self::$Records->AddObject($iName,$objSuppImp-> | + | self::$Records->AddObject($iName,$objSuppImp->supplier); |
// self::$Records->List[$iName] = $objSuppImp->Supplier; | // self::$Records->List[$iName] = $objSuppImp->Supplier; | ||
// if (!$objSuppImp->Supplier->isFound) { | // if (!$objSuppImp->Supplier->isFound) { | ||
| Line 537: | Line 1,486: | ||
// save list of (new) suppliers to database | // save list of (new) suppliers to database | ||
| − | public function | + | public function SaveImport($iCommit) { |
global $db; | global $db; | ||
$result = '<ul>'; | $result = '<ul>'; | ||
| Line 634: | Line 1,583: | ||
class clsSupplierImport { | class clsSupplierImport { | ||
| − | public $ | + | public $supplier; // points to supplier data |
| − | public $ | + | public $status; // indicates status of this particular import of that data |
// Supplier record has already been created, so use it: | // Supplier record has already been created, so use it: | ||
public function ImportOld($iObj) { | public function ImportOld($iObj) { | ||
| − | $this-> | + | $this->supplier = $iObj; |
| − | $this-> | + | $this->status = HTML_STATUS_NOTED; |
} | } | ||
// Supplier record needs to be created: | // Supplier record needs to be created: | ||
| Line 646: | Line 1,595: | ||
global $db; | global $db; | ||
| − | $this-> | + | $this->supplier = new clsSupplier; |
| − | $this-> | + | $this->supplier->Init($iName); |
| − | if ($this-> | + | if ($this->supplier->isFound) { |
| − | $this-> | + | $this->status = HTML_STATUS_EXISTS; |
} else { | } else { | ||
| − | $this-> | + | $this->status = HTML_STATUS_NEW; |
} | } | ||
} | } | ||
| Line 681: | Line 1,630: | ||
// add any new categories to database | // add any new categories to database | ||
| − | public function | + | public function SaveImport($iCommit) { |
foreach (self::$Records->List as $obj) { | foreach (self::$Records->List as $obj) { | ||
if (!$obj->isFound) { | if (!$obj->isFound) { | ||
| − | $sqlOut .= $obj-> | + | $sqlOut .= $obj->SaveImport($iCommit); |
} | } | ||
} | } | ||
| Line 748: | Line 1,697: | ||
return $this->intID; | return $this->intID; | ||
} | } | ||
| − | public function | + | public function SaveImport($iCommit) { |
global $db; | global $db; | ||
| Line 783: | Line 1,732: | ||
class clsCategoryImport { | class clsCategoryImport { | ||
| − | public $ | + | public $category; |
| − | public $ | + | public $status; |
public function Import($iName) { | public function Import($iName) { | ||
| Line 790: | Line 1,739: | ||
if (clsCategories::Exists($iName)) { | if (clsCategories::Exists($iName)) { | ||
//echo 'EXISTS '; | //echo 'EXISTS '; | ||
| − | $this-> | + | $this->category = clsCategories::GetObject($iName); |
| − | $this-> | + | $this->status = HTML_STATUS_NOTED; |
} else { | } else { | ||
//echo '*NEW* '; | //echo '*NEW* '; | ||
| − | $this-> | + | $this->category = clsCategories::Create($iName); |
| − | if ($this-> | + | if ($this->category->isFound) { |
| − | $this-> | + | $this->status = HTML_STATUS_EXISTS; |
} else { | } else { | ||
| − | $this-> | + | $this->status = HTML_STATUS_NEW; |
} | } | ||
} | } | ||
Latest revision as of 14:04, 15 May 2007
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"> >
'; // 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 '';
$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 ''; echo ''; echo ' | '; echo ''; echo ' |
'; echo ''; } 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 '
| 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').' |
| (Please be patient...) | |
'; echo ''; } 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 ' '; $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 ' ' .'' .''; // 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 . '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 | |||||||
|---|---|---|---|---|---|---|---|
| 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::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 '
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 .= ' 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>