Move/copy and rename most recently modified file - php

I have a folder with some randomly named files that contain data that I need.
In order to use the data, I have to move the files to another folder and name the file 'file1.xml'
Every time a file is moved and renamed, it replaces a previous 'file1.xml' in the destination folder.
The source folder contains all the other randomly named files which are kept as an archive.
The php will be run via a cron job every 48 hours
The following works, but it's for ftp. I need to edit it for local files.
$conn = ftp_connect('ftp.source.com'); ftp_login($conn, 'username', 'password'); // get file list $files = ftp_nlist($conn, '/data'); $mostRecent = array( 'time' => 0, 'file' => null ); foreach ($files as $file) { // get the last modified time $time = ftp_mdtm($conn, $file); if ($time > $mostRecent['time']) { // this file is the most recent so far $mostRecent['time'] = $time; $mostRecent['file'] = $file; } } ftp_get($conn, "/destinationfolder/file1.xml", $mostRecent['file'], FTP_BINARY); ftp_close($conn);

I didn't test it but I think this should work (comparing your ftp script):
<?php
$conn = ftp_connect('ftp.source.com');
ftp_login($conn, 'username', 'password');
// get file list
$files = ftp_nlist($conn, '/data');
$mostRecent = array( 'time' => 0, 'file' => null );
foreach ($files as $file) {
// get the last modified time
$time = ftp_mdtm($conn, $file);
if ($time > $mostRecent['time']) {
// this file is the most recent so far
$mostRecent['time'] = $time;
$mostRecent['file'] = $file;
}
}
ftp_get($conn, "/destinationfolder/file1.xml", $mostRecent['file'], FTP_BINARY); ftp_close($conn);
?>
New:
<?php
$sourceDir = "./data";
$destDir = "./destinationfolder";
if (!is_dir($sourceDir) || !is_dir($destDir)) {
exit("Directory doesn't exists.");
}
if (!is_writable($destDir)) {
exit("Destination directory isn't writable.");
}
$mostRecentFilePath = "";
$mostRecentFileMTime = 0;
$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($sourceDir), RecursiveIteratorIterator::CHILD_FIRST);
foreach ($iterator as $fileinfo) {
if ($fileinfo->isFile()) {
if ($fileinfo->getMTime() > $mostRecentFileMTime) {
$mostRecentFileMTime = $fileinfo->getMTime();
$mostRecentFilePath = $fileinfo->getPathname();
}
}
}
if ($mostRecentFilePath != "") {
if (!rename($mostRecentFilePath, $destDir . "/file1.xml")) {
exit("Unable to move file.");
}
}
?>

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);

Upload files to user folder

I'm trying to create a new folder within the upload folder so that a user can upload file to there own folder.
Can I do this using PHP or do I need to a column "LONGBLOB" in MYSQL?
I've read that it's not good practice to store images in you database
<?php
header('Content-Type: application/json');
$succeeded = [];
$failed =[];
$uploaded = [];
$allowed = ['png', 'gif', 'jpg'];
if(!empty($_FILES["file"])) {
foreach ($_FILES['file']['name'] as $key => $name) {
if ($_FILES['file']['error'][$key] === 0) {
$temp = $_FILES['file']['tmp_name'][$key];
$ext = explode('.', $name);
$ext = strtolower(end($ext));
$file = md5_file($temp) . time() . '.' . $ext;
if (in_array($ext, $allowed) === true && move_uploaded_file($temp, "uploads/{$file}") === true) {
$succeeded[] = array(
'name' => $name,
'file' => $file
);
}else{
$failed[] = array(
'name' => $name);
}
}
}
}
if (!empty($_POST['ajax'])) {
echo json_encode(array(
'succeeded' => $succeeded,
'failed' => $failed ));
}
?>
Assuming you have the user's username or id in a session variable then that could be used as the basis for the new folder into which he/she would upload files.
Obiously that same username,id would have to be used when they wish to download the file. By storing a hash and the filepath you can generate links that do not reveal filename, folder path, owner etc as the db could check the ash and return the file and path when needed.
The following is an untested example of generating the user's own folder and using that in the upload process - hope it gives you some ideas / guidance.
<?php
$succeeded = [];
$failed =[];
$uploaded = [];
$allowed = ['png', 'gif', 'jpg'];
/*
generate a suitable name for the new folder,
remove characters which might be troublesome
*/
$userdir = str_replace(
array("'",'"','-'),
array('','','_'),
$_SESSION['username']
);
/*
new path into which the files are saved
It might be better to have the files
stored outside of the document root.
*/
$savepath = 'uploads/' . $userdir;
/* create the folder if it does not exist */
if( !file_exists( $savepath ) ) {
mkdir( $savepath );
chown( $savepath, $username );
chmod( $savepath, 0644 );
}
if( !empty( $_FILES["file"] ) ) {
foreach( $_FILES['file']['name'] as $key => $name ) {
if( $_FILES['file']['error'][$key] === 0 ) {
$temp = $_FILES['file']['tmp_name'][$key];
/*
is there anything to be gained by hashing the filename?
the hash would be the same for filenames with the same
name anyway.
If the file is large, calculating the hash of the file could
take some time...
*/
$ext = explode('.', $name);
$ext = strtolower( end( $ext ) );
$file = md5_file( $temp ) . time() . '.' . $ext;
/* generate a random hash to use in downloads */
$hash=uniqid( md5( date(DATE_COOKIE) ) );
/* here probably - store reference in db? Assign permissions based upon owner etc */
$sql='insert into `table` (`filename`,`username`,`uid`,`datetime`,`hash`) values (?,?,?,?,?);';
/* bind params and execute - not shown */
if ( in_array( $ext, $allowed ) === true && move_uploaded_file( $temp, "{$savepath}/{$file}") === true ) {
$succeeded[] = array( 'name' => $name, 'file' => $file );
}else{
$failed[] = array( 'name' => $name );
}
}
}
}
if (!empty($_POST['ajax'])) {
header('Content-Type: application/json');
echo json_encode(array(
'succeeded' => $succeeded,
'failed' => $failed ));
} else {
header( 'HTTP/1.1 404 Not Found', true, 404 );
}
?>

Error 500 Creating default object from empty value when uploading a file

I'm creating a form to upload a file, using yii and php 5.5.3. Here is my code in the controller:
foreach($_FILES['settings']['name'] as $settingName => $value) {
$setting = Setting::model()->find('setting_name=:name', array(':name' => $settingName));
$setting->image_file = CUploadedFile::getInstanceByName('settings['.$settingName.']');
if (!empty($setting->image_file)) {
$extension = "jpg";
$filename = "";
if (($pos = strrpos($setting->image_file, '.')) !== FALSE) {
$extension = substr($setting->image_file, $pos + 1);
$filename = substr($setting->image_file, 0, $pos)."_".strtotime("now");
}
if (!file_exists("uploads") and !is_dir("uploads"))
mkdir("uploads", 0777, TRUE);
$setting->image_file->saveAs("uploads/" . $filename.".".$extension, false);
$setting->setting_value = "uploads/" . $filename.".".$extension;
$setting->save();
}
}
image_file is an extra attribute in model:
array('image_file', 'file', 'types' => 'gif, jpg, jpeg, png', 'maxSize' => 1024 * 1024, 'tooLarge' => 'File upload must not exceed 1MB.'),
and here is the view:
<input type="file" name="settings[store_logo]" class="input-small">
$setting->image_file->saveAs can successfully upload the file, but it also generates
Error 500 Creating default object from empty value
What went wrong? Any help would be much appreciated.
i guess, the $_FILES['settings']['name'] has a empty value in the last Key.
If you upload a File(s), they will be process as expected. The last value in your POST-array cause a NULL-return here:
// $setting === null
$setting = Setting::model()->find('setting_name=:name', array(':name' => $settingName))
and this call throws the 500.
$setting->image_file = CUploadedFile::getInstanceByName('settings['.$settingName.']');
This is my Version of your code:
<?php
foreach($_FILES['settings']['name'] as $settingName => $value) {
$setting = Setting::model()->find('setting_name=:name', array(':name' => $settingName));
// catch null-return
if(!$setting) {
echo "can't find stuff at<pre>"; print_r($settingName); echo "</pre>";
continue;
}
$setting->image_file = CUploadedFile::getInstanceByName('settings['.$settingName.']');
if ($setting->image_file) {
$extension = "jpg";
$filename = "";
if (($pos = strrpos($setting->image_file, '.')) !== FALSE) {
$extension = substr($setting->image_file, $pos + 1);
$filename = substr($setting->image_file, 0, $pos)."_".strtotime("now");
}
if (!file_exists("uploads") and !is_dir("uploads"))
// dont 0777!
mkdir("uploads", 0740, TRUE);
$setting->image_file->saveAs("uploads/" . $filename.".".$extension, false);
$setting->setting_value = "uploads/" . $filename.".".$extension;
$setting->save();
}
}
?>

PHP Run a function for each file in directory

Hello i'm rely stuck here,
Ok i already have a working function to update my database for ONE specified file, in my directory,
now i need a php code to do the same thing for each file on directory and then delete it.
$fileName = "IEDCBR361502201214659.RET";
$cnab240 = RetornoFactory::getRetorno($fileName, "linhaProcessada");
$retorno = new RetornoBanco($cnab240);
$retorno->processar();
the function linhaProcessada is
function linhaProcessada2($self, $numLn, $vlinha) {
if($vlinha["registro"] == $self::DETALHE )
{
if($vlinha["registro"] == $self::DETALHE && $vlinha["segmento"] == "T" ) {
//define a variavel do nosso numero como outra usavel
$query ="SELECT * FROM jos_cobra_boletos WHERE nosso_numero = ".$vlinha['nosso_numero']."";
echo "Boleto de numero: ".$vlinha['nosso_numero']." Atualizado com sucesso!<hr>";
$testResult = mysql_query($query) or die('Error, query failed');
if(mysql_fetch_array($testResult) == NULL){
}else{
$query = "UPDATE jos_cobra_boletos
SET status_pagamento='Pago'
WHERE nosso_numero=".$vlinha['nosso_numero']."";
$result = mysql_query($query) or die('Erro T');
}
}
}
}
Really need help on this one
PHP's opendir() ought to do the trick. More info here: http://php.net/manual/en/function.opendir.php
<?php
// Set Directory
$dir = '/abs/path/with/trailing/slash/';
if ($handle = opendir( $dir )) { // Scan directory
while (false !== ($file = readdir($handle))) { // Loop each file
$fileName = $dir . $file;
// Run code on file
$cnab240 = RetornoFactory::getRetorno($fileName, "linhaProcessada");
$retorno = new RetornoBanco($cnab240);
$retorno->processar();
// Delete file
unlink( $fileName );
}
closedir( $handle );
}
<? //PHP 5.4+
foreach(
new \GlobIterator(
__DIR__ . '/*.RET', //Or other directory where these files are
\FilesystemIterator::SKIP_DOTS |
\FilesystemIterator::CURRENT_AS_PATHNAME
)
as $pathname
){
(new RetornoBanca(
RetornoFactory::getRetorno($pathname, 'linhaProcessada')
))
->processar();
\unlink($pathname);
}
?>

PHP: Rename file before upload

I'm trying to rename each file before uploading to Amazon S3.
I am trying to use this exact method of which was answered by #Silvertiger: PHP - upload and overwrite a file (or upload and rename it)?
If exists, rename to a random name although somehow it doesn't work.
Here is the upload post Parameter from the Amazon S3 Class:
public static function getHttpUploadPostParams($bucket, $uriPrefix = '', $acl = self::ACL_PRIVATE, $lifetime = 3600,
$maxFileSize = 5242880, $successRedirect = "201", $amzHeaders = array(), $headers = array(), $flashVars = false)
{
// Create policy object
$policy = new stdClass;
$policy->expiration = gmdate('Y-m-d\TH:i:s\Z', (time() + $lifetime));
$policy->conditions = array();
$obj = new stdClass; $obj->bucket = $bucket; array_push($policy->conditions, $obj);
$obj = new stdClass; $obj->acl = $acl; array_push($policy->conditions, $obj);
$obj = new stdClass; // 200 for non-redirect uploads
if (is_numeric($successRedirect) && in_array((int)$successRedirect, array(200, 201)))
$obj->success_action_status = (string)$successRedirect;
else // URL
$obj->success_action_redirect = $successRedirect;
array_push($policy->conditions, $obj);
if ($acl !== self::ACL_PUBLIC_READ)
array_push($policy->conditions, array('eq', '$acl', $acl));
array_push($policy->conditions, array('starts-with', '$key', $uriPrefix));
if ($flashVars) array_push($policy->conditions, array('starts-with', '$Filename', ''));
foreach (array_keys($headers) as $headerKey)
array_push($policy->conditions, array('starts-with', '$'.$headerKey, ''));
foreach ($amzHeaders as $headerKey => $headerVal)
{
$obj = new stdClass;
$obj->{$headerKey} = (string)$headerVal;
array_push($policy->conditions, $obj);
}
array_push($policy->conditions, array('content-length-range', 0, $maxFileSize));
$policy = base64_encode(str_replace('\/', '/', json_encode($policy)));
// Create parameters
$params = new stdClass;
$params->AWSAccessKeyId = self::$__accessKey;
$params->key = $uriPrefix.'${filename}';
$params->acl = $acl;
$params->policy = $policy; unset($policy);
$params->signature = self::__getHash($params->policy);
if (is_numeric($successRedirect) && in_array((int)$successRedirect, array(200, 201)))
$params->success_action_status = (string)$successRedirect;
else
$params->success_action_redirect = $successRedirect;
foreach ($headers as $headerKey => $headerVal) $params->{$headerKey} = (string)$headerVal;
foreach ($amzHeaders as $headerKey => $headerVal) $params->{$headerKey} = (string)$headerVal;
return $params;
}
Here is #Silvertiger's method:
// this assumes that the upload form calls the form file field "myupload"
$name = $_FILES['myupload']['name'];
$type = $_FILES['myupload']['type'];
$size = $_FILES['myupload']['size'];
$tmp = $_FILES['myupload']['tmp_name'];
$error = $_FILES['myupload']['error'];
$savepath = '/yourserverpath/';
$filelocation = $svaepath.$name;
// This won't upload if there was an error or if the file exists, hence the check
if (!file_exists($filelocation) && $error == 0) {
// echo "The file $filename exists";
// This will overwrite even if the file exists
move_uploaded_file($tmp, $filelocation);
}
// OR just leave out the "file_exists()" and check for the error,
// an if statement either way
This is my upload form:
<form method="post" action="<?php echo $uploadURL; ?>" enctype="multipart/form-data">
<?php
foreach ($params as $p => $v)
echo " <input type=\"hidden\" name=\"{$p}\" value=\"{$v}\" />\n";
?>
<input type="file" name="file" /> <input type="submit" value="Upload" />
</form>
And this is the Input info:
public static function inputFile($file, $md5sum = true)
{
if (!file_exists($file) || !is_file($file) || !is_readable($file))
{
self::__triggerError('S3::inputFile(): Unable to open input file: '.$file, __FILE__, __LINE__);
return false;
}
return array('file' => $file, 'size' => filesize($file), 'md5sum' => $md5sum !== false ?
(is_string($md5sum) ? $md5sum : base64_encode(md5_file($file, true))) : '');
}
You can do your renaming at this point in your code:
move_uploaded_file($tmp, $filelocation);
The $filelocation can be changed to whatever you want and the uploaded file will be renamed to that path.
Edit: The S3::getHttpUploadPostParams method always uses the file name from the upload to create the S3 resource. To change that you have to copy the method but change this line:
$params->key = $uriPrefix.'${filename}';
The '${filename} must be changed to a path of your choosing.
Replace this:
// Create parameters
$params = new stdClass;
$params->AWSAccessKeyId = self::$__accessKey;
$params->key = $uriPrefix.'${filename}';
with this:
function rand_string( $length ) {
$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
$size = strlen( $chars );
for( $i = 0; $i < $length; $i++ ) {
$str .= $chars[ rand( 0, $size - 1 ) ];
}
return $str;
}
// Create parameters
$params = new stdClass;
$params->AWSAccessKeyId = self::$__accessKey;
$params->key = $uriPrefix.rand_string(5).'${filename}';
You can easily put this code.. 100 percent working.
<?php
$file=$_FILES['file']['name'];
$path ="upload/".$file;
$ext=pathinfo($path,PATHINFO_EXTENSION);
$name=pathinfo($path,PATHINFO_FILENAME);
if(file_exists($path))
{
echo "File alredy exists .So name is changed automatically & moved";
$path1="upload/";
$new_name=$path1.$name.rand(1,500).".".$ext;
move_uploaded_file($_FILES['file']['tmp_name'],$new_name);
}
else
{
echo"uploaded Sucessfully without any change";
move_uploaded_file($_FILES['file']['tmp_name'],$path);
}
?>

Categories