How to get/fetch the authenticated User from Data Provider Class or Entity Class - api-platform.com

i'm using JWT authentication and all works correctly: i'm able to get the token and login successfully from Swagger UI.
Now I'm stucked because i'm not able to take the authenticated User instance from Data Provider Class or Entity Class, any suggestion?
Thanks

I'm injected a Security instance in the DataProvider __construct so I can fetch the logged User!
Now I can use $security->getUser().
namespace App\DataProvider;
use ApiPlatform\Core\DataProvider\ItemDataProviderInterface;
use ApiPlatform\Core\DataProvider\RestrictedDataProviderInterface;
use App\Entity\Order;
use Symfony\Component\Security\Core\Security;
final class OrderItemDataProvider implements ItemDataProviderInterface, RestrictedDataProviderInterface {
private $security = null;
public function __construct(Security $security)
{
$this->security = $security;
}
public function supports(string $resourceClass, string $operationName = null, array $context = []): bool {
return Order::class === $resourceClass;
}
public function getItem(string $resourceClass, $id, string $operationName = null, array $context = []): ?Order {
return new Order($id);
}
}

Related

Call to a member function reply() on null laravel botman

This is the code of model. I am unable to change access the function of conversation using the model method as i am passing data from view to botman conversation constructor through request.
<?php
This is the conversation class
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use App\Conversations\TestConversation;
class CheckSaved extends Model
{
public function hasDate($scheduled_date):bool
{
if($scheduled_date)
{
$testconv = new TestConversation($scheduled_date);
$testconv->showOther();
}
return false;
}
}][1]
<?php
namespace App\Conversations;
use BotMan\BotMan\Messages\Incoming\Answer;
use BotMan\BotMan\Messages\Conversations\Conversation;
use App\Http\Traits\PropertyDetails;
use App\Models\CheckSaved;
class TestConversation extends Conversation
{
public $is_saved;
public function __construct($request)
{
if(isset($request->scheduled_date))
{
$checkDate = new CheckSaved();
$this->is_saved = $checkDate->hasDate($request->scheduled_date);
}
}
public function sayHi()
{
// dd($request);
$this->say("<input type='datetime-local' id='birthdaytime' name='birthdaytime'>");
$this->say("<button class='btn-date' onclick='test()'>Save</button>");
}
public function showOther()
{
$this->say('Hi');
}
public function run()
{
$this->sayHi();
}
}
This is the image of Model
I am getting reply() on null if try to call a function called "showOther()" inside TestConversation. I am stuck on it please someone help or contact me.

How to use laravel repository pattern searchable array?

I am using laravel-repository pattern ,i have one api which is responsible for getting all users it's working fine ,if we are using that package by default search should support for that i set $fieldSearchable array in the repository class.
i hit an api like this localhost.com/api/lists?search=foo,it's not working can you please help me where did i mistake
UserController.php
public function __construct(UserRepositoryInterface $repository)
{
$this->repository = $repository;
}
public function getUsers(){
$data = $this->repository->show();
return response()->json(fractal($data, new UserTransformer()));
}
UserRepositoryInterface.php
interface UserRepositoryInterface extends RepositoryInterface
{
public function show();
}
UserRepository.php
<?php
namespace App\Repositories;
use Prettus\Repository\Eloquent\BaseRepository;
use Prettus\Repository\Criteria\RequestCriteria;
use App\User as AppUser;
use App\UserSection;
use App\Validators\UserValidator;
use Illuminate\Support\Facades\DB;
/**
* Class UserRepositoryEloquent.
*
* #package namespace App\Repositories;
*/
class UserRepository extends BaseRepository implements UserRepositoryInterface
{
protected $fieldSearchable = ['phone_number'];
/**
* Specify Model class name
*
* #return string
*/
public function model()
{
return AppUser::class;
}
/**
* Boot up the repository, pushing criteria
*/
public function boot()
{
$this->pushCriteria(app(RequestCriteria::class));
}
public function show(){
return $this->model()::get();
}
}
It maybe resolved by utilising pre-difined methods No need to write show() function logic because by default l5-Repository pattern contains some methods to get all the data all()or paginate().in your controller write like this in getUsers()
$data = $this->repository->all();
or
$data = $this->repository->paginate('25');
all() is for fetch all the data from DB and paginate($limit) is fetch the data per page based on the limit.
if you are using any one of the above mentioned method then automatically search functionality will work

initialize objects in ASP.custom middleware and inject them

I have an ASP.NET Core Web API which reads an auth token in the request header and decodes the values in it.
I have written custom middleware to decode the token. I have also created a UserContext object to hold the values decoded from the token and I'm setting the decoded values into the UserContext object.
I now want to be able to inject the UserContext object (which was created inside the custom middleware) into my contollers, and I'm unable to figure out how to do that.
Please help.
You can use the HttpContext.Items
In your middleware you will have access to the HttpContext, ofcourse
You can store your user context in the items dictionary which is transient and scoped to the lifetime of one http request. Below is an example middleware where 'context' is the Http context object. You will have this object in your middleware.
app.Use(async (context, next) =>
{
context.Items.Add("UserContext", new UserContext());
await next.Invoke();
});
You can then access the HttpContext in your controller by injecting the IHttpContextAccessor object.
public class ApiController : Controller
{
public readonly IHttpContextAccessor _context;
public ApiController(IHttpContextAccessor context)
{
_context = context;
}
public IActionResult Get()
{
// Get the http context
UserContext userContext = (UserContext) _context.HttpContext.Items["UserContext"];
return Ok();
}
}
From the IHttpContextAccessor, you can get the HttpContext object, and from that you can get the Items dictionary.
Of course, do some checking to see if the key "UserContext" exists but I think this will work for you
EDIT
Because you will want to pass it to other repository/services.
Instead of passing the HttpContextAccessor to all of them, which you can do. Create a service the encapsulates the creation of the UserContext object.
It can look something like this.
public interface IRepositry { }
public class Repositry : IRepositry
{
private IUserContextService _userContextService;
public Repositry(IUserContextService userContextService)
{
_userContextService = userContextService;
}
}
public class UserContext
{
}
public interface IUserContextService
{
UserContext GetUser();
}
public class UserContextService : IUserContextService
{
private readonly IHttpContextAccessor _context;
public UserContextService(IHttpContextAccessor context)
{
_context = context;
}
public UserContext GetUser()
{
var token = _context.HttpContext.Request.Headers["UserToken"];
// do something with the token to create the UserContext;
return new UserContext();
}
}
Create a UserContextService that reads from the HttpContext. Make the UserContextService a singleton but when you get the user, always return a new UserContext, this is because you of course in a multi-threaded environment and you never want to persist this object because you may end up reading someone else's UserContext, so always return new. Register this service in your ConfigureServices method in your startup class .
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IUserContextService, UserContextService>();
services.AddSingleton<IRepositry, Repositry>(serviceCollection => new Repositry(serviceCollection.GetService<IUserContextService>()));
}
You can then inject your repository to your API controller for example
public class ApiController : Controller
{
public readonly IRepositry _repositry;
public ApiController(IRepositrycontext repositry)
{
_repositry= repositry;
}
public IActionResult Get()
{
// Get the http context
return Ok();
}
}

ZF2 using FilterProviderInterface to filter class method

I have a model class witch basically is the fields from a database table with getter and setters.
class RealEstate extends BaseModel implements FilterProviderInterface
{
public $cityId;
public $stateId;
...
public $transferFields = array();
public function getFilter()
{
return new MethodMatchFilter('getTransferFields');
}
public function setTransferFields($transferFields)
{
$this->transferFields = $transferFields;
}
public function getTransferFields()
{
return $this->transferFields;
}
...
}
In my BaseTableGateway class I have a method save which takes this model object and extracts the data using get methods into an array.
$hydrator = new ClassMethods(false);
$model_data = $hydrator->extract($model);
I need the getTransferFields() method to bind the object to my form but I dont need it to be in the final array (be excluded while extracting).
public function getFilter()
{
return new MethodMatchFilter('getTransferFields');
}
This method does exactly what I want but only for 1 method. I can't find out how to filter more than 1 method. Does anyone know how this would be achieved?
Simply return a FilterComposite object. The FilterComposite implements FilterInterface and is treated the same as the MethodMatchFilter.
For example:
public function getFilter()
{
$myFilters = new FilterComposite();
$myFilters->addFilter('someParam', new MethodMatchFilter('getSomeParam'));
$myFilters->addFilter('someOtherParam', new MethodMatchFilter('getSomeOtherParam'));
return $myFilters;
}

Symfony2 Use Doctrine in Service Container

How do I use Doctrine in a service container?
The Code just causes an error message "Fatal error: Call to undefined method ...::get()".
<?php
namespace ...\Service;
use Doctrine\ORM\EntityManager;
use ...\Entity\Header;
class dsdsf
{
protected $em;
public function __construct(EntityManager $em)
{
$this->em = $em;
}
public function create()
{
$id = 10;
$em = $this->get('doctrine')->getEntityManager();
$em->getRepository('...')->find($id);
}
}
services.yml
service:
site:
class: ...\Service\Site
According to your code, you already have an EntityManager injected. You don't need to call $em = $this->get('doctrine')->getEntityManager() — just use $this->em.
If you don't inject an EntityManager already, read this.
UPDATE:
You need to make the container inject an EntityManager into your service. Here's an example of doing it in config.yml:
services:
your.service:
class: YourVendor\YourBundle\Service\YourService
arguments: [ #doctrine.orm.entity_manager ]
I prefer to define bundles' services in their own services.yml files, but that's a bit more advanced, so using config.yml is good enough to get started.
For easily accessing the Entitymanager use the following one:
//services.yml
your service here:
class: yourclasshere
arguments: [#doctrine.orm.entity_manager]
And in the class itself:
class foo
{
protected $em;
public function __construct(\Doctrine\ORM\EntityManager $em)
{
$this->em = $em;
}
public function bar()
{
//Do the Database stuff
$query = $this->em->createQueryBuilder();
//Your Query goes here
$result = $query->getResult();
}
}
This is my first answer so any comments are appreciated :)
Please try this code:
$em=$this->container->get('doctrine')->getEntityManager();
$rolescheduels=$em->getRepository('OCSOCSBundle:RoleScheduel')->findByUser($user->getId());
For Symfony 3.x
The most easy-peasy solution for me was to just turn on autowiring/autoconfiguring, and then injecting the service I needed via the constructor. Note that I have also allowed any controller to be injected as a service by setting resource: '../../src/AppBundle/*'
#services.yml or config.yml
services:
_defaults:
autowire: true
autoconfigure: true
public: false
# Allow any controller to be used as a service
AppBundle\:
resource: '../../src/AppBundle/*'
# you can exclude directories or files
# but if a service is unused, it's removed anyway
exclude: '../../src/AppBundle/{Entity,Repository,Tests,DataFixtures,Form}'
Then in any service, you can inject & use the entity manager $em (or any other service/controller) via the constructor like this:
// class xyz
private $em;
// constructor
public function __construct(\Doctrine\ORM\EntityManager $em) {
$this->em = $em;
}
public function bar() {
//Do the Database stuff
$query = $this->em->createQueryBuilder();
//Your Query goes here
$result = $query->getResult();
}
for anyone who works with symfony3: u need to do the following inside config/services.yml in order to use doctrine in Service Container:
servicename_manager:
class: AppBundle\Services\MyServiceClass
arguments: [ "#doctrine.orm.entity_manager" ]
in the Symfony 3.4. If you want to use Doctrine in a service you can do it:
Only this method worked for me
services.yml:
YourBundle\PatchService\YourService:
public: true
arguments: [ '#doctrine.orm.entity_manager' ]
Service:
class YourService
{
private $em;
public function __construct($em) {
$this->em = $em;
}
Controller:
use YourBundle\PatchService\YourService;
/**
* #Route("/YourController/",name="YourController")
*/
public function indexAction()
{
$em = $this->getDoctrine()->getManager();
$Notification = new YourService($em);
I am using Symfony 3.4. If you want to create a service in a bundle this works for me:
services:
Vendor\YourBundle\Service\YourService:
arguments:
$em: '#doctrine.orm.entity_manager'
In your Service.php
<?php
namespace Hannoma\ElternsprechtagBundle\Service;
use Doctrine\ORM\EntityManager;
use Hannoma\ElternsprechtagBundle\Entity\Time;
class TimeManager
{
protected $em;
public function __construct(EntityManager $em)
{
$this->em = $em;
}
}
Since 2017 and Symfony 3.3 you can register Repository as service, with all its advantages it has.
Your code would change like this.
1. Service configuration
# app/config/services.yml
services:
_defaults:
autowire: true
...\Service\:
resource: ...\Service
2. Create new class - custom repository:
use Doctrine\ORM\EntityManagerInterface;
class YourRepository
{
private $repository;
public function __construct(EntityManagerInterface $entityManager)
{
$this->repository = $entityManager->getRepository(YourEntity::class);
}
public function find($id)
{
return $this->repository->find($id);
}
}
3. Use in any Controller or Service like this
class dsdsf
{
private $yourRepository;
public function __construct(YourRepository $yourRepository)
{
$this->yourRepository = $yourRepository;
}
public function create()
{
$id = 10;
$this->yourRepository->find($id);
}
}
Do you want to see more code and pros/cons lists?
Check my post How to use Repository with Doctrine as Service in Symfony.

Resources