I am trying to update a record which consist of a pdf file . record is updating successfully but the file field becomes empty on update .
my controller code is
$model2=$this->loadModel($alldata[0]->frm_id,'Forms');
$values=array();
$tagsarray=$_POST['searched_tag']; // matched tag values
$pdfval=$_POST['searched_tag_pdf']; // pdf form values
for($i=0;$i< count($pdfval);$i++)
{
$values[$pdfval[$i]]=$tagsarray[$i];
}
$model2->analyse_data=json_encode($values);
$model2->frm_status=2;
if($model2->save())
{
Yii::app()->user->setFlash('pdfupload','Form analysis done! data saved.');
$this->redirect(Yii::app()->createUrl('/formsupload'));
}else
{
Yii::app()->user->setFlash('pdfupload','Some error to save the data.');
$this->redirect(Yii::app()->createUrl('/formsupload'));
}
and model rules is
public function rules()
{
// NOTE: you should only define rules for those attributes that
// will receive user inputs.
return array(
array('frm_code,frm_desc,frm_pdf', 'required'),
array('frm_code', 'unique'),
array('is_approve', 'safe'),
//array('desc', 'min'=>1, 'max'=>200)
array('frm_pdf', 'file', 'types'=>'pdf','allowEmpty'=>true),
);
}
Update
also tried this solution here
unable to catch the problem .
Handling file upload updates in yii can be a bit tricky. Try setting the file attribute to be unsafe and see if that helps. Yii seems to set the value of that attribute to null if it cannot find an uploaded file. Setting it to unsafe should prevent that.
You can check my answer at the yii forum link below to someone running into a similar problem for more info.
http://www.yiiframework.com/forum/index.php/topic/63506-how-can-i-update-records-without-adding-same-image-again/page__p__279888#entry279888
Related
I have tried following this https://github.com/samdark/yii2-cookbook/blob/master/book/forms-validator-multiple-attributes.md
Unfortunately, it already has an issue raised that it no longer works with updates to Yii2 and I can't find any way to make it work.
I have two attributes which must be unique from each other. (Both are an array of strings.)
My validation logic works, but I can't find a way to display errors (or remove errors) on both attributes at the same time.
I have tried making a custom validator class, and also an inline validator, with the same problem:
When entering data in the form, only the attribute being edited will have its error message updated.
Below is the simplest version of my code that doesn't work, I want to display an error on both attributes after editing either one of them.
public function rules()
{
return [
[['attribute1', 'attribute2'], 'customValidator'],
];
}
// declare validator
public function customValidator($attribute, $params)
{
$this->addError('attribute1', 'error');
$this->addError('attribute2', 'error');
}
Yesterday I posted a question CakePHP 3 - Using reusable validators but am still struggling to see how to validate data when it is not tied to a particular database table, or set of fields in a table.
What I'm trying to do is upload a CSV file. The data in the CSV may well end up in the database, but before any of that happens, I want to validate the file to make sure it's valid - extension is .csv, MIME type is text/csv, file size is <1 Mb. This particular validation has absolutely nothing to do with a database.
Where does such validation go, since it's nothing to do with a database table?
The approach I've used is as follows - but this does not work:
I have a UploadsController.php with an upload() method. This method handles the upload (form posts to /uploads/upload)
I have added the following to my src/Model/Table/UploadsTable.php (because I don't know where else to put such code):
public function validationDefault(Validator $validator)
{
$validator
->add('submittedfile', [
'mimeType' => [
'rule' => array('mimeType', array('text/csv')),
'message' => 'Upload csv file only',
'allowEmpty' => TRUE,
],
'fileSize' => [
'rule' => array('fileSize', '<=', '1MB'),
'message' => 'File must be less than 1MB.',
'allowEmpty' => TRUE,
]
]);
return $validator;
}
In UploadsController::upload() I have this:
if ($this->request->is('post')) {
debug($this->request->data['submittedfile']);
$uploads = TableRegistry::get('Uploads');
$entity = $uploads->newEntity($this->request->data['submittedfile']);
debug($entity);
}
No matter what file I upload, no errors are returned. Even if I comment-out the entire validationDefault method, the behaviour doesn't change.
This is becoming very frustrating as all of the documentation on Cake's website talks about data relating to DB tables. Well, what if you're trying to validate something that's nothing to do with a DB table?
I've opened this as a new question, because the last one doesn't really address this problem.
Other questions posted about this do not address this problem, because in this case they are writing the file info to a DB table, and therefore validating the file at the same time. In my case I'm not trying to do that, I just want to validate the file, before considering anything to do with the DB at all. I also want the code to validate a CSV to be re-usable (i.e. not in one specific Controller method) because if I want to check for a valid CSV in 5 different parts of the application, why should I repeat code that does the same thing all over?
Use a model-less form, it has validation built in, to validate your uploaded file. If you want your validation code to be reusable put it in a trait or separate class
In theory you could then do something like this:
$form = new CsvForm();
if ($this->request->is('post')) {
$result = $form->execute($this->request->getData());
if ($result && $this->Model->saveMany($result) {
$this->Flash->success('We will get back to you soon.');
} else {
$this->Flash->error('There was a problem submitting your form.');
}
}
Let your form validate the CSV document and return the pure CSV data, or already turn the rows into a set of entites you save.
So, i have this particular issue.
I have made a form with dropzone included, and the images are uploaded via AJAX, and everything is working from that point of view (selected images are stored, and can be deleted from the box).
So the problem is the following:
When i submit the form, and some validation error happens, the images i have uploaded are already on the server, but dont display on the dropzone form, i have to reupload them again, but then i just fill my storage with unwated data, and the images that were uploaded earlier before the validation cannot be accessed or deleted by any methods later on, so its basically junk data.
Is there any way to prevent this from happening? I would LOVE to show the already uploaded images after validation error (or refresh for example). If there cant be any solution for this, suggest me different approach.
Thanks.
I managed to get a working solution.
My thinking was following: If there are images posted, then using the $validator->fails() method i am deleting the images from the server.
Here is the complete code, if someone needs it:
// Validating the request
public function validate(Request $request){
$rules = []; //define your rules
$messages = []; //define your rules
// We make new validator with request data, rules and messages
$validator = Validator::make($request->all(), $rules, $messages);
// Deleting images if the validator fails
if($validator->fails()){
if(isset($request->images)){
foreach($request->images as $image){
// unlink your image here
}
}
return Redirect::back()->withInput()->withErrors($validator);
}
}
Then in the method store/edit (or custom method) just call:
public function store(Request $request){
// If it fails, return the redirect we defined.
if($this->validate($request)){
return $this->validate($request);
}
}
You can also define the validator directly in the store method, but since i use it few times in my Controller, i made a separate method just for it. We must return its value if we like to redirect back with the errors.
Cheers.
I would like to validate an embedded form field before it gets saved in the database. Currently it will save an empty value into the database if the form field is empty. I'm allowing empty fields, but I want nothing inserted if the form field is empty.
Also quick question, how to alter field values before validating/saving an embedded form field?
$this->form->getObject works in the action, but $this->embeddedForm->getObject says object not found
I found a really easy solution. The solution is to override your Form's model class save() method manually.
class SomeUserClass extends myUser {
public function save(Doctrine_Connection $conn = null)
{
$this->setFirstName(trim($this->getFirstName()));
if($this->getFirstName())
{
return parent::save();
}else
{
return null;
}
}
}
In this example, I'm checking if the firstname field is blank. If its not, then save the form. If its empty, then we don't call save on the form.
I haven't been able to get the validators to work properly, and this is an equally clean solution.
Symfony gives you a bunch of hooks into the form/object saving process.
You can overwrite the blank values with null pre/post validation using by overriding the the doSave() or processValues() functions of the form.
You can read more about it here: http://www.symfony-project.org/more-with-symfony/1_4/en/06-Advanced-Forms#chapter_06_saving_object_forms
I have a form for an object called AccountImport. This form lives in an admin-generated module. In addition to the fields that map directly to this object's attributes, I need a couple extra fields.
If I just add the fields to the AccountImport form, it won't save correctly because the form will no longer match the AccountImport object.
If I create a template manually and splice the extra fields in that way, I'm throwing away all the stuff the admin generator gives me for free (i.e. formatting, "Back to list" button, save buttons).
What's a "good" way to do what I'm trying to do?
If you define additional fields in generator.yml, you can override one of the admin generator actions to handle the fields however you want.
Look at the generated actions.class.php in cache/YOURAPP/YOURENV/modules/autoYOURMODULE/actions/actions.class.php . You can override any of those functions with your own in apps/YOURAPP/modules/YOURMODULE/actions/actions.class.php, because it inherits from that cached file. When you make changes to generator.conf, the cached file is updated but your code will still override it. You probably want to override processForm().
I have an example of this in step 5 at this blog post:
protected function processForm(sfWebRequest $request, sfForm $form)
{
$form->bind($request->getParameter($form->getName()), $request->getFiles($form->getName()));
if ($form->isValid())
{
$notice = $form->getObject()->isNew() ? 'The item was created successfully.' : 'The item was updated successfully.';
// NEW: deal with tags
if ($form->getValue('remove_tags')) {
foreach (preg_split('/\s*,\s*/', $form->getValue('remove_tags')) as $tag) {
$form->getObject()->removeTag($tag);
}
}
if ($form->getValue('new_tags')) {
foreach (preg_split('/\s*,\s*/', $form->getValue('new_tags')) as $tag) {
// sorry, it would be better to not hard-code this string
if ($tag == 'Add tags with commas') continue;
$form->getObject()->addTag($tag);
}
}
try {
$complaint = $form->save();
// and the remainder is just pasted from the generated actions file
When I realized I could read the generated files in the cache to see exactly what the admin generator was doing, and that I could override any part of them, it made me a lot more productive with the admin generator.
I asume you have added the extra fields as widgets to your form object, but have you also added their validators?
No matter which form fields you include in the form object, as long as the generator.yml file doesn't override the settings of the form (ie you don't set any value for the [new|form|edit].display key in that file) the object should get successfully saved on valid input.