Laravel passing over variables to functions - php

I create a GUID everytime a new database entry is being made and will be saved with the database entry to the database. The GUID should be my unique reference for further usage as reference to this entry. This part works fine.
My question: I need this GUID to perform a seach afterwards in the database for this entry, as another function needs the database entry details to work. As all the necessecary information is only created before saving to the database, how do I get a hold of this variable GUID to be used in another function?
public function createIncident(PrepareIncidentRequest $request)
{
$incidentReference = TicketSystem::generateIncidentReference();
$incidentID = TicketSystem::generateIncidentID();
$data = $request->all();
$data = $data + [
'incident_reference' => $incidentReference,
'incident_id' => $incidentID,
];
$incident = Incident::create($data);
Auth::user()->incidents()->save($incident);
}
When the entry is saved, and for example this would happen 100times in an hour, how do I know what to search for in another function? So how do I "pass over" this GUID I created in the function above to be used in another function?
For example here: I want to search for a user, and all the info needed is in a specific database entry. This entry could be found with the GUID I created. But as soon as it is saved, I need a way how to know, what to search for in another function when I want to retrieve the info.

If you need to persist data between the page views then session is the way to do it.
Add data to session like this
Session::put('key', 'value');
And read like that
Session::get('key');

Related

Eloquent DB::Post->where()->update() returns 1 always regardless of any changes made

I'm trying to figure out how to properly code the update() function in eloquent to return either 0 or 1 based on user input in a form. For example, if I hit the update button without making any changes, it returns 1. Shouldn't it return 0?
I tried researching for solutions like here in stackoverflow to see if anyone has the same problem as I am facing. But so far not luck. I also tried modifying the code, but no luck.
public function update(Request $request, $id)
{
$UCPost = UCPost::find($id);
$UCPost->gown_2019 = $request->input('Gown2019');
$UCPost->gown_2017_2018 = $request->input('Gown20172018');
$UCPost->gown_2016 = $request->input('Gown2016');
$UCPost->gown_2015 = $request->input('Gown2015');
$UCPost->Light_Blue = $request->input('LightBlue');
$UCPost->Seconds = $request->input('Seconds');
$UCPost->Velveteen = $request->input('Velveteen');
$UCPost->Velveteen_discolored = $request->input('Velveteen_discolored');
$UCPost->Rental = $request->input('Rental');
$UCPost->Rentals_Out = $request->input('Rentals_Out');
$UCPost->Rentals_Left = $request->input('Rentals_Left');
return $UCPost->where('id', $id)->update(
[
'gown_2019' => $UCPost->gown_2019,
'gown_2017_2018' => $UCPost->gown_2017_2018,
'gown_2016' => $UCPost->gown_2016,
'gown_2015' => $UCPost->gown_2015,
'Light_Blue' => $UCPost->Light_Blue,
'Seconds' => $UCPost->Seconds,
'Velveteen' => $UCPost->Velveteen,
'Velveteen_discolored' => $UCPost->Velveteen_discolored,
'Rental' => $UCPost->Rental ,
'Rentals_Out' => $UCPost->Rentals_Out,
'Rentals_Left' => $UCPost->Rentals_Left
]
);
}
The code above as I mentioned earlier, it always returns 1 regardless of any changes made to the form. I want it to return 0 if there are no changes by the user or if they accidentally hit the update button. I'm trying to find the equivalent of mysqli_affected_rows in Eloquent.
You are calling the update() method on your model. This will return 1 if the update was successful. It doesn't matter if there were any changes made, always 1 on successful update.
If you would like to only save to the database if there are changes, you can use the save() method instead, which checks to see if changes are present, and only writes to the database if the data is different. You have already created code to do this, by setting the model to have all of the new data from the sheet, so a simple save() at the end (with a check to see if it saves), will do what you want.
However, your current code is doing a lot of extra work. You are assigning all the variables to the model, and then updating based on that assignment of data to the model. You don't have to do all that assignment again in the update method. Once you have set the fields, you can save immediately, you don't have to re-assign all the variables. So:
$UCPost->gown_2019 = $request->input('Gown2019');
// etc..
$UCPost->Rentals_Left = $request->input('Rentals_Left');
$UCPost->save();
Will get you where you want to go and will only save if different.
If you have control over your form, and can change the form element names to match your database, this can be even easier. You can do all of this in one line:
$UCPost->update($request->all());
If you want to check if the model is dirty just call isDirty():
if($UCPost->isDirty()){
// changes have been made
}
Finally, if you want to verify if anything was changed after either method (save or update):
if ($UCPost->wasChanged()) {
// changes have been made
}
Hope this helps

Get Session data in store function

Is it right to get Session data in a store function and store them into db?
public function store(){
...
$idgroup = Session::get('invitation_userid')];
...
}
Or need a store function always a Request Object?
public function store(Request $request){
...
$idgroup = $request('idgroup');
...
}
In both functions is of course a validation part for the input data.
Both approaches are fine, but you should use them appropriately to your use case, I prefer to use the Request data. The main difference is that if u store that inside the Session it will be available application wide, while if u send inside Request it will be available inside the method only
This depends entirely on the context of what your controller is actually named, how this data is being used and why you are not using a database session driver in the first place if you want to do this.
You could simply use the database driver for the session:
https://laravel.com/docs/5.7/session#introduction
It also depends on what your controller is named if you strictly want to follow restful routes:
https://gist.github.com/alexpchin/09939db6f81d654af06b
To answer the second question you don't always need a Request object in your store action. Most of the time you won't even see a Request object because you are simply creating an entirely new resource.
The Global Session Helper
You may also use the global session PHP function to retrieve and store data in the session. When the session helper is called with a single, string argument, it will return the value of that session key. When the helper is called with an array of key / value pairs, those values will be stored in the session:
$value = session('key');

how to save data in Yii and be sure on correct saving?

Example: we have test table, which has 3 columns: id, watchers, title.
We have a code:
$test = Test::model()->findByPk(1);
echo $test->watchers; // 0
$test->title = 'another';
$test->save();
When we call save() ir generates sql query like "UPDATE test SET title='another', watchers='0' WHERE id='1'". SO, seams like everything is okay. But the problem is that if some another process will update watchers variable in the time between findByPk and save in current script, the code will generate wrong value. So:
$test = Test::model()->findByPk(1);
echo $test->watchers; // 0
$test->title = 'another';
//HERE WE HAVE A CODE WHICH PERFORMS FOR 1 SECOND. MEANWHILE ANOTHER PROCESS
// UPDATES TABLE WITH WATCHERS = 1
$test->save();
So, this code will save record's watchers field back to 0. How to overcome this? Why Yii ORM doesn't save only changed values? Why it tries to save all values? Thank you.
Since you get each value in $test, so when you do $test->save(); every attribute gets saved with new record or the previous value it contained.
When you query $test = Test::model()->findByPk(1); then $test->watchers; will be the same value which was there when you executed the query, this value will only change (if the value of watchers was changed by another update query) when you do another select query. Hope that makes sense :P
You can try the following update method :
Test::model()->updateByPk(1, array(
'title' => 'another'
));
Which will execute the following query:
UPDATE `test` SET `title`=:yp0 WHERE `test`.`id`=1.
Bound with :yp0='another'
I would tackle the issue as such:
$test = Test::model()->findByPk(1);
$test->title = 'another';
/*according to the api the second parameter only saves the columns
that are mentioned in the array. In this case it will save just the
title
*/
$test->save(true,array('title'));
{or}
$test = Test::model()->findByPk(1);
$test->title = 'another';
/*according to the api the parameter only saves the columns
that are mentioned in the array. In this case it will save just the
title
*/
$test->saveAttributes(array('title'));
As for me, the best solution is to inherit and rewrite the save() method and do it's behaviour the same as it is in Yii2 (getDirtyAttributes() method). W must compar eattributes to fetched from the db attributes and save only those ones, which were modified. I've successfully implemented this and can cinfirm it works.

Laravel Updating Record with optional image

I'm trying to recreate a simple blog functionality and allowing an admin to update a blog post.
My problem is the photo that has its name stored in the blog table under 'thumbnail' is not getting updated correctly. My save a new post function works but my update function does not work.
When you do an update without updating the image the rest of the blog items get updated but the photo name get set to blank and if you do try to update the image the photo does get moved but the field in the database is getting set to the temporary location (/Applications/MAMP/tmp/php/phpx1jwMA).
That may be two separate issues.
In the update form I added a hidden field with the photos name:
{{ Form::hidden('old_photo', $blog->thumbnail) }}
And it produces this in the form as expected:
<input name="old_photo" type="hidden" value="1391122313-2013 12 01_0567.JPG">
And in my controller I have this as my update function:
public function update($id) {
$input = Input::all();
$blog = Blog::find($id);
if(Input::hasFile('thumbnail')) {
$file = Input::file('thumbnail');
$name = time() . '-' . $file->getClientOriginalName();
$file = $file->move(public_path() . '/images/blog/', $name);
$blog->thumbnail = $name;
}
$blog->save();
return View::make('admin.blog.index', [
'blogs' => Blog::all()
]);
}
I'm trying to say in that code that if there is a new file in the thumbnail then create a unique name, move the file and set 'thumbnail' to that name (That is how my create function works) but if there has been no uploaded file to 'thumbnail' then set the 'thumbnail' to the old name.
Is there a better way to handle this process? Obviously there is because this way does not work. I am just learning Laravel and I have 3 books on it but none of them cover how to do this.
Thanks.
Instead of $blog->update($input); use $blog->save();. You already modified the model, just save it. With the update() method, all key/value pairs of the array you pass in will be assigned to the model.
Also you don't need your else case. If you don't want to change a models property just don't do it. You don't need to assign the value explicitly if you don't want to change it.
Omit your else case.
Side note on that:
Assigning Model properties manually e.g.
$model = Model::find(5);
$model->prop = 'val';
$model->save();
is better most of the time than Mass Assigning them e.g.
$model->find(5)->update($newvalues);
You have more control over what get's inserted and updated, when mass-assigning you have to take care of what's going to be assigned otherwise just every property could be changed. That's a security issue. (However laravel comes with $guarded and $fillable)
Also in your case you would not want to pass the whole input since you probably don't want certain fields to get updated if they did not change. So if nothing changed you had to explicitly exclude the Key/Value pairs you don't want to update when you just pass your whole Input to it (this is because the keys exist but the values are empty).
Well you get what I mean. When you assign your values manually you have full control on when and what you assign.
Happy Coding!

Using session variables versus Request parameters when persisting data between pages in Zend Framework PHP

I’m trying to better understand what the best method would be to persist data between requests in this scenario (using Zend Framework):
Say I have an Events controller and the default (index) view displays any existing Announcements (if there are any), and a link to Add a new Announcement (Both Event and Announcement are arbitrary objects). I’m trying to retrieve the eventId so I can associate the new Announcement with it when saving it to the database. Compositionally, an Event consists of 0 to many Announcements. From my limited understanding of the Zend Framework, I see two main options.
Option one: Make the URL something like ‘/event/addAnnouncement/eventId/5’, which makes retrieving the eventId easy via route/path parameters.
Option two: In the indexAction of the controller, save the eventId to a session variable, which can then be retrieved in the addAnnouncementAction of the Event controller. This way the Add Announcement link would simply be ‘/event/addAnnouncement/’.
Can anyone shed some light on which of these two ways is better, or if there is another way I’m not aware of?
As always, any help is much appreciated. Thanks.
The question to ask yourself is, how long do you need to persist the data? If you only need to save the data to pass it to the next action you can use POST or GET, the GET would pass through the url and the POST would not(typically).
The example you presented would suggest that you need to persist the data just long enough to validate, filter and process the data. So you would likely be very satisfied passing the few pieces of data around as parameters(POST or GET). This would provide the temporary persistence you need and also provide the added benefit of the data expiring as soon as a request was made that did not pass the variables.
A quick example (assume your form passes data with the POST method):
if ($this->getRequest()->isPost()) {
if ($form->isValid($this->getRequest()->getPost()){
$data = $form->getValues();//filtered values from form
$model = new Appliction_Model_DbTable_MyTable();
$model->save($data);
//but you need to pass the users name from the form to another action
//there are many tools in ZF to do this with, this is just one example
return $this->getHelper('Redirector')->gotoSimple(
'action' => 'newaction',
array('name' => $data['name'])//passed data
);
}
}
if you need to persist data for a longer period of time then the $_SESSION may come in handy. In ZF you will typically use Zend_Session_Namespace() to manipulate session data.
It's easy to use Zend_Session_Namespace, here is an example of how I often use it.
class IndexController extends Zend_Controller_Action {
protected $_session;
public function init() {
//assign the session to the property and give the namespace a name.
$this->_session = new Zend_Session_Namespace('User');
}
public function indexAction() {
//using the previous example
$form = new Application_Form_MyForm();
if ($this->getRequest()->isPost()) {
if ($form->isValid($this->getRequest()->getPost()){
$data = $form->getValues();//filtered values from form
//this time we'll add the data to the session
$this->_session->userName = $data['user'];//assign a string to the session
//we can also assign all of the form data to one session variable as an array or object
$this->_session->formData = $data;
return $this->getHelper('Redirector')->gotoSimple('action'=>'next');
}
}
$this->view->form = $form;
}
public function nextAction() {
//retrieve session variables and assign them to the view for demonstration
$this->view->userData = $this->_session->formData;//an array of values from previous actions form
$this->view->userName = $this->_session->userName;//a string value
}
}
}
any data you need to persist in your application can sent to any action, controller or module. Just remember that if you resubmit that form the information saved to those particular session variables will be over written.
There is one more option in ZF that kind of falls between passing parameters around and storing data in sessions, Zend_Registry. It's use is very similar to Zend_Session_Namespace and is often used to save configuration data in the bootstrap (but can store almost anything you need to store) and is also used by a number of internal Zend classes most notably the flashmessenger action helper.
//Bootstrap.php
protected function _initRegistry() {
//make application.ini configuration available in registry
$config = new Zend_Config($this->getOptions());
//set data in registry
Zend_Registry::set('config', $config);
}
protected function _initView() {
//Initialize view
$view = new Zend_View();
//get data from registry
$view->doctype(Zend_Registry::get('config')->resources->view->doctype);
//...truncated...
//Return it, so that it can be stored by the bootstrap
return $view;
}
I hope this helps. Pleas check out these links if you have more questions:
The ZF Request Object
Zend_Session_Namespace
Zend_Registry
Option 1 is better, although in your example this is not a POST (but it could be done with a POST).
The problems with option 2 are:
If a user had multiple windows or tabs open at the same time, relating to different events, how would you track which event ID should be used?
If a user bookmarked the add event page and came back later, the session var may not be set
Option 2 is also a little more complicated to implement, and adds a reliance on sessions.

Categories