Package Data | |
---|---|
Maintainer Username: | imanghafoori1 |
Maintainer Contact: | imanghafoori1@gmail.com (Iman Ghafoori) |
Package Create Date: | 2018-07-04 |
Package Last Update: | 2024-06-15 |
Home Page: | |
Language: | PHP |
License: | MIT |
Last Refreshed: | 2024-10-31 03:04:52 |
Package Statistics | |
---|---|
Total Downloads: | 34,139 |
Monthly Downloads: | 231 |
Daily Downloads: | 2 |
Total Stars: | 919 |
Total Watchers: | 26 |
Total Forks: | 37 |
Total Open Issues: | 1 |
Very well tested, optimized and production ready !
In fact, We have tackled a lot of complexity
behind the scenes, to provide you with a lot of simplicity
.
https://github.com/barryvdh/laravel-debugbar
composer require imanghafoori/laravel-heyman
Here you can see a good example at :
https://github.com/imanghafoori1/council
Specially this file:
https://github.com/imanghafoori1/council/blob/master/app/Providers/AuthServiceProvider.php
This is fork from result of laracasts.com tutorial series refactored to use the Heyman package.
<= Laravel Heyman
Imagine your boss comes to you and says :
Hey man !!!
When you visit the login form,
You should be guest,
Otherwise you get redirected to '/panel',
Write the code for me, just now... But KEEP IN MIND you are not allowed to touch the current code. it is very sensitive and we do not want you to tamper with it. You may break it.
And you write code like this in a Service Provider boot
method to implement what your boss wanted.
1 - This way you can fully decouple
authorization and a lot of guarding code from the rest of your application code and put it in an other place. So your Controllers and Routes become less crowded and you will have a central place where you limit the access of users to your application or perform Request validation.
2 - In fact, when you write your code in the way, you are conforming to the famous "Tell don't ask principle.
"
You are telling the framework what to do in certain situations rather than getting information and decide what to do then.
Procedural code gets information then makes decisions. Object-oriented code tells objects to do things. — Alec Sharp
3 - This approach is paticularly useful when you for example write a package which needs ACL but you want to allow your package users to override and apply they own ACL (or validation) rules into your package routes...
And that becomes possible when you use laravel-HeyMan for ACL. The users can easily cancel out the default rules and re-write their favorite acl or validation stuff in a regular ServiceProviders.
HeyMan, that is Amazing stuff !!!
// This is written in package and lives in vendor folder, So we can not touch it.
HeyMan::whenYouHitRouteName('myPackageRoute')->youShouldHaveRole(....;
To override that we use the forget
method, within app/Providers/...
:
public function boot() {
// Cancels out the current rules
HeyMan::forget()->aboutRoute('myPackageRoute');
// Add new rules by package user.
HeyMan::whenYouHitRouteName('myPackageRoute')-> ...
}
You do not need any cheat sheet.
IDE
Auto-completion
is fully supported.
Heyman::
calls ?You may put them in
AuthServiceProvider.php
(or any other service provider)boot
method.
You should call the following method of the HeyMan Facade class.
use Imanghafoori\HeyMan\Facades\HeyMan;
// or
use HeyMan; // <--- alias
Again we recommend visiting this link for examples:
https://github.com/imanghafoori1/council/blob/master/app/Providers/AuthServiceProvider.php
HeyMan:: (situation) -> (condition) -> otherwise() -> (reaction) ;
HeyMan::whenYouVisitUrl(['/welcome', '/home'])->... // you can pass an Array
HeyMan::whenYouVisitUrl('/admin/*')->... // or match by wildcard
HeyMan::whenYouSendPost('/article/store')-> ...
HeyMan::whenYouSendPatch('/article/edit')-> ...
HeyMan::whenYouSendPut('/article/edit')-> ...
HeyMan::whenYouSendDelete('/article/delete')-> ...
HeyMan::whenYouHitRouteName('welcome.name')->... // For route names
HeyMan::whenYouHitRouteName('welcome.*')->... // or match by wildcard
HeyMan::whenYouCallAction('HomeController@index')->...
HeyMan::whenYouCallAction('HomeController@*')->... // or match by wildcard
HeyMan::whenYouMakeView('article.editForm')->... // also accepts an array
HeyMan::whenYouMakeView('article.*')->... // You can watch a group of views
Actually it refers to the moment when view('article.editForm')
is executed.
HeyMan::whenEventHappens('myEvent')->...
Actually it refers to the moment when event('myEvent')
is executed.
HeyMan::whenYouSave(\App\User::class)->...
HeyMan::whenYouFetch(\App\User::class)->...
HeyMan::whenYouCreate(\App\User::class)->...
HeyMan::whenYouUpdate(\App\User::class)->...
HeyMan::whenYouDelete(\App\User::class)->...
Actually it refers to the moment when eloquent fires it's internal events like: (saving, deleting, creating, ...)
HeyMan:: (situation) -> (condition) -> otherwise() -> (reaction) ;
After considering situations it is time to check some conditions
// define Gate
Gate::define('hasRole', function(){...});
Then you can use the gate:
HeyMan::whenYouVisitUrl('/home')->thisGateShouldAllow('hasRole', 'editor')->otherwise()->...;
Passing a Closure as a Gate:
$gate = function($user, $role) {
/// some logic
return true;
}
HeyMan::whenYouVisitUrl('/home')->thisGateShouldAllow($gate, 'editor')->otherwise()->...;
HeyMan::whenYouVisitUrl('/home')-> youShouldBeGuest() ->otherwise()->...;
HeyMan::whenYouVisitUrl('/home')-> youShouldBeLoggedIn() ->otherwise()->...;
Closure
or Method
or Value
:HeyMan::whenYouVisitUrl('home')->thisMethodShouldAllow('someClass@someMethod', ['param1'])->otherwise()->...;
HeyMan::whenYouVisitUrl('home')->thisClosureShouldAllow( function($a) { ... }, ['param1'] ) ->otherwise()->...;
HeyMan::whenYouVisitUrl('home')->thisValueShouldAllow( $someValue )->otherwise()->...;
HeyMan::whenYouHitRouteName('articles.store')->yourRequestShouldBeValid([
'title' => 'required', 'body' => 'required',
]);
You can also modify the data before validation by calling beforeValidationModifyData()
.
$modifier = function ($data) {
// removes "@" character from the "name" before validation.
$data['name'] = str_replace('@', '', $data['name']);
return $data;
}
HeyMan::whenYouHitRouteName('welcome.name')
->yourRequestShouldBeValid(['name' => 'required'])
->beforeValidationModifyData($modifier);
You can also declare some check points some where, within your application code:
HeyMan::checkPoint('MyLane');
And put some rules for it
HeyMan::whenYouReachCheckPoint('MyLane')->youShouldHaveRole('Zombie')-> ...
HeyMan::whenYouVisitUrl('home')->always()-> ...
HeyMan::whenYouVisitUrl('home')->sessionShouldHave('key1')->...
You can also use one of these:
HeyMan::whenYouVisitUrl('home')->always()-> ...
HeyMan::whenYouVisitUrl('home')->sessionShouldHave('key1')->...
You can extend the conditions and introduce new methods into heyman API like this:
// Place this code:
// In the `boot` method of your service providers
HeyMan::condition('youShouldBeMan', function () {
return function () {
return auth()->user() && auth()->user()->gender === 'Man';
};
});
// or
HeyMan::condition('youShouldBeMan', '\App\SomeWhere\SomeClass@someMethod');
Then you can use it like this:
HeyMan::whenYouVisitUrl('home')->youShouldBeMan()-> ...
Nice, isn't it ?!
HeyMan:: (situation) -> (condition) -> otherwise() -> (reaction) ;
HeyMan::whenSaving(\App\User::class)->thisGateShouldAllow('hasRole', 'editor')->otherwise()->weDenyAccess();
An AuthorizationException
will be thrown if needed
HeyMan::whenYouVisitUrl('/login')-> ... ->otherwise()->redirect()->to(...) ->with([...]);
HeyMan::whenYouVisitUrl('/login')-> ... ->otherwise()->redirect()->route(...) ->withErrors(...);
HeyMan::whenYouVisitUrl('/login')-> ... ->otherwise()->redirect()->action(...) ->withInput(...);
HeyMan::whenYouVisitUrl('/login')-> ... ->otherwise()->redirect()->intended(...);
HeyMan::whenYouVisitUrl('/login')-> ... ->otherwise()->redirect()->guest(...);
In fact the redirect method here is very much like the laravel's redirect()
helper function.
$msg = 'My Message';
HeyMan::whenYouVisitUrl('/login')
->youShouldBeGuest()
->otherwise()
->weThrowNew(AuthorizationException::class, $msg);
HeyMan::whenYouVisitUrl('/login')-> ... ->otherwise()->abort(...);
Calling these functions generate exact same response as calling them on the response()
helper function:
return response()->json(...);
HeyMan::whenYouVisitUrl('/login')-> ... ->otherwise()->response()->json(...);
HeyMan::whenYouVisitUrl('/login')-> ... ->otherwise()->response()->view(...);
HeyMan::whenYouVisitUrl('/login')-> ... ->otherwise()->response()->jsonp(...);
HeyMan::whenYouVisitUrl('/login')-> ... ->otherwise()->response()->make(...);
HeyMan::whenYouVisitUrl('/login')-> ... ->otherwise()->response()->download(...);
HeyMan::whenYouVisitUrl('/login')->
...
->otherwise()
->weRespondFrom('\App\Http\Responses\Authentication@guestsOnly');
namespace App\Http\Responses;
class Authentication
{
public function guestsOnly()
{
if (request()->expectsJson()) {
return response()->json(['error' => 'Unauthenticated.'], 401);
}
return redirect()->guest(route('login'));
}
}
Hey man, You see ? we have just an Http response here. So our controllers are free to handle the right situaltions and do not worry about exceptional ones.
Hey man, You may want to call some method or fire an event right before you send the response back.
You can do so by afterCalling()
and afterFiringEvent()
methods.
HeyMan::whenYouVisitUrl('/login')-> ... ->otherwise()->afterFiringEvent('explode')->response()->json(...);
HeyMan::whenYouVisitUrl('/login')-> ... ->otherwise()->afterCalling('someclass@method1')->response()->json(...);
You can disable HeyMan chacks like this (useful while testing):
HeyMan::turnOff()->eloquentChecks();
...
/// You may save some eloquent models here...
/// without limitations from HeyMan rules.
...
HeyMan::turnOn()->eloquentChecks();
If you find an issue, or have a better way to do something, feel free to open an issue or a pull request. If you use laravel-heyman in your open source project, create a pull request to provide it's url as a sample application in the README.md file.
If you discover any security related issues, please email imanghafoori1@gmail.com instead of using the issue tracker.
As always if you found this package useful and you want to encourage us to maintain and work on it. Just press the star button to declare your willing.
:gem: A minimal yet powerful package to give a better structure and caching opportunity for your laravel apps.
:gem: A minimal yet powerful package to give you opportunity to refactor your controllers.
:gem: It allows you login with any password in local environment only.