share session info with laravel and back - php

Our web site is built on top of a custom php mvc framework and we wanted to slowly convert each flow (for eg: signups) to Laravel.
So in essence, the existing code and the new code using laravel have to co-exist. But we hit a snag, where session information set by laravel is not availble to the other mvc and vice-versa because of their conventions.
For eg, the custom mvc uses the following.
$_SESSION['AUTH']='TRUE';
While Laravel uses something like this.
Session::put('AUTH', 'TRUE');
We tried to set $_SESSION['AUTH'] = 'TRUE' through laravel classes. But we are not able to access it when control is passed to the older MVC.
I know its complicated, and i should just wait to convert the entire code base to Laravel, and be done with it. But we are a small company with minimal resources. So we dont have the luxury to stop feature development and spend time re-writing using Laravel Exclusively.
So my question is this. How , if by any mechanism, can we achieve this?
Global variables?
Any other suggestions?

I would recommend you to use Laravel's Auth-Class here, listen to the auth.login event and set your session flag by hand.
Event::listen('auth.login', function($user)
{
$_SESSION['AUTH']='TRUE';
});
It is the easiest way and you only have to delete the event listener when you completly migrated to Laravel.
I know this is a quick and dirty thing, but after full migration you don't want to use the $_SESSION ever again to manage your authentication ;) so I think this should be a very good bridge between your new and old codebase.

For example if you have the following folder stuctures
projectFolder/oldMVC
projectFolder/Laravel
in the oldMvC/main.php we included the following
require '../Laravel/bootstrap/autoload.php';
require_once '../Laravel/bootstrap/start.php';
After that we were able to access session and other config variables set in Laravel from the non Laravel MVC.

Actually only by requiring bootstrap/autoload.php and bootstrap/start.php you will not be able to access the real Laravel session. Not even by calling Application::boot() anymore.
I've created a Gist, that makes it possible to share Laravel's session and check authentication from external projects:
https://gist.github.com/frzsombor/ddd0e11f93885060ef35

Related

What is the best way to store AND update global variables programatically for your website in laravel 8?

I need to store some global variables for my laravel website, but I need to update them programmatically. Here is my situation:
the admin should be able to enable popups, and configure which post it has to link, which will show when a visitor comes to the website.
Other answers and why they did not satisfy me.
Making a laravel config file.
A database table.
Static variable somewhere in a controller or model.
A Laravel config file seemed to be the best option at first, but it didn't fit with the need to update them at running time. I've readt answers that suggested to call an artisan cache clear in the controller in order to update the values. but this seems just off to me. I don't think its a good idea to mess with the cache like that.
A database is still an option, however, it has some downsides as well. Making just an SQL table for 2 config variables seems like a waste of tables, it also means i need to make 2 query's on the admin dashboard, and also 1 on the homepage (to get the popup config), which i rather keep database-free.
A static variable in a model or controller. I saw this suggestion as well altough noted: it is probably a very bad design choice. Nevertheless i tried it in a desperate attempt and it didnt work. It did not stay updated on page reload.
I'm a laravel noob in case you didn't notice. Is there anything I am doing or understanding wrong? Or is there a solution I am not aware of?
There is no need for me to save the variable when the website is offline. It would be nice if it did but its only a minor inconvience for the admin to set it on restart.
For your situation, spatie write a nice package.
Just install as in documentation and use.
Use a db table to store the configuration, also having one extra table does not have any serious downside and it won't hurt the performance, also most popular applications/frameworks use it.
To reduce the db queries, create a wrapper class for your db config load, and in your wrapper cache the data for some amount of time, and when you want to change the config, remember to invalidate the cache.
If you want global access to it, bind it to laravel service provider, and use Facade or other container methods to fetch it. Also with this approach you keep the exposed config interface the same even if you change the implementation different in future.
About file solution: If you have one admin, you can go with file solution, but you never know how they will grow in numbers in future and it will be a hassle to go around what you did in file.
You can set config values dynamically at runtime with config() helper:
config([ 'app.popup1' => true ]);
Another solution is to write the config value into session at startup and only update the session:
session([ 'app.popup1' => true ]);

Where should I store the Laravel Session data based on the MVC pattern?

I'm working with the Laravel integrated to the WordPress and struggling to understand where should I put the session data based on the MVC design pattern?
Back in the day, I used to put everything inside the view (header.php and footer.php) files and after some time, it became a mess, complete mess.
As written here:
As MVC I use CodeIgniter, so I don't know if this can be true for your specific environment, but I usually set session values from the controller. It is possible to do it even in view but the correct way is to keep code in controller (as keeping database stuff in models).
In the controller, you can use standard php $_SESSION array or, it it exists, your framework session class.
Yea, I understand it's a good practice to not mess around with the view and put session variables inside the controller. Here is the problem:
As I'm using the WordPress, the goal is to have a place where the session variables are always loaded, doesn't matter if I changed the theme or anything, they should stay in the Laravel backend.
Without any testing, I could think about a couple option:
Use Laravel Service Provider and insert session variables inside the boot function.
Use Laravel Middleware functionality, however, not sure how to implement this.
You can use the laravel https://laravel.com/docs/5.6/session Session helper.
Then you can just do Session::put('hello','world'); Session::save(); and retrieve it with Session::get('hello'); You can do this anywhere you'd like, as long as you remember to save the session after putting things in it, modifying things or removing things.
As long as Laravel is loaded and the domain has the laravel session cookie, you can access them.

Flat PHP Legacy App - How to wrap in silex routes

I have been tasked with finding a solution to wrapping a custom made application in the silex framework as they are going to continue forward using silex. The dilemma is the legacy application is a flat php style with no controllers or models, and php with mysql queries embedded within the via files.
I have been struggling to find any clean solution to wrap the legacy app in the routing of silex to allow for new portions to be done in a controller based setyp instead of flat php. I have been checking for some time between stack overflow and other Google results, but they an del seem to end up specifying ways of doing default routes with a legacy app that has a controller based setup.
For good measure, the legacy app does use session variables so the solution must allow for those to be used.
Any and all help is appreciated.
Before people ask, I have looked at Routing in Silex/Symfony - Providing a default route and it is similar to how I would like to do it, but I need to make it work with the flat php app, not legacy controllers.
The solution ended up being a 2 part process.
Place the legacy code within the web root of the silex application.
Get the silex application to store sessions that are accessible by both Silex, and the legacy application.
Code Placement
By placing the legacy code into the web folder, anything in the URL that matches a file will go to that file instead of looking for a route. This allows for not needing to create routes for all of the old code, as it is not controller based in our situation and needs to be handled differently than most of the other restructuring that has been referred to on this site.
Placing the code into the web directory also means that we can continue to make updates and changes to the old code, while writing new Silex based code to replace it in our available time.
Sessions
When it came to using the same sessions, the option we went with was....less than desirable, but it allows for us to continue with our plans without hindering the use of either application. The current plan is to implement database stored sessions once we have completed migrating the application's code to Silex.
We went with an option first identified in this post Symfony session avoid _sf2_attributes. This is quite an ugly solution, but allows for the flexibility we need in attempting to migrate the application over in time with minimal effort up front. The goal is to migrate it over completely to the new Silex application, but the timeframe is over a year or more to do so.
Here is how the session is configured in our Silex application. It is using file based storage.
$app->register(new Silex\Provider\SessionServiceProvider(), array(
'cookie_lifetime' => 86400,
));
$app['session.storage'] = $app->share(function () use ($app) {
return new \Symfony\Component\HttpFoundation\Session\Storage\LegacySessionStorage;
});
Here is a copy of the controller code located originally here, in case it is removed at some point.
<?php
use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage;
/**
* Session sotrage that avoids using _sf2_attributes subkey
* in the $_SESSION superglobal but instead it uses
* the root variable.
*/
class LegacySessionStorage extends NativeSessionStorage
{
const SYMFONY_SESSION_SUBKEY = '_sf2_attributes';
/**
* #inheritdoc
*/
protected function loadSession(array &$session = null)
{
if (null === $session) {
$session = &$_SESSION;
}
parent::loadSession($session);
foreach ($this->bags as $bag) {
$key = $bag->getStorageKey();
if (self::SYMFONY_SESSION_SUBKEY === $key)
{
$bag->initialize($session);
}
}
}
}
I hope this helps some others in allowing them to migrate to a new coding style from an old application that is a thorn in their side. Wanted to make sure to sum up our findings over time in order to ensure others don't have to look as much in the future hopefully.
there is a really good article written by Matthias Noback about this. Basically the trick would be to match the legacy urls and return the legacy output inside a Silex Response object. Beware of memory use with ob_* methods.
An alternative is to modernize the flat PHP application in place (leaving you with one unified codebase) instead of wrapping it (which leaves you with 2 codebases). The step-by-step details are in Modernizing Legacy Applications in PHP but the overview is this:
Implement an autoloader
Consolidate classes and functions to a central location
Remove globals in favor of dependency injection
Remove the new keyword in favor of dependency injection
Write unit tests
Extract SQL code to Gateway classes ("Model, Part 1")
Extract domain logic to Transaction classes ("Model, Part 2")
Extract presentation logic to Response classes ("View")
Extract action logic to Controller classes ("Controller")
Extract remaining includes
Extract application code from the document root
Implement a front controller
Prepare the application for a dependency injection container
Add a dependency injection container
Hope that helps.

Where to store global data?

I'm writing this small blogging platform in Laravel 4.1, for learning purpose. My first obstacle is, I don't know where the global data (ie. dynamic blog settings, plugin and theme array) should be put, so that I can access them from anywhere (similar to how $wpdb in WordPress works - we only need global $wpdb; to access it).
Of course $GLOBALS works, but we know that it's evil and should be avoided. Also, I'd like everything to be as Laravel'y as possible.
Have tried:
App::bind('settings', []); // error
App::instance('settings', []); // how to populate and retrieve it back?
Any ideas? Thanks in advance.
If this is not something you need to keep between sessions, you can use:
Config::set('myglobals.name', 'An Phan');
And then
var_dump( Config::get('myglobals.name') );
But you also have to think a bit and think why would you need globals in the first place. Take a look at this: http://c2.com/cgi/wiki?GlobalVariablesAreBad.
EDIT
This is not a workaround, this is something Laravel provides out of the box and you can use yourself. Usually the purpose of Config would be having configuration files to be used by your application, but sometimes you just need to change those values during the request, that's why Laravel provides also a set() method.
Unfortunately WP has an old codebase and if you are trying do things the way WP does things, you're goind the in wrong path.
What would be the Laravel way depends on what you're trying to accomplish with your project, so you'll have to tell a little bit more about it.
The mindset to start with is: "I don't need globals" and when you get to a point where a global is needed, you ask yourself "how do I do this without using a global?".
Usually, you just need global values if you have settings to store. If it's something that you have to use to set a state during a request, you need to use objects. You can have global objects in Laravel, you can have singletons (objects that has only one instance in the whole application), you can create properties objects:
class SidebarProperties {
private $width;
public function __construct($width)
{
$this->width = $width
}
public getWidth()
{
return $this->width;
}
}
So you have an uncountable number of way to not use globals, you just have to think about your project and pick the one is best at that moment.
Well, global in a Laravel context means relative to Application, if you are not writing anything that "lives" outside of Application context.
There are couple of ways in which you can make you data available to application. But first, you have to make decision what kind of "globals" do you need ?
First and most important rule is that any change that you make besides Application specific folder structure, has to be told to composer.
Second, without making any changes, Laravel has default locations for most important parts of any "ordinary" web application.
Application folder structure is pretty self descriptive, but in short:
Configurations belongs to app/config
Models to app/models
Views to app/views
Controllers to app/controllers
Database to app/database
Routes to app/routes.php
If you follow this basic structure, you can create amazing web-apps. these folders and files are already namespaced and classes inside them are auto resolved. In you example you were trying to bind something to application, which is redundant in you case. Bindings to container are used in cases when you want to add some new classes and functionality to existing structure.
In short:
create you first route in routes.php like this:
Route::get("GET",function(){
return "my first route";
})
And from that point follow basic MVC flow, which is no different then most frameworks. Laravel is talking to you, just open you ears :)
And if you stack, just ask here, somebody will help.

PHP authentication library, how to build and configure it?

The Title may not be as clear but Il explain what's my problem.
Im building PHP MVC framework for my project. I know there are awsome PHP frameworks, but I like to code and Im doing this to learn more about PHP and MVC and other OOP patterns.
It works great, at least components I built so far.
I use PHP 5.3 and namespaces, so I can require/load classes based on their namespaces/names.
I built SPR-0 class loader class and it enables me to use other libraries that use SPR-0 "standard"/convention like Doctrine or Symfony2 components inside my framework. And all functionality of the framework itself, i call it Core, is writen as a component. So i have \Core\Controller\Controller() class or \Core\Router\Dispatcher() class or \Filesystem\FileManager() class. So I use them where I need them. And Core components enables me to add routes, detect them, call aproppriate controller/action etc... to build an MVC basicly.
And now I need Authentication modul to check if user is loged in on protected pages.
How do I setup that? The bigest problem is how do I tell Authentication Module what tables to use? Where to find usernames and where to find passwords? How do I configure Authentication module, so it knows where to look for username and password?
I could setup users table in database and never change it, and then instruct Authentication where to find stuff he needs. But what if on next project I would like to use different database design, and i would like to use email row instead of username?
Hope you understand whats bothering me...
The short question is how to setup Authentication class/module so you can configure it later to use other rows to fetch data from, and how flexible can that class can be, as far as configuration goes? Should I map some where in configuration that variable username maps to table users row username, so i can change it latter to email? How do you build flexible and configurable Auth library?
The question is long, so thanks for reading...
If I understand you correctly, you want to be able to choose different DB tables for Auth depending upon what project you're working in...
Well why don't you create a config file that gets 'read' by the framework first thing?
That's what other frameworks do I think. You provide host,dbname,user and so on... In your case you'd, in addition to that, write in the config what tables and fields to use for authentication/auhorization?

Categories