13

I have a Laravel 4.2 API that, when creating a resource, accepts file uploads. The file is retrieved with Input::file('file')

Now I want to write a script (also in Laravel) that will batch create some resources (so I can't use a HTML form that POSTs to API's endpoint). How can I translate a file path into an instance of UploadedFile so that Input::file('file') will pick it up in the API?

whonoes
  • 483
  • 1
  • 5
  • 14

3 Answers3

19

Just construct an instance yourself. The API is:

http://api.symfony.com/2.0/Symfony/Component/HttpFoundation/File/UploadedFile.html

So you should be able to do:

$file = new UploadedFile(
    '/absolute/path/to/file',
    'original-name.gif',
    'image/gif',
    1234,
    null,
    TRUE
);

Notice: You have to specify the 6th constructing parameter as TRUE, so the UploadedFile class knows that you're uploading the image via unit testing environment.

Alex Kyriakidis
  • 2,861
  • 1
  • 19
  • 28
Cody Caughlan
  • 32,456
  • 5
  • 63
  • 68
  • Using this approach, `$file->isValid()` returns false (because `is_uploaded_file()` returns false); therefore in the API I'm not able to pick the `UploadedFile` instance using `Input::file()`, and I also can't do `$file->move()`. Your answer pointed me in the right direction though, and with some minor adjustments in the API I managed to solve the problem. Thanks! – whonoes Sep 14 '14 at 16:26
  • You have to specify the 6th constructing parameter as TRUE, so the UploadedFile class knows that you're uploading the image via unit testing environment. – Alex Kyriakidis Oct 28 '15 at 23:22
  • @Alexandros - It was marked as correct a year ago and upvoted, are you certain this is not just a quirk of your own code? Example: Can you prove this is required? – Jesse Oct 29 '15 at 00:33
  • 1
    Yep I am sure. UploadedFile constructor is `public function __construct($path, $originalName, $mimeType = null, $size = null, $error = null, $test = false)` If you dont pass $test as TRUE then phpunit tests are failing. I think @AlexandreThebaldi had the same issued. – Alex Kyriakidis Oct 29 '15 at 00:38
  • @Alexandros - looks like it is updated now. Thank you for pointing this out. – Jesse Oct 30 '15 at 17:03
8
  /**
   * Create an UploadedFile object from absolute path 
   *
   * @static
   * @param     string $path
   * @param     bool $public default false
   * @return    object(Symfony\Component\HttpFoundation\File\UploadedFile)
   * @author    Alexandre Thebaldi
   */

  public static function pathToUploadedFile( $path, $public = false )
  {
    $name = File::name( $path );

    $extension = File::extension( $path );

    $originalName = $name . '.' . $extension;

    $mimeType = File::mimeType( $path );

    $size = File::size( $path );

    $error = null;

    $test = $public;

    $object = new UploadedFile( $path, $originalName, $mimeType, $size, $error, $test );

    return $object;
  }
Alexandre Thebaldi
  • 4,546
  • 6
  • 41
  • 55
4

Here for Laravel 8.x based on Alexandre Thebaldi's answer:

use Illuminate\Filesystem\Filesystem;
use Illuminate\Http\UploadedFile;

/**
 * Create an UploadedFile object from absolute path 
 *
 * @param     string $path
 * @param     bool $test default true
 * @return    object(Illuminate\Http\UploadedFile)
 * 
 * Based of Alexandre Thebaldi answer here:
 * https://stackoverflow.com/a/32258317/6411540
 */
public function pathToUploadedFile( $path, $test = true ) {
    $filesystem = new Filesystem;
    
    $name = $filesystem->name( $path );
    $extension = $filesystem->extension( $path );
    $originalName = $name . '.' . $extension;
    $mimeType = $filesystem->mimeType( $path );
    $error = null;

    return new UploadedFile( $path, $originalName, $mimeType, $error, $test );
}
Darkproduct
  • 1,062
  • 13
  • 28