PhpSpreadsheet - Check if file is open - php

I need to check if the excel file is currently open using PHPSpreadsheet.
I thought of a solution by handling this line $writer->save(file_name) into if else condition but still doesn't work.
if($writer->save(file_name){
//file is open
}else{
//file is not open
}
What else can I do to solve my problem?

I need to check if the excel file is currently open using PHPSpreadsheet.
Checking if a file is open isn't really useful, since the open/closed state could change at any time, or the failure could be caused by other filesystem problems.
What you need to do is handle the failure during file operations as:
try {
$writer->save(file_name);
}
catch (Exception $e) {
echo 'Unable to save file. Please close any other applications(s) that are using it: [", $e->getMessage(), "]\n";
}

Answered by #terry-carmen will be Incorrect in following situation:
It will still show "Resource Unavailable" error If file is exists but being used by some application and $writer->save() will try to unlink() the file.
To Overcome this situations I edited the save() function as following:
(Located at: "\vendor\phpoffice\phpspreadsheet\src\PhpSpreadsheet\Writer\Xlsx.php")
public function save($pFilename)
{
if ($this->spreadSheet !== null) {
// garbage collect
$this->spreadSheet->garbageCollect();
// If $pFilename is php://output or php://stdout, make it a temporary file...
$originalFilename = $pFilename;
if (strtolower($pFilename) == 'php://output' || strtolower($pFilename) == 'php://stdout') {
$pFilename = #tempnam(File::sysGetTempDir(), 'phpxltmp');
if ($pFilename == '') {
$pFilename = $originalFilename;
}
}
$saveDebugLog = Calculation::getInstance($this->spreadSheet)->getDebugLog()->getWriteDebugLog();
Calculation::getInstance($this->spreadSheet)->getDebugLog()->setWriteDebugLog(false);
$saveDateReturnType = Functions::getReturnDateType();
Functions::setReturnDateType(Functions::RETURNDATE_EXCEL);
// Create string lookup table
$this->stringTable = [];
for ($i = 0; $i < $this->spreadSheet->getSheetCount(); ++$i) {
$this->stringTable = $this->getWriterPart('StringTable')->createStringTable($this->spreadSheet->getSheet($i), $this->stringTable);
}
// Create styles dictionaries
$this->styleHashTable->addFromSource($this->getWriterPart('Style')->allStyles($this->spreadSheet));
$this->stylesConditionalHashTable->addFromSource($this->getWriterPart('Style')->allConditionalStyles($this->spreadSheet));
$this->fillHashTable->addFromSource($this->getWriterPart('Style')->allFills($this->spreadSheet));
$this->fontHashTable->addFromSource($this->getWriterPart('Style')->allFonts($this->spreadSheet));
$this->bordersHashTable->addFromSource($this->getWriterPart('Style')->allBorders($this->spreadSheet));
$this->numFmtHashTable->addFromSource($this->getWriterPart('Style')->allNumberFormats($this->spreadSheet));
// Create drawing dictionary
$this->drawingHashTable->addFromSource($this->getWriterPart('Drawing')->allDrawings($this->spreadSheet));
$zip = new ZipArchive();
if (file_exists($pFilename)) {
// Added by muhammad.begawala#gmail.com
// '#' will stop displaying "Resource Unavailable" error because of file is open some where.
// 'unlink($pFilename) !== true' will check if file is deleted successfully.
// Throwing exception so that we can handle error easily instead of displaying to users.
if (#unlink($pFilename) !== true) {
throw new WriterException('Could not delete file: ' . $pFilename . ' Please close all applications that are using it.');
}
}
// Try opening the ZIP file
if ($zip->open($pFilename, ZipArchive::OVERWRITE) !== true) {
if ($zip->open($pFilename, ZipArchive::CREATE) !== true) {
throw new WriterException('Could not open ' . $pFilename . ' for writing.');
}
}
// Add [Content_Types].xml to ZIP file
$zip->addFromString('[Content_Types].xml', $this->getWriterPart('ContentTypes')->writeContentTypes($this->spreadSheet, $this->includeCharts));
//if hasMacros, add the vbaProject.bin file, Certificate file(if exists)
if ($this->spreadSheet->hasMacros()) {
$macrosCode = $this->spreadSheet->getMacrosCode();
if ($macrosCode !== null) {
// we have the code ?
$zip->addFromString('xl/vbaProject.bin', $macrosCode); //allways in 'xl', allways named vbaProject.bin
if ($this->spreadSheet->hasMacrosCertificate()) {
//signed macros ?
// Yes : add the certificate file and the related rels file
$zip->addFromString('xl/vbaProjectSignature.bin', $this->spreadSheet->getMacrosCertificate());
$zip->addFromString('xl/_rels/vbaProject.bin.rels', $this->getWriterPart('RelsVBA')->writeVBARelationships($this->spreadSheet));
}
}
}
//a custom UI in this workbook ? add it ("base" xml and additional objects (pictures) and rels)
if ($this->spreadSheet->hasRibbon()) {
$tmpRibbonTarget = $this->spreadSheet->getRibbonXMLData('target');
$zip->addFromString($tmpRibbonTarget, $this->spreadSheet->getRibbonXMLData('data'));
if ($this->spreadSheet->hasRibbonBinObjects()) {
$tmpRootPath = dirname($tmpRibbonTarget) . '/';
$ribbonBinObjects = $this->spreadSheet->getRibbonBinObjects('data'); //the files to write
foreach ($ribbonBinObjects as $aPath => $aContent) {
$zip->addFromString($tmpRootPath . $aPath, $aContent);
}
//the rels for files
$zip->addFromString($tmpRootPath . '_rels/' . basename($tmpRibbonTarget) . '.rels', $this->getWriterPart('RelsRibbonObjects')->writeRibbonRelationships($this->spreadSheet));
}
}
// Add relationships to ZIP file
$zip->addFromString('_rels/.rels', $this->getWriterPart('Rels')->writeRelationships($this->spreadSheet));
$zip->addFromString('xl/_rels/workbook.xml.rels', $this->getWriterPart('Rels')->writeWorkbookRelationships($this->spreadSheet));
// Add document properties to ZIP file
$zip->addFromString('docProps/app.xml', $this->getWriterPart('DocProps')->writeDocPropsApp($this->spreadSheet));
$zip->addFromString('docProps/core.xml', $this->getWriterPart('DocProps')->writeDocPropsCore($this->spreadSheet));
$customPropertiesPart = $this->getWriterPart('DocProps')->writeDocPropsCustom($this->spreadSheet);
if ($customPropertiesPart !== null) {
$zip->addFromString('docProps/custom.xml', $customPropertiesPart);
}
// Add theme to ZIP file
$zip->addFromString('xl/theme/theme1.xml', $this->getWriterPart('Theme')->writeTheme($this->spreadSheet));
// Add string table to ZIP file
$zip->addFromString('xl/sharedStrings.xml', $this->getWriterPart('StringTable')->writeStringTable($this->stringTable));
// Add styles to ZIP file
$zip->addFromString('xl/styles.xml', $this->getWriterPart('Style')->writeStyles($this->spreadSheet));
// Add workbook to ZIP file
$zip->addFromString('xl/workbook.xml', $this->getWriterPart('Workbook')->writeWorkbook($this->spreadSheet, $this->preCalculateFormulas));
$chartCount = 0;
// Add worksheets
for ($i = 0; $i < $this->spreadSheet->getSheetCount(); ++$i) {
$zip->addFromString('xl/worksheets/sheet' . ($i + 1) . '.xml', $this->getWriterPart('Worksheet')->writeWorksheet($this->spreadSheet->getSheet($i), $this->stringTable, $this->includeCharts));
if ($this->includeCharts) {
$charts = $this->spreadSheet->getSheet($i)->getChartCollection();
if (count($charts) > 0) {
foreach ($charts as $chart) {
$zip->addFromString('xl/charts/chart' . ($chartCount + 1) . '.xml', $this->getWriterPart('Chart')->writeChart($chart, $this->preCalculateFormulas));
++$chartCount;
}
}
}
}
$chartRef1 = 0;
// Add worksheet relationships (drawings, ...)
for ($i = 0; $i < $this->spreadSheet->getSheetCount(); ++$i) {
// Add relationships
$zip->addFromString('xl/worksheets/_rels/sheet' . ($i + 1) . '.xml.rels', $this->getWriterPart('Rels')->writeWorksheetRelationships($this->spreadSheet->getSheet($i), ($i + 1), $this->includeCharts));
// Add unparsedLoadedData
$sheetCodeName = $this->spreadSheet->getSheet($i)->getCodeName();
$unparsedLoadedData = $this->spreadSheet->getUnparsedLoadedData();
if (isset($unparsedLoadedData['sheets'][$sheetCodeName]['ctrlProps'])) {
foreach ($unparsedLoadedData['sheets'][$sheetCodeName]['ctrlProps'] as $ctrlProp) {
$zip->addFromString($ctrlProp['filePath'], $ctrlProp['content']);
}
}
if (isset($unparsedLoadedData['sheets'][$sheetCodeName]['printerSettings'])) {
foreach ($unparsedLoadedData['sheets'][$sheetCodeName]['printerSettings'] as $ctrlProp) {
$zip->addFromString($ctrlProp['filePath'], $ctrlProp['content']);
}
}
$drawings = $this->spreadSheet->getSheet($i)->getDrawingCollection();
$drawingCount = count($drawings);
if ($this->includeCharts) {
$chartCount = $this->spreadSheet->getSheet($i)->getChartCount();
}
// Add drawing and image relationship parts
if (($drawingCount > 0) || ($chartCount > 0)) {
// Drawing relationships
$zip->addFromString('xl/drawings/_rels/drawing' . ($i + 1) . '.xml.rels', $this->getWriterPart('Rels')->writeDrawingRelationships($this->spreadSheet->getSheet($i), $chartRef1, $this->includeCharts));
// Drawings
$zip->addFromString('xl/drawings/drawing' . ($i + 1) . '.xml', $this->getWriterPart('Drawing')->writeDrawings($this->spreadSheet->getSheet($i), $this->includeCharts));
} elseif (isset($unparsedLoadedData['sheets'][$sheetCodeName]['drawingAlternateContents'])) {
// Drawings
$zip->addFromString('xl/drawings/drawing' . ($i + 1) . '.xml', $this->getWriterPart('Drawing')->writeDrawings($this->spreadSheet->getSheet($i), $this->includeCharts));
}
// Add comment relationship parts
if (count($this->spreadSheet->getSheet($i)->getComments()) > 0) {
// VML Comments
$zip->addFromString('xl/drawings/vmlDrawing' . ($i + 1) . '.vml', $this->getWriterPart('Comments')->writeVMLComments($this->spreadSheet->getSheet($i)));
// Comments
$zip->addFromString('xl/comments' . ($i + 1) . '.xml', $this->getWriterPart('Comments')->writeComments($this->spreadSheet->getSheet($i)));
}
// Add unparsed relationship parts
if (isset($unparsedLoadedData['sheets'][$this->spreadSheet->getSheet($i)->getCodeName()]['vmlDrawings'])) {
foreach ($unparsedLoadedData['sheets'][$this->spreadSheet->getSheet($i)->getCodeName()]['vmlDrawings'] as $vmlDrawing) {
$zip->addFromString($vmlDrawing['filePath'], $vmlDrawing['content']);
}
}
// Add header/footer relationship parts
if (count($this->spreadSheet->getSheet($i)->getHeaderFooter()->getImages()) > 0) {
// VML Drawings
$zip->addFromString('xl/drawings/vmlDrawingHF' . ($i + 1) . '.vml', $this->getWriterPart('Drawing')->writeVMLHeaderFooterImages($this->spreadSheet->getSheet($i)));
// VML Drawing relationships
$zip->addFromString('xl/drawings/_rels/vmlDrawingHF' . ($i + 1) . '.vml.rels', $this->getWriterPart('Rels')->writeHeaderFooterDrawingRelationships($this->spreadSheet->getSheet($i)));
// Media
foreach ($this->spreadSheet->getSheet($i)->getHeaderFooter()->getImages() as $image) {
$zip->addFromString('xl/media/' . $image->getIndexedFilename(), file_get_contents($image->getPath()));
}
}
}
// Add media
for ($i = 0; $i < $this->getDrawingHashTable()->count(); ++$i) {
if ($this->getDrawingHashTable()->getByIndex($i) instanceof WorksheetDrawing) {
$imageContents = null;
$imagePath = $this->getDrawingHashTable()->getByIndex($i)->getPath();
if (strpos($imagePath, 'zip://') !== false) {
$imagePath = substr($imagePath, 6);
$imagePathSplitted = explode('#', $imagePath);
$imageZip = new ZipArchive();
$imageZip->open($imagePathSplitted[0]);
$imageContents = $imageZip->getFromName($imagePathSplitted[1]);
$imageZip->close();
unset($imageZip);
} else {
$imageContents = file_get_contents($imagePath);
}
$zip->addFromString('xl/media/' . str_replace(' ', '_', $this->getDrawingHashTable()->getByIndex($i)->getIndexedFilename()), $imageContents);
} elseif ($this->getDrawingHashTable()->getByIndex($i) instanceof MemoryDrawing) {
ob_start();
call_user_func(
$this->getDrawingHashTable()->getByIndex($i)->getRenderingFunction(),
$this->getDrawingHashTable()->getByIndex($i)->getImageResource()
);
$imageContents = ob_get_contents();
ob_end_clean();
$zip->addFromString('xl/media/' . str_replace(' ', '_', $this->getDrawingHashTable()->getByIndex($i)->getIndexedFilename()), $imageContents);
}
}
Functions::setReturnDateType($saveDateReturnType);
Calculation::getInstance($this->spreadSheet)->getDebugLog()->setWriteDebugLog($saveDebugLog);
// Close file
if ( #$zip->close() === false ) { // updated by muhammad.begawala#gmail.com
throw new WriterException("Could not close zip file $pFilename.");
}
// If a temporary file was used, copy it to the correct file stream
if ($originalFilename != $pFilename) {
if (copy($pFilename, $originalFilename) === false) {
throw new WriterException("Could not copy temporary zip file $pFilename to $originalFilename.");
}
#unlink($pFilename);
}
return true;
// Return True to make sure that file is created successfully with no ExceptionsAdded by muhammad.begawala#gmail.com
} else {
throw new WriterException('PhpSpreadsheet object unassigned.');
}
}
Major Changes:
1) Handling "Resource Unavailable" error by unlink() as Exception using try catch so that It doesn't show error when file is being used by some applications when we tries to delete it using unlink.
if (file_exists($pFilename)) {
// Added by muhammad.begawala#gmail.com
// '#' will stop displaying "Resource Unavailable" error because of file is open some where.
// 'unlink($pFilename) !== true' will check if file is deleted successfully.
// Throwing exception so that we can handle error easily instead of displaying to users.
if (#unlink($pFilename) !== true) {
throw new WriterException('Could not delete file: ' . $pFilename . ' Please close all applications that are using it.');
}
}
2) $writer->save('hello world.xlsx') will return TRUE if file is successfully created else throw Exception.
Usage:
try {
$writer->save('hello world.xlsx');
echo 'File Created';
}
catch (Exception $e) {
echo $e->getMessage(); // Will print Exception thrown by save()
}

Related

jodit Yii2 changing file name while uploading

I'm trying to set up a Jodit WYSIWYG and I'm finding their documentation rather confusing. I'm looking at a way to change the file name while uploading.
cause: if I upload the file name with the same name in the root directory it will be replaced the old file.
So, How changing file name while uploading for voiding replace the old name file.
here procedure is upload Image 3 files
1.jpg,2.jpg,3.jpg
when Debug mode the name of the file is in
$files = $_FILES[$source->defaultFilesKey];
in function
public function move(Config $source) {
$files = $_FILES[$source->defaultFilesKey];
/**
* #var $output File[]
*/
$output = [];
try {
if (isset($files) and is_array($files) and isset($files['name']) and is_array($files['name']) and count($files['name'])) {
foreach ($files['name'] as $i => $file) {
if ($files['error'][$i]) {
throw new \Exception(isset(Helper::$upload_errors[$files['error'][$i]]) ? Helper::$upload_errors[$files['error'][$i]] : 'Error', $files['error'][$i]);
}
$path = $source->getPath();
$tmp_name = $files['tmp_name'][$i];
$new_path = $path . Helper::makeSafe($files['name'][$i]);
if (!move_uploaded_file($tmp_name, $new_path)) {
if (!is_writable($path)) {
throw new \Exception('Destination directory is not writeble', Consts::ERROR_CODE_IS_NOT_WRITEBLE);
}
throw new \Exception('No files have been uploaded', Consts::ERROR_CODE_NO_FILES_UPLOADED);
}
$file = new File($new_path);
try {
$this->accessControl->checkPermission($this->getUserRole(), $this->action, $source->getRoot(), pathinfo($file->getPath(), PATHINFO_EXTENSION));
} catch (\Exception $e) {
$file->remove();
throw $e;
}
if (!$file->isGoodFile($source)) {
$file->remove();
throw new \Exception('File type is not in white list', Consts::ERROR_CODE_FORBIDDEN);
}
if ($source->maxFileSize and $file->getSize() > Helper::convertToBytes($source->maxFileSize)) {
$file->remove();
throw new \Exception('File size exceeds the allowable', Consts::ERROR_CODE_FORBIDDEN);
}
$output[] = $file;
}
}
} catch (\Exception $e) {
foreach ($output as $file) {
$file->remove();
}
throw $e;
}
return $output;
}
so $file is keep the name file in array
i need to foreach $fiels and change array['name'] value.
but i don't konw how to change it.
UPDATE after I try i got a solution
use foreach statment for loop $files['name'].
public function move(Config $source) {
$files = $_FILES[$source->defaultFilesKey];
foreach ($files['name'] as $i => $file) {
$files['name'][$i] = round(microtime(true)).($files['name'][$i]);
}
/**
* #var $output File[]
*/
$output = [];
.
.
.
}
You can use saveas method of php to upload new renamed file:
//New name for file
$newName = date("m-d-Y-h-i-s", time())."-".$filename.'.'.$ext;
$model->files = CUploadedFile::getInstance($model,'files');
$fullFileSource = Yii::getPathOfAlias('webroot').'/upload/'.$newName;
$model->files->saveAs($fullFileSource);

PHP : How to count the number of invalid emails in a CSV file

I upload csv files from a VueJS frontend to a cakephp API. In those CSV files there are emails which need to get validated. But my problem appear after that, I would like to count the number of emails that are not valid in the CSV file and then put this value in a database.
Here is my code : I tested with "count()" but that doesn't work because I did it wrong I think.
public function upload()
{
// POST ?
$this->myMethodError(['post']);
// reading parameters
$uploadFileName = $this->request->getData('uploadFileName') ? $this->request->getData('uploadFileName') : '';
$uploadFile = $this->request->getData('uploadFile') ? $this->request->getData('uploadFile') : '';
// Uploaded with .csv extension ?
$uploadFileExtension = pathinfo($this->request->data['name'])['extension']; // .csv ?
if (!(in_array($uploadFileExtension, ['csv']))) {
$this->myError(['error' => 'Wrong File extension: ' . $uploadFileExtension . '. .csv expected.']);
}
//copy the file in a repertory with date
$destinationFile = TMP . "" . date("YmdHis") . "_annonceur_marque_campagne" . "." . $uploadFileExtension;
if (move_uploaded_file($uploadFile['tmp_name'], $destinationFile)) {
//---------------
// Read .CSV
//---------------
if (($handle = fopen($destinationFile, "r")) !== FALSE) {
//-------------------
// Reading datas
//--------------------
$numrow = 0;
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
$numrow++;
if (count($data) != 13) {
$this->myError(['error' => 'Structure de fichier invalide détectée ligne ' . $numrow]);
exit;
}
if ($numrow == 1) {
continue;
} // on saute les titres des colonnes
if($data[4] == "")
{
$this->myError(['error' => 'Le champs email est obligatoire. ligne ' . $numrow]);
exit;
}
}
//insert in database
$uploadTable = TableRegistry::get('Locationsets');
$upload = $uploadTable->newEntity();
if(!filter_var($data[4], FILTER_VALIDATE_EMAIL) === true){
$upload->nbr_errors_email = count(filter_var($data[4], FILTER_VALIDATE_EMAIL));
}
$upload->name = $uploadFileName;
$upload->csv_files_dir = $destinationFile;
if($uploadTable->save($upload)){
$uploadId = $upload->id;
} else {
$this->myError(['error' => 'Insert failed']);
}
// return in Json
$this->myOutput([$data]);
} else {
$this->myError(['error' => 'Reading csv file failed']);
}
} else {
$this->myError(['error' => 'Csv file upload failed']);
}
}
This code add 1 in the database but that's not the result I should have.
Hope you can help.
EDIT :
An example of the content of $data

PHP script is running out of memory

I wrote the following PHP script (symphony 1.4 Task), which loops over a CSV file an d imports the data via Doctrine into MySQL.
Unfortunately the script is aborted because it allocates to much memory. The used memory grows with each foreach cycle. I tried a lot of things, but i am not able to keep the used memory more stable.
Could anyone give me a hint?
<?php
class importERPTask extends sfBaseTask
{
protected function configure()
{
$this->addOptions(array(
new sfCommandOption('application', null, sfCommandOption::PARAMETER_REQUIRED, 'The application name', 'frontend'),
new sfCommandOption('env', null, sfCommandOption::PARAMETER_REQUIRED, 'The environment', 'dev'),
new sfCommandOption('connection', null, sfCommandOption::PARAMETER_REQUIRED, 'The connection name', 'doctrine'),
// add your own options here
));
$this->namespace = 'w2';
$this->name = 'importERP';
$this->briefDescription = 'Imports product data .';
}
public function execute($arguments = array(), $options = array())
{
// initialize the database connection
$databaseManager = new sfDatabaseManager($this->configuration);
$connection = $databaseManager->getDatabase($options['connection'])->getConnection();
$this->logSection('importERP', 'Start');
if(!(file_exists(sfConfig::get('sf_root_dir'). DIRECTORY_SEPARATOR .'import_data'.DIRECTORY_SEPARATOR.'VK.csv') && file_exists(sfConfig::get('sf_root_dir'). DIRECTORY_SEPARATOR .'import_data'.DIRECTORY_SEPARATOR.'Artikel.csv')))
{
$this->logSection('importERP', 'No import CSV');
$this->logSection('importERP', 'Done.');
return;
}
$this->importPrices();
//import products
$this->logSection('importERP', 'Import products');
Doctrine::getTable('CatalogueProduct')->setAllImportFalse();
$file_handle = fopen(sfConfig::get('sf_root_dir'). DIRECTORY_SEPARATOR .'import_data'.DIRECTORY_SEPARATOR.'Artikel.csv', 'r');
if($file_handle)
{
$i = 0;
while(!feof($file_handle))
{
//skip first line
if(++$i == 1)
{
continue;
}
$this->importProduct($file_handle);
}
fclose($file_handle);
}
$this->deleteProducts();
unlink(sfConfig::get('sf_root_dir'). DIRECTORY_SEPARATOR .'import_data'.DIRECTORY_SEPARATOR.'VK.csv');
unlink(sfConfig::get('sf_root_dir'). DIRECTORY_SEPARATOR .'import_data'.DIRECTORY_SEPARATOR.'Artikel.csv');
$this->logSection('importERP', 'Done.');
}
private function importPrices()
{
//import price helper table
$this->logSection('importERP', 'Import price helper table');
Doctrine::getTable('ImportHelperPrice')->clearAllData();
$file_handle = fopen(sfConfig::get('sf_root_dir'). DIRECTORY_SEPARATOR .'import_data'.DIRECTORY_SEPARATOR.'VK.csv', 'r');
if($file_handle)
{
$i = 0;
while(!feof($file_handle))
{
$line_of_text = fgetcsv($file_handle, 0, ';', '"');
//skip first line
if(++$i == 1)
{
continue;
}
$price = new ImportHelperPrice();
$price->setImportId($line_of_text[0]);
$price->setStartAmount($line_of_text[1]);
$price->setPrice(str_replace(',', '.', $line_of_text[2]));
$price->save();
}
}
}
private function importProduct($file_handle)
{
$line_of_text = fgetcsv($file_handle, 0, ';', '"');
$this->logSection('importERP', 'Import product '.$line_of_text[1]);
//no empty article number
if($line_of_text[0] == '')
{
$this->logSection('importERP', '... skipped');
return;
}
if($line_of_text[4] == '')
{
$this->logSection('importERP', '... has no category');
return;
}
$my_product = Doctrine::getTable('CatalogueProduct')->findOneByCode($line_of_text[0]);
$my_cat = Doctrine::getTable('CatalogueCategory')->findOneByImportCode($line_of_text[4]);
if(!$my_cat)
{
$this->logSection('importERP', '... has no category');
return;
}
if(!$my_product)
{
$this->logSection('importERP', '... is new');
$my_product = new CatalogueProduct();
$my_product->setCode($line_of_text[0]);
// do not overwrite handmade configurations from backend
$my_product->setVatId(1);
$my_product->setTemplateId(4);
}
else
{
$this->logSection('importERP', '... is updated');
}
//get prices
$price = Doctrine::getTable('ImportHelperPrice')->getPriceForImportId($line_of_text[0]);
if(!$price)
{
return;
}
$my_product->setPriceGrossEur($price->getPrice());
$my_product->Translation['de']->title = $line_of_text[2];
$my_product->Translation['de']->shortdescription = $line_of_text[3];
$my_product->Translation['de']->description =$line_of_text[3];
$my_product->setCatalogueCategory($my_cat);
$my_product->setHidden(false);
$my_product->setImportFlag(true);
$config_prices = Doctrine::getTable('ImportHelperPrice')->getPriceConfigForImportId($line_of_text[0]);
if($config_prices)
{
$price_config = '';
foreach($config_prices as $cp)
{
$discount = 100 - ($cp->getPrice() / ($price->getPrice() / 100));
if($discount == 0)
{
continue;
}
if($price_config != '')
{
$price_config .= ';';
}
$price_config .= $cp->getStartAmount() . ':' . number_format($discount, 2, ',', '');
}
$my_product->setPriceConfig($price_config);
}
//move images
$img_default = sfConfig::get('sf_root_dir'). DIRECTORY_SEPARATOR .'import_data'.DIRECTORY_SEPARATOR.'images'.DIRECTORY_SEPARATOR.$line_of_text[1].'_m.jpg';
if(file_exists($img_default))
{
rename($img_default, sfConfig::get('sf_web_dir').DIRECTORY_SEPARATOR.'products'.DIRECTORY_SEPARATOR.$line_of_text[1].'_m.jpg');
$my_product->setImageDefault($line_of_text[1].'_m.jpg');
$this->logSection('importERP', '... '.$my_product->getImageDefault().' saved');
}
else
{
$this->logSection('importERP', '... '.$img_default.' not found');
}
$img_zoom = sfConfig::get('sf_root_dir'). DIRECTORY_SEPARATOR .'import_data'.DIRECTORY_SEPARATOR.'images'.DIRECTORY_SEPARATOR.$line_of_text[1].'_gr.jpg';
if(file_exists($img_zoom))
{
rename($img_zoom, sfConfig::get('sf_web_dir').DIRECTORY_SEPARATOR.'products'.DIRECTORY_SEPARATOR.$line_of_text[1].'_zoom.jpg');
$my_product->setImageZoom($line_of_text[1].'_zoom.jpg');
$this->logSection('importERP', '... '.$my_product->getImageZoom().' saved');
}
else
{
$this->logSection('importERP', '... '.$img_zoom.' not found');
}
$img_icon = sfConfig::get('sf_root_dir'). DIRECTORY_SEPARATOR .'import_data'.DIRECTORY_SEPARATOR.'images'.DIRECTORY_SEPARATOR.$line_of_text[1].'_kl.jpg';
if(file_exists($img_icon))
{
rename($img_icon, sfConfig::get('sf_web_dir').DIRECTORY_SEPARATOR.'products'.DIRECTORY_SEPARATOR.$line_of_text[1].'_icon.jpg');
$my_product->setImageIcon($line_of_text[1].'_icon.jpg');
$this->logSection('importERP', '... '.$my_product->getImageIcon().' saved');
}
else
{
$this->logSection('importERP', '... '.$img_icon.' not found');
}
$my_product->save();
$this->logSection('importERP', 'Memory usage '.memory_get_peak_usage() / 1048576,2 .' MB');
}
private function deleteProducts()
{
//delete not mentioned products
$this->logSection('importERP', 'Delete not mentioned products');
$del_products = Doctrine::getTable('CatalogueProduct')->getAllImportFalse();
foreach($del_products as $dp)
{
$this->logSection('importERP', 'Delete '.$dp->getCode());
//delete images
$img_default = sfConfig::get('sf_web_dir').DIRECTORY_SEPARATOR.'products'.DIRECTORY_SEPARATOR.$dp->getImageDefault();
$img_zoom = sfConfig::get('sf_web_dir').DIRECTORY_SEPARATOR.'products'.DIRECTORY_SEPARATOR.$dp->getImageZoom();
$img_icon = sfConfig::get('sf_web_dir').DIRECTORY_SEPARATOR.'products'.DIRECTORY_SEPARATOR.$dp->getImageIcon();
if($dp->getImageDefault() != NULL && $dp->getImageDefault() != '' && file_exists($img_default))
{
unlink($img_default);
}
if($dp->getImageZoom() != NULL && $dp->getImageZoom() != '' && file_exists($img_zoom))
{
unlink($img_zoom);
}
if($dp->getImageIcon() != NULL && $dp->getImageIcon() != '' && file_exists($img_icon))
{
unlink($img_icon);
}
//delete product
$dp->delete();
}
}
}
The best solution would be to edit your php.ini file. Allocate:
memory_limit = 16M
Not sure if 16M is default but it should be close. Anyway, that's the amount of memory a PHP script is allowed to use. You can just set this number higher and solve the problem.
Alternatively you can write this on the top of your PHP script:
ini_set('memory_limit', '16M');
Where 16M can be changed to whatever amount of memory you wish the script to allow.
Watch out for ini_sets with values ending with 'M' - they don't work as expected. Shorthand notation works only in php.ini, appropriate info is included in the docs: http://php.net/manual/en/faq.using.php#faq.using.shorthandbytes
You should do:
...
$my_product->save();
$my_product->free();
unset($my_product);
...
Assuming your CSV is just too big for your server to handle in memory in one swoop, I would consider splitting the CSV into smaller files, which is quite a simple task with Unix commands (split, etc).
You would then execute each bitesize CSV asynchronously with your PHP script.

slim php framework image upload put database

I am new to slim php framework, I want to upload an image and put the file name in the database via POST, can some one kindly give me some example code.
Here's the router:
$app->post('/', 'uploadFile');
this will point to the function below:
function uploadFile () {
if (!isset($_FILES['uploads'])) {
echo "No files uploaded!!";
return;
}
$imgs = array();
$files = $_FILES['uploads'];
$cnt = count($files['name']);
for($i = 0 ; $i < $cnt ; $i++) {
if ($files['error'][$i] === 0) {
$name = uniqid('img-'.date('Ymd').'-');
if (move_uploaded_file($files['tmp_name'][$i], 'uploads/' . $name) === true) {
$imgs[] = array('url' => '/uploads/' . $name, 'name' => $files['name'][$i]);
}
}
}
$imageCount = count($imgs);
if ($imageCount == 0) {
echo 'No files uploaded!! <p>Try again';
return;
}
$plural = ($imageCount == 1) ? '' : 's';
foreach($imgs as $img) {
printf('%s <img src="%s" width="50" height="50" /><br/>', $img['name'], $img['url']);
}
}
If anyone have better answer, please be welcome to alter mine.
The creator of Slim has made a library to handle file uploading through Slim: https://github.com/brandonsavage/Upload

Multiple file upload with a loop

I currently have this script where users (using a form where they can upload up to seven images) can upload multiple images to a folder and the image name to my database, without any success. Please help.
if (isset($_POST['submit'])) { $ref_49 = $_POST['ref_49'];
$name = $_POST['name'];
$contact = $_POST['contact'];
$email = $_POST['email'];
$rent_sell = $_POST['rent_sell'];
$heading = $_POST['heading'];
$price = $_POST['price'];
$limitedtextarea = $_POST['limitedtextarea'];
$type = $_POST['type'];
$where = $_POST['where'];
$address = $_POST['address'];
$bedroom = $_POST['bedroom'];
$bathroom = $_POST['bathroom'];
$garages = $_POST['garages'];
$carports = $_POST['carports'];
$granny_flat = $_POST['granny_flat'];
$ref_99 = $_POST['ref_99'];
$fulldesc = $_POST['full_desc'];
if ($ref_99=="") {
$full_ad = "yes";
} else {
$full_ad = "no";
}
$todays_date = date("Y-m-d");
mkdir("gallery/" . $_POST["name"], 0777);
for ($i = 0; $i < 7; $i++)
{
$file_name = $_FILES['uploadFile' . $i]['name'];
// strip file_name of slashes
$file_name = stripslashes($file_name);
$file_name = str_replace("'", "", $file_name);
// $copy = copy($_FILES['uploadFile'. $i]['tmp_name'], "gallery/" . $_POST["name"] . "/" . $file_name);
if ((($_FILES['uploadFile' . $i]["type"] == "image/gif")
|| ($_FILES['uploadFile' . $i]["type"] == "image/jpeg")
|| ($_FILES['uploadFile' . $i]["type"] == "image/pjpeg"))
&& ($_FILES['uploadFile' . $i]["size"] < 200000000))
{
if ($_FILES['uploadFile' . $i]["error"] > 0)
{
$message = "Return Code: " . $_FILES['uploadFile' . $i]["error"] . "<br />";
}
else
{
$query = "INSERT INTO property (
name, contact, email, type_of_listing, rent_sell, address, prop_desc, area, price, main_image, image_1, image_2, image_3, image_4, image_5, image_6, heading, bathroom, bedroom, garages, carports, granny_flat, full_description, full_ad, 49_ref, 99_ref, listed
) VALUES (
'{$name}', '{$contact}', '{$email}', '{$type}', '{$rent_sell}', '{$address}', '{$limitedtextarea}', '{$where}', '{$price}', '{$photo_1}', '{$photo_2}', '{$photo_3}', '{$photo_4}', '{$photo_5}', '{$photo_6}', '{$photo_7}', '{$heading}', '{$bathroom}', '{$bedroom}', '{$garages}', '{$carports}', '{$granny_flat}', '{$fulldesc}', '{$full_ad}', 'ref_49_{$ref_49}', 'ref_99_{$ref_99}', ''
)";
$result = mysql_query($query, $connection);
if (file_exists("gallery/" . $_POST["name"] . "/" . $_FILES['uploadFile' . $i]["name"]))
{
$message = "<h3>" . $_FILES['uploadFile' . $i]["name"] . " already exists.</h3>";
}
else
{
move_uploaded_file($_FILES['uploadFile' . $i]["tmp_name"], "gallery/" . $_POST["name"] . "/" . $_FILES['uploadFile' . $i]["name"]);
$message = "File: " . $_FILES['uploadFile' . $i]["name"] . " uploaded.";
}
}
}
else
{
$message = "<h3>Invalid file or no file selected.</h3><br />• Only JPEG OR GIF allowed.<br />• Size limited may not exceed 200KB.<br />Return";
}
}
}
}
There could be a lot of things going wrong here. Have you tried to break this up into pieces? Are you sure the DB is connecting? Are you sure php has access to write to the directories it's attempting to write to? Are you sure those directories exist...etc. etc.
Comment out the vast majority of the code, and start testing all the components piece by piece, or wrap stuff in try/catch and see what errors are produced.
[edit]
If the problem only occurs when you upload < 7 files then the problem is in that you've hard coded a 7 into your loop!
Loop through how many files are actually being uploaded, not a fixed number.
Assuming they're all being named sequentially (and starting at 0) you can test for the existence of your hashed FILE value in the loop and just keep ingesting until it comes up null (probably good to add a limiter to make sure it can't go on for ever)
something like this...
[edit 2] modified the condition to include a test for file size
for($i=0; $_FILES['uploadFile' . $i] && $_FILES['uploadFile' . $i]['size'] > 0 && $i<100 ; $i++){
try{
//do your upload stuff here
}catch(e){}
}
[EDIT]
To modify your page to include a dynamic number of fields do this:
check out this fiddle: http://jsfiddle.net/RjcHY/2/
Click the plus and minus buttons on the right side to see how it works. I made it so that it's naming the file buttons as per your php's expectations.
While dealing with common tasks like file uploading, write some library for handling those tasks and call necessary function wherever needed . If you create an uploader class file , you can simply invoke one of the methods you created to handle file uploads .
Here i will give you a Uploader class
<?php
//Save file as Uploader.php
//File Uploading Class
class Uploader
{
private $destinationPath;
private $errorMessage;
private $extensions;
private $allowAll;
private $maxSize;
private $uploadName;
private $seqnence;
public $name='Uploader';
public $useTable =false;
function setDir($path){
$this->destinationPath = $path;
$this->allowAll = false;
}
function allowAllFormats(){
$this->allowAll = true;
}
function setMaxSize($sizeMB){
$this->maxSize = $sizeMB * (1024*1024);
}
function setExtensions($options){
$this->extensions = $options;
}
function setSameFileName(){
$this->sameFileName = true;
$this->sameName = true;
}
function getExtension($string){
$ext = "";
try{
$parts = explode(".",$string);
$ext = strtolower($parts[count($parts)-1]);
}catch(Exception $c){
$ext = "";
}
return $ext;
}
function setMessage($message){
$this->errorMessage = $message;
}
function getMessage(){
return $this->errorMessage;
}
function getUploadName(){
return $this->uploadName;
}
function setSequence($seq){
$this->imageSeq = $seq;
}
function getRandom(){
return strtotime(date('Y-m-d H:iConfused')).rand(1111,9999).rand(11,99).rand(111,999);
}
function sameName($true){
$this->sameName = $true;
}
function uploadFile($fileBrowse){
$result = false;
$size = $_FILES[$fileBrowse]["size"];
$name = $_FILES[$fileBrowse]["name"];
$ext = $this->getExtension($name);
if(!is_dir($this->destinationPath)){
$this->setMessage("Destination folder is not a directory ");
}else if(!is_writable($this->destinationPath)){
$this->setMessage("Destination is not writable !");
}else if(empty($name)){
$this->setMessage("File not selected ");
}else if($size>$this->maxSize){
$this->setMessage("Too large file !");
}else if($this->allowAll || (!$this->allowAll && in_array($ext,$this->extensions))){
if($this->sameName==false){
$this->uploadName = $this->imageSeq."-".substr(md5(rand(1111,9999)),0,8).$this->getRandom().rand(1111,1000).rand(99,9999).".".$ext;
}else{
$this->uploadName= $name;
}
if(move_uploaded_file($_FILES[$fileBrowse]["tmp_name"],$this->destinationPath.$this->uploadName)){
$result = true;
}else{
$this->setMessage("Upload failed , try later !");
}
}else{
$this->setMessage("Invalid file format !");
}
return $result;
}
function deleteUploaded(){
unlink($this->destinationPath.$this->uploadName);
}
}
?>
Using Uploader.php
<?php
$uploader = new Uploader();
$uploader->setDir('uploads/images/');
$uploader->setExtensions(array('jpg','jpeg','png','gif')); //allowed extensions list//
$uploader->setMaxSize(.5); //set max file size to be allowed in MB//
if($uploader->uploadFile('txtFile')){ //txtFile is the filebrowse element name //
$image = $uploader->getUploadName(); //get uploaded file name, renames on upload//
}else{//upload failed
$uploader->getMessage(); //get upload error message
}
?>
For handling multiple uploads , ex 3 images uploading
repeat the block as follows
<?php
for($i=1;$i<=3;$i++){
$uploader->setExtensions(array('jpg','jpeg','png','gif')); //allowed extensions list//
$uploader->setMaxSize(.5); //set max file size to be allowed in MB//
$uploader->setSequence($i);
if($uploader->uploadFile('txtFile'.$i)){ //txtFile is the filebrowse element name //
$image = $uploader->getUploadName(); //get uploaded file name, renames on upload//
}else{//upload failed
$uploader->getMessage(); //get upload error message
}
}
?>
in above example , file browse components are named as txtFile1,txtFile2,txtFile3
Hope you will understand my explanation .

Categories