I can use only one middleware at a time..inside a constructor..I want to use if else condition inside constructor or two middleware.
I can use only one middleware inside constructor & if else condition also not working
I want only one function work or use according to middleware.I have two seprate table for authentication
Following middleware pointing to diffrent table
$this->middleware('auth:admin') - admins
$this->middleware('auth')- user
Example are follows
If else
class HRJob extends Controller
{
public function __construct()
{
if(Auth::guard('admin'))
{
$this->middleware('auth:admin');
}
else
{
$this->middleware('auth');
}
}
public function userdetails()
{
dd(Auth::user());
}
}
Two middleware
class HRJob extends Controller
{
public function __construct()
{
$this->middleware('auth:admin');
$this->middleware('auth');
}
public function userdetails()
{
dd(Auth::user());
}
}
You can try like this in the controller
class UserController extends Controller
{
/**
* Instantiate a new UserController instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('auth');
$this->middleware('log', ['only' => [
'fooAction',
'barAction',
]]);
$this->middleware('subscribed', ['except' => [
'fooAction',
'barAction',
]]);
}
}
Also you can use Middleware groups
/**
* The application's route middleware groups.
*
* #var array
*/
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
],
'api' => [
'throttle:60,1',
'auth:api',
],
];
More: https://laravel.com/docs/master/middleware
Related
this is my Auth Service Provider :
<?php
namespace App\Providers;
use App\Models\Profile;
use App\Policies\ProfilePolicy;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use RequestManager\Http\Models\RequestState;
use RequestManager\Policies\RequestStatePolicy;
class AuthServiceProvider extends ServiceProvider
{
protected $policies = [
Profile::class=>ProfilePolicy::class,
RequestState::class=>RequestStatePolicy::class,
];
public function boot()
{
$this->registerPolicies();
}
}
this is my policy array :
array:2 [
"App\Models\Profile" => "App\Policies\ProfilePolicy"
"RequestManager\Http\Models\RequestState" => "RequestManager\Policies\RequestStatePolicy"
]
I have a policy that is in its own module folder with this structure :
this is my controller :
public function showDepartmentRequests($id)//id = department id
{
$request=RequestState::where('department_id',$id)->get();
dd(\Gate::forUser(User::find(2))->allows('view',$request));
}
and this is my policy :
<?php
namespace RequestManager\Policies;
use RequestManager\Http\Models\RequestState;
use App\Models\User;
use Illuminate\Auth\Access\HandlesAuthorization;
class RequestStatePolicy
{
use HandlesAuthorization;
public function view(User $user, RequestState $requestState)
{
dd("test view policy");
}
}
Nothing is printed when I call the gate!
Is this error because I have to register a policy within a specific auth service Provider
other than the app\AuthServiceProvider?
I am working on a laravel app where i have a user(organizer) who post an event ,and other users can comment on this event .
I am trying to make notifications system in laravel 8 between the organizer and the users when commenting on these event !
but i get this error (Call to a member function notify() on null).
This is my class :
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
class NewCommentPosted extends Notification
{
use Queueable;
protected $user;
protected $event;
public function __construct($user, $event)
{
$this->user = $user;
$this->event = $event;
}
public function via($notifiable)
{
return ['database'];
}
public function toArray($notifiable)
{
return [
'user' => $this->user->name,
'eventTitle' => $this->event->title,
'eventId' => $this->event->id
];
}
This is storefunction() in my controller :
namespace App\Http\Controllers;
use App\Models\Event;
use App\Models\Comment;
use App\Notifications\NewCommentPosted;
use Illuminate\Http\Request;
class CommentController extends Controller
{
public function store(Event $event)
{
request()->validate([
'content' => 'required|min:5'
]);
$comment = new Comment();
$comment->content = request('content');
$comment->user_id = auth()->user()->id;
$event->comments()->save($comment);
$event->user->notify(new NewCommentPosted(auth()->user(), $event));
return redirect()->route('events.show', [$event->id, $event->title]);
}
Any help please !!?
I am developing an API under symfony4 and I wish I could create a parent controller that I could use to call functions that would be repeated in another controller. Here are my controllers that I would like to extend from a parent controller:
My DeliveryController:
<?php
namespace App\Controller;
use App\Entity\DeliveryMan;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Symfony\Component\Routing\Annotation\Route;
/**
* Class AuthController
* #package App\Controller
* #Route("/api")
*/
class DeliveryController extends AbstractController
{
/**
* #Route(
* name="api_delivery_man_post",
* path="/delivery_man",
* methods={"POST"},
* defaults={
* "_api_resource_class"=DeliveryMan::class,
* "_api_collection_operation_name"="post"
* }
* )
*/
public function postAction(DeliveryMan $data, UserPasswordEncoderInterface $encoder): DeliveryMan
{
return $this->encodePassword($data, $encoder);
}
protected function encodePassword(DeliveryMan $data, UserPasswordEncoderInterface $encoder): DeliveryMan
{
$encoded = $encoder->encodePassword($data, $data->getPassword());
$data->setPassword($encoded);
return $data;
}
}
My AuthController:
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use App\Entity\User;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
/**
* Class AuthController
* #package App\Controller
* #Route("/api")
*/
class AuthController extends AbstractController
{
/**
* #Route(
* name="api_users_post",
* path="/users",
* methods={"POST"},
* defaults={
* "_api_resource_class"=User::class,
* "_api_collection_operation_name"="post"
* }
* )
*/
public function postAction(User $data, UserPasswordEncoderInterface $encoder): User
{
return $this->encodePassword($data, $encoder);
}
protected function encodePassword(User $data, UserPasswordEncoderInterface $encoder): User
{
$encoded = $encoder->encodePassword($data, $data->getPassword());
$data->setPassword($encoded);
return $data;
}
}
As can be seen I call 2 identical actions in 2 different controllers the only difference that there would be the entities and the path of the road.
So I was thinking of creating a ResourceController parent controller that would be extended from AbstractController and that the child controllers would be extended from ResourceController but I do not see how after how to create my methods in my parent controller and retrieve them in the child controllers.
If someone has already done that I am a taker :) Thank you for your help.
EDIT Result ResourceController:
<?php
namespace App\Controller;
use App\Entity\DeliveryMan;
use App\Entity\User;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
class ResourcesController extends AbstractController
{
private $encoder;
public function __construct(UserPasswordEncoderInterface $encoder)
{
$this->encoder = $encoder;
}
public function encodePassword(User $data): User
{
$encoded = $this->encoder->encodePassword($data, $data->getPassword());
$data->setPassword($encoded);
return $data;
}
public function encodePasswordDelivery(DeliveryMan $data): DeliveryMan
{
$encoded = $this->encoder->encodePassword($data, $data->getPassword());
$data->setPassword($encoded);
return $data;
}
}
Just make a ResourceController wich extends Symfony AbstractController.
Write your 2 shared methods here, then in any Controller that extends ResourceController you can call them as you would normally call a class method: using $this
class ResourceController extends AbstractController
{
private $encoder;
public function __construct(UserPasswordEncoderInterface $encoder)
{
$this->encoder = $encoder;
}
public function encodePassword(Object $data): Object
{
$encoded = $this->encoder->encodePassword($data, $data->getPassword());
$data->setPassword($encoded);
return $data;
}
}
class AuthController extends ResourceController
{
public function someAction(User $data)
{
return $this->encodePassword($data);
}
}
I also suggest you write an interface with a getPassword method that User and DeliveryMan will implements. Not only you'll ensure that the method is implemented but you' also be able to typehint, say AuthenticatedEntityInterface, instead of Object
Let's say that I had the following API set up:
Controller:
<?php
namespace app\modules\v1\controllers;
use yii;
class ResourceController extends \yii\rest\ActiveController
{
public $modelClass = 'app\modules\v1\models\Resource';
}
Model:
use yii;
class Resource extends \yii\db\ActiveRecord
{
public static function tableName()
{
return 'ResourceTable';
}
public function fields()
{
return [
'id' => 'ResourceID',
'title' => 'ResourceTitle',
];
}
}
where my table only has the two columns, ResourceID and Title.
When I try a GET request on the API, it works fine and returns the list of resources (or single resource in the case of resource/{id}) with the aliased field names. But when I try to POST to create a resource, I want to use the aliased field names (e.g. title instead of ResourceTitle). The problem is that the default CreateAction supplied by Yii does $model->load(), which looks for the field names in the table. If I use the aliased names then it returns an error. If I use the table field names, it works fine.
So my question is, is there a way to expose resource attributes to the end user where the field names (using the fields() function) are the same for reading and creating? If possible, I'd like to avoid writing my own CreateAction.
It's necessary to add rules for new virtual properties, if you want to $model-load() save parameters to them
class OrganizationBranch extends BaseOrganization{
public function rules()
{
return array_replace_recursive(parent::rules(),
[
[['organizationId', 'cityId'], 'safe'],
]);
}
public function fields() {
return ['id',
'cityId' => 'city_id',
'organizationId' => 'organization_id',
'address',
'phoneNumbers' => 'phone_numbers',
'schedule',
'latitude',
'longitude',
];
}
public function extraFields() {
return ['branchType', 'city'];
}
public function getOrganizationId() {
return $this->organization_id;
}
public function setOrganizationId($val) {
$this->organization_id = $val;
}
public function getCityId() {
return $this->city_id;
}
public function setCityId($val) {
$this->city_id = $val;
}
}
You can create getters/setters for alias.
public function getTitle(){ return $this->ResourceTitle; }
public function setTitle($val){ $this->ResourceTitle = $val ; }
I am trying to create dynamic attributes, properties and rules in model class from one table values as columns.
Consider i have one table named "XXX" which has column "Name" now i want to create model class with rules,properties and attributes using the Name values stored in DB.
I am new to YII Framework Can anybody give idea to this ?
This is something i mocked up quickly, I hope it points ou in the right direction
$sql="SELECT 'Name' FROM XXX";
$names =$connection->createCommand($sql)->query()->readAll();
$myDynamicObject = new DynamicModel($names);
class DynamicModel extends CModel
{
protected $_members = array();
public function __construct($nameFields)
{
foreach ($nameFields as $member) {
$this->_members[$member] = null;
}
parent::__construct();
}
/**
* #return array validation rules for model attributes.
*/
public function rules()
{
$allMembers = implode(', ', array_keys($this->_members));
return array(
array($allMembers, 'required'),
);
}
public function __get($attribute)
{
if (in_array($attribute, array_keys($this->_members))) {
return $this->_members[$attribute];
} else {
return parent::__get($attribute);
}
}
public function __set($attribute, $value)
{
if (in_array($attribute, array_keys($this->_members))) {
return $this->_members[$attribute] = $value;
} else {
return parent::__set($attribute, $value);
}
}
public function getAttributes()
{
return $this->_members;
}
public function setAttributes($attributes)
{
$this->_members = $attributes;
}
}