How do I do File uploading in Zend Framework 2? - php

I have been looking into file uploading in ZF2.
I understand that many of you will think that this is too vague a question, but what is the best way to create form elements which have a bit more processing?
I can't seem to work out where to start. I have ruled out processing it in the controller as this will break DRY principles. The form object doesn't seem to have a place to 'hook' any code into. The view helper is just that, for the view so it doesn't make sense to do anything in that. So that leaves the input filter. That doesn't seem right either.
I have been steered towards transfer adapters but the code looks like it's not very ZF2.
I'm sorry that this is such a vague question and I'm hoping it falls on sympathetic ears. It's hard learning a framework that has very little documentation and compounded with the fact that my zend framework 1 knowledge is a little thin it, progress is a little slow.
Once I have a good example working I will perhaps find some place to post it.

it's simple:
[In Your Controller]
$request = $this->getRequest();
if($request->isPost()) {
$files = $request->getFiles()->toArray();
$httpadapter = new \Zend\File\Transfer\Adapter\Http();
$filesize = new \Zend\Validator\File\Size(array('min' => 1000 )); //1KB
$extension = new \Zend\Validator\File\Extension(array('extension' => array('txt')));
$httpadapter->setValidators(array($filesize, $extension), $files['file']['name']);
if($httpadapter->isValid()) {
$httpadapter->setDestination('uploads/');
if($httpadapter->receive($files['file']['name'])) {
$newfile = $httpadapter->getFileName();
}
}
}
UPDATE :
I found better way to use file validation with form validation :
Add this class to your module e.g : Application/Validators/File/Image.php
<?php
namespace Application\Validators\File;
use Application\Validator\FileValidatorInterface;
use Zend\Validator\File\Extension;
use Zend\File\Transfer\Adapter\Http;
use Zend\Validator\File\FilesSize;
use Zend\Filter\File\Rename;
use Zend\Validator\File\MimeType;
use Zend\Validator\AbstractValidator;
class Image extends AbstractValidator
{
const FILE_EXTENSION_ERROR = 'invalidFileExtention';
const FILE_NAME_ERROR = 'invalidFileName';
const FILE_INVALID = 'invalidFile';
const FALSE_EXTENSION = 'fileExtensionFalse';
const NOT_FOUND = 'fileExtensionNotFound';
const TOO_BIG = 'fileFilesSizeTooBig';
const TOO_SMALL = 'fileFilesSizeTooSmall';
const NOT_READABLE = 'fileFilesSizeNotReadable';
public $minSize = 64; //KB
public $maxSize = 1024; //KB
public $overwrite = true;
public $newFileName = null;
public $uploadPath = './data/';
public $extensions = array('jpg', 'png', 'gif', 'jpeg');
public $mimeTypes = array(
'image/gif',
'image/jpg',
'image/png',
);
protected $messageTemplates = array(
self::FILE_EXTENSION_ERROR => "File extension is not correct",
self::FILE_NAME_ERROR => "File name is not correct",
self::FILE_INVALID => "File is not valid",
self::FALSE_EXTENSION => "File has an incorrect extension",
self::NOT_FOUND => "File is not readable or does not exist",
self::TOO_BIG => "All files in sum should have a maximum size of '%max%' but '%size%' were detected",
self::TOO_SMALL => "All files in sum should have a minimum size of '%min%' but '%size%' were detected",
self::NOT_READABLE => "One or more files can not be read",
);
protected $fileAdapter;
protected $validators;
protected $filters;
public function __construct($options)
{
$this->fileAdapter = new Http();
parent::__construct($options);
}
public function isValid($fileInput)
{
$options = $this->getOptions();
$extensions = $this->extensions;
$minSize = $this->minSize;
$maxSize = $this->maxSize;
$newFileName = $this->newFileName;
$uploadPath = $this->uploadPath;
$overwrite = $this->overwrite;
if (array_key_exists('extensions', $options)) {
$extensions = $options['extensions'];
}
if (array_key_exists('minSize', $options)) {
$minSize = $options['minSize'];
}
if (array_key_exists('maxSize', $options)) {
$maxSize = $options['maxSize'];
}
if (array_key_exists('newFileName', $options)) {
$newFileName = $options['newFileName'];
}
if (array_key_exists('uploadPath', $options)) {
$uploadPath = $options['uploadPath'];
}
if (array_key_exists('overwrite', $options)) {
$overwrite = $options['overwrite'];
}
$fileName = $fileInput['name'];
$fileSizeOptions = null;
if ($minSize) {
$fileSizeOptions['min'] = $minSize*1024 ;
}
if ($maxSize) {
$fileSizeOptions['max'] = $maxSize*1024 ;
}
if ($fileSizeOptions) {
$this->validators[] = new FilesSize($fileSizeOptions);
}
$this->validators[] = new Extension(array('extension' => $extensions));
if (! preg_match('/^[a-z0-9-_]+[a-z0-9-_\.]+$/i', $fileName)) {
$this->error(self::FILE_NAME_ERROR);
return false;
}
$extension = pathinfo($fileName, PATHINFO_EXTENSION);
if (! in_array($extension, $extensions)) {
$this->error(self::FILE_EXTENSION_ERROR);
return false;
}
if ($newFileName) {
$destination = $newFileName.".$extension";
if (! preg_match('/^[a-z0-9-_]+[a-z0-9-_\.]+$/i', $destination)) {
$this->error(self::FILE_NAME_ERROR);
return false;
}
} else {
$destination = $fileName;
}
$renameOptions['target'] = $uploadPath.$destination;
$renameOptions['overwrite'] = $overwrite;
$this->filters[] = new Rename($renameOptions);
$this->fileAdapter->setFilters($this->filters);
$this->fileAdapter->setValidators($this->validators);
if ($this->fileAdapter->isValid()) {
$this->fileAdapter->receive();
return true;
} else {
$messages = $this->fileAdapter->getMessages();
if ($messages) {
$this->setMessages($messages);
foreach ($messages as $key => $value) {
$this->error($key);
}
} else {
$this->error(self::FILE_INVALID);
}
return false;
}
}
}
Use in form and add filterInput :
array(
'name' => 'file',
'required' => true,
'validators' => array(
array(
'name' => '\Application\Validators\File\Image',
'options' => array(
'minSize' => '64',
'maxSize' => '1024',
'newFileName' => 'newFileName2',
'uploadPath' => './data/'
)
)
)
)
And in your controller :
$postData = array_merge_recursive((array)$request->getPost(), (array)$request->getFiles());
$sampleForm->setData($postData);
if ($sampleForm->isValid()) {
//File will be upload, when isValid returns true;
} else {
var_dump($sampleForm->getMessages());
}

This is a old question, but in case someone else get here, I found this good article:
Create Simple Upload Form with File Validation
This is a good start to work with files in ZF2. ;)

From what i asked / seen in irc (#Zftalk.2) the file component is yet to be refactored

to retrieve the $_FILES, you do the following in the controller:
$request= $this->getRequest();
if($request->isPost()){
$post= array_merge_recursive($request->getPost()->toArray(), $request->getFiles()->toArray());
print_r($post);
}
This post is old but i hope this helps someone.

File upload factory and validation is scheduled to ZF2.1
Mean while I use $_FILES :(
Check the following links:
http://www.michaelgallego.fr/blog/?p=190
http://packages.zendframework.com/docs/latest/manual/en/modules/zend.form.quick.start.html

Related

Codeigniter 4 Multiple Image Upload Issue

When I update the database, it uploads a single image. How do I upload multiple?
$id = $this->request->getPost('id');
$model = new UrunModel();
$file = $this->request->getFile('resim');
$resim_eski = $model->find($id);
if($file->isValid() && !$file->hasMoved()){
$eski_resim = $resim_eski['resim'];
if(file_exists("dosyalar/uploads".$eski_resim)){
unlink("dosyalar/uploads".$eski_resim);
}
$imagename = $file->getRandomName();
$file->move("dosyalar/uploads", $imagename);
}else{
$imagename = $resim_eski['resim'];
}
if ($this->request->getFileMultiple('images')) {
foreach($this->request->getFileMultiple('images') as $res)
{
$res->move(WRITEPATH . 'dosyalar/uploads');
$data=[
'baslik' => $this->request->getPost('baslik'),
'slug' => mb_url_title($this->request->getPost('baslik'), '-', TRUE),
'kisa_aciklama' => $this->request->getPost('kisa_aciklama'),
'kategori' => $this->request->getPost('kategori'),
'query_kategori' => $this->request->getPost('query_kategori'),
'aciklama' => $this->request->getPost('aciklama'),
'fiyat' => $this->request->getPost('fiyat'),
'indirimli_fiyat' => $this->request->getPost('indirimli_fiyat'),
'resim' => $imagename,
'resimler' => $res->getClientName(),
'type' => $res->getClientMimeType()
];
$model -> update($id,$data);
}
}
return redirect()->to(base_url('yonetim/urunler'));
}
Controller code above, I've been struggling for 2 days, I couldn't manage it somehow.
When I run the code, it just adds 1 image to each product. I want to add more than one image to 1 product for the gallery part. Any suggestions for this code or a different solution?
function add()
{
$length = count($_FILES['image']['name']);
$filename = $_FILES['image']['name'];
$tempname = $_FILES['image']['tmp_name'];
$allimage = array();
foreach($filename as $key =>$value)
{
move_uploaded_file($tempname[$key],'media/uploads/mobile_product/'.$filename[$key]);
$allimage[] = $filename[$key];
}
if(!empty($allimage))
{
$allimage = json_encode($allimage);
}
else
{
$allimage = '';
}
$data['image'] = $allimage;
$this->db->insert('table',$data);
}
CI4 Controller:
if($this->request->getFileMultiple('image_files')) {
$files = $this->request->getFileMultiple('image_files');
foreach ($files as $file) {
if ($file->isValid() && ! $file->hasMoved())
{
$newNames = $file->getRandomName();
$imageFiles = array(
'filename' => $newNames
);
$modelName->insert($imageFiles );
$file->move('uploads/', $newNames);
}
}
}
HTML
<input type="file" name="image_files[]">
This is the shortest way to do that

Can't upload file more than 2 MB in codeigniter 4

i can't upload file more than 2 MB in codeigniter 4. How to increase the limit size in codeingiter 4?
public function store()
{
helper('text');
$data = $this->request->getPost();
if($data['type'] === 'structure and written expression'){
$file = $this->request->getFile('story');
$path = WRITEPATH.'uploads';
$filename = $file->getRandomName();
$file->move($path, $filename);
$data = [
'type' => $data['type'],
'text_question' => $filename
];
}
$story = new StoryModel;
$id = $story->insert($data);
if($story->errors())
{
return $this->fail($story->errors());
}
if($id === false)
{
return $this->failServerError("Server Error");
}
$data=null;
return $this->respondCreated(['status' => 'created success', 'id'=>$id]);
}
this is my create function in controller
I agree what in link with Marged shared, and you can add more code to compress image with:
$config['quality']='50%';

How to differentiate filename without hardcoding it?

i have a config like so :
$CONF['log']['TSEL_MV_GW_SERV101_MT_CONNECTOR_STATUS'] = array(
'folder' => $CONF['mainFolder']."/log_sample/tsel",
'files' => array(
'connector_access_log*.log',
'engine_dr_to_app_hit_dr_url*.log'
)
);
then i'm getting all the files with that pattern that has today date.
foreach($CONF['log'] as $label => $arrayData){
$filePaths = array();
$today = date("Ymd", time());
foreach($arrayData['files'] as $filePrefix){
$glob = glob($arrayData['folder']."/".$filePrefix, GLOB_ERR);
if(count($glob) >= 1){
foreach($glob as $file){
if(strpos($file, $today)){
$filePaths[] = $file;
}
}
}
}
}
$filePaths array content :
Array
(
[0] =>/dirpath/connector_access_log_20171025.log
[1] =>/dirpath/engine_dr_to_app_hit_dr_url_20171025.log
)
Now, i need to process each file differently, how can i do this using foreach loop ?
using hardcode such as if(preg_match("connector_access_log")) is not allowed.
this is my approach before :
foreach($filePaths as $filePath){
if(preg_match("/connector_access_log_/", $filePath, $match)){
#some code
} else if (preg_match("/engine_dr_to_app_hit_dr_url_/", $filePath, $match)){
#some code
}
}
What you could do is, you could tweak the configuration to store files in assosiative array Eg.
$CONNECTOR_ACCESS_LOG = 'connector_access_log'
$ENGINE_URL_LOG = 'engine_dr_to_app_hit_dr_url'
$CONF['log']['TSEL_MV_GW_SERV101_MT_CONNECTOR_STATUS'] = array(
'folder' => $CONF['mainFolder']."/log_sample/tsel",
'files' => array(
$CONNECTOR_ACCESS_LOG => 'connector_access_log*.log',
$ENGINE_URL_LOG => 'engine_dr_to_app_hit_dr_url*.log'
)
);
And then in the loop you can get these keys and switch case between them. Eg.
foreach($CONF['log'] as $label => $arrayData){
$today = date("Ymd", time());
foreach($arrayData['files'] as $filetype => $filePrefix){
$glob = glob($arrayData['folder']."/".$filePrefix, GLOB_ERR);
if(count($glob) >= 1){
foreach($glob as $file){
if(strpos($file, $today)){
switch($filetype) {
case $CONNECTOR_ACCESS_LOG: doConnection($file); break;
case $ENGINE_URL_LOG : doEngine($file); break;
}
}
}
}
}
}
Please pardon my php syntax, i am just trying to give an idea.
If you really don't want to use a hardcode you should pass a handler for each file type through your config. Like mostly frameworks do. Please see yii2 logger for more examples. Here is a piece of pseudocode:
$CONF['log']['TSEL_MV_GW_SERV101_MT_CONNECTOR_STATUS'] = array(
new FirstLogger($CONF['mainFolder']."/log_sample/tsel", 'connector_access_log*.log'),
new SecondLogger($CONF['mainFolder']."/log_sample/tsel", 'engine_dr_to_app_hit_dr_url*.log'),
);
Next, proccess your log files by your handler in your handler class.
class FirstLogger
{
protected $dir = null;
protected $fileWildCard = null;
public function __construct($dir, $fileWildcard)
{
$this->dir = $dir;
$this->fileWildCard = $fileWildcard;
}
public function getFiles()
{
$filePaths = [];
$today = date("Ymd", time());
$glob = glob($this->dir."/".$this->fileWildCard, GLOB_ERR);
if(count($glob) >= 1){
foreach($glob as $file){
if(strpos($file, $today)){
$filePaths[] = $file;
}
}
}
return $filePaths;
}
public function handleLogs()
{
$files = $this->getFiles();
//some of your logic
}
}
Next, you probably want to create an interface for all of your loggers and an abstract class from which your loggers will be inherited.

ValidatorPluginManager get fails to do its job in model input filter

I have a question about Abstract Validators. I was trying to implement the solution of Mb Rostami found here.
This is the error I get:
Zend\Validator\ValidatorPluginManager::get was unable to fetch or create an instance for Application\Validators\File\Image
All I need to do I guess is to somehow inject the class into the model. What is Application\Validators\File\Image?
So how to fix this error? Most easy solution would be to add the validator class as an invocable to the module?
The input filter in model class:
public function getInputFilter()
{
if (!$this->inputFilter) {
$inputFilter = new InputFilter();
$inputFilter->add(array(
'name' => 'eid',
'required' => true,
'filters' => array(
array('name' => 'Int'),
)
));
$newFileName = sha1(time(), true);
$inputFilter->add(
array(
'name' => 'ImageValidator',
'required' => true,
'validators' => array(
array(
'name' => '\Application\Validators\File\Image',
'options' => array(
'minSize' => '64',
'maxSize' => '5120',
'newFileName' => $newFileName,
'uploadPath' => './data/'
),
),
)
)
);
$this->inputFilter = $inputFilter;
}
return $this->inputFilter;
}
Validator class:
<?php
namespace Application\Validators\File;
use Zend\Validator\File\Extension;
use Zend\File\Transfer\Adapter\Http;
use Zend\Validator\File\FilesSize;
use Zend\Filter\File\Rename;
use Zend\Validator\File\MimeType;
use Zend\Validator\AbstractValidator;
class Image extends AbstractValidator
{
const FILE_EXTENSION_ERROR = 'invalidFileExtention';
const FILE_NAME_ERROR = 'invalidFileName';
const FILE_INVALID = 'invalidFile';
const FALSE_EXTENSION = 'fileExtensionFalse';
const NOT_FOUND = 'fileExtensionNotFound';
const TOO_BIG = 'fileFilesSizeTooBig';
const TOO_SMALL = 'fileFilesSizeTooSmall';
const NOT_READABLE = 'fileFilesSizeNotReadable';
public $minSize = 64; //KB
public $maxSize = 1024; //KB
public $overwrite = true;
public $newFileName = null;
public $uploadPath = './data/';
public $extensions = array('jpg', 'png', 'gif', 'jpeg');
public $mimeTypes = array(
'image/gif',
'image/jpg',
'image/png',
);
protected $messageTemplates = array(
self::FILE_EXTENSION_ERROR => "File extension is not correct",
self::FILE_NAME_ERROR => "File name is not correct",
self::FILE_INVALID => "File is not valid",
self::FALSE_EXTENSION => "File has an incorrect extension",
self::NOT_FOUND => "File is not readable or does not exist",
self::TOO_BIG => "All files in sum should have a maximum size of '%max%' but '%size%' were detected",
self::TOO_SMALL => "All files in sum should have a minimum size of '%min%' but '%size%' were detected",
self::NOT_READABLE => "One or more files can not be read",
);
protected $fileAdapter;
protected $validators;
protected $filters;
public function __construct($options)
{
$this->fileAdapter = new Http();
parent::__construct($options);
}
public function isValid($fileInput)
{
$options = $this->getOptions();
$extensions = $this->extensions;
$minSize = $this->minSize;
$maxSize = $this->maxSize;
$newFileName = $this->newFileName;
$uploadPath = $this->uploadPath;
$overwrite = $this->overwrite;
if (array_key_exists('extensions', $options)) {
$extensions = $options['extensions'];
}
if (array_key_exists('minSize', $options)) {
$minSize = $options['minSize'];
}
if (array_key_exists('maxSize', $options)) {
$maxSize = $options['maxSize'];
}
if (array_key_exists('newFileName', $options)) {
$newFileName = $options['newFileName'];
}
if (array_key_exists('uploadPath', $options)) {
$uploadPath = $options['uploadPath'];
}
if (array_key_exists('overwrite', $options)) {
$overwrite = $options['overwrite'];
}
$fileName = $fileInput['name'];
$fileSizeOptions = null;
if ($minSize) {
$fileSizeOptions['min'] = $minSize * 1024;
}
if ($maxSize) {
$fileSizeOptions['max'] = $maxSize * 1024;
}
if ($fileSizeOptions) {
$this->validators[] = new FilesSize($fileSizeOptions);
}
$this->validators[] = new Extension(array('extension' => $extensions));
if (!preg_match('/^[a-z0-9-_]+[a-z0-9-_\.]+$/i', $fileName)) {
$this->error(self::FILE_NAME_ERROR);
return false;
}
$extension = pathinfo($fileName, PATHINFO_EXTENSION);
if (!in_array($extension, $extensions)) {
$this->error(self::FILE_EXTENSION_ERROR);
return false;
}
if ($newFileName) {
$destination = $newFileName . ".$extension";
if (!preg_match('/^[a-z0-9-_]+[a-z0-9-_\.]+$/i', $destination)) {
$this->error(self::FILE_NAME_ERROR);
return false;
}
} else {
$destination = $fileName;
}
$renameOptions['target'] = $uploadPath . $destination;
$renameOptions['overwrite'] = $overwrite;
$this->filters[] = new Rename($renameOptions);
$this->fileAdapter->setFilters($this->filters);
$this->fileAdapter->setValidators($this->validators);
if ($this->fileAdapter->isValid()) {
$this->fileAdapter->receive();
return true;
} else {
$messages = $this->fileAdapter->getMessages();
if ($messages) {
$this->setMessages($messages);
foreach ($messages as $key => $value) {
$this->error($key);
}
} else {
$this->error(self::FILE_INVALID);
}
return false;
}
}
}
The solution was simple, at least in my case. Like I mentioned above: check the folder structure. Zend Framework has it's own way of structuring project files, so the file path needs to match.

Why is my app running out of memory? Unsetting variables, using chunk

I have the simple app below. I'm turning off query logging in Laravel, I'm unsetting where possible, yet this function will only process about 800 records before I'm out of RAM on my 2GB Linode. I know I'm asking a lot of you guys but I can't seem to see where I'm leaking memory.
There are really only two major steps.
Step 1 - Move records from a temp table to production
class ListingMigrator
{
public function __construct($tempListing, $feed)
{
$this->tempListing = $tempListing;
$this->listing = $this->listingInstance();
$this->feed = $feed;
}
public static function migrateListing($listing, $feed)
{
$instance = new static($listing, $feed);
return $instance->migrate();
}
public function migrate()
{
$this->addExternalData();
$this->populateListing();
$this->processPhotos();
$this->deleteTempListing();
}
private function listingInstance()
{
DB::connection()->disableQueryLog();
$listing = Listing::findByMud($this->tempListing->matrix_unique_id);
return $listing ?: new Listing;
}
private function processPhotos()
{
$retsApi = new RetsFeedApi($this->feed);
/* Initialize Object */
$rets = $retsApi->findMostRecent();
$photos = $rets->getPhotosForListing($this->listing->matrix_unique_id);
foreach ($photos as $photo)
{
$uploader = new PhotoProcessor($this->listing, $photo);
$uploader->process();
}
}
private function populateListing()
{
DB::connection()->disableQueryLog();
$this->listing->fill($this->tempListing->toArray());
$this->listing->imported_at = $this->tempListing->created_at;
$this->listing->board = $this->tempListing->board;
return $this->listing->save();
}
private function addExternalData()
{
// Get Google lattitude and longitude
$googlecoords = getGoogleMapInfo($this->tempListing->FullAddress, $this->tempListing->City);
$this->listing->GoogleLat = $googlecoords['GoogleLat'];
$this->listing->GoogleLong = $googlecoords['GoogleLong'];
// Add or update the Subdivision Table (helper function)
$subdivisiondata = SubdivisionUpdate($this->tempListing->board, $this->tempListing->SubCondoName, $this->tempListing->Development);
$this->listing->SubdivisionID = $subdivisiondata['id'];
}
private function deleteTempListing()
{
return $this->tempListing->delete();
}
}
Step 2 - Download photos and reupload to Amazon S3
class PhotoProcessor
{
public function __construct(Listing $listing, $photoData)
{
$this->bucket = 'real-estate-listings';
$this->s3 = App::make('aws')->get('s3');
$this->tempFileName = 'app/storage/processing/images/retsphotoupload';
$this->photoData = $photoData;
$this->listing = $listing;
$this->photo = new RetsPhoto;
}
public function process()
{
$this->storeTempFile();
$this->storeFileInfo();
$this->buildPhoto();
$success = $this->pushToS3();
// if Result has the full URL or you want to build it, add it to $this->photo
DB::connection()->disableQueryLog();
$this->listing->photos()->save($this->photo);
$this->removeTempFile();
unset ($this->photoData);
return $success;
}
private function storeTempFile()
{
return File::put($this->tempFileName, $this->photoData['Data']) > 0;
}
private function storeFileInfo()
{
$fileInfo = getimagesize($this->tempFileName);
// Could even be its own object
$this->fileInfo = [
'width' => $fileInfo[0],
'height' => $fileInfo[1],
'mimetype' => $fileInfo['mime'],
'extension' => $this->getFileExtension($fileInfo['mime'])
];
}
private function buildPhoto()
{
$this->photo->number = $this->photoData['Object-ID']; // Storing this because it is relevant order wise
$this->photo->width = $this->fileInfo['width'];
$this->photo->height = $this->fileInfo['height'];
$this->photo->path = $this->getFilePath();
}
private function getFilePath()
{
$path = [];
if ($this->listing->City == NULL)
{
$path[] = Str::slug('No City');
}
else
{
$path[] = Str::slug($this->listing->City, $separator = '-');
}
if ($this->listing->Development == NULL)
{
$path[] = Str::slug('No Development');
}
else
{
$path[] = Str::slug($this->listing->Development, $separator = '-');
}
if ($this->listing->Subdivision == NULL)
{
$pathp[] = Str::slug('No Subdivision');
}
else
{
$path[] = Str::slug($this->listing->Subdivision, $separator = '-');
}
if ($this->listing->MLSNumber == NULL)
{
$pathp[] = Str::slug('No MLSNumber');
}
else
{
$path[] = Str::slug($this->listing->MLSNumber, $separator = '-');
}
$path[] = $this->photoData['Object-ID'].'.'.$this->fileInfo['extension'];
return strtolower(join('/', $path));
}
private function pushToS3()
{
return $this->s3->putObject([
'Bucket' => $this->bucket,
'Key' => $this->photo->path,
'ContentType'=> $this->fileInfo['mimetype'],
'SourceFile' => $this->tempFileName
]);
}
private function getFileExtension($mime)
{
// Use better algorithm than this
$ext = str_replace('image/', '', $mime);
return $ext == 'jpeg' ? 'jpg' : $ext;
}
private function removeTempFile()
{
return File::delete($this->tempFileName);
}
}
Edit to show RetsPhoto
class RetsPhoto extends Eloquent {
protected $table = 'rets_property_photos';
public function listing() {
return $this->belongsTo('Listing', 'matrix_unique_id', 'matrix_unique_id');
}
}
Edit #2: Chunk Call
This is in the app/command and the only thing in there is the fire() function below:
public function fire()
{
// Turn off query logging
DB::connection()->disableQueryLog();
$feeds = RetsFeed::where('active','=',1)->get();
foreach ($feeds as $feed)
{
$class = "TempListing{$feed->board}";
$listings = $class::orderBy('MatrixModifiedDT','desc');
$listings->chunk(50, function($listings) use($feed) {
$listings->each(function($listing) use ($feed) {
ListingMigrator::migrateListing($listing,$feed);
echo "Feed: $feed->board\r\n";
echo "SubcondoName: $listing->SubCondoName\r\n";
echo "Development: $listing->Development\r\n";
echo "\r\n";
});
});
}
}
I think I have figured it out.
Your system holds in memory all of the photo data. As witnessed by the unset ($this->photoData);
The problem is that you need to first complete the process function. Your application is not likely processing ANY photos so when you keep grabbing them from the file system you run out of memory BEFORE you even process a single one.
To Confirm this, simply grab 1 file not using the chunk method.
I am not very familar with Laravel, it could be grabbing all of the files all at once as well and eating the ram.
You can do some tracing with memory_get_usage(true) to find out exactly where the ram is getting eaten from. I would suggest analysing the fire method first.

Categories