Can't save filenames into the database with JInput - joomla

I have a form with input fields of type text and file. I have a problem of the filenames not saving in the database but everything else does. I vardumped $myForm and everything is there but the files, so I created another array with the filenames and merged it with $myForm. I then tried to set it to 'jform' but it doesn't seem to be working. Anyone have any ideas to why? Thanks!
controller.php
function save()
{
$jinput = JFactory::getApplication()->input;
$myForm = $jinput->get('jform', null, 'array');
//$files = $jinput->files->get('jform');
$file_array = ['image1' => 'test.png',
'image2' => 'test2.png'];
$merged_array = array_merge($myForm, $file_array);
$jinput->set('jform',$merged_array);
//or $jinput->post->set('jform',$merged_array); (this doesn't work either)
return parent::save();
}

Do not use $_POST unless you plan on writing extensive validation code to secure the user input.
Instead, use $jinput->get('jform', null, 'raw');
This will still apply some validation, but should keep your values in tact.

Related

The Laravel $model->save() response?

If you are thinking this question is a beginner's question, maybe you are right. But really I was confused.
In my code, I want to know if saving a model is successful or not.
$model = Model::find(1);
$model->attr = $someVale;
$saveStatus = $model->save()
So, I think $saveStatus must show me if the saving is successful or not, But, now, the model is saved in the database while the $saveStatus value is NULL.
I am using Laravel 7;
save() will return a boolean, saved or not saved. So you can either do:
$model = new Model();
$model->attr = $value;
$saved = $model->save();
if(!$saved){
//Do something
}
Or directly save in the if:
if(!$model->save()){
//Do something
}
Please read those documentation from Laravel api section.
https://laravel.com/api/5.8/Illuminate/Database/Eloquent/Model.html#method_getChanges
From here you can get many option to know current object was modified or not.
Also you can check this,
Laravel Eloquent update just if changes have been made
For Create object,
those option can helpful,
You can check the public attribute $exists on your model
if ($model->exists) {
// Model exists in the database
}
You can check for the models id (since that's only available after the record is saved and the newly created id is returned)
if(!$model->id){
App::abort(500, 'Some Error');
}

Laravel attach a non-physically saved file

I'm trying to find a way to attach a non-physical file to an email that's being made on the spot.
I'm using the following lines in my controller:
$columns = ['line1', 'line2'];
$rows = [
['line1' => 'first', 'line2' => 'second'],
['line1' => 'first', 'line2' => 'second'],
['line1' => 'first', 'line2' => 'second'],
];
Mail::to('email#email.com')->send(new ExportMail($columns, $rows));
And the following build function in the ExportMail class:
public function build()
{
$file = fopen('php://output', 'w'); // Tried w+ too
fputcsv($file, $this->columns);
foreach ($this->rows as $row) {
fputcsv($file, $row);
}
// I tried a couple of things:
return $this->view('emails.myTestMail')
->attach($file);
return $this->view('emails.myTestMail')
->attach(fopen($file, 'r'));
return $this->view('emails.myTestMail')
->attach(fopen('php://output', 'r'));
return $this->view('emails.myTestMail')
->attach(file_get_contents($file));
return $this->view('emails.myTestMail')
->attach(file_get_contents(fopen($file, 'r')));
return $this->view('emails.myTestMail')
->attach(file_get_contents(fopen('php://output', 'r')));
}
But none if it works so I'm beginning to question if there is a way to send an email with a file that is never physically saved.
You can attach file data directly with the attachData method documented here:
https://laravel.com/docs/9.x/mail#raw-data-attachments
I use this regularly to attach dynamically generated PDF files, for example.
You should be able to do something like this:
return $this->view('emails.myTestMail')
->attachData($yourCsvData, "attachment.csv");
Also, I think you want to look at how you are generating your CSV data. Right now using php://output the CSV data will be sent out to the browser immediately, not stored in a variable.
There are a couple ways you can solve this, output buffering being one, or using php://temp instead, or using one of many CSV libraries (like https://csv.thephpleague.com/). I put together a fully working example for you here using php://temp:
https://laravelplayground.com/#/snippets/aa5b6594-4493-4ca4-9d12-837c102b7cc5
Expand the rawAttachments attribute on that Message on the right, and you'll see the attached CSV file.

Laravel filtered collection is no longer filtered after json encoding

I have an Eloquent collection with an eager loaded relationship. When I filter this eager loaded relationship, it works fine, but if I encode it as JSON (to pass it to my front end Javascript framework), the collection is no longer filtered.
Simplified example:
$questions = Question::with('variables')->get();
foreach($questions as $key => $q) {
$questions[$key]->variables = $q->variables->reject(function($v) {
return $v->type == 3;
});
}
dd($questions);
If I look at the $questions variable at this point, my collection is correctly filtered. If, however, I add json_decode(json_encode($questions)) following line before dumping, the collection is no longer filtered.
Note that in my real application, I have to do some things with the rejected variables before throwing them out of the collection, so I cannot simply filter them out during the query.
My workaround right now is to json encode and decode the collection, then do an array filter to get rid of the variables I do not want to pass to the front end. This works, but seems like a terribly inelegant and unnecessary solution. Am I doing something wrong or is this the expected behavior?
I'm still running Laravel 5.8 on this application in the event that this behavior has changed on newer versions.
Why not just load the variables twice then?
$questions = Question::with(['variables' => fn($v) => $v->where('type', '!=', 3)])->get();
// do whatever you need to do with the filtered collection
// reload variables relationship
$questions->load('variables');
// do whatever you need to do with the question and all its variables.
You can try
$questionsWithFilteredVariables = $questions->map(function($question) {
$variables = $question->variables->reject(fn($var) => $var->type === 3);
unset($question->variables);
$question->variables = $variables;
return $question;
});
//Now do json_decode(json_encode(...)), it will still contain filtered variables
$questionsWithFilteredVariables = json_decode(
json_encode($questionsWithFilteredVariables)
);

Codeigniter Datamapper not running get rules on fields with NULL values

I'm using Datamapper v1.8.2 with Codeigniter v2.1.2 and have a "get" rule that doesn't seem to run on fields with NULL values. Here's the model:
class Page extends Datamapper {
public $validation = array(
'name' => array(
'rules' => array('required'),
'get_rules' => array('get_page_name')
)
);
function _get_page_name($field)
{
$this->$field = 'TESTING '.$this->id;
}
}
Example code:
$page = new Page();
foreach ($page->get() as $p) echo $p->name;
When the table field name has any non-null value including an empty string it works fine outputting something like TESTING 358, but when the value is NULL (which is the default value for this field), it outputs nothing. There is no difference using get_iterated().
I guess I could work around this by changing the default value, but I'm wondering if I'm doing something wrong or missed something in the documentation, or maybe it's a bug? Does anyone know what the issue is?
Also, if someone could point me to the proper thread in the CI forums for Datamapper 1.8.2 support that would be great, I'm trying to find it and getting lost in a maze of links to threads for old versions of DM.
You need to add the allow_null to the get_rules array to make this work. I'm not sure about the intent of the creator but this is how get_rules are implemented (however i don't see it mentioned in the docs).

Codeigniter form validation failing when it should succeed

I'm building an admin utility for adding a bulk of images to an app I'm working on. I also need to to log certain properties that are associated with the images and then store it all into the database.
So basically the script looks into a folder, compares the contents of the folder to records in the database. All of the info must be entered in order for the database record to be complete, hence the form validation.
The validation is working, when there are no values entered it prompts the entry of the missing fields. However it happens even when the fields ARE filled.
I'm doing something a bit funny which may be the reason.
Because I'm adding a bulk of images I'm creating the data within a for loop and adding the validation rules within the same for loop.
Here is the results:
http://s75151.gridserver.com/CI_staging/index.php/admin_panel/bulk_emo_update
Right now I have default test values in the form while testing validation. The submit button is way at the bottom. I'm printing POST variable for testing purposes.
Here is the code:
function bulk_emo_update() {
$img_folder_location = 'img/moodtracker/emos/';//set an image path
$emo_files = $this->mood_model->get_emo_images('*.{png,jpg,jpeg,gif}', $img_folder_location); //grab files from folder
$emo_records = $this->mood_model->get_all_emos(); //grab records from db
$i=1; //sets a counter to be referenced in the form
$temp_emo_info = array(); //temp vairable for holding emo data that will be sent to the form
//loop through all the files in the designated folder
foreach($emo_files as $file) {
$file_path = $img_folder_location.$file;//builds the path out of the flder location and the file name
//loops through all the database reocrds for the pupose of checking to see if the image file is preasent in the record
foreach($emo_records as $record) {
//compairs file paths, if they are the
if($record->picture_url != $file_path) {
//FORM VALIDATION STUFF:
$rules['segment_radio['.$i.']'] = "required";
$rules['emo_name_text_feild['.$i.']'] = "required";
//populating the temp array which will be used to construct the form
$temp_emo_info[$i]['path'] = $file_path;
$temp_emo_info[$i]['name'] = $file;
}
}
$i++;
}
//sets the reference to validation rules
$this->validation->set_rules($rules);
//checks to see if the form has all it's required fields
if ($this->validation->run() == FALSE) { //if validation fails:
print_r($_POST);
//prepairs the data array to pass into the view to build the form
$data['title'] = 'Bulk Emo Update';
$data['intro_text'] = 'fill out all fields below. hit submit when finished';
$data['emos_info'] = $temp_emo_info;
$this->load->view('admin_bulk_emo_update_view',$data);
} else { // if it succeeds:
//printing for test purposes
print_r($_POST);
$this->load->view('form_result');
}
}
I'm new to codeigniter and php in general so if anything looks outrageously weird please tell me, don't worry about my feelings I've got thick skin.
if ($this->validation->run() == FALSE)
if you are calling the run() method of the validation class every time the script is run, will it ever return TRUE and run the else? Maybe a different return?
I'm a little cornfused by what's going on. Generally, if I'm having a problem like this, I will figure out a way to force the result I'm looking for. e.g. in your code, I'd force that else to run... once I get it to run, break down what happened to make it run. Rudimentary, but it has served me well.
You use array of rules in
$this->form_validation->set_rules()
wrong.
If you want to pass the rules in array you must stick to the key names like described here http://codeigniter.com/user_guide/libraries/form_validation.html#validationrulesasarray
So instead of
$rules['input_name'] = "required"
try this:
array(
'field' => 'input_name',
'label' => 'Name that you output in error message',
'rules' => 'required'
)

Resources