How to use the file cache with Laravel Multi tenancy - php

I'm using the following multi tenancy package:
https://laravel-tenancy.com/docs/hyn/5.3
Laravel: 5.7
I current made the caching tenant aware by changing the config on the switched event.
Event::listen(Switched::class, function (Switched $event) {
config(['cache.stores.file.path' => storage_path('framework/cache/' . $event->website->uuid)]);
});
This works well when doing a command like:
php artisan tenancy:run my:caching-command --tenant=2
This does not work well:
php artisan tenancy:run my:caching-command
In this case only a cache dir is created for the first tenant. When debugging it, I found that the config is actually properly updated for each tenant. However the cache driver is not using the new path...
Anyone any ideas?

I needed to rebuild the cache instance with:
app()->forgetInstance('cache');
If lateron in your code the cache instance is accessed via app('cache'), it will be rebuild with your current config.

Related

Getting error for artisan commands ( In routes-v7.php Call to undefined method Closure::__set_state() )

I have upgraded Laravel version from 5.7 to 8.34. I'm getting this error for all artisan commands.
To others: removing the routes-v7 might help, but it's possibly caused due to a return in your routes file (web.php). Remove it and use a controller to return a specific view/back() etc.
Call to undefined method Closure::__set_state()
In my case, I delete the bootstrap/cache/config.php file and run the PHP artisan vendor: publish but the same error occurs in the terminal.
Solution:-
1 Delete the routes-v7.php under the bootstrap folder path(bootstrap/cache/routes-v7.php) .
2 Run the PHP artisan optimize Command. then they recreate the deleted file in the repository.
Laravel 8 && Laravel 9
Please Support !!!!
https://stackoverflow.com/users/16749364/hitesh-sharma
#Tjab answer is the correct one. Just a few more thoughts:
It's because you're using Closures (a.k.a. Lambda functions function () use() {}) in your configuration. I'm pretty sure it's because you're using HTTP redirect routes. DON'T USE THAT FEATURE, since you won't be able to cache your routes, which is actually a good idea because it should increase your application speed. Otherwise your config can't be serialized (what caching actually means) to disk.
Instead create controller and action for each redirect.
Also check your configuration files for Closures and remove them (same for all other PHP frameworks).

Laravel with SQLite doesn't keep Auth data

I have project in Laravel 6 with MySQL database and its working fine. My client wants to use SQLite instead of MySQL database.
So i converted my existing database from database.sql to database.sqlite using following online tool
Online database conversion done here : https://www.rebasedata.com/
https://www.rebasedata.com/convert-mysql-to-sqlite-online
After that i have configured database.sqlite into .env file and into config/database.php file.
Issue : I am not able to go beyond login page. Every time i try to login it redirects me back to login page.
Debug : I reviewed that if I remove Authentication function then i am able to access controller which comes after login.
If I do comment to this line $this->middleware('auth'); following function It starts working.
public function __construct()
{
// $this->middleware('auth');
}
Conclusion : I found that I am not getting any value for $user = Auth::user();
So I think that session is not getting generated and stored correctly with SQLite database
Notes :
I have exported existing database using phpmyadmin and removed all
unnecessary comments from database.sql file.
I converted database.sql file online using this tool
https://www.rebasedata.com/convert-mysql-to-sqlite-online
As per my investigation Auth is not getting generated and stored.
I am using default laravel Auth, I generated that using laravel terminal command.
This setup works fine if I configure project with MySql database.
SQLite database configure Path is correct. I found error of not proper path while configuring it and i solved that.
I have already tested using this commands. : php artisan cache:clear --- php artisan route:cache --- php artisan config:cache --- php artisan view:clear
Any help are appreciated. Thanks in advance.

Clarity on the use of pragmarx/firewall package for Laravel 5.2

so I've just completed the install of antonioribeiro/firewall package for laravel, which essentially allows blacklisting and whitelist of IP address and countries.
I'm working through the section on Artisan Commands, but when i try to run 'php artisan firewall:whitelist country:za' I get the following error:
[Symfony\Component\Console\Exception\CommandNotFoundException]
Command "firewall:whitelist" is not defined.
Did you mean one of these?
firewall:list
firewall:tables
I have done all the necessary installation steps outlined in the documentation.
What am i doing wrong ? should I be using this command elsewhere ?
I am aware that these can be manually entered into the DB, but this functionality would be great to have.
I managed to fix the problem:
SOLUTION: When you run 'php artisan vendor:publish' it creates a new file called 'firewall.php' in the config directory. This is where you set default options. Simply change 'use_database' to true and the Database specific commands will work.
firewall:blacklist
firewall:clear
firewall:remove
firewall:whitelist

You have requested a non-existent service "phpexcel"

I know there are some questions almost identical but none of them seems to be my case.
I have a symfony 2.8.3 project that reads and imports data from an excel file into mysql database. Its all working nice on localhost but in the last 48 hours I've been trying to get it working on my server. Its a shared hosting, with no SSH access to the linux.
When I am trying to load it from the server I get this error: "You have requested a non-existent service "phpexcel"."
Looks like you want to use service from ExcelBundle. But that bundle is not loaded. Check if you have it added for production env.
$bundles = array(
// ...
new Liuggio\ExcelBundle\LiuggioExcelBundle(),
);
Don't forget to clear cache on production environment after any config (AppKernel.php also) change.
To clear cache run php app/console cache:clear. You can also add env parameter: --env=dev or --env=prod - depending on your env. If it don't help then just remove all content of app/cache/ directory (or var/cache/ in case of Symfony3 app)
Pawel answered correctly, but something is missing: after you add this line: new Liuggio\ExcelBundle\LiuggioExcelBundle(), to the AppKernel.php file, inside the $bundles array, don't forget to clear the cache: delete the file from app/cache/dev in case you're in developer mode or app/cache/prod in case on production mode.

Creating a new ServiceProvider / Facade as a package in Laravel 5

Introduction
I've never worked with a framework before (Zend, CakePHP, etc) and finally decided to sit down and learn one. I'm starting with Laravel because the code looks pretty and unlike some other frameworks I tried to install, the "Hello, World!" example worked on the first try.
The Goal
For the time being, I want my app to do something very simple:
User submits a request in the form of: GET /dist/lat,lng
The app uses the remote IP address and MaxMind to determine $latitude1 and $longitude1
This request path is parsed for $latitude2 and $longitude2
Using these two positions, we calculate the distance between them. To do this I'm using Rafael Fragoso's WorldDistance PHP class
Since I plan to re-use this function in later projects, it didn't seem right to throw all of the code into the /app directory. The two reusable parts of the application were:
A service provider that connects to MaxMind and returns a latitude and longitude
A service provider that takes two points on a globe and returns the distance
If I build facades correctly then instead of my routes.php file being a mess of closures within closures, I can simply write:
Route::get('dist/{input}', function($input){
$input = explode( "," , $input );
return Distance::getDistance( GeoIP::getLocation(), $input );
});
What I've tried
Initial Attempt
For the first service provider, I found Daniel Stainback's Laravel 5 GeoIP service provider. It didn't install as easily as it should have (I had to manually copy geoip.php to the /config directory, update /config/app.php by hand, and run composer update and php artisan optimize) however it worked: A request to GET /test returned all of my information.
For the second service provider, I started by trying to mimic the directory structure and file naming convention of the GeoIP service provider. I figured that if I had the same naming convention, the autoloader would be able to locate my class. So I created /vendor/stevendesu/worlddistance/src/Stevendesu/WorldDistance\WorldDistanceServiceProvider.php:
<?php namespace Stevendesu\WorldDistance;
use Illuminate\Support\ServiceProvider;
class WorldDistanceServiceProvider extends ServiceProvider {
protected $defer = false;
public function register()
{
// Register providers.
$this->app['distance'] = $this->app->share(function($app)
{
return new WorldDistance();
});
}
public function provides()
{
return ['distance'];
}
}
I then added this to my /config/app.php:
'Stevendesu\WorldDistance\WorldDistanceServiceProvider',
This fails with a fatal error:
FatalErrorException in ProviderRepository.php line 150:
Class 'Stevendesu\WorldDistance\WorldDistanceServiceProvider' not found
Using WorkBench
Since this utterly failed I figured that there must be some other file dependency: maybe without composer.json or without a README it gives up. I don't know. So I started to look into package creation. Several Google searches for "create package laravel 5" proved fruitless. Either:
They were using Laravel 4.2, in which case the advice was "run php artisan workbench vendor/package --resources"
Or
They were using Laravel 5, in which case the docs were completely useless
The official Laravel 5 docs give you plenty of sample code, saying things like:
All you need to do is tell Laravel where the views for a given namespace are located. For example, if your package is named "courier", you might add the following to your service provider's boot method:
public function boot()
{
$this->loadViewsFrom(__DIR__.'/path/to/views', 'courier');
}
This makes the assumption that you have a service provider to put a boot method in
Nothing in the docs says how to create a service provider in such a way that it will actually be loaded by Laravel.
I also found several different resources all of which assume you have a repository and you just want to include it in your app, or assume you have "workbench". Nothing about creating a new package entirely from scratch.
PHP Artisan did not even have a "workbench" command, and there was no "workbench.php" file in /config, so anything I found related to workbench was worthless. I started doing some research on Workbench and found several different questions on StackOverflow.
After a long time and some experimentation, I managed to get laravel/workbench into my composer.json, composer update, composer install, manually build a workbench.php config file, and finally use the PHP Artisan Workbench command to make a new package:
php artisan workbench Stevendesu/WorldDistance --resources
This created a directory: /workbench/stevendesu/world-distance with a number of sub-directories and only one file: /workbench/stevendesu/world-distance/src/Stevendesu/WorldDistance/WorldDistanceServiceProvider.php
This service provider class looked essentially identical to the file I created before, except that it was in the /workbench directory instead of the /vendor directory. I tried reloading the page and I still got the fatal error:
FatalErrorException in ProviderRepository.php line 150:
Class 'Stevendesu\WorldDistance\WorldDistanceServiceProvider' not found
I also tried php artisan vendor:publish. I don't really know what this command does and the description wasn't helpful, so maybe it would help? It didn't.
Question
How do I create a new service provider as a package so that in future projects I can simply include this package and have all the same functionality? Or rather, what did I do wrong so that the package I created isn't working?
After two days of playing with this I managed to find the solution. I had assumed that the directory structure mapped directly to the autoloader's path that it checked (e.g. attempting to access a class Stevendesu\WorldDistance\WorldDistanceServiceProvider would look in vendor/stevendesu/world-distance/WorldDistanceServiceProvider)... This isn't the case.
Reading through the composer source code to see how it actually loads the files, it builds a "classmap" - essentially a gigantic array mapping classes to their respective files. This file is built when you run composer update or composer install - and it will only be built correctly if composer knows the details of your package. That is - if your package is included in your project's composer.json file
I created a local git repository outside of my app then added my package to my app's composer.json file then ran composer update -- suddenly everything worked perfectly.
As for the:
It didn't install as easily as it should have
the secret sauce here was first add the service provider to /config/app.php then, second run php artisan vendor:publish

Categories