Laravel Artisan event:generate command throwing a Fatal error - php

I'm following the official documentation for Laravel 5.7 on the events registration and generation: https://laravel.com/docs/5.7/events#generating-events-and-listeners
I have an EventServiceProvider with the following events defined:
<?php
namespace App\Providers;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
class EventServiceProvider extends ServiceProvider
{
/**
* The event handler mappings for the application.
*
* #var array
*/
protected $listen = [
'App\Events\FormBeforeCreate' => [
'App\Listeners\WebhookBeforeCreate',
],
'App\Events\FormAfterCreate' => [
'App\Listeners\NotifyAfterCreate',
'App\Listeners\WebhookAfterCreate',
],
'App\Events\FormBeforeUpdate' => [
'App\Listeners\WebhookBeforeUpdate',
],
'App\Events\FormAfterUpdate' => [
'App\Listeners\NotifyAfterUpdate',
'App\Listeners\WebhookAfterUpdate',
],
'App\Events\FormBeforeDelete' => [
'App\Listeners\WebhookBeforeDelete',
],
'App\Events\FormAfterDelete' => [
'App\Listeners\NotifyAfterDelete',
'App\Listeners\WebhookAfterDelete',
],
'App\Events\FormBeforeSave' => [
'App\Listeners\WebhookBeforeSave',
],
'App\Events\FormAfterSave' => [
'App\Listeners\NotifyAfterSave',
'App\Listeners\WebhookAfterSave',
],
];
/**
* The subscriber classes to register.
*
* #var array
*/
protected $subscribe = [
'App\Listeners\UserEventSubscriber',
];
/**
* Register any other events for your application.
*
* #return void
*/
public function boot()
{
parent::boot();
}
}
The error:
When I run the command php artisan event:generate I get the following error:
PHP Fatal error: Call to a member function listens() on null in /app/vendor/laravel/framework/src/Illuminate/Foundation/Console/EventGenerateCommand.php on line 35
[Symfony\Component\Debug\Exception\FatalErrorException]
Call to a member function listens() on null
According to the doc, it should do this:
This command will generate any events or listeners that are listed in
your EventServiceProvider. Events and listeners that already exist
will be left untouched
I don't understant what I've missed since I didn't find any similar error by searching the web

This is the line that is returning null:
$providers = $this->laravel->getProviders(EventServiceProvider::class);
therefore, there are some problems with your EventServiceProvider... please, try using this:
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Event;
use Illuminate\Auth\Events\Registered;
use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
class EventServiceProvider extends ServiceProvider
{
/**
* The event listener mappings for the application.
*
* #var array
*/
protected $listen = [
'App\Events\FormBeforeCreate' => [
'App\Listeners\WebhookBeforeCreate',
],
'App\Events\FormAfterCreate' => [
'App\Listeners\NotifyAfterCreate',
'App\Listeners\WebhookAfterCreate',
],
'App\Events\FormBeforeUpdate' => [
'App\Listeners\WebhookBeforeUpdate',
],
'App\Events\FormAfterUpdate' => [
'App\Listeners\NotifyAfterUpdate',
'App\Listeners\WebhookAfterUpdate',
],
'App\Events\FormBeforeDelete' => [
'App\Listeners\WebhookBeforeDelete',
],
'App\Events\FormAfterDelete' => [
'App\Listeners\NotifyAfterDelete',
'App\Listeners\WebhookAfterDelete',
],
'App\Events\FormBeforeSave' => [
'App\Listeners\WebhookBeforeSave',
],
'App\Events\FormAfterSave' => [
'App\Listeners\NotifyAfterSave',
'App\Listeners\WebhookAfterSave',
],
];
/**
* Register any events for your application.
*
* #return void
*/
public function boot()
{
parent::boot();
//
}
}

My bad, it seems like I was really tired yesterday night, Our project runs on Docker, I was running the command outside of the docker instead of inside.
I have no idea why it showed this bug in particular but once I ran the command in the docker all files generated correctly.

Related

Jwt token unable to generate

I am trying to generate a JWT Token in laravel. I am using Tymon. I am working in laravel 5.8 and I need to copy most of the stuff from 5.4 version.
This is what so far I have tried.
Controller
$payload = (object)array("userid" => $user->userid);
$extra = [
"userid" => $user->userid,
"username" => $user->username,
"useremail" => $user->useremail
];
$return = JWTAuth::fromUser($payload, $extra);
User.php
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Tymon\JWTAuth\Contracts\JWTSubject;
class User extends Authenticatable implements JWTSubject
{
use Notifiable;
protected $fillable = [
'name', 'email', 'password',
];
protected $hidden = [
'password', 'remember_token',
];
protected $casts = [
'email_verified_at' => 'datetime',
];
public function getJWTIdentifier()
{
return $this->getKey();
}
public function getJWTCustomClaims()
{
return [];
}
}
I am trying this using postman where I am getting this error:
Symfony \ Component \ Debug \ Exception \ FatalThrowableError (E_RECOVERABLE_ERROR)
Argument 1 passed to Tymon\JWTAuth\JWT::fromUser() must be an instance of Tymon\JWTAuth\Contracts\JWTSubject, instance of stdClass given, called in
To Use JWT Auth in Laravel you must follow these steps -
Install in Composer.json via:
composer require tymon/jwt-auth
Add the service provider to the providers array in the config/app.php config
file as follows:
'providers' => [
...
Tymon\JWTAuth\Providers\LaravelServiceProvider::class,
]
Run the following command to publish the package config file:
php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"
You should now have a config/jwt.php file that allows you to configure the basics of this package.
Generate the secret Key via this command:
php artisan jwt:secret
this should update your .env file with something like:
JWT_SECRET=foobar
Then Update the User model as:
<?php
namespace App;
use Tymon\JWTAuth\Contracts\JWTSubject;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable implements JWTSubject
{
use Notifiable;
// Rest omitted for brevity
/**
* Get the identifier that will be stored in the subject claim of the JWT.
*
* #return mixed
*/
public function getJWTIdentifier()
{
return $this->getKey();
}
/**
* Return a key value array, containing any custom claims to be added to the JWT.
*
* #return array
*/
public function getJWTCustomClaims()
{
return [];
}
}
finally, configure the Auth guard in config/auth.php as:
'defaults' => [
'guard' => 'api',
'passwords' => 'users',
],
...
'guards' => [
'api' => [
'driver' => 'jwt',
'provider' => 'users',
],
],
Then You are ready to go..
As the error message says, you are passing a stdClass instance where JWTSubject instance is expected as the first parameter of the JWTAuth::fromUser method.
Have a look at this issue: github issue
The developers suggest to either pass User model or implementation of Tymon\JWTAuth\Contracts\JWTSubject interface

Naming Strategy for table and column names (Doctrine ORM)

Is it possible to have a naming strategy take care of mapping table and column names in Doctrine ORM?
Right now all names are specified via annotation in the entity classes, e.g.
<?php
namespace App\Entity;
use DateTimeInterface;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity()
* #ORM\Table(name="role")
*/
class Role
{
/**
* #ORM\Id()
* #ORM\Column(name="id", type="guid")
* #ORM\GeneratedValue(strategy="NONE")
* #var string
*/
private $id;
/**
* #ORM\Column(name="created_at", type="datetime")
* #var \DateTimeImmutable
*/
private $createdAt;
/**
* #ORM\Column(name="created_by", type="string")
* #var string
*/
private $createdBy;
// [..]
}
Table and column names are all snake_case while class and property names are all camelCase.
I've tried to remove table and column name declarations in the entity classes and provided a naming strategy` via configuration, trying to set it in the following two ways.
<?php
use Doctrine\ORM\Mapping\UnderscoreNamingStrategy;
return [
'doctrine' => [
'connection' => [
// [..]
],
'driver' => [
// [..]
],
'annotation' => [
// [..]
],
'entity_managers' => [
'default' => [
'naming_strategy' => UnderscoreNamingStrategy::class,
],
],
'orm' => [
'naming_strategy' => UnderscoreNamingStrategy::class,
],
],
];
When trying to retrieve an entity, an error is thrown.
Doctrine\DBAL\Exception\InvalidFieldNameException: An exception occurred while executing 'SELECT t0.id AS id_1, t0.createdAt AS createdAt_2, t0.createdBy AS createdBy_3, t0.updatedAt AS updatedAt_4, t0.updatedBy AS updatedBy_5, t0.name AS name_6, t0.desc AS desc_7, t0.isCore AS isCore_8 FROM Role t0':
SQLSTATE[42S22]: Column not found: 1054 Unknown column 't0.createdAt' in 'field list' in file C:\project\path\vendor\doctrine\dbal\lib\Doctrine\DBAL\Driver\AbstractMySQLDriver.php on line 60
After a bit of studying and experimenting, I got the following solution to work in a Zend Expressive application.
Configure naming strategy in doctrine.local.php
<?php
declare(strict_types = 1);
use Doctrine\ORM\Mapping\UnderscoreNamingStrategy;
return [
'doctrine' => [
'connection' => [
// [..]
],
'driver' => [
// [..]
],
'annotation' => [
// [..]
],
'configuration' => [
'orm_default' => [
'naming_strategy' => UnderscoreNamingStrategy::class,
],
],
],
];
Implement a factory for the naming strategy
<?php
namespace App;
use Interop\Container\ContainerInterface;
use Zend\ServiceManager\Factory\FactoryInterface;
class NamingStrategyFactory implements FactoryInterface
{
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
return new $requestedName();
}
}
Register factory in ConfigProvider.php
<?php
declare(strict_types = 1);
namespace App;
use Doctrine\ORM\Mapping\UnderscoreNamingStrategy;
class ConfigProvider
{
public function __invoke()
{
return [
'dependencies' => $this->getDependencies(),
];
}
public function getDependencies(): array
{
return [
'invokables' => [
],
'factories' => [
// [..]
UnderscoreNamingStrategy::class => NamingStrategyFactory::class,
],
];
}
}

The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed

I am developing an auth api with laravel, passport and postman. I have seen related post but none of them solved my problem. If I try to send a request it shows me this error. I have tried all I can but it just displays this error
{
"error": "invalid_request",
"message": "The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed.",
"hint": "Check the `username` parameter"
}
my value for the application is
{
"grant_type" : "password",
"client_id" : "2",
"client_secret" : "fsDFrzGtmpMjoxWtplnvcmgKT3USzKFfKQu6alGF",
"email":"john#gmail.com",
"pssword" : "12345",
"scope" : "*"
}
api.php
<?php
use Illuminate\Http\Request;
Route::middleware('auth:api')->get('/user', function (Request $request) {
return $request->user();
});
Route::post('signup', 'SignUp#signUp');
auth.php
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'passport',
'provider' => 'users',
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
User.php
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password','vCode',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
AuthServiceProvider.php
namespace App\Providers;
use Laravel\Passport\Passport;
use Illuminate\Support\Facades\Gate;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
class AuthServiceProvider extends ServiceProvider
{
/**
* The policy mappings for the application.
*
* #var array
*/
protected $policies = [
'App\Model' => 'App\Policies\ModelPolicy',
];
/**
* Register any authentication / authorization services.
*
* #return void
*/
public function boot()
{
$this->registerPolicies();
//
Passport::routes();
}
}
Please any solution will be really appreciated
you required 'username' field and passing value in postman parameter
After all your code is absolutly right.nothing error.
You need to add refresh_token parameter
{
"grant_type" : "password",
"refresh_token" : 'your_refresh_token',
"client_id" : "2",
"client_secret" : "fsDFrzGtmpMjoxWtplnvcmgKT3USzKFfKQu6alGF",
"email":"john#gmail.com",
"pssword" : "12345",
"scope" : "*"
}
See the documentation for more information : https://laravel.com/docs/5.8/passport#refreshing-tokens

How to create a different log folder for different modules in a Yii2

In my yii2 application there is two modules in the backend, I have to create different folders/file name for each modules like as follows
#app/runtime/logs/{my_module_name}/app.log
or
#app/runtime/logs/{my_module_name}.log
How can I achieve that ?
For this purpose you can override yii\log\FileTarget.
Our custom Logger:
use yii\log\FileTarget;
/**
* Class CustomLogger
* #package common\components
*/
class CustomLogger extends FileTarget
{
/**
* #param $logFile
* #return $this
*/
public function setLogFile($logFile)
{
$this->logFile = $logFile;
return $this;
}
}
Register the Logger in common/config/main.php:
return [
'log' => [
'traceLevel' => YII_DEBUG ? 3 : 0,
'targets' => [
[
'class' => 'common\components\CustomLogger',
'levels' => ['error','warning']
]
]
]
];
Usage:
$logger = Yii::getLogger();
$logger->setLogFile('path/to/log/file.log')->log('some message', Logger::LEVEL_ERROR)
Also you can check if $logFile is not exist you can create it inside setLogFile method.

Laravel Socialite and Office365: InvalidArgumentException in Manager.php line 90: Driver [microsoft] not supported

So I definitely can't wrap my head around this one. I'm following a Laravel 5.2 tutorial here.
http://blog.damirmiladinov.com/laravel/laravel-5.2-socialite-facebook-login.html#.V2gUIrgrJPY
And getting the error listed above in the title. My routes look like this:
Route::get('/', function () {
if(Auth::check()) return view('auth/register');
return view('auth/login');
});
Route::get('/redirect', 'MailAuthController#redirect');
Route::get('/callback', 'MailAuthController#callback');
Controller looks like this:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use Socialite;
class MailAuthController extends Controller
{
//
public function redirect()
{
return \Socialite::with('microsoft')->redirect();
}
public function callback()
{
// when microsoft calls with token
}
public function user()
{
}
}
And services.php looks like this:
<?php
return [
/*
|--------------------------------------------------------------------------
| Third Party Services
|--------------------------------------------------------------------------
|
| This file is for storing the credentials for third party services such
| as Stripe, Mailgun, Mandrill, and others. This file provides a sane
| default location for this type of information, allowing packages
| to have a conventional place to find your various credentials.
|
*/
'mailgun' => [
'domain' => env('MAILGUN_DOMAIN'),
'secret' => env('MAILGUN_SECRET'),
],
'mandrill' => [
'secret' => env('MANDRILL_SECRET'),
],
'ses' => [
'key' => env('SES_KEY'),
'secret' => env('SES_SECRET'),
'region' => 'us-east-1',
],
'sparkpost' => [
'secret' => env('SPARKPOST_SECRET'),
],
'stripe' => [
'model' => App\User::class,
'key' => env('STRIPE_KEY'),
'secret' => env('STRIPE_SECRET'),
],
'microsoft' => [
'client_id' => env('MICROSOFT_CLIENT_ID'),
'client_secret' => env('MICROSOFT_CLIENT_SECRET'),
'redirect' => env('http://localhost:8000/callback'),
],
];
And other than that I have no idea where I might be going wrong. Light my way!
I would recommend using the Microsoft Graph provider from the Socialite Providers package.
Pull in the Microsoft-Graph provider via your composer.json file:
"require": {
...
"laravel/socialite": "^2.0",
"socialiteproviders/microsoft-graph": "dev-master"
},
Run composer update.
Next, add the connection credentials to config/services.php:
...
'graph' => [
'client_id' => 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
'client_secret' => 'xxxxxxxxxxxxxxxxxxxxxxx',
'redirect' => 'https://my-app.dev',
],
*Note: if committing config/services.php to a public repo, extract these values to your .env file and reference them via the env helper method;
In config/app.php add the SocialiteProviders/Generators service provider to the providers array:
'providers' => [
...
/*
* Package Service Providers...
*/
Laravel\Socialite\SocialiteServiceProvider::class,
// This is a dependency of the socialiteproviders/microsoft-graph provider, and will be installed with the provider via it's composer.json file
SocialiteProviders\Manager\ServiceProvider::class,
Register the Socialize facade (also in config/app.php):
'aliases' => [
...
'Socialize' => 'Laravel\Socialite\Facades\Socialite',
],
Register an event listener in app/Providers/EventServiceProvider.php:
protected $listen = [
...
'SocialiteProviders\Manager\SocialiteWasCalled' => [
'SocialiteProviders\Graph\GraphExtendSocialite#handle'
],
];
Create your controller to handle the requests:
<?php
namespace App\Http\Controllers\Auth;
use Illuminate\Http\Request;
use Socialize;
class AuthController extends \App\Http\Controllers\Controller
{
/**
* Redirect the user to the Graph authentication page.
*
* #return Response
*/
public function redirectToProvider()
{
return Socialize::with('graph')->redirect();
}
/**
* Obtain the user information from graph.
*
* #return Response
*/
public function handleProviderCallback(Request $request)
{
$user = Socialize::with('graph')->user();
// $user->token;
}
}
Finally add your routes in routes/web.php:
<?php
Route::get('auth/graph', 'Auth\AuthController#redirectToProvider');
Route::get('auth/graph/callback','Auth\AuthController#handleProviderCallback');
If anyone still arrives here with the same error, but using the SocialiteProviders Microsoft provider already:
Check if you have set up the library correctly.
Make sure to install socialiteproviders/microsoft from composer
Add the SocialiteProviders Manager to your config/providers.php: \SocialiteProviders\Manager\ServiceProvider::class
Add the event listener to your app/Providers/EventServiceProvider.php:
\SocialiteProviders\Manager\SocialiteWasCalled::class => [
[SocialiteProviders\Microsoft\MicrosoftExtendSocialite::class, 'handle'],
],
The last step is important, and what caused the error for me, because I didn't understand the event listener is required (and not just an optional way to extend the provider).
So this might seem obvious but both in my case and judging from the info provided in the question, this step is also missing. I changed from the current Microsoft to the Graph and still got the same error, however I then realized this error happens when the Driver is not registered in the service provider. Make sure you are using the same spelling of the service provider in vendor and that you include the Service provider, in my case:
<?php
namespace App\Providers;
use Illuminate\Auth\Events\Registered;
use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Event;
class EventServiceProvider extends ServiceProvider
{
/**
* The event to listener mappings for the application.
*
* #var array<class-string, array<int, class-string>>
*/
protected $listen = [
Registered::class => [
SendEmailVerificationNotification::class,
],
\SocialiteProviders\Manager\SocialiteWasCalled::class => [
// ... other providers
/*--- I forgot this --->*/\SocialiteProviders\Graph\GraphExtendSocialite::class.'#handle',
],
];
/**
* Register any events for your application.
*
* #return void
*/
public function boot()
{
//
}
/**
* Determine if events and listeners should be automatically discovered.
*
* #return bool
*/
public function shouldDiscoverEvents()
{
return false;
}
}
This added worked with microsoft graph, driver: "graph" from: https://github.com/SocialiteProviders/Microsoft-Graph
I never got to try with the listed driver "Microsoft" on socialiteproviders.com
and as of the time of this writing Graph was removed from that website, however all I care is that it works and it worked as expected!

Categories