How to differentiate filename without hardcoding it? - php

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.

Related

Problem of Curly Brackets in my controller Php Symfony

I want to call my function but when I call it I have a problem with curly Brackets at the end of my code and i have this error Error SYMFONY ( {} ) in my Controller.
I have no idea where to put them for my code to work. I have this problem when I add my function that allows me to retrieve the
history of the action. The mentioned function goes as this:
$this->logHistory->addHistoryConnection($project->getId(), $user->getId(), 'Delete Local Suf', $sf_code);
Function Supp Suf
/**
* #Route("/creation/suf/supp", name="suf_supp")
*/
public function suf(
Request $request,
ShapesRepository $shapesRepository
) {
$params = $this->requestStack->getSession();
$projet = $params->get('projet');
$modules = $params->get('modules');
$fonctionnalites = $params->get('fonctionnalites');
$user = $this->getUser()->getUserEntity();
$manager = $this->graceManager;
$mapManager = $this->mapManager;
$countElements = $mapManager->getCount();
$shapes = $shapesRepository->findBy(array('projet' => $projet->getId()));
$adresseWeb = $this->getParameter('adresse_web');
$carto = $params->get('paramCarto');
$centrage = $params->get('centrage');
$cableColor = $params->get('cableColor');
$sf_code = '';
if ($request->get('suf') != '') {
$sf_code = $request->get('suf');
}
$suf = $manager->getSuf($sf_code);
$success = '';
$error = '';
$warning = '';
if ($request->query->get('success')) {
$success = $request->query->get('success');
} elseif ($request->query->get('error')) {
$error = $request->query->get('error');
} elseif ($request->query->get('warning')) {
$warning = $request->query->get('warning');
}
if ($request->isMethod('POST')) {
if ($request->request->get('sf_code') != '') {
$sf_code = $request->request->get('sf_code');
}
if ($request->get('val') != '') {
$val = $request->get('val');
}
$dir = $this->getparameter('client_directory');
$dossier = str_replace(' ', '_', $projet->getProjet());
$dir = $dir . $dossier . '/documents/';
$cable = $val[0];
$chem = $val[1];
$t_suf = $this->graceCreator->supprimeSuf($sf_code, $cable, $chem);
if ($t_suf[0][0] == '00000') {
$this->logHistorique->addHistoryConnection($projet->getId(), $user->getId(), 'Suppression Suf Local', $sf_code);
// $creator->delDirObjet( $st_code, $dir );
$data = new JsonResponse(array("success" => "create!"));
return $data;
} else {
$data = new JsonResponse(array("error" => "Error : " . $t_suf));
return $data;
}
return $this->render('Modifications/supSuf.html.twig', array(
'user' => $user,
'paramCarto' => $carto,
'cableColor' => $cableColor,
'suf' => $suf,
'adresseWeb' => $adresseWeb,
'centrage' => $centrage,
'shapes' => $shapes,
'projet' => $projet,
'modules' => $modules,
'fonctionnalites' => $fonctionnalites,
'countElements' => $countElements
));
}
}
Your only return statement is inside of an if condition. If the code does not pass the condition, it has nothing to return. The code must return something in all possible cases. If you are not still used to these practices, an IDE might guide you until it becomes a routine. PHPStorm is my personal preference.
BTW, I recommend you to switch from the array() syntax to the more globally accepted [] although you must be in PHP 5.4 or higher.

Access variable outside of Excel::load in Laravel

I would like to ask if how can I access the error message variable when I execute the a foreach loop inside the Excel::load function which reads the csv file that I uploaded so that I can return it via the Response::json();
Here's my code:
$errorMessage['error'] = [];
if($request->hasFile('file')){
if($request->file('file')->getClientOriginalExtension() != "csv"){
$errorMessage['error'][] = "File should be in csv format";
}
else {
$fileName = $request->file('file')->getClientOriginalName().".csv";
$destination = base_path().'/storage/excel/imports';
$request->file('file')->move($destination, $fileName);
$csvFile = base_path().'/storage/excel/imports/'.$fileName;
$demographics = $request->get('demographics');
\Excel::load($csvFile, function($reader) use($demographics,$errorMessage) {
if($demographics == "region"){
foreach($reader->get()->toArray() as $data){
$region = Region::whereRaw("LCASE(`short_name`) = ?", array(strtolower($data['region_name'])))->first();
if($region){
$regionData = Region::find($region->id);
$regionData->total_number_of_provinces = $data['total_provinces'];
$regionData->total_number_of_cities_municipalities = $data['total_cities_and_municipalities'];
$regionData->save();
}
else {
$errorMessage['error'][] = $data['region_name'] . " is not existing in the database";
}
}
}
});
}
}
else {
$errorMessage['error'][] = "Please specify a file";
}
return \Response::json($errorMessage);
Bit smelly, but you can declare it a class property.
/**
* #var array
*/
protected $errorMessage;
public function doStuff()
{
// ...
\Excel::load($file, function($reader) use ($demographics) {
// ...
$this->errormessage['error'][] = $data['region_name'];
});
// ...
return \Response::json($this->errorMessage);
}
Note
You can also pass $errorMessage by reference, which a lot of people think is the better choice (you're using a throw-away function after all).
\Excel::load($file, function($reader) use ($demographics, &$errorMessage)
I don't like to do this however, because in my opinion it's less readable what I meant to do. You can choose one of either picks though!
Useful and short explanation: http://culttt.com/2013/03/25/what-are-php-lambdas-and-closures/
$fileName = md5(time()) .'.'.$request->file('file')->getClientOriginalExtension();
$sheet_id = $request->session()->get('sheet_id');
$excel=Excel::load(public_path('/uploads/importsheet/'.$fileName),function ($reader)use ($sheet_id) {
$reader->each(function($sheet) use ($sheet_id) {
$headings = $sheet->keys()->toArray();
for($i=0; $i<count($headings); $i++){
$sheet_id = DB::table('import_sheets_attributes')->insertGetId(
[
'import_sheets_id' => $sheet_id,
'attribute' => $headings[$i],
'created_at' => date('Y-m-d H:i:s'),
'updated_at' => date('Y-m-d H:i:s')
]);
}
});
});
Hope the above sample code will help.

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.

Batch-API: what am I doing wrong in this code?

I am trying to develop a module to insert a lot of node at one time and I would like to use Batch-API to display the progress of operations.
I read the example into 'Example' module and I wrote this code.
But don't made anything. I can see the progress bar go head but it don't save any node.
Can anyone help me on this?
function custom_content_archive_import_contents_submit($form, &$form_state) {
$file=$form_state['values']['file'];
unset($form_state['values']['file']);
$file->status = FILE_STATUS_PERMANENT;
file_save($file);
drupal_set_message(t('The file #filename was uploaded successfully.', array('#filename' => $file->filename)));
ini_set('auto_detect_line_endings',TRUE);
$path = drupal_realpath($file->uri);
$importer = new CsvImporter($path, true, variable_get('custom_content_archive_file_delimiter'), variable_get('custom_content_archive_file_enclosure'));
$data = $importer->get();
ini_set('auto_detect_line_endings',FALSE);
$_SESSION['http_request_count'] = 0; // reset counter for debug information.
$all_data = array(
'ctype' => $form_state['values']['list'],
'data' => $data,
'user' => $form_state['values']['user'],
'lang' => $form_state['values']['languages'],
);
batch_set(start_batch_creation_nodes($all_data));
}
function start_batch_creation_nodes($all_data) {
$num_operations = count($all_data['data']);
$operations = array();
$i = 0;
// leggo il file uploadato e creo i nodi
foreach ($all_data['data'] as $node) {
$operations[] = array('create_node',
array($node,
$all_data['ctype'],
$all_data['user'],
$all_data['lang'],
t('(Operation #operation)', array('#operation' => $i))
)
);
$i++;
}
$batch = array(
'operations' => $operations,
'finished' => 'custom_content_archive_import_contents_finished',
);
return $batch;
}
function create_node($arrnode, $ctype, $user, $lang, $operation_details, &$context) {
$node = new stdClass(); // Create a new node object
$node->type = $ctype; // Or page, or whatever content type you like
node_object_prepare($node); // Set some default values
$node->uid = $user; // UID of the author of the node; or use $node->name
$node->language = $lang; // Or e.g. 'en' if locale is enabled
$node->promote = 0;
foreach ($arrnode as $field => $value){
switch ($field) {
case 'title':
$node->title = $arrnode['title'];
break;
case'body':
$node->body[LANGUAGE_NONE][0]['value'] = nl2br($arrnode['body']);
$node->body[LANGUAGE_NONE][0]['summary'] = text_summary($bodytext);
$node->body[LANGUAGE_NONE][0]['format'] = 'filtered_html';
break;
default:
$arrfield = field_info_field($field);
switch ($arrfield['type']) {
case 'datetime':
$my_date = new DateTime($value);
$node->{$field}[LANGUAGE_NONE][0][value] = date_format($my_date, 'Y-m-d H:i:s');
break;
case 'text':
$node->{$field}[LANGUAGE_NONE][0][value] = $value;
break;
case 'email':
$node->{$field}[LANGUAGE_NONE][0][email] = $value;
break;
case 'link_field':
$node->{$field}[LANGUAGE_NONE][0][url] = $value;
break;
}
}
}
if($node = node_submit($node)) { // Prepare node for saving
node_save($node);
workflow_execute_transition($node, 3, $comment = NULL, $force = TRUE);
// Store some results for post-processing in the 'finished' callback.
// The contents of 'results' will be available as $results in the
// 'finished' function (in this example, batch_example_finished()).
$context['results'][] = $node->nid . ' : ' . check_plain($node->title);
// Optional message displayed under the progressbar.
$context['message'] = t('Saving node "#title"', array('#title' => $node->title)) . ' ' . $operation_details;
_custom_content_archive_import_contents_update_http_requests();
}
}
function custom_content_archive_import_contents_finished($success, $results, $operations) {
if ($success) {
// Here we could do something meaningful with the results.
// We just display the number of nodes we processed...
drupal_set_message(t('#count results processed in #requests HTTP requests.', array('#count' => count($results), '#requests' => _custom_content_archive_import_contents_get_http_requests())));
drupal_set_message(t('The final result was "%final"', array('%final' => end($results))));
} else {
// An error occurred.
// $operations contains the operations that remained unprocessed.
$error_operation = reset($operations);
drupal_set_message(t('An error occurred while processing #operation with arguments : #args', array('#operation' => $error_operation[0], '#args' => print_r($error_operation[0], TRUE))));
}
}
function _custom_content_archive_import_contents_update_http_requests() {
$_SESSION['http_request_count']++;
}
function _custom_content_archive_import_contents_get_http_requests() {
return !empty($_SESSION['http_request_count']) ? $_SESSION['http_request_count'] : 0;
}
You have to include node.pages.inc in your function to make node_object_prepare() work.
module_load_include('inc', 'node', 'node.pages');

How do I do File uploading in Zend Framework 2?

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

Categories