Move files after Upload many

Move files after Upload many

lincolncbennettlincolncbennett Posts: 25Questions: 11Answers: 1
edited July 22 in Editor

Hi, I'm using the upload many field successfully but I'm now trying to move the recently uploaded files to a client folder after the row is created using the postCreate event handler. I'm using the below server side code but my files aren't being moved. The $file array is returning only the id of the files but not the filename, I'm gettin the error filename is not defined. This is my code:

->join(
        Mjoin::inst('files')
            ->link('deceased.id', 'deceased_files.deceased_id')
            ->link('files.id', 'deceased_files.file_id')
            ->fields(
                Field::inst( 'id' ),
                Field::inst( 'filename' )
                    ->upload( Upload::inst( '../../../files/'.$GLOBALS['orgid'].'/__ID__.__EXTN__' )
                        ->db( 'files', 'id', array(
                            'filename'    => Upload::DB_FILE_NAME,
                            'filesize'    => Upload::DB_FILE_SIZE,
                            'web_path'    => Upload::DB_WEB_PATH,
                            'system_path' => Upload::DB_SYSTEM_PATH
                        ) )
                        ->validator( Validate::fileSize( 5000000, 'Files must be smaller that 5Mb' ) )
                        ->validator( Validate::fileExtensions( array( 'png', 'jpg', 'jpeg', 'gif', 'pdf' ), "Please upload an image or pdf file" ) )
                    )
            )
    )
->on('postCreate', function ($editor, $id, $values, $row) use ($orgid) {
        // Create a directory for the new record if it doesn't exist
        $dir = '../../../files/' . $orgid . '/' . $id;
        if (!file_exists($dir)) {
            mkdir($dir, 0777, true);
        }
        // Copy the index.html file
        copy('../../../index.html', $dir . '/index.html');
        // Move uploaded files to the new record's directory
        foreach ($values['files'] as $file) {   
            if (!empty($file)) {
                $sourcePath = '../../../files/' . $orgid . '/' . $file['filename'];
                $destPath = $dir . '/' . $file['filename'];
                if (file_exists($sourcePath)) {
                    rename($sourcePath, $destPath);
                }
            }
        }
    })

Edited by Allan to add syntax highlighting

This question has an accepted answers - jump to answer

Answers

  • allanallan Posts: 63,516Questions: 1Answers: 10,473 Site admin
    Answer ✓

    Hi,

    If you want to move files around from the upload, you need to that that in a custom upload handler.

    One of the key things to remember here is that the upload action is async to the rest of the form - you can create a record without uploading a file. You could also upload a file and then not create a row! (This we call an orphaned file).

    So any moving of files should be done in the upload handlers, rather than an event such as postCreate.

    Allan

  • lincolncbennettlincolncbennett Posts: 25Questions: 11Answers: 1

    Hi Allan, thanks for your reply. I think I took the postCreate event hanlder because I wanted to use the .$id of the 'files' table as part of the directory which isn't set until after editor is submitted and the new row created in my database. Instead of the custom upload handler I added 'extn' column and then looped through all the filenames and all my allowed extensions to find the file/s uploaded before moving to the correct client folder. It may not be the best way but it is working now.
    Lincoln.

    ->join(
            Mjoin::inst('files')
                ->link('deceased.id', 'deceased_files.deceased_id')
                ->link('files.id', 'deceased_files.file_id')
                ->fields(
                    Field::inst('extn'),
                    Field::inst('filename'),
                    Field::inst('id')
                        ->upload( Upload::inst( '../../../files/'.$GLOBALS['orgid'].'/__ID__.__EXTN__' )
                            ->db( 'files', 'id', array(
                                'filename'    => Upload::DB_FILE_NAME,
                                'filesize'    => Upload::DB_FILE_SIZE,
                                'web_path'    => Upload::DB_WEB_PATH,
                                'system_path' => Upload::DB_SYSTEM_PATH,
                                'extn' => Upload::DB_EXTN,
                            ) )
                            ->validator( Validate::fileSize( 5000000, 'Files must be smaller that 5Mb' ) )
                            ->validator( Validate::fileExtensions( array( 'png', 'jpg', 'jpeg', 'pdf' ), "Please upload an image or pdf file" ) )
                        )
                )
        )
    
    
    ->on('postCreate', function ($editor, $id, $values, $row) use ($orgid) {
        // Create a directory for the new record if it doesn't exist
        $dir = '../../../files/' . $orgid . '/' . $id;
        if (!file_exists($dir)) {
            mkdir($dir, 0777, true);
        }
        // Copy the index.html file
        copy('../../../index.html', $dir . '/index.html');
    
        // Helper function to get the source path and filename
        function getSourcePath($orgid, $fileId) {
            $extensions = ['pdf', 'jpg', 'jpeg', 'png'];
            foreach ($extensions as $ext) {
                $path = "../../../files/$orgid/$fileId.$ext";
                if (file_exists($path)) {
                    return ['sourcePath' => $path, 'fileName' => "$fileId.$ext"];
                }
            }
            return null;
        }
    
        // Move uploaded files to the new record's directory
        foreach ($values['files'] as $file) {
            if (!empty($file)) {
                $fileInfo = getSourcePath($orgid, $file['id']);
                if ($fileInfo) {
                    $sourcePath = $fileInfo['sourcePath'];
                    $destPath = $dir . '/' . $fileInfo['fileName'];
    
                    //echo "<script>console.error('Error moving file: " .json_encode($destPath)."');</script>";
    
                    if (file_exists($sourcePath)) {
                        rename($sourcePath, $destPath);
                    }
                }
            }
        }
    })
    
Sign In or Register to comment.