file upload cakephp - file

when uploading an image to the server using cakephp
$this->Model->Behaviors->attach('ImageUpload', Configure::read('photo.files'));
photo uploaded successfully, and the database fields also
but shows following error instead of returning to index page.
Notice (8): Undefined index: class [CORE\cake\libs\model\behaviors\upload.php, line 104]
Notice (8): Undefined index: class [CORE\cake\libs\model\behaviors\upload.php, line 107]
Warning (2): Cannot modify header information - headers already sent by (output started at E:\umoorthy_105act10\projects\dev1base\core\cake\basics.php:111) [CORE\cake\libs\controller\controller.php, line 614]
wat to do?

Cake has already wrote where to look for a problem
Configure::read('photo.files')
do following to check if everything is ok
pr(Configure::read('photo.files'))

public function uploadFilesIphone($folder, $formdata, $replace , $itemId = null) {
// setup dir names absolute and relative echo "<pre>"; print_r($formdata); exit;
$folder_url = WWW_ROOT.$folder;
$rel_url = $folder; //echo
// create the folder if it does not exist
if(!is_dir($folder_url)) {
mkdir($folder_url);
}
// if itemId is set create an item folder
if($itemId) {
// set new absolute folder
$folder_url = WWW_ROOT.$folder.'/'.$itemId;
// set new relative folder
$rel_url = $folder.'/'.$itemId;
// create directory
if(!is_dir($folder_url)) {
mkdir($folder_url);
}
}
// list of permitted file types, this is only images but documents can be added
$permitted = array('image/gif','image/jpeg','image/pjpeg','image/png','application/octet-stream');
// loop through and deal with the files;
$key = array();
$value = array();
foreach($formdata as $key => $value)
{
if($key == is_array($value))
{
$filename = str_replace(".", $replace , $value['name']);
}
// replace spaces with underscores
// assume filetype is false
$typeOK = false;
// check filetype is ok
foreach($permitted as $type)
{
if($key == is_array($value))
{
if($type == $value['type'])
{
$typeOK = true;
break;
}
}
}
// if file type ok upload the file
if($typeOK) {
// switch based on error code
if($key == is_array($value))
{
switch($value['error'])
{
case 0:
// check filename already exists
if(!file_exists($folder_url.'/'.$filename))
{
// create full filename
$full_url = $folder_url.'/'.$filename;
$url = $rel_url.'/'.$filename;
// upload the file
if($key == is_array($value))
{
$success = move_uploaded_file($value['tmp_name'], $url);
}
}
else
{
// create unique filename and upload file
// ini_set('date.timezone', 'Europe/London');
$now = date('Y-m-d-His');
$full_url = $folder_url.'/'.$now.$filename;
$url = $rel_url.'/'.$now.$filename;
if($key == is_array($value))
{
$success = move_uploaded_file($value['tmp_name'], $url);
}
}
// if upload was successful
if($success)
{
// save the url of the file
$result['urls'][] = $url;
}
else
{
$result['errors'][] = "Error uploaded $filename. Please try again.";
}
break;
case 3:
// an error occured
$result['errors'][] = "Error uploading $filename. Please try again.";
break;
default:
// an error occured
$result['errors'][] = "System error uploading $filename. Contact webmaster.";
break;
}
}
elseif($value['error'] == 4)
{
// no file was selected for upload
$result['nofiles'][] = "No file Selected";
}
else
{
// unacceptable file type
$result['errors'][] = "$filename cannot be uploaded. Acceptable file types: gif, jpg, png.";
}
}
}
return $result;
}

Related

PUT request with formData could not update using react.js and laravel

I am not receiving formdata in the Api endpoint which is being sent by fetch and PUT method.
I used the POST method and it worked out which i think is not recommended for updating.
I have react running on localhost:3000 and the laravel-API running on localhost:5000.
This is the route in API
Route::put('updateSlide/{id}', 'SlidesController#updateSlide');
This is what is in the controller
public function updateImage(Request $request, int $id)
{
$image = $this->slideRepo->findSlideById($id)->image;
if ($image) {
$result = Storage::disk('ucmp')->delete($image);
}
if ($request->hasFile('image') && $request->file('image') instanceof UploadedFile) {
return $this->slideRepo->saveCover($request->file('image'));
} // return response()->json($data);
// data is an array (note)
return null;
}
public function updateSlide(Request $request, int $id)
{
$imageUrl=$this->updateImage($request, $id);
return response()->json($this->slideRepo->updateSlide([
'caption' => $request['caption'],
'image' => $imageUrl,
'url' => $request['url']
],$id));
}
This is the function sending to fetch
export const updateSlideApi = (token, _slide, id) => {
return {
url: `${BASE_URL}/api/updateSlide/${id}`,
opt: API.requestOptions("PUT",token,null,{ body: _slide }, true)
};
};
In my header i do not have the content-type.
I expect json data from the laravel API function but am having an error, " Can only throw objects"
PHP does not parse the body of a PUT request.
Use POST and add parameter _method with value PUT.
PHP put has given me tough time, use this function will save your time parsing it else method:
function parsePutRequest()
{
// Fetch content and determine boundary
$raw_data = file_get_contents('php://input');
$boundary = substr($raw_data, 0, strpos($raw_data, "\r\n"));
// Fetch each part
$parts = array_slice(explode($boundary, $raw_data), 1);
$data = array();
foreach ($parts as $part) {
// If this is the last part, break
if ($part == "--\r\n") break;
// Separate content from headers
$part = ltrim($part, "\r\n");
list($raw_headers, $body) = explode("\r\n\r\n", $part, 2);
// Parse the headers list
$raw_headers = explode("\r\n", $raw_headers);
$headers = array();
foreach ($raw_headers as $header) {
list($name, $value) = explode(':', $header);
$headers[strtolower($name)] = ltrim($value, ' ');
}
// Parse the Content-Disposition to get the field name, etc.
if (isset($headers['content-disposition'])) {
$filename = null;
preg_match(
'/^(.+); *name="([^"]+)"(; *filename="([^"]+)")?/',
$headers['content-disposition'],
$matches
);
list(, $type, $name) = $matches;
isset($matches[4]) and $filename = $matches[4];
// handle your fields here
switch ($name) {
// this is a file upload
case 'userfile':
file_put_contents($filename, $body);
break;
// default for all other files is to populate $data
default:
$data[$name] = substr($body, 0, strlen($body) - 2);
break;
}
}
}
return $data;
}

Get array data and insert into database

I'm trying to get the data in the array that came from another function(that function is extracting the data in the csv file) and when i tried calling the two fields from that array it shows an error that it is unidentified variables.
The $this->csv_process(); as shown on the function action() is the function that extracts the data from the csv file and stores it in an array which is successful since I tried checking it on var_dump();
I also named the two fields as $name and $email as shown below:
Function CSV_process()
public function csv_process()
{
/* variables for openning the csv file */
if (!in_array($extension, $allowed_ext)) {
$this->session->set_flashdata("message", "Sorry, CSV file only.");
} else {
if ($filesize > 0) {
$file = fopen($filename, "r");
$toWrite = array();
$error = false;
$col_size = 2;
$skip = 0;
while ($data = fgetcsv($file, 10000, ","))
{
$skip++;
if ($skip == 1) {
continue;
}
$numofcol = count($data);
if ($numofcol != $col_size ) {
$this->session->set_flashdata("message", "Column count exceeded or missing.");
} else {
$name1 = $data[0];
$name = str_replace("'", "''", $name1);
$email1 = $data[1];
$email = str_replace("'", "''", $email1);
$toWrite[] = [
'name' => $name,
'email' => $email
];
}
}
}
}
return $toWrite;
}
Function Action()
function action(){
$toWrite[] = $this->csv_process();
foreach ($toWrite as $arr) {
list($name, $email) = $arr;
//die(var_dump($arr));
$query = $this->db->query("SELECT * FROM import WHERE name ='$name' AND email = '$email'");
if ($query->num_rows() >= 1) {
} else {
if ($name == "" OR $email == "") {
} else {
if ((filter_var($email, FILTER_VALIDATE_EMAIL)) == FALSE ) {
} else {
$this->db->query("INSERT INTO import(name, email, created_date) VALUES('".$name."', '".$email."', '".date("Y-m-d h-i-s")."')");
$this->session->set_flashdata('message', 'SUCCESS YEAY');
redirect('Clean_csv/index');
}
}
}
$query->free_result();
}
}
Listing arrays doesn't seem to work for here, anyone knows how to extract the data array from $arr?
You don't need to extract the values. You can use each $arr in a bound query. It simplifies the syntax for the select query.
For inserting use CodeIgniter's insert() method. Again, the $arr can be used directly by adding the date to it before the insert is attempted.
I think this will work.
function action()
{
$toWrite[] = $this->csv_process();
foreach($toWrite as $arr)
{
$query = $this->db->query("SELECT * FROM import WHERE name=? AND email=?", $arr);
if($query->num_rows() >= 1)
{}
else
{
if($arr['name'] == "" OR $arr['email'] == "")
{}
else
{
if((filter_var($email, FILTER_VALIDATE_EMAIL)) == FALSE)
{}
else
{
$arr['created_date'] = date("Y-m-d h-i-s");
$this->db->insert("import", $arr);
$this->session->set_flashdata('message', 'SUCCESS YEAY');
//??? redirect('Clean_csv/index');
//Are you sure, you may still have more $arr in $toWrite to process - right?
}
}
}
$query->free_result();
}
}
You need to know what a terrible idea it is to repeatedly run database queries inside a loop. Even though you use free_result() it could be a massive drain on server resources. If your csv file has several thousand items you are severely stressing the database and the server.

CakePHP 3.x: log as serialized array

I'm writing my own parser log for CakePHP.
I only need one thing: that is not written a log "message" (as a string), but a serialized array with various log information (date, type, line, stack traces, etc.).
But I don't understand what method/class I should rewrite, although I have consulted the APIs. Can you help me?
EDIT:
For now I do the opposite: I read the logs (already written) and I transform them into an array with a regex.
My code:
$logs = array_map(function($log) {
preg_match('/^'.
'([\d\-]+\s[\d:]+)\s(Error: Fatal Error|Error|Notice: Notice|Warning: Warning)(\s\(\d+\))?:\s([^\n]+)\n'.
'(Exception Attributes:\s((.(?!Request|Referer|Stack|Trace))+)\n)?'.
'(Request URL:\s([^\n]+)\n)?'.
'(Referer URL:\s([^\n]+)\n)?'.
'(Stack Trace:\n(.+))?'.
'(Trace:\n(.+))?(.+)?'.
'/si', $log, $matches);
switch($matches[2]) {
case 'Error: Fatal Error':
$type = 'fatal';
break;
case 'Error':
$type = 'error';
break;
case 'Notice: Notice':
$type = 'notice';
break;
case 'Warning: Warning':
$type = 'warning';
break;
default:
$type = 'unknown';
break;
}
return (object) af([
'datetime' => \Cake\I18n\FrozenTime::parse($matches[1]),
'type' => $type,
'error' => $matches[4],
'attributes' => empty($matches[6]) ? NULL : $matches[6],
'url' => empty($matches[9]) ? NULL : $matches[9],
'referer' => empty($matches[11]) ? NULL : $matches[11],
'stack_trace' => empty($matches[13]) ? (empty($matches[16]) ? NULL : $matches[16]) : $matches[13],
'trace' => empty($matches[15]) ? NULL : $matches[15]
]);
}, af(preg_split('/[\r\n]{2,}/', $logs)));
For now I do the opposite: I read the logs (already written) and with a regex I transform them into an array.
The problem is this is terribly expensive. and that it would be better to do the opposite: to write directly to the logs as a serialized array.
I think what you want to do is write your own LogAdapter.
You simply create a class ArrayLog (extends BaseLog) as mentioned in the docs and configure cakePHP to use it. Within the log function you append the information like $level, $message and $context to a file as an array. This will result in a log file with several arrays that then can be split.
That being said, I would suggest to log to the database and read it out instead of parsing.
Ok, that's it!
(note that this code is absolutely experimental, I have yet to test it properly)
One interesting thing that I want to do: for each log, write to the serialized file and also simultaneously in a plan file.
This allows me either to read logs as a plain text file, or they can be manipulated using the serialized file.
use Cake\Log\Engine\FileLog;
class SerializedLog extends FileLog {
protected function _getLogAsArray($level, $message) {
$serialized['level'] = $level;
$serialized['datetime'] = date('Y-m-d H:i:s');
//Sets exception type and message
if(preg_match('/^(\[([^\]]+)\]\s)?(.+)/', $message, $matches)) {
if(!empty($matches[2]))
$serialized['exception'] = $matches[2];
$serialized['message'] = $matches[3];
}
//Sets the exception attributes
if(preg_match('/Exception Attributes:\s((.(?!Request URL|Referer URL|Stack Trace|Trace))+)/is', $message, $matches)) {
$serialized['attributes'] = $matches[1];
}
//Sets the request URL
if(preg_match('/^Request URL:\s(.+)$/mi', $message, $matches)) {
$serialized['request'] = $matches[1];
}
//Sets the referer URL
if(preg_match('/^Referer URL:\s(.+)$/mi', $message, $matches)) {
$serialized['referer'] = $matches[1];
}
//Sets the trace
if(preg_match('/(Stack )?Trace:\n(.+)$/is', $message, $matches)) {
$serialized['trace'] = $matches[2];
}
$serialized['full'] = date('Y-m-d H:i:s').' '.ucfirst($level).': '.$message;
return (object) $serialized;
}
public function log($level, $message, array $context = []) {
$message = $this->_format(trim($message), $context);
$filename = $this->_getFilename($level);
if (!empty($this->_size)) {
$this->_rotateFile($filename);
}
$pathname = $this->_path . $filename;
$mask = $this->_config['mask'];
//Gets the content of the existing logs and unserializes
$logs = #unserialize(#file_get_contents($pathname));
if(empty($logs) || !is_array($logs))
$logs = [];
//Adds the current log
$logs[] = $this->_getLogAsArray($level, $message);
//Serializes logs
$output = serialize($logs);
if (empty($mask)) {
return file_put_contents($pathname, $output);
}
$exists = file_exists($pathname);
$result = file_put_contents($pathname, $output);
static $selfError = false;
if (!$selfError && !$exists && !chmod($pathname, (int)$mask)) {
$selfError = true;
trigger_error(vsprintf(
'Could not apply permission mask "%s" on log file "%s"',
[$mask, $pathname]
), E_USER_WARNING);
$selfError = false;
}
return $result;
}
}

Backup an entire website and database using PHP

I've been at this for a bit now and this is the closest I've gotten to backing up an entire site and database with PHP. The issue is I can't figure out why I continue to receive errors on lines 145 and 154.
Error:Notice: Undefined variable: arr_zip in C:\xampp\htdocs\wordpress\backup.php on line 145
Warning: Invalid argument supplied for foreach() in C:\xampp\htdocs\wordpress\backup.php on line 145
Notice: Undefined variable: delete_zip in C:\xampp\htdocs\wordpress\backup.php on line 154
<?php
ini_set ("max_execution_time", 0);
$dir = "site-backup-stark";
if(!(file_exists($dir)))
{
mkdir($dir, 0777);
}
$host = "localhost"; //host name
$username = "wordpress_user"; //username
$password = "pasword99"; // your password
$dbname = "wordpress_db"; // database name
$zip = new ZipArchive();
backup_tables($host, $username, $password, $dbname);
/* backup the db OR just a table */
function backup_tables($host,$user,$pass,$name,$tables = '*')
{
$con = mysql_connect($host,$user,$pass);
mysql_select_db($name,$con);
//get all of the tables
if($tables == '*')
{
$tables = array();
$result = mysql_query('SHOW TABLES');
while($row = mysql_fetch_row($result))
{
$tables[] = $row[0];
}
}
else
{
$tables = is_array($tables) ? $tables : explode(',',$tables);
}
$return = "";
//cycle through
foreach($tables as $table)
{
$result = mysql_query('SELECT * FROM '.$table);
$num_fields = mysql_num_fields($result);
$return.= 'DROP TABLE '.$table.';';
$row2 = mysql_fetch_row(mysql_query('SHOW CREATE TABLE '.$table));
$return.= "nn".$row2[1].";nn";
while($row = mysql_fetch_row($result))
{
$return.= 'INSERT INTO '.$table.' VALUES(';
for($j=0; $j<$num_fields; $j++)
{
$row[$j] = addslashes($row[$j]);
$row[$j] = preg_replace("#n#","n",$row[$j]);
if (isset($row[$j]))
{
$return.= '"'.$row[$j].'"' ;
}
else
{
$return.= '""';
}
if ($j<($num_fields-1)) { $return.= ','; }
}
$return.= ");n";
}
$return.="nnn";
}
//save file
$handle = fopen('db-backup-'.time().'-'.(md5(implode(',',$tables))).'.sql','w+');
fwrite($handle,$return);
fclose($handle);
}
if (glob("*.sql") != false)
{
$filecount = count(glob("*.sql"));
$arr_file = glob("*.sql");
for($j=0;$j<$filecount;$j++)
{
$res = $zip->open($arr_file[$j].".zip", ZipArchive::CREATE);
if ($res === TRUE)
{
$zip->addFile($arr_file[$j]);
$zip->close();
unlink($arr_file[$j]);
}
}
}
//get the current folder name-start
$path = dirname($_SERVER['PHP_SELF']);
$position = strrpos($path,'/') + 1;
$folder_name = substr($path,$position);
//get the current folder name-end
$zipname = date('Y/m/d');
$str = "stark-".$zipname.".zip";
$str = str_replace("/", "-", $str);
// open archive
if ($zip->open($str, ZIPARCHIVE::CREATE) !== TRUE)
{
die ("Could not open archive");
}
// initialize an iterator
// pass it the directory to be processed
$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator("../$folder_name/"));
// iterate over the directory
// add each file found to the archive
foreach ($iterator as $key=>$value)
{
if( strstr(realpath($key), "stark") == FALSE)
{
$zip->addFile(realpath($key), $key) or die ("ERROR: Could not add file: $key");
}
}
// close and save archive
$zip->close();
echo "Archive created successfully.";
if(glob("*.sql.zip") != false)
{
$filecount = count(glob("*.sql.zip"));
$arr_file = glob("*.sql.zip");
for($j=0;$j<$filecount;$j++)
{
unlink($arr_file[$j]);
}
}
//get the array of zip files
if(glob("*.zip") != false)
{
$arr_zip = glob("*.zip");
}
//copy the backup zip file to site-backup-stark folder
foreach ($arr_zip as $key => $value) //error here
{
if (strstr($value, "stark"))
{
$delete_zip[] = $value;
copy("$value", "$dir/$value");
}
}
for ($i=0; $i < count($delete_zip); $i++) //error here
{
unlink($delete_zip[$i]);
}
?>
In this block of code:
//get the array of zip files
if(glob("*.zip") != false)
{
$arr_zip = glob("*.zip");
}
//copy the backup zip file to site-backup-stark folder
foreach ($arr_zip as $key => $value) //error here
If your call to glob("*.zip") returns a 'falsey' value your variable $arr_zip won't be initialised and you'll get an error in the foreach that follows it. Check for false explicitly with
if(glob("*.zip") !== false)
If this continues to fail you need to investigate why glob() is failing. I don't have a suggestion for that.
Later, you haven't initialised $delete_zip at all, somewhere you need
$delete_zip = array();

File upload does not work on cakePHP 2.x

I am trying to upload the user pictures, but with the following example nothing is getting saved into the database and no errors are given. I know that the validation has to be done and it will once I get the files to be stored.
Here are the snippets from the view file:
<?php
echo $this->Form->create('User', array('enctype' => 'multipart/form-data'));
echo $this->form->input('upload', array('type' => 'file'));
echo $this->Form->end('Submit');
?>
The controller:
public function add() {
if ($this->request->is('post')) {
if(!empty($this->data['User']['upload']['name'])){
$file = $this->data['User']['upload'];
move_uploaded_file($file['tmp_name'], WWW_ROOT . 'img/uploads/users/' . $file['name']);
$this->data['User']['image'] = $file['name'];
}
if ($this->User->save($this->request->data)) {
$this->Session->setFlash('The employee has been saved');
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash('The employee could not be saved. Please, try again.');
}
}
}
change your view like this
<?php echo $this->Form->file('Document.submittedfile'); ?>
and your controller like this
public function fileupload() {
if ($this->request->is('post') || $this->request->is('put')) {
//die();
$file = $this->request->data['Document']['submittedfile'];
//$this->pdfadd1->save($this->request->data);
move_uploaded_file($this->data['Document']['submittedfile']['tmp_name'], $_SERVER['DOCUMENT_ROOT'] . '/cakephp3/cakephp1/cakephp/app/webroot/files/' . $this->data['Document']['submittedfile']['name']);
if ($this->User->save($this->request->data)) {
$this->Session->setFlash(__('Thanks for the submission'));
return $this->redirect(array('controller' => 'users','action' => 'index'));
}
}
dnt forget to create a folder in webroot or in any other place(for uploaded files)
Check the following link :
http://www.jamesfairhurst.co.uk/posts/view/uploading_files_and_images_with_cakephp
public function uploadFilesIphone($folder, $formdata, $replace , $itemId = null) {
// setup dir names absolute and relative
$folder_url = WWW_ROOT.$folder;
$rel_url = $folder; //echo
// create the folder if it does not exist
if(!is_dir($folder_url)) {
mkdir($folder_url);
}
// if itemId is set create an item folder
if($itemId) {
// set new absolute folder
$folder_url = WWW_ROOT.$folder.'/'.$itemId;
// set new relative folder
$rel_url = $folder.'/'.$itemId;
// create directory
if(!is_dir($folder_url)) {
mkdir($folder_url);
}
}
// list of permitted file types, this is only images but documents can be added
$permitted = array('image/gif','image/jpeg','image/pjpeg','image/png','application/octet-stream');
// loop through and deal with the files;
$key = array();
$value = array();
foreach($formdata as $key => $value)
{
if($key == is_array($value))
{
$filename = str_replace(".", $replace , $value['name']);
}
// replace spaces with underscores
// assume filetype is false
$typeOK = false;
// check filetype is ok
foreach($permitted as $type)
{
if($key == is_array($value))
{
if($type == $value['type'])
{
$typeOK = true;
break;
}
}
}
// if file type ok upload the file
if($typeOK) {
// switch based on error code
if($key == is_array($value))
{
switch($value['error'])
{
case 0:
// check filename already exists
if(!file_exists($folder_url.'/'.$filename))
{
// create full filename
$full_url = $folder_url.'/'.$filename;
$url = $rel_url.'/'.$filename;
// upload the file
if($key == is_array($value))
{
$success = move_uploaded_file($value['tmp_name'], $url);
}
}
else
{
// create unique filename and upload file
// ini_set('date.timezone', 'Europe/London');
$now = date('Y-m-d-His');
$full_url = $folder_url.'/'.$now.$filename;
$url = $rel_url.'/'.$now.$filename;
if($key == is_array($value))
{
$success = move_uploaded_file($value['tmp_name'], $url);
}
}
// if upload was successful
if($success)
{
// save the url of the file
$result['urls'][] = $url;
}
else
{
$result['errors'][] = "Error uploaded $filename. Please try again.";
}
break;
case 3:
// an error occured
$result['errors'][] = "Error uploading $filename. Please try again.";
break;
default:
// an error occured
$result['errors'][] = "System error uploading $filename. Contact webmaster.";
break;
}
}
elseif($value['error'] == 4)
{
// no file was selected for upload
$result['nofiles'][] = "No file Selected";
}
else
{
// unacceptable file type
$result['errors'][] = "$filename cannot be uploaded. Acceptable file types: gif, jpg, png.";
}
}
}
return $result;
}

Resources