Doctrine 2/ Multi-step form / entity into session - session

I am working under Symfony2 and Doctrine 2.1.6 and I try to setup a multi-step form.
Between each form page, I try to send the doctrine entity into $_SESSION.
According to that dotrine documentation it is possible and even the way to settle multipage forms:
http://docs.doctrine-project.org/en/2.1/cookbook/entities-in-session.html
But according to a lot of other post on stackoverflow, it is just not possible to send entities into session.
I have the following controller Action where i pretty much copied/ past the doctrine documentation.
public function indexAction(Request $request, $id)
{
$session = $request->getSession();
$em = $this->getDoctrine()->getEntityManager();
if (isset($_SESSION['propertyAdd'])) {
$property = $_SESSION['propertyAdd'];
$property = $em->merge($property);
}
else {
$property = new property;
}
$form = $this->createForm(new propertyType($this->getDoctrine()),$property);
// check form
if ($request->getMethod() == 'POST') {
$form->bindRequest($request);
if ($form->isValid()){
$em->detach($property);
$_SESSION['propertyAdd'] = $property;
// redirection to next step here
}
}
return $this->render('AddProperty:'.$id.'.html.twig', array(
'form' => $form->createView(),));
}
the line $_SESSION['propertyAdd'] = $property; give me the following error:
Fatal error: Uncaught exception 'ErrorException' with message 'Notice: Unknown: "id" returned as member variable from __sleep() but does not exist in Unknown line 0' in G:..\Symfony\vendor\symfony\src\Symfony\Component\HttpKernel\Debug\ErrorHandler.php on line 65
If I replace this line by using the Symfony2 helper
$session->set('propertyAdd', $property);
It throws the following exception:
Symfony\Bundle\FrameworkBundle\DataCollector\RequestDataCollector::serialize() must return a string or NULL
Is the doctrine example workable.

This doesn't answer your question, but why would you:
Create an entity
Serialize it
Put it in the session (I personally don't believe it's a good thing to transform an object to a string)
Get it from the session in the form's next step
Deserialize it
Add the new data to it
Serialize it
Put it again in the session
An so on...
Why don't you store the form data directly in the session, and create the entity after all the form's steps were complete?
If you're doing this to validate the entity, you can simply use forms (that aren't linked to an entity) and add the validation constraints to them.

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');
}

How to acces is_* property in laravel model?

I am working with laravel 4.2 and have table in db with property is_active.
When I try to access this model property:
$model->is_active
I am getting following error:
Relationship method must return an object of type Illuminate\Database\Eloquent\Relations\Relation
So question is how to access this property?
Please do not recommend to rename this field in the database if possible because this is already existing database in production.
Here is my model class:
class Position extends \Eloquent {
protected $table = "hr_positions";
protected $fillable = ['slug', 'info_small', 'info_full', 'is_active', 'start_date', 'end_date', 'tags', 'user_create_id', 'user_update_id'];
use \MyApp\Core\StartEndDateTrait;
public function postulations(){
return $this->hasMany('Postulation', 'position_id', 'id');
}
}
Latest notice:
All this error ocurrs on a page where I am creating my entity. In the controller before forwarding to the page I am doing:
$position = new \Position();
and then, for example, following code produce error as well:
dd(($position->getAttribute('is_active')));
but if I replace $position = new \Position(); with
$position = \Position::first();
error is gone?
What is going on here?????
Laravel does a lot of magic behind the scenes, as in, calls a lot of php magic methods.
If a called property is not defined, __call is invoked which in Eloquent calls getAttribute().
Steps taken by getAttribute($key) are
Is there a database field by this key? If so, return it.
Is there a loaded relationship by this key? If so, return it.
Is there a camelCase method of this key? If so, return it. (is_active looks for isActive method)
Returns null.
The only time that exception is thrown is in step 3.
When you create a new instance, eloquent has no idea what kind of fields it has, so if you have a method by the same name, it will always throw a relation error, this seems to be the case in both Laravel4 and Laravel5.
How to avoid it? Use the getAttributeValue($key) method. It has no relation checks and returns null by default.
Alternatively you can also add a get mutator for your field.
I have found a hack for this. Still not ideal but at least I have some solution. Better any than none.
So This code produce problem:
$position = new \Position();
if($position->is_active){
//
}
and this one works fine, this is solution even hacky but solution:
$position = new \Position(['is_active' => 0]);
if($position->is_active){
//
}
I will wait if someone give better, cleaner solution. If no one comes in next few days I will accept mine.

In a user's Edit Info form, how do I include the name of the field(s) and user's input value(s) in a response from the model

On a Yii2 project, in a user's Edit Info form (inside a modal):
I'm currently figuring out which fields were changed using the jQuery .change() method, and I'm grabbing their value with jQuery's .val() method.
However, I want to do less with JavaScript and do more with Yii's framework.
I can see in the Yii debugger (after clicking into the AJAX POST request) that Yii is smart enough to know which fields were changed -- it's showing SQL queries that only UPDATE the fields that were changed.
What do I need to change in the controller of this action to have Yii include the name of the field changed -- including it's value -- in the AJAX response? (since my goal is to update the main view with the new values)
public function actionUpdateStudentInfo($id)
{
$model = \app\models\StudentSupportStudentInfo::findOne($id);
if ($model === null) {
throw new NotFoundHttpException('The requested page does not exist.');
}
$model->scenario = true ? "update-email" : "update-studentid";
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->renderAjax('_student_support_alert_success');
}
return $this->renderAjax("_edit_student_info",[
"model" => $model,
]);
}
I'm currently returning a static success view.
You can use $model->dirtyAttributes just after load the data to get a $attrib => $value pair array.
http://www.yiiframework.com/doc-2.0/yii-db-baseactiverecord.html#getDirtyAttributes()-detail (this docs says:)
Returns the attribute values that have been modified since they are loaded or saved most recently.
The comparison of new and old values is made for identical values using ===.
public array getDirtyAttributes ( $names = null )
(sorry for formatting, sent by mobile)

View Same user_id

//Anyone can help to create a view data with same id? it is a multiple viewing.
this is my Controller. i dont khow apply in Model and View
function Get_Pitch($id){
$this->load->model('users_model');
$data['query'] = $id;
$this->load->view('view_pitch', $data);
}
Example this is my url "http://localhost/SMS_System/home/sample/102"
in my database is
id=1 name=erwin user_id=102
id=2 name=flores user_id=102
id=3 name=sample user_id=202
how to view the same user_id?
First of all with what you've supplied your URL won't work, you aren't following the normal conventions for CI so it won't know where to look. I am assuming your controller is called sample then you need to tell the application which function you're calling in that controller, finally URL names should be lower case so I changed that, so your URL should read:
"http://localhost/SMS_System/home/sample/get_pitch/102"
Also you need to get your data from a model, you loaded the model then didn't use it. The line after loading the model calls a function from that model and passes it the id you got from your url. Notice the if not isset on the id, this ensures that if someone goes to that page without the id segment there are no errors thrown from the model having a missing parameter, it will just return nothing, that is handled in the view.
Controller:
function get_pitch($id){
//the following line gets the id based on the segment it's in in the URL
$id=$this->uri_segment(3);
if(!isset($id))
{
$id = 0;
}
$this->load->model('users_model');
$data['query'] = $this->users_model->getUserData($id);
$this->load->view('view_pitch', $data);
}
Your model takes the id passed from the controller and uses that to retrieve the data from the database. I normally create the array I am going to return as an empty array and handle that in the view, this makes sure you get no errors if the query fails. The data then returns to the controller in the last line and is passed to the view in your load view call.
Model:
function getUserData($id)
{
$this->db->where('id',$id);
$result = $this->db->get('users') //assuming the table is named users
$data = array(); //create empty array so we aren't returning nothing if the query fails
if ($result->num_rows()==1) //only return data if we get only one result
{
$data = $result->result_array();
}
return $data;
}
Your view then takes the data it received from the model via the controller and displays it if present, if the data is not present it displays an error stating the user does not exist.
View:
if(isset($query['id']))
{
echo $query['id']; //the variable is the array we created inside the $data variable in the controller.
echo $query['name'];
echo $query['user_id'];
} else {
echo 'That user does not exist';
}

How to use form_validation library rules for AJAX requests

One of my forms uses AJAX to send data. Since my page never reloads because of AJAX, is there a way I can still make use of form_validation to validate and output which fields are wrong? The url my form sends to using jquery is contact/ajax_send.
The entire AJAX works fine except I haven't inserted any validation yet.
Since you are using ajax to send the data, what you can do is, simply add the form_validation code calls before inserting into the database.
If there are any validation errors, you can either return the error messages as json response to the front end to display the error messages.
The form validation library assigns all errors that occurred to a private array called _error_array, but does not expose it or provide documentation on it (notice the first underscore?). Just return a json encoded object of the errors in the controller:
echo json_encode($this->form_validation->_error_array);
If you wish, you can extend CodeIgniter's form validation library, perhaps returning FALSE instead of an empty array... or whatever you see fit:
/* libraries/MY_Form_validation.php */
<?php
class MY_Form_validation extends CI_Form_validation
{
function __construct($config = array())
{
parent::__construct($config);
}
function error_array()
{
if (count($this->_error_array) === 0) return FALSE;
else return $this->_error_array;
}
}
Now, drop the initial underscore in the controller:
echo json_encode($this->form_validation->error_array);
Then decode and display errors on the client.
I found a method, thanks in part to Jordan's answer. This returns an array containing the names of the fields which have errors.
// library/MY_Form_validation.php
class MY_Form_validation extends CI_Form_validation {
public function get_field_data(){
return count($this->_field_data) ? $this->_field_data : FALSE;
}
}
// Controller file
$field_data = $this->form_validation->get_field_data();
foreach($field_data as $key=>$val){
if($key == '__proto__') break;
foreach($val as $k=>$v){
if($k == 'error' && !empty($v)) $errors[] = $key;
}
}
$return = array('success'=>FALSE, 'errors'=>$errors);
The above code checks the error key whether it's empty or not. Empty values mean that it passed the CI validation while none empty values would contain the string you see when you use validation_errors(). Since I'm after those fields which have errors, I only needed to see which values are not empty disregardig those which are.

Resources