codesleeve / laravel-stapler Goto Github PK
View Code? Open in Web Editor NEWStapler-based file upload package for the Laravel framework.
License: MIT License
Stapler-based file upload package for the Laravel framework.
License: MIT License
First of all this may be an edge case, because I'm using Stapler in a polymorphic approach. That means I have:
Uploads table looks like this:
----------------------------------------------------------------------------------------------------------------------------
| id | file_file_name | file_file_size | file_content_type | file_updated_at | illustrable_type | illustrable_id |
----------------------------------------------------------------------------------------------------------------------------
| 21 | 03.jpg | 72433 | image/jpeg | 2014-07-24 15:41:09 | ListingRequest | 2 |
----------------------------------------------------------------------------------------------------------------------------
| 22 | hello-world-test.pdf | 17588 | application/pdf | 2014-07-24 15:41:12 | ListingRequest | 2 |
----------------------------------------------------------------------------------------------------------------------------
This allows me to bind multiple files to a model without adding a bajillion columns. The problem is since all uploads have a single "file" attachement and thumbnail styles are defined for all. When I try to upload any file that is not an image Stapler crashes.
i wonder if a table have multiple files how to do that?
The file "2EE20CEF-D1EB-43BB-9115-69162E716A83.jpg" exceeds your upload_max_filesize ini directive.
I'd like to validate against filesizes before the upload begins, as well as catching errors such as the above. Thus far have been unable to do so. Any suggestions?
In laravel5 the folder structure changed. the database directory is no longer inside the app folder. Also the Class Str couldn't be found.
I changed it to the following and it worked:
//FastenCommand.php line: 76
$path = base_path() . '/database/migrations';
if (!is_dir($path)) mkdir($path);
...
$data['className'] = 'Add' . $data['attachment'] . 'FieldsTo' . $data['table'] . 'Table';
Hey,
First off, stapler is awesome. It is a wonderful package. Thanks for the hard work. I have run into a problem which I can't seem to figure out. I am trying to delete associated files upon updating a model.
My polypmorphic relationships work great and I can add images/docs all day. But removing them has become harder:
// save
if($job->save()) {
// delete old photos
foreach($job->photos as $photo) {
$photo->image->delete();
}
// add photos
// $photos is a separate array of objects
if($photos != null && isset($photos)) {
foreach($photos['photos'] as $photo) {
$job->photos()->create(array(
'image' => $photo,
'imageable_id' => $job->id,
'imageable_type' => 'Job'
));
}
}
}
Here is a simple example of the code. Photo is the model and image is the stapler object. Destroying the photos works but doesn't remove them from the database.
Unless I'm missng something is there a mechanism to override the config file for specifying alternative upload folders. I currently host using httpdocs for the "public" folder which I can only overwrite in the vendor configuration.
Thanks
When attempting to apply an avatar to a model, I'm receiving an exception "ErrorException (E_UNKNOWN) Undefined index: tmp_name"
Looking at the stacktrace; it appears to the createFromArray function in Factories/File.php trying to create a new SymfonyUploadedFile with the incorrect parameters. It expects $file to have $file['tmp_name'] but if you dump the contents of the array it appears as the following:
[test:Symfony\Component\HttpFoundation\File\UploadedFile:private] =>
[originalName:Symfony\Component\HttpFoundation\File\UploadedFile:private] => Avatar - Atrox.png
[mimeType:Symfony\Component\HttpFoundation\File\UploadedFile:private] => image/png
[size:Symfony\Component\HttpFoundation\File\UploadedFile:private] => 376989
[error:Symfony\Component\HttpFoundation\File\UploadedFile:private] => 0
[pathName:SplFileInfo:private] => /tmp/phpVATNfG
[fileName:SplFileInfo:private] => phpVATNfG
"require": {
"laravel/framework": "5.0.*",
"codesleeve/laravel-stapler": "dev-master"
},
after adding service provider 'Codesleeve\LaravelStapler\LaravelStaplerServiceProvider', show get error:
exception 'BadMethodCallException' with message 'Call to undefined method [package]' in C:\OpenServer\domains\my-project\vendor\laravel\framework\src\Illuminate\Support\ServiceProvider.php:226
Error launching fasten command:
[InvalidArgumentException]
No hint path defined for [stapler-l4]
The problem is located in line 84 of FastenCommand class but I've seen that in the code the bug is fixed.
If I change the settings to support S3 can I reprocess all items and have them moved to Amazon?
Is there anyway to make the refresh command more efficient so that when running the artisan command, it isn't killed by the system when it runs out of memory?
Could the memory be flushed after each image reprocess potentially?
Upload works with no errors. Database information for the image is put into the database table. However, the image does not appear in "system" folder. The folder is writable and has the proper group permissions so there shouldn't be a reason for the directories and file write to be failing.
Any ideas on what might cause this? Is there not a try/catch if the file failed to be created on the system?
Currently I am doing it this way, are there any other ways to directly call my helper Imagefixer::resize()
?
public function __construct(array $attributes = array()) {
$this->hasAttachedFile('profilepic', [
'styles' => [
'thumbnail' => '75x75',
'test1' => function($file, $imagine)
{
return Imagefixer::resize($file, $imagine, 200, 200);
},
'test2' => function($file, $imagine)
{
return Imagefixer::resize($file, $imagine, 350, 250);
}
]
]);
parent::__construct($attributes);
}
Can this be done?
I'd like to use stapler with MyClass::save instead of MyClass::create. How would I go about doing this?
When passing the config for hasAttachedFile,
's3_object_config' => [
'Bucket' =>
'Bucket' - need to start will a capital 'B'. A lower case 'b' will cause an exception.
This is inconsistent with examples from Stapler.
Is there a way for
<img src="<?= $user->avatar->url() ?>" >
to return the absolute url to the image?
When generating pdfs from a page you need the full url for the image to be included in the pdf.
php artisan stapler:refresh "Electricpulp\Users\Models\User" results in:
[Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException]
The file "/public/uploads/Electricpulp/Users/Models/User/avatars/000/000/060/original/mitch_glasses_purple.png" does not exist
It does actually exist, but I'm not sure the pathing is right. I'm wondering if it shouldn't include the first slash, or be fully qualified from the system root?
Any chance of getting Laravel 5 support soon?
I don't think there's much that needs changing.
Or if someone can guide me on how to setup the framework agnostic Stapler with Laravel 5's new structure that would help a lot!
When trying to update to laravel 5, composer tells me
codesleeve/laravel-stapler v1.0.01 requires laravel/framework ~4
I'm using stapler to upload file attachments. I need to allow authenticated users to download them but I don't want to the files to be publicly accessible in case the link were inadvertently sent out. Is it possible to obtain an S3 url that will expire in nn minutes using Stapler or do I need to explore the S3 SDK?
The README instructs us to create a folder named 'system' inside the docroot (eg. public/system) and files seem to be uplaoded there automatically. This is fine for the use-case where the files being uploaded are images for public consumption. But this is a security problem for other common situations.
I'd like to know if there's a way to configure this package (ideally on a per-field basis) to store and retrieve files from an alternate filesystem location.
My composer:
{
..
"require": {
"laravel/framework": "5.0.*",
"illuminate/html": "~5.0",
"codesleeve/laravel-stapler": "1.0.*"
},
..
}
app.php
...
'Codesleeve\LaravelStapler\LaravelStaplerServiceProvider'
...
Post.php
<?php namespace App;
use Codesleeve\Stapler\ORM\StaplerableInterface;
use Codesleeve\Stapler\ORM\EloquentTrait;
use Illuminate\Database\Eloquent\Model;
class Post extends Model implements StaplerableInterface
{
use EloquentTrait;
protected $table = 'posts';
//..
}
composer dump-autoload
And..
Output:
Whoops, looks like something went wrong.
1/1
BadMethodCallException in ServiceProvider.php line 226:
Call to undefined method [package]
in ServiceProvider.php line 226
at ServiceProvider->__call('package', array('codesleeve/laravel-stapler', null, '/Users/Test/L5/example/vendor/codesleeve/laravel-stapler/src')) in LaravelStaplerServiceProvider.php line 25
at LaravelStaplerServiceProvider->package('codesleeve/laravel-stapler', null, '/Users/Test/L5/example/vendor/codesleeve/laravel-stapler/src') in LaravelStaplerServiceProvider.php line 25
at LaravelStaplerServiceProvider->boot()
at call_user_func_array(array(object(LaravelStaplerServiceProvider), 'boot'), array()) in Container.php line 523
at Container->call(array(object(LaravelStaplerServiceProvider), 'boot')) in Application.php line 672
at Application->bootProvider(object(LaravelStaplerServiceProvider)) in Application.php line 654
at Application->Illuminate\Foundation\{closure}(object(LaravelStaplerServiceProvider), '21')
at array_walk(array(object(EventServiceProvider), object(RoutingServiceProvider), object(AuthServiceProvider), object(ControllerServiceProvider), object(CookieServiceProvider), object(DatabaseServiceProvider), object(EncryptionServiceProvider), object(FilesystemServiceProvider), object(FormRequestServiceProvider), object(FoundationServiceProvider), object(PaginationServiceProvider), object(SessionServiceProvider), object(ValidationServiceProvider), object(ViewServiceProvider), object(AppServiceProvider), object(BusServiceProvider), object(ConfigServiceProvider), object(EventServiceProvider), object(RouteServiceProvider), object(SluggableServiceProvider), object(FlashServiceProvider), object(LaravelStaplerServiceProvider), object(BusServiceProvider)), object(Closure)) in Application.php line 655
at Application->boot() in BootProviders.php line 15
at BootProviders->bootstrap(object(Application)) in Application.php line 167
at Application->bootstrapWith(array('Illuminate\Foundation\Bootstrap\DetectEnvironment', 'Illuminate\Foundation\Bootstrap\LoadConfiguration', 'Illuminate\Foundation\Bootstrap\ConfigureLogging', 'Illuminate\Foundation\Bootstrap\HandleExceptions', 'Illuminate\Foundation\Bootstrap\RegisterFacades', 'Illuminate\Foundation\Bootstrap\RegisterProviders', 'Illuminate\Foundation\Bootstrap\BootProviders')) in Kernel.php line 195
at Kernel->bootstrap() in Kernel.php line 106
at Kernel->sendRequestThroughRouter(object(Request)) in Kernel.php line 84
at Kernel->handle(object(Request)) in index.php line 56
Hi, I've had this issue with model observers and stapler: if using "boot" method on model to add model observer, s3 storage fails (without error) when saving an attachment on that model: e.g.:
public static function boot()
{
parent::boot();
// Setup event bindings...
User::observe(new UserObserver);
}
I've found it kind of hard to modify the configuration at runtime as it's read once during the service provider and then saved. If I want to modify the default styles at runtime how would I go about it ?
Currently to do it at the instance level I have to do this:
$config = Config::get('laravel-stapler::stapler');
$config += Config::get('laravel-stapler::filesystem');
$config['styles'] = $newStyles;
$config = new AttachmentConfig('file', $config);
$this->file->setConfig($config);
But now I need a way to modify the styles for all instances at runtime and Config::set('stapler::stapler.styles', $styles)
doesn't work.
So, the migration command does not work due to forgotten stepler-l4 hint in the Service Provider.
Should be fixed with this in the boot method:
public function boot()
{
$this->package('codesleeve/laravel-stapler', 'stapler-l4');
$this->bootstrapStapler();
}
I am trying to set null on all empty values by doing this in my model that implements StaplerableInterface and uses EloquentTrait:
use Codesleeve\Stapler\ORM\StaplerableInterface;
use Codesleeve\Stapler\ORM\EloquentTrait;
class FooBar extends Eloquent implements StaplerableInterface{
use EloquentTrait;
protected $table = 'foobars';
protected $fillable = ['file_attachment_1'];
public function __construct(array $attributes = array()) {
$this->hasAttachedFile('file_attachment_1');
parent::__construct($attributes);
}
/**
* Override setAttribute
*/
public function setAttribute($key, $value)
{
parent::setAttribute($key, $value);
if ( is_null($value) || empty($value))
{
$this->attributes[$key] = null;
}
}
}
I get this error:
Illuminate \ Database \ QueryException (42S22)
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'file_attachment_1' in 'field list' (SQL: update `foobars` set
Any page that touches a model with laravel-stapler in it now results in this error.
Symfony \ Component \ Debug \ Exception \ FatalErrorException
Class 'GD' not found
Trace shows:
vendor/codesleeve/stapler/src/Codesleeve/Stapler/Stapler.php
*
* @param string $type
* @return \Imagine\Image\ImagineInterface
*/
public static function getImagineInstance($type)
{
if (!isset(static::$imageProcessors[$type])) {
static::$imageProcessors[$type] = new $type;
}
When I upload a file the eventual name is based on the temporary file name generated on upload, rather than the original name of the file. This causes the Imagine GD resizer to fail with an InvalidArgumentException, because it uses the suffix to detect the filetype. I switched to Imagick and that is happy with unsuffixed files but since nobody else is reporting this issue I wonder if there is something in my set-up that's unusual. Any thoughts?
I have this huge issue working with Stapler that it completely stops uploading pictures whenever I add certain packages to the same project. These packages break it so bad that I have simply removing them doesn't fix the issue. I have to recreate the whole project from scratch and be wary of not using them ever again because they break the project.
Here are the two culprits that have caused this issue:
https://github.com/panique/laravel-sass
https://github.com/shift31/laravel-elasticsearch
I can live without the SASS compiler since I'm using Koala instead now but the my project really requires elasticsearch. Can anyone point out why this is happening and can provide a fix for the issue
Hello,
I have been trying to implement this package and cannot get the files to save at all. It does not update the database table and their is no Symfony object when the file is uploaded. Files are set to 'true'. I am using Entrust and Confide so when updating a user I have to call ->updateUniques() instead of ->save(). Not sure if this is part of the problem.
I walked through this ticket (#10) and realized I was not getting a Symfony object upon upload of the files just the string that is the name of the file.
Any ideas what is going on? I believe I set up and installed everything correctly. I have had a hard time with Entrust and Confide so there is part of me that believes it could be related to the update function of these
Hi
I'd like the know it's possible for mutiple file upload?
I applied the Stapler to my User model as suggested in the example. But on trying to login and logout I get this error:
Illuminate\Auth\EloquentUserProvider::validateCredentials() must be an instance of Illuminate\Auth\UserInterface, instance of User given
Apparently since I'm not implementing Illuminate\Auth\UserInterface anymore, something goes wrong. Yet when I add use Illuminate\Auth\UserInterface back to the "implements" section appended to StablerableInterface is says I my class should be declared abstract.
Any thoughts?
I've gotten Stapler working well for image uploads but I am wondering if there is any way I can send an image url retrieved from the Twitter API through the works instead of uploading?
After updating to the latest version I'm getting this error. Any idea?
PHP Fatal error: Cannot access parent:: when current class scope has no parent in ..../vendor/codesleeve/stapler/src/Codesleeve/Stapler/Stapler.php on line 59
Currently the stapler:refresh
commands just stays silent for a few minutes if you have a lot of uploads. If would be nice if more information on the progress of thumbnails generation was given, via the Progress class per example.
Sounds like a stupid question but how can I save an image as a jpg file regardless of the uploaded format (gif, png or whatever)?
I tried to add the file extension in the config like so:
'url' => '/uploads/:attachment/:id_partition/:style/:filename.jpg'
Using this line png files remain png files (but have a .jpg file extension).
If I have a system folder and I have an image source that points to this folder, the image is not being shown. I am on xampp and image url just goes to http://localhost/system/ as it will find this folder and bypass the htaccess.
Am I doing something wrong here? I just did what was in docs.
It is stated in Packagist.org that it is still compatible with Laravel 4.*, but it clearly is not. Hence, using composer update to the latest stable version doesn't consider Laravel version as an issue and updates to 07829c7
.
This conflict resaults in :
ErrorException (E_UNKNOWN)
include(/var/www/html/eclub/vendor/codesleeve/laravel-stapler/src/Codesleeve/LaravelStapler/LaravelStaplerServiceProvider.php): failed to open stream: No such file or directory
It should be stated in Packagist.org in order for composer to update to latest stable version based on Laravel version.
Thanks!
Hi,
This is the error I had this morning :
{"error":{"type":"ErrorException","message":"Argument 1 passed to Codesleeve\LaravelStapler\Commands\FastenCommand::__construct() must be an instance of Illuminate\View\Factory, instance of Robbo\Presenter\View\Environment given, called in /Users/me/vendor/codesleeve/laravel-stapler/src/LaravelStaplerServiceProvider.php on line 91 and defined","file":"/Users/me/vendor/codesleeve/laravel-stapler/src/Commands/FastenCommand.php","line":45}}
Something with https://github.com/robclancy/presenter
Rolling back to 1.0.02 then it works again.
So, we've got:
[quote]This package currently requires php >= 5.4 as well as Laravel >= 4.[/quote]
But ImageMagick requires PHP GD to function. Turns out that Heroku doesn't load that out of the box!
It would be nice to have at the very least have the readme reflect this requirement. Additionally, it would be nice to see the image manipulation to be an optional package (as I am currently not really interested in manipulating images into thumbnails)
Hi my friends. I have the same problem Files are not uploaded #10, and I do not understand how to solve it
<?php namespace Acme\Entities;
use Illuminate\Auth\UserTrait;
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableTrait;
use Illuminate\Auth\Reminders\RemindableInterface;
use Hash;
use Laracasts\Presenter\PresentableTrait;
use Watson\Validating\ValidatingTrait;
use Codesleeve\Stapler\ORM\StaplerableInterface;
use Codesleeve\Stapler\ORM\EloquentTrait;
class User extends \Eloquent implements UserInterface, RemindableInterface, StaplerableInterface {
use UserTrait, RemindableTrait, PresentableTrait, ValidatingTrait, EloquentTrait;
public function __construct(array $attributes = array()) {
$this->hasAttachedFile('avatar', [
'styles' => [
'medium' => '300x300',
'thumb' => '100x100',
'gravatar' => '74x74'
],
'url' => '/img/:attachment/:id_partition/:style/:filename',
'default_url' => '/img/missing.png'
]);
parent::__construct($attributes);
}
public static function boot()
{
parent::boot();
static::bootStapler();
}
The record is updated in db, but no files are stored in /public/img/avatar
What am I doing wrong?
I have users who are uploading images with cyrillic filenames such as "Скриншот 2014-06-23 10.06.29.png"
This gets saved in the column image_file_name and when I try loading the image it fails to do so. Any way you can rename these files or add support for cyrillic?
I had Stapler working perfectly using use EloquentTrait;
and later added my own event handling through my model's boot
method.
This breaks Stapler, as the EloquentTrait boot was no longer being called. The solution was to call bootStapler()
in my own boot function.
Perhaps the documentation could mention this?
Hi Travis,
I was looking for a file upload package and found yours. It looks like exactly what I need.
However, I noticed that when I installed the package the vendor/codesleeve/laravel-stapler/src/Providers directory is missing on my end. So you may have fixed the Laravel 5 issues as seen in the following issues:
But I think it still throwing an error because of the missing directory on install from Composer. I'm trying to figure out why that directory is being excluded from the download and install by Composer.
Thanks for all the hard work on this. I want to try and fix this on my own and send you a pull request but as I'm not familiar with Composer package layout it may take me some time. So you may be able to fix this quicker than I can.
Again thanks for sharing your hard work with everyone.
-Daniel
First of all congrats for the great package you have deleoped 👍
I have a simple question, is it possible to crop an uploaded image using the coordinates comming from a javascript client side cropper? for an user avatar for example.
I've been looking into the docs but could not find anything about.
Thaks for your help :)
I've got two issues. First, none of the commands are showing up in artisan. I dumped the composer autoload and ran artisan dump-autoload as well. I was able to manually register the fasten command in app/start/artisan.php. Second, I get an error when running that fasten command: "No hint path defined for [laravel-stapler]." I tried with the version in the readme, 1.0, as well as dev-master. Neither works. I'm running a fresh install of the most recent version of laravel, 4.2.*
Using laravel-stapler, my laravel eloquent model is trying to save an attachment to S3. S3 Configuration has been set and are being picked up properly by the laravel-stapler package.
Here's my eloquent model:
use Codesleeve\Stapler\ORM\StaplerableInterface;
use Codesleeve\Stapler\ORM\EloquentTrait;
class SwiftDocument extends Eloquent implements StaplerableInterface{
use Illuminate\Database\Eloquent\SoftDeletingTrait;
use EloquentTrait;
protected $table = "swift_document";
protected $guarded = array('id');
protected $fillable = ["document_file_name","document_file_size","document_content_type","document_updated_at","user_id"];
public $timestamps = true;
protected $dates = ['deleted_at'];
public function __construct(array $attributes = array())
{
// Define an attachment named 'document' that stores files locally.
$this->hasAttachedFile('document', [
'storage' => 's3',
'url' => '/upload/:attachment/:id/:filename',
'default_url' => '/defaults/:style/missing.png',
'keep_old_files' => true
]);
parent::__construct($attributes);
}
/*
* Event Observers
*/
public static function boot() {
parent:: boot();
/*
* Set User Id on Save
*/
static::saving(function($model){
$model->user_id = Sentry::getUser()->id;
});
static::bootStapler();
}
....
Upon saving an attachment, the following error is being thrown (in JSON format since it was an ajax call):
{"error":{"type":"Aws\S3\Exception\InvalidArgumentException","message":"","file":"/extvol/www/html/scottswift/http/vendor/aws/aws-sdk-php/src/Aws/Common/Exception/NamespaceExceptionFactory.php","line":91}}
As you can see the message part is blank.
Any thoughts on this?
while for image its working but for some others image its not working .. not showing any error just a white page with internel server error in browser inspect. please suggest me a solution
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.