This forum has moved to a new location and is in read-only mode. Please visit talk.octobercms.com to access the new location.
I have a form, with a multiple upload field. The form does quite a bit of things, but I have a button right below the upload field, that when is clicked, it calls a function in my controller. This all works fine and dandy. However, in the function, when I try to parse the uploaded files, it can't find them. Just skips over the for loop.
Using xdebug, I've looked at the model, and under attachMany I can see the variable the files are supposed to be in.
Is this because of deferred binding? When the button is clicked the model hasn't been technically saved yet.
Code:
public function onPDF()
{
$model = $this->getQRModel(post('recordID'));
$model->save();
foreach ($model->pdfs as $pdf) {
echo $pdf->getPath();
}
}
I tried a few of the suggestions I've found in the forms, but nothing works. Just skips over it like the files aren't there.
Last updated
Hey,
I had quite a lot of trouble getting my form to upload a file as well and finally have it working well:
This is the markup in my form (which I've built as a Frontend Component)
{{ form_open({files: true, request: 'onFileUpload'}) }}
<!--File Input-->
<input type="file" name="file-upload" required="required">
<!--File Input-->
<!--Submit/Upload Button-->
<button type="submit">Upload</button>
{{ form_close() }}
Once the user selects a file and clicks the Submit button, an 'onFileUpload' method is triggered on my Component file which looks like this:
public function onFileUpload()
{
$file = new System\Models\File;
$file->data = Input::file('file-upload');
$file->save();
// Attach the uploaded file to your model
$model->file()->add($file);
// The above line assumes you have proper attachOne or attachMany relationships defined on your model - in this case, I have named the relationship simply as "file"
$model->file_path = url('/') . $model->file->getPath();
$model->save();
return Redirect::back();
}
I save the absolute file_path as a property on my model itself for easy access later. Of course, you will need to have proper error and validation checks in place. I didn't include them to make the uploading logic be clear.
You can see the full live form here - http://accliveinc.com/job-seekers#submit-resume.
Hope it helps!
Last updated
You should be able to use this logic in a loop to get the functionality you want to build.
pratyushpundir6424 said:
Hey,
I had quite a lot of trouble getting my form to upload a file as well and finally have it working well:
This is the markup in my form (which I've built as a Frontend Component)
{{ form_open({files: true, request: 'onFileUpload'}) }} <!--File Input--> <input type="file" name="file-upload" required="required"> <!--File Input--> <!--Submit/Upload Button--> <button type="submit">Upload</button> {{ form_close() }}
Once the user selects a file and clicks the Submit button, an 'onFileUpload' method is triggered on my Component file which looks like this:
public function onFileUpload() { $file = new System\Models\File; $file->data = Input::file('file-upload'); $file->save(); // Attach the uploaded file to your model $model->file()->add($file); // The above line assumes you have proper attachOne or attachMany relationships defined on your model - in this case, I have named the relationship simply as "file" $model->file_path = url('/') . $model->file->getPath(); $model->save(); return Redirect::back(); }
I save the absolute file_path as a property on my model itself for easy access later. Of course, you will need to have proper error and validation checks in place. I didn't include them to make the uploading logic be clear.
You can see the full live form here - http://accliveinc.com/job-seekers#submit-resume.
Hope it helps!
I got this error,
Cannot redeclare Rahman\Galleries\Models\Petfie::$attachOne
Do you know why?
Last updated
@surahman.duang8307 - Check your "Petfie" model, looks like you are redeclaring an attachOne relationship more than once.
pratyushpundir6424 said:
@surahman.duang8307 - Check your "Petfie" model, looks like you are redeclaring an attachOne relationship more than once.
Is it different between $attachOne and $hasOne?
Could you give me your github code?
Last updated
@surahman.duang8307 - OctoberCMS uses hasOne and attachOne relationships for different purposes.
Basically it's this,
-
hasOne - represents a one-to-one relation between 2 model classes. For example - every User will have only one Profile or vice-a-versa. Read more here - http://octobercms.com/docs/database/model#relation-hasone-hasmany
- attachOne - this is used to attach a SINGLE file (an instance of Systems\Model\File) of any given "type" to a database record. By "type" I do not mean the mime type of the attachment but instead the "type/class" you will refer it as.
For example - User will have only one ProfileImage attached to him/her. Here, the ProfileImage is obviously an image file. You can attach more image files to the User as long as one of these things are true:
- The other images are not attached using the ProfileImage relation name.
- The ProfileImage was attached using a attachMany relation instead of attachOne. Read more about this here - http://octobercms.com/docs/database/model#file-attachments
Sorry, I do not at present have any publicly shareable code that uses both of these but the docs I have linked to do show some code examples as well. Hope it helps.
If you can share you code here or (github would be so much easier though), it'll be a lot easier to help you out.
pratyushpundir6424 said:
If you can share you code here or (github would be so much easier though), it'll be a lot easier to help you out.
pratyushpundir6424 said:
If you can share you code here or (github would be so much easier though), it'll be a lot easier to help you out.
here's my code,
Petfie -> Model
class Petfie extends Model
{
/**
* @var string The database table used by the model.
*/
public $table = 'rahman_galleries_petfies';
/**
* @var array Guarded fields
*/
protected $guarded = ['*'];
/**
* @var array Fillable fields
*/
protected $fillable = [];
/**
* @var array Relations
*/
public $hasOne = [];
public $hasMany = [];
public $belongsTo = [];
public $belongsToMany = [];
public $morphTo = [];
public $morphOne = [];
public $morphMany = [];
public $attachOne = [];
public $attachMany = [];
public $attachMany = [
'photo' => ['System\Models\File'],
];
}
Column.yaml
# ===================================
# List Column Definitions
# ===================================
columns:
id:
label: ID
searchable: true
file_path:
type: text
photo:
type: fileupload
mode: image
component
{{ form_open({'files': 'true', request: 'onUpload'}) }}
<input name="image" type="file">
<button type="submit">Upload File</button>
{{ form_close() }}
Petfie Class for Component
public function onUpload()
{
$file = new \System\Models\File;
$file->data = Input::file('image');
$file->save();
$model = new PetfieModel;
$model->photo()->add($file);
$model->file_path = url('/') . $model->photo->getPath();
$model->save();
return Redirect::back();
}
Hi,
There are quite a few things that're wrong here:
In your List Column Definition, the fileupload column type will not work. 'fileupload' is a form-widget so it can only be used as part of a form (not a list). Are you trying to display the image uploaded for each record in the backend list?
Since you're using an attachMany relation, I'm assuming you want to attach more than a single image to your model, in that case you should rename the relationship to be 'photos' instead of 'photo':
public $attachMany = [
'photos' => ['System\Models\File']
]
Also, the below code in your handler will throw an error:
$model->photos->getPath()
This is because you're using an attachMany relation, hence it will return something like an array of files instead of a single file and getPath() on an array will not work. You can access these paths using something like this:
foreach($model->photos as $photo) {
echo($photo->getPath());
}
Another thing is that you're using a 'file_path' property in both your List Column Definition and the onUpload() handler. Since you intend to attach more than one 'photo', a single file_path property will not suffice. I mean, which photo's path will you save to this property and which ones will you leave unsaved? You might want to think about that. I suggest you look at a different strategy of storing file-paths to these photos. In fact, you might want to skip saving them to the model itself.
Also, I would suggest that you remove any unused relations from the model. Once you have worked these things out, let us know of any errors you get and then we can work it out. What is also needed is if you could make us understand the complete frontend and backend functionality you are after. Looks like you have a few things mixed up..
Last updated
just a thing I saw...
public function onFileUpload()
{
$file = new System\Models\File;
$file = $file->fromPost(Input::file('file-upload'));
$file->save();
// Attach the uploaded file to your model
$model->file()->add($file);
// The above line assumes you have proper attachOne or attachMany relationships defined on your model - in this case, I have named the relationship simply as "file"
$model->file_path = url('/') . $model->file->getPath();
$model->save();
return Redirect::back();
}
Last updated
@Tschallacka - I can't really find a reference to the fromUpload() method so can't confirm this till I try it out.. Maybe tomorrow.
pratyushpundir6424 said:
Hi,
There are quite a few things that're wrong here:
Sorry, I just tested to change from $attachOne
to $attachMany
to make sure I typed the right code (Maybe I'll get different error.)
For now, I understood about column.yaml. Please avoid it.
But when I changed to $attachOne, here's the error,
and my Petfie table,
public function up()
{
Schema::create('rahman_galleries_petfies', function($table)
{
$table->engine = 'InnoDB';
$table->increments('id');
$table->string('photo');
$table->string('file_path');
$table->timestamps();
});
}
Last updated
Remove these lines from your model:
public $hasOne = [];
public $hasMany = [];
public $belongsTo = [];
public $belongsToMany = [];
public $morphTo = [];
public $morphOne = [];
public $morphMany = [];
public $attachOne = [];
public $attachMany = [];
And remove this line from your migration:
$table->string('photo');
You don't need the property photo as it is defined as a 'relation' on your model. Do these changes and it should be fixed.
Last updated
Guys, if you need Frontend-File upload with files attached to a model use this excellent plugin: https://github.com/responsiv/uploader-plugin
If you follow the steps in the README and your relation is set up correctly it works like a charm.
pratyushpundir6424 said:
Remove these lines from your model:
public $hasOne = []; public $hasMany = []; public $belongsTo = []; public $belongsToMany = []; public $morphTo = []; public $morphOne = []; public $morphMany = []; public $attachOne = []; public $attachMany = [];
And remove this line from your migration:
$table->string('photo');
You don't need the property photo as it is defined as a 'relation' on your model. Do these changes and it should be fixed.
wow, thank you. It's work!
But, why? I just remove the code like above.
and (I hope the last question), So how to get the path of photo? So I can save the path to path_file in my model.
Last updated
@surahman.duang8307 - The error you were getting was very clear. You were declaring $attachOne on your model more than once. You can see that the lines you deleted in your model included an empty $attachOne relation. But you were later creating your own $attachOne right under those lines. That caused the error.
So for your last question, the answer is in the first response from me but here it is again -
$model->file_path = $model->photo->getPath();
Last updated
@surahman.duang8307 - May be you should brush up on ObjectOriented PHP. It'll go a long way!!!
pratyushpundir6424 said:
@surahman.duang8307 - The error you were getting was very clear. You were declaring $attachOne on your model more than once. You can see that the lines you deleted in your model included an empty $attachOne relation. But you were later creating your own $attachOne right under those lines. That caused the error.
So for your last question, the answer is in the first response from me but here it is again -
$model->file_path = $model->photo->getPath();
OMG, I know what the meaning of "redeclare" but I don't see $attachOne in this code (I see now the code is before the last one),
public $hasOne = [];
public $hasMany = [];
public $belongsTo = [];
public $belongsToMany = [];
public $morphTo = [];
public $morphOne = [];
public $morphMany = [];
public $attachOne = [];
public $attachMany = [];
Maybe, cuz I'm so tired. :(
Sorry, for my fool question...
This code $model->file_path = $model->photo->getPath();
result this error,
Call to a member function getPath() on a non-object