Laravel redirect and continue executing script - php

How can I redirect user and then store data in database about that user.
return Redirect::to('http:www.google.com');
// Strore analytics
$ip = $_SERVER['...']
$analytic = new Analytic();
$analytic->ip = $ip;
$analytic->save();
Actually there is not only ip. I need to store a lot more data and if I first store that and then return redirect user needs to wait until everything is finished.
How to first redirect and then continue savin data?

Basically you can't do that. Once you redirect the user to a different location then the code after that line won't be executed. You should save the data first and then redirect and it shouldn't take much time (IMO).
But...
If you want to redirect the user first (without saving the data) then you may use Laravel's queue. You may create a class like this:
class SaveData {
public function fire($job, $data)
{
//
}
}
Then you may use the class like this:
Queue::push('SaveData', array('ip' => $ip, 'otherField' => 'value'));
return Redirect::to('someurl');
There are several drivers available and you need to setup configuration in app/config/queue.php, so read more about queues. This is just a basic idea about queue, read more on the Laravel website.

Are you using Sentry to Handle User sessions??
https://cartalyst.com/manual/sentry
http://bundles.laravel.com/bundle/sentry
eg,
$user = Sentry::getUser();
if ( isset($user) )
{
$id = Helpers::loggedInUser()->id;
$ip = Helpers::loggedInUser()->ip;
}

Related

Is AWS MySQL caching data? Laravel 5

I'm making a simple API endpoint that returns an access code for an event.
If the event does not have access code, then it gets assigned one and saved in the database. Then, it checks if it's currently public or private. If private, return access code, if public, return empty string.
This is the endpoint controller:
public function getAc($eventId) {
// Pull event
$event = $this->eventService->api->getEventForce($eventId);
// If no access code for the event, generate one and update event record accordingly
if ($event->access_code == null) {
$access_code = $this->generateAccessCode();
DB::update('update events set access_code = ? where id = ?', [$access_code, $eventId]);
// Load updated event from DB.
$event = $this->eventService->api->getEventForce($eventId);
}
// Is the event currently private? return access code
if ($event->privacy=='private') {
return $event->access_code; // HERE: value comes back from the API but on MySQL Workbench it's still null.
}
// Is it public ? return empty string.
else {
return '';
}
}
My problem is that even though everything works as expected. When access_code is created it does come back from the api.
However when I check the record on MySQL Workbench (that connects to AWS Instance) it's still null! event though I pulled it from the database as a non-null value using the API endpoint.
Little confused with your code. From debugging I'd suggest checking your API for this issue. From what I can see you're doing this:
Ask API for event with ID 1
Check if event has a parameter
If no parameter, update using local DB
So I'm left asking, if the problem is with the API, why are you updating using the local instance of the DB? Furthermore could this be resolved using events? (I'm going to call your class something other than event so not to get confusing)
For instance:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Party extends Model {
public $table = 'parties';
public $fillable = [];
public static function boot() {
parent::boot();
static::creating(function($party) {
//create some fancy access code
$access_code = 'heyyyy';
//Check not manually set
if (!isset($party->attributes['access_code']) || is_null($party->attributes['access_code'])) {
$party->access_code = $access_code;
}
}
}
}
Now every time you create an event or 'party' using Party::create(); or $party = new Party; $party->save(); the creating event will pick up the save and also assign the access_code if you haven't set it manually like $party->access_code = 'you can\'t come';.
That's my thought anyway. However in your immediate case I think you need to ask yourself some more questions like:
Does the DB object from the instance of Laravel I'm using have access to the database to save said object?
Do I need to call the API in order to update my entity/model?
If the instance of Laravel I'm using from the \DB::update call have the same credentials as my API?
If this is a command or job, do my code changes affect it? Do I need to restart a supervisor/cron command to re-instance my code?
Who wrote this API? Is it reliable enough to use? And does it have documentation?

Why Am I Able to Use user() method in laravel, without even defining it

I do have a UserController and User Model in my Laravel 5 source.
Also there is one AuthController is also Present (shipped prebuilt with laravel source).
I would like to query data from db in my blades making use of Eloquent Models.
However, Neither in my User Model (Eloquent ) nor in any of the controller, the user() method is defined. even then, I could use it in my blade by accessing it from Auth class. why?
For example,
in my blade, {{ Auth::user()->fname }} works. it retrieve the data fnamefrom my users table and echo it.
What is the logic behind it, and can i emulate the same for other db tables such as tasks?
Whenever you do it automatically or manually some like this
if (Auth::attempt(['email' => $email, 'password' => $password]))
{
}
The selected User's Data will be stored in the storage/framework/sessions
It will have data something like
a:4:{s:6:"_token";s:40:"PEKGoLhoXMl1rUDNNq2besE1iSTtSKylFFIhuoZu";s:9:"_previous";a:1:{s:3:"url";s:43:"http://localhost/Learnings/laravel5/laravel";}s:9:"_sf2_meta";a:3:{s:1:"u";i:1432617607;s:1:"c";i:1432617607;s:1:"l";s:1:"0";}s:5:"flash";a:2:{s:3:"old";a:0:{}s:3:"new";a:0:{}}}
The above sessions file doesn't have any data and it will have the data such as user's id, url, token in json format.
Then whenever you call the {{ Auth::user()->fname }} Laravel recognises that you're trying to fetch the logged in user's fname then laravel will fetch the file and get the user's primary key and refer it from the user's table from your database. and you can do it for all coloumns of the users table that you have.
You can learn more about it here
This user function is defined under
vendor/laravel/framework/src/Illuminate/Auth/Guard.php
with following content :
/**
* Get the currently authenticated user.
*
* #return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function user()
{
if ($this->loggedOut) return;
// If we have already retrieved the user for the current request we can just
// return it back immediately. We do not want to pull the user data every
// request into the method because that would tremendously slow an app.
if ( ! is_null($this->user))
{
return $this->user;
}
$id = $this->session->get($this->getName());
// First we will try to load the user using the identifier in the session if
// one exists. Otherwise we will check for a "remember me" cookie in this
// request, and if one exists, attempt to retrieve the user using that.
$user = null;
if ( ! is_null($id))
{
$user = $this->provider->retrieveById($id);
}
// If the user is null, but we decrypt a "recaller" cookie we can attempt to
// pull the user data on that cookie which serves as a remember cookie on
// the application. Once we have a user we can return it to the caller.
$recaller = $this->getRecaller();
if (is_null($user) && ! is_null($recaller))
{
$user = $this->getUserByRecaller($recaller);
if ($user)
{
$this->updateSession($user->getAuthIdentifier());
$this->fireLoginEvent($user, true);
}
}
return $this->user = $user;
}
this Guard.php has more functions defined in it which we use every now and then without even knowing where they are coming from
It works because Laravel comes with decent authentication.
Auth is the authentication library and has plenty of features like this, check out the documentation!

Symfony 2 stop saving form process

I am trying to link my local users stored in the database with some external services, so they can login anywhere with the same credentials.
I have an EventListener waiting for some FOSUserEvents like FOSUserEvents::REGISTRATION_SUCCESS or FOSUserEvents::CHANGE_PASSWORD_SUCCESS, fired when the data are valid but not actually saved, to perform some call to the various external services and replicate the new user credentials.
If the services return a message saying that the data are replicated, everything work fine.
But if a service say that there is a problem, no mater what it is, I would like to interrupt the saving process of the form and adding an error message.
The objective is to prevent Symfony to save the data, even if they are valid, if an external service say no, and I don't know how to perform this kind of emergency stop.
Actually, it's only based on FOSUserBundle but if I find a working solution, I will have to execute something similar for other entities, that why I try to be as generic as possible.
Here a some of my code
class MyListener implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return array(
FOSUserEvents::REGISTRATION_SUCCESS => 'createUser',
FOSUserEvents::CHANGE_PASSWORD_SUCCESS => 'editUser'
);
}
public function createUser(FormEvent $event)
{
$user = $event->getForm()->getData();
// Check if the user exists before trying to edit
$result = $this->_userExists($user);
if($result['value'] == false)
{
// Create the user
$result = $this->_createUser($user);
// Check if the user is successfully replicated
if($result['result'] != 'success')
{
/*
* Emergency stop (user not replicated)
*/
}
}else{
/*
* Emergency stop (user doesn't exists)
*/
}
}
. . .
}
Actually I didn't find any way to stop the saving workflow and returning to the form page to display an error message. So if somebody has an idea of how to perform this, feel free so write your idea, and thanks you all guys. Stackoverflow is really the best ;-)

Does PHP's Laravel 4 hit the Database on every call to the Auth class?

I am building my first Laravel 4 Application (PHP).
I find myself needing to call somthing like this often in most of my Models and Controllers...
$this->user = Auth::user();
So my question is, is calling this several times in the application, hitting the Database several times, or is it smart enough to cache it somewhere for the remainder of the request/page build?
Or do I need to do it differently myself? I glanced over the Auth class but didnt have time to inspect every file (16 files for Auth)
Here is the code for the method Auth::user().
// vendor/laravel/framework/src/Illuminate/Auth/Guard.php
/**
* Get the currently authenticated user.
*
* #return \Illuminate\Auth\UserInterface|null
*/
public function user()
{
if ($this->loggedOut) return;
// If we have already retrieved the user for the current request we can just
// return it back immediately. We do not want to pull the user data every
// request into the method becaue that would tremendously slow the app.
if ( ! is_null($this->user))
{
return $this->user;
}
$id = $this->session->get($this->getName());
// First we will try to load the user using the identifier in the session if
// one exists. Otherwise we will check for a "remember me" cookie in this
// request, and if one exists, attempt to retrieve the user using that.
$user = null;
if ( ! is_null($id))
{
$user = $this->provider->retrieveByID($id);
}
// If the user is null, but we decrypt a "recaller" cookie we can attempt to
// pull the user data on that cookie which serves as a remember cookie on
// the application. Once we have a user we can return it to the caller.
$recaller = $this->getRecaller();
if (is_null($user) and ! is_null($recaller))
{
$user = $this->provider->retrieveByID($recaller);
}
return $this->user = $user;
}
To me, it looks like it will get the user from the database only once per request. So, you can call it as many times as you want. It will only hit the DB once.
Auth::user() only hits the DB once, so it's not a problem invokes it many times. Btw, you can cache useful information of the user that you want to access frequently.

storing permissions into multi dimensional array php

OK, I am just trying to get better at making more loosely coupled classes etc in PHP just to improve my skills. I have a local test database on my computer and for the user table I have a column named "role". I am trying to build a function that is a general function for getting permissions for a user so it doesn't depend on a specific task they are trying to do.
When a user tries to do something such as create a new forum topic etc, I want to query the database and if "role" is a certain value, store permissions in a multidimensional array like the following:
$permissions = array(
'forums' => array("create", "delete", "edit", "lock"),
'users' => array("edit", "lock")
);
Then I want to be able to search that array for a specific permission without typing the following at the top of every PHP file after a user posts a form by checking isset($var). So if the user is trying to edit a user I want to be able to do something like the following via a class method if possible
if (Class::get_permissions($userID),array($permissionType=>$permission))) {
// do query
} else {
// return error message
}
How would be a good way to have a loosely coupled permission checking function that will be able to do something like this? It doesn't have to be laid out exactly like this but just be loosely coupled so it can be reused and not be bound to a certain task. But I want to be able to have an array of permissions instead of just "admin","user", etc for reusability and so it doesn't restrict my options down the road. Because I have a bunch of code that is like this right now in the top of my php script files.
if (Class::get_permissions($userID) == "admin") {
// allow query
} else {
// return error
}
Thanks for any input to help me get this to where I don't keep writing the same stuff over and over.
Your question is a little vague, but I will do my best. You said you're storing their permissions in an array $permissions.
public static $permissions = array();
public static function setPermissions($perms)
{
if (!is_array($perms)) {
throw new Exception('$perms must be an array.');
}
self::$permissions = $perms;
}
public static function hasPermission($section, $action)
{
if (array_key_exists($section, self::$permissions)
&& in_array($action, self::$permissions[$section])
) {
return true;
}
return false;
}
Using that logic, when you read a user's permissions from the DB, then set the Class::$permissions static var like so:
Class::setPermissions($permissions);
// ...
if (Class::hasPermissions($page, $action)) {
// user has permission
}
Note, my code is pretty generic and will have to remain that way until I have more information. For now, I'm assuming your permissions array is using a page section as the index and the array is a list of actions within that page section that the user has access to. So, assuming $page has been set to something like "forums" and the user is currently trying to perform an edit (so $action = 'edit'), the Class::hasPermission() function would return true.
I ran out of characters in the comments... But this is to your comment.
#corey instead of having a static object, I include a function that sets my permissions in the user's session. It as part of my LoginCommand class that gets called whenever the user logs in, obviously.
The permissions are then stored from view to view and I don't have to keep querying. The permissions check for most things only happen when the user logs in. However, certain sensitive things I'll run another query to double check. This has the disadvantage that, if the user's permissions change while the user has an active session, these changes won't be pushed to the user.
Remember to exercise good session security.
PHP Session Security
The only reason you wouldn't store data in your session size is because your session got too big. But unless you sessions are megabyte's, you probably don't need to worry about this.

Categories