Laravel 8 - Disable migrations for specific package - laravel

Scenario is the following:
I'm building a software where the frontend and the programm that does the work are separated from each other. To have the frontend be able to use the models of the worker-programm, I've build a package that holds them. The package has the following code to it's provider:
public function boot()
{
if($this->app->runningInConsole()){
$this->loadMigrationsFrom(__DIR__ . '/MyPackageMigrations');
}
}
Now my problem is that I want those migrations to be run when the artisan migrate command is run in the worker-programm, but not in the UI-programm, since both databases are separated from each other aswell. Is there a way to supress those migrations in the UI-programm?
Greetings

Rather than using loadMigrationsFrom() in the boot() method of your ServiceProvider, you can use $this->puiblishes() which gives you control over publishing migrations rather than having them load automatically.
public function boot()
{
if ($this->app->runningInConsole()) {
$this->publishes([
__DIR__ . '/../database/migrations/create_models_table.php.stub'
=> database_path('migrations/' . date('Y_m_d_His', time()) . 'create_models_table.php'),
// you can add any number of migrations here
], 'migrations');
}
}
Then all you need to do is publish the migrations in the projects you want to use the migrations in:
php artisan vendor:publish --provider="Husky110\Husky110Package\Husky110PackageServiceProvider" --tag="migrations"
Update
You can check for the existence of migration by doing something like:
if (!class_exists('CreateModelsTable')) {
// perform migration
}
If you have migrations which alter the structure of a table, you might do:
if (!class_exists('AlterModelsTableAddField')) {
// perform migration
}

Related

Can we exclude a custom service provider when running php artisan migrate in laravel?

I have a custom service provider in which I am accessing a model in boot(). But when I run php artisan migrate, it shows the below error:
[Illuminate\Database\QueryException] SQLSTATE[42S02]: Base table or view not found: 1146 Table '********' doesn't exist
I found that if we add if (!app()->runningInConsole()) { inside boot(), it works successfully.
This is the code we have used in the service provider:
public function boot()
{
$this->bindCurrentPartToNav();
}
private function bindCurrentPartToNav(): void
{
$currentPartName = \App\Http\Helpers\Part::getPartName();
view()->composer(
'includes.partials.part',
function ($view) use ($currentPartName) {
$view->with('currentPartName', $currentPartName);
}
);
}
Helper file:
public static function getPartName(): ?string
{
return PartModel::PartKey()->active()->pluck('name')->first();
}
Model:
public function scopePartKey($query): Builder
{
return $query->where('identifier', config('env.PART_KEY'));
}
Is there any way to remove that service provider from php artisan migrate so that we can remove runningInConsole() check in each refresh?
Thanks for your help in advance.
As any environment configuration, in your case a general configuration, you should assign a default value fall back.
public static function getSectionName(): ?string
{
try {
return SectionModel::sectionKey()->active()->pluck('name')->first();
} catch (\Exception $e) {
return null;
}
}
This will simulate the case where the section model with that specific identification_key is missing in the database.
This will also prevent any issues with the initial migration.
But in the end, you tied a model with a view rendering code. You should find another solution to dissociate them. For example, you can move the boot() code out of the model and link it to a middleware.
You can also use Singleton pattern (since it's like a general unique config across the application)

JWTGenerateCommand::handle() does not exist

I am using Laravel 5.4 and JWT Auth Library for user authentication in API development. After installation while i am running php artisan jwt:generate then it throws me error of
Method Tymon\JWTAuth\Commands\JWTGenerateCommand::handle() does not exist
Any idea what i am missing ?
This error generally display when you install jwt package in laravel 5.5 version. then after you set service providers and run following command.
php artisan jwt:generate
then you seen this error message in terminal.
how to resolve it? simple follow this step
Step - 1 Re-install package
composer require tymon/jwt-auth:dev-develop --prefer-source
or the following is a new release package use laravel 6.X
composer require tymon/jwt-auth:1.0.*
in this developement version this errors fixed.
Step - 2 Set Service Provider
'providers' => [
....
Tymon\JWTAuth\Providers\JWTAuthServiceProvider::class to
Tymon\JWTAuth\Providers\LaravelServiceProvider::class
],
Step - 3 Generate key
php artisan jwt:secret
i found this solution from here https://laravelcode.com/post/method-tymonjwtauthcommandsjwtgeneratecommandhandle-does-not-exist
Go to JWTGenerateCommand.php file located in vendor/tymon/src/Commands and paste this method
public function handle() { $this->fire(); }
It's never a great idea to change anything in the vendor folder but the there's two ways to deal with this ...
Generate a random string yourself and just change the value in the JWT config file.
Go to Tymon\JWTAuth\Commands\JWTGenerateCommand and change the fire method to handle.
go to given file path
vendor/tymon/jwt-auth/src/Commands/JWTGenerateCommand.php
change function name
public function fire() to public function handle()
run command:
php artisan jwt:generate
I'm publishing this answer because I have crash in this error more than one time.
The only solution I found that it works with Laravel 5.6 is the following:
Add "tymon/jwt-auth": "1.0.0-rc.1" to composer.json and run composer update
Open config/app.php and add the following:
config/app.php:
'providers' => [
/*
* JWT Service Provider...
*/
Tymon\JWTAuth\Providers\LaravelServiceProvider::class,
],
'aliases' => [
'JWTAuth' => Tymon\JWTAuth\Facades\JWTAuth::class,
'JWTFactory' => Tymon\JWTAuth\Facades\JWTFactory::class,
],
Execute:
php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"
Finally, execute: php artisan jwt:secret
After all that, when I hit my endpoint for login I got the following exception:
Class Tymon\JWTAuth\Providers\JWT\NamshiAdapter does not exist
This was fixed by:
Open config/jwt.php and change the following:
config/jwt.php:
'jwt' => Tymon\JWTAuth\Providers\JWT\Namshi::class,
'auth' => Tymon\JWTAuth\Providers\Auth\Illuminate::class,
'storage' => Tymon\JWTAuth\Providers\Storage\Illuminate::class,
Finally, note that in order to work your User model should be defined as follows:
class User extends Authenticatable implements JWTSubject
{
...
public function getJWTIdentifier()
{
return $this->getKey();
}
public function getJWTCustomClaims()
{
return [];
}
...
}
I can advise one solution. Go to JWTGenerateCommand.php file located in vendor/tymon/src/Commands and paste this part of code public function handle() { $this->fire(); }
I know this is not an elegant solution, but it works. I hope this might help until official fix arrive.
see here for more info
Change fire() function to handle() in this path
vendor/tymon/jwt-auth/src/commands/JWTGenerateCommand.php
In the file path: /vendor/tymon/jwt-auth/src/Commands/JWTGenerateCommand.php
Add public function
public function handle()
{
$this->fire();
}

Check Directory folders in Laravel

I know create: makeDirectory(). Also, I know delete, copy, move (deleteDirectory, copyDirectory, moveDirectory). But, how can I verify if the folder exists with laravel. that´s my function
public function storeFile(Request $request)
{
$request->all();
$folders = $request->file01;
if($request->hasFile('file01'))
{
$request->file01->store('public/'.$folders);
return "Saved!";
}
}
You can use several methods.
With Laravel you can simply use File::isDirectory($dir). Laravel API
With PHP you can also just is is_dir, PHP Docs
you can use a php function: is_dir
is_dir($path)

how to create global function that can be accessed from any controller and blade file

I have two controller file homecontroller and backendcontroller. What is the best way to create global function and access it from both files?
I found here Arian Acosta's answer helpful but I wonder if there is an easiest way. I would appreciate any suggestions.
Solution
One way to do this is to create a class and use its instance, this way you can not only access the object of the class within a controller, blade, or any other class as well.
AppHelper file
In you app folder create a folder named Helpers and within it create a file name AppHelper or any of your choice
<?php
namespace App\Helpers;
class AppHelper
{
public function bladeHelper($someValue)
{
return "increment $someValue";
}
public function startQueryLog()
{
\DB::enableQueryLog();
}
public function showQueries()
{
dd(\DB::getQueryLog());
}
public static function instance()
{
return new AppHelper();
}
}
Usage
In a controller
When in a controller you can call the various functions
public function index()
{
//some code
//need to debug query
\App\Helpers\AppHelper::instance()->startQueryLog();
//some code that executes queries
\App\Helpers\AppHelper::instance()->showQueries();
}
In a blade file
Say you were in a blade file, here is how you can call the app blade helper function
some html code
{{ \App\Helpers\AppHelper::instance()->bladeHelper($value) }}
and then some html code
Reduce the overhead of namespace (Optional)
You can also reduce the overhead of call the complete function namespace \App\Helpers by creating alias for the AppHelper class in config\app.php
'aliases' => [
....
'AppHelper' => App\Helpers\AppHelper::class
]
and in your controller or your blade file, you can directly call
\AppHelper::instance()->functioName();
Easy Solution:
Create a new Helpers folder in your app directory.
Create a php file named your_helper_function.php in that Helpers directory.
Add your function(s) inside your_helper_function.php
function your_function($parameters){
//function logic
}
function your_another_function($parameters){
//function logic
}
Add this file to the Files key of your composer.json like
"autoload": {
...
"files": [
"app/Helpers/your_helper_function.php"
]
...
}
Finally, regenerate composer autoload files. (Run this in your project directory)
composer dump-autoload
That's it! and now you can access your_function() or your_another_function() in any part of your Laravel project.
If you still have any confusion, check my blog post on how to do this:
How to Add a Global Function in Laravel Using Composer?
Updated:
Step 1
Add folder inside app folder
app->Helper
Step 2
add php Class inside Helper folder
Eg. Helper.php
Add namespace and class to the Helper.php
namespace App\Helper;
class Helper
{
}
Register this Helper.php into config/app.php file
'aliases' => [
....
'Helper' => App\Helper\Helper::class
]
Now, write all the functions inside Helper.php and it will be accessible everywhere.
How to access from Controller?
Step 1 - Add a namespace at top of the controller.
use App\Helper\Helper;
Step 2 - Call function - Assume there a getInformation() inside the Helper Class.
$information = Helper::getInformation()
In your Controller.php which extends BaseController, you can create a function like;
public function data($arr = false)
{
$data['foo'] = 'bar';
return array_merge($data,$arr);
}
And from any controller when you send a data to a view;
public function example()
{
$data['smthg'] = 'smthgelse';
return view('myView',$this->data($data));
}
The data in the the main controller can be accessed from all controllers and blades.
The Laravel Service Provider way
I've been using global function within Laravel for a while and I want to share how I do it. It's kind of a mix between 2 answers in this post : https://stackoverflow.com/a/44021966/5543999 and https://stackoverflow.com/a/44024328/5543999
This way will load a file within a ServiceProvider and register it within your Laravel app.
Where is the difference, the scope, it's always about the scope.
Composer //Autload whitin composer.json method
|
|--->Laravel App //My method
|
|--->Controller //Trait method
|--->Blade //Trait method
|--->Listener //Trait method
|--->...
This is a really simplist way to explain my point, all three methods will achieve the purpose of the "Global function". The Traits method will need you to declare use App\Helpers\Trait; or App\Helpers\Trait::function().
The composer and service provider are almost about the same. For me, they answer better to the question of what is a global function, because they don't require to declare them on each place you want to use them. You just use them function(). The main difference is how you prefer things.
How to
Create the functions file : App\Functions\GlobalFunctions.php
//App\Functions\GlobalFunctions.php
<?php
function first_function()
{
//function logic
}
function second_function()
{
//function logic
}
Create a ServiceProvider:
//Into the console
php artisan make:provider GlobalFunctionsServiceProvider
Open the new file App\Providers\GlobalFunctionsServiceProvider.php and edit the register method
//App\Providers\GlobalFunctionsServiceProvider.php
public function register()
{
require_once base_path().'/app/Functions/GlobalFunctions.php';
}
Register your provider into App\Config\App.php wihtin the providers
//App\Config\App.php
'providers' => [
/*
* Laravel Framework Service Providers...
*/
Illuminate\Auth\AuthServiceProvider::class,
...
Illuminate\Validation\ValidationServiceProvider::class,
Illuminate\View\ViewServiceProvider::class,
App\Providers\GlobalFunctionsServiceProvider::class, //Add your service provider
Run some artisan's commands
//Into the console
php artisan clear-compiled
php artisan config:cache
Use your new global functions
//Use your function anywhere within your Laravel app
first_function();
second_function();
Laravel uses namespaces by default. So you need to follow the method described in that answer to setup a helper file.
Though in your case you want to access a method in different controllers. For this there's a simpler way. Add a method to you base controller app/Http/Controllers/Controller.php and you can access them in every other controller since they extend it.
// in app/Http/Controllers/Controller.php
protected function dummy()
{
return 'dummy';
}
// in homecontroller
$this->dummy();
There are a few ways, depending on the exact functionality you're trying to add.
1) Create a function inside Controller.php, and make all other controller extend that controller. You could somewhat compair this to the master.blade.php
2) Create a trait, a trait can do a lot for you, and keeping ur controllers clean. I personally love to use traits as it will look clean, keep my Controller.php from being a mess with tons of different lines of code.
Creating a global function
create a Helpers.php file under a folder, let's name it 'core'.
core
|
-- Helpers.php
namespace Helpers; // define Helper scope
if(!function_exists('html')) {
function html($string) {
// run some code
return $str;
}
}
In your composer.json
"autoload": {
"psr-4": {
},
"files": [
"core/Helpers.php"
]
}
in the file that you want to use it
// the " use " statement is not needed, core/Helpers is loaded on every page
if(condition_is_true) {
echo Helpers\html($string);die();
}
Remove the namespace in Helpers.php if you want to call your function without the need to prefix namespace. However I advise to leave it there.
Credit: https://dev.to/kingsconsult/how-to-create-laravel-8-helpers-function-global-function-d8n
By using composer.json and put the function containing file(globalhelper.php) to the autoload > files section, then run
composer dump-autoload
You can access the function inside the file(globalhelper.php) without having to calling the class name, just like using default php function.

How to rewrite field in Laravel?

I tried to rewrite a primary key in laravel like as:
public function setIdAttribute($value)
{
$this->attributes['id'] = $value; // or instead $value $this->attributes['idCity']
}
So I need to replace value of id field on value of idCity field
Rename a columns you should create a new migration
To create migration for this change write on console
php artisan make:migration swapKeyId
then go to database->migrations->...swapkey....php
in method called function up() write the code below but replace your table name in my case i use users
Schema::table('users', function ($table) {
$table->renameColumn('id', 'userId');
});
now its time to push migrates to database
php artisan migrate
and its done. this method is renamin it via laravel, also you can change it directly to the database(MySQL,MariaDB,SQL Server etc)
Setting an attribute in your model to define how php should store a value is something entirely different from creating a primary key in MySQL. Setup your migrations following the documentation and there isn't a lot that can go wrong:
Migrations in Laravel 5.2

Resources