I'm trying to do my own custom user provider,In Symfony - php

I'm trying to do my own custom user provider,In Symfony tutorial From
"http://symfony.com/doc/current/security/custom_provider.html#create-a-user-class" This Site Tutorial But Couldn't Understand how to implement This site code in my localhost.Pleace help me some step by step process or a video process.

You have to create a class that implements this interface
Symfony\Component\Security\Core\User\UserProviderInterface
For that, you must create a public function called loadUserByUserName that receives as a parameter a string (the user name) then you have to implement the logic to get the user entity (you may need to call Doctrine and find it on the database or make some calls to an API...) whatever service you need must be injected.
You also have to implement the method refreshUSer() that I'm not sure when is used.
and finally, the suportsClass method that checks if a given classname is supported (usually you have to check it against your user class classname)
Once done, you have to setup this class as a service in tour services.yml file. Remember to inject here the dependencies (with setters or using the constructor, this is up to you)

Related

Symfony Attribute class to check if user is logged in

Hi I have problem with Attribute class.
I created attribute class that takes RequestStack object as an argument. I need to check in this class if user was binded to request attributes, but there is no way to autowire it or pass an instance. If I pass it like, new RequestStack(), then I don't have access to any request, but there is no exception.
How can I fix it. I wanna use it like the symfony security bundle do it, Fe.
#[IsGranted('ROLE_USER')]
I tried:
configuring services.yaml
configuring in services.yaml arguments and binding service to it
rewriting it to annotaion, but result is the same
instancing RequestStack inside attribute class
I'm currently thinking to use reflection class, but I'm not sure if the RequestStack is going to contain all the requests (also the original/main one). It's important to me to keep track the request instance.

Symfony 2.8 Autowiring for method injection

Update 2020 (this should have been much sooner). There can be a new class for each controller action. Each controller can be named by the action it is going to do, with an Invoke() method. Consider "Action Domain Responder" (ADR).
Why do I want to do this? Controllers do not necessarily adhere to SRP, and I'm not about to go creating a new class for each of, what is effectively, a controller 'action'. Therefore, a controller should not have everything injected via constructor, but the relevant method being called should be able to state explicitly "I require these objects" and another method "these other objects".
As of Symfony 2.8, the Dependency Injection component now provides auto-wiring for your services if you provide autowire: true in services.yml.
I'm defining my controller as a service, like so:
test_controller:
class: AppBundle\Controller\TestController
autowire: true
My controller looks as follows:
class TestController
{
public function indexAction(TestClass1 $tc1, $id)
{
return new Response('The slug is: ' . $id);
}
}
You will notice I'm typehinting for TestClass, which is just an empty class. However, the following error appears when I refresh the page:
What do I need to change in my services.yml file to have auto wiring dependency injection in my controller method? Just a note, the issue isn't because I have an $id 'slug' afterwards. Removing it does nothing.
Edit: I've created a bundle allowing to do more or less what you want called DunglasActionBundle.
Disclaimer: I'm the author of the Symfony autowiring system.
The Symfony Dependency Injection Component (and the autowiring system is part of it) doesn't work that way. It only allows to automatically inject dependencies in the class constructor of services and knows nothing about controller classes, actions and other parts of the HttpKernel Component.
It's not currently possible to do what you want to do. Initially, the autowiring system has been designed for domain services, not for controllers.
It should be possible to bridge the autowiring system with controller parameters using a custom param converter. However, I'll suggest you take another way I've first described here:
There is another approach I want to discuss since several time but I
did not have the time to blog about it.
It's a derivate of/similar to the ADR pattern, applied to Symfony.
An action is a single class with a __invoke() method containing all it's
logic (should be only some lines of glue code to call the domain and
the responder).
Actions are registered as a service (it can be
automated using a compiler pass and some conventions, similar to how
we discover controllers right now, with the ability to override the
definition if needed)
On such action services, autowiring is enabled.
It means that almost as easy as current controllers to use for the
developper, but with an explicit dependency graph and a better
reusability. Only things that are really necessary are injected. In
fact, it's already doable to use such system with Symfony. We do it in
API Platform master. Here is one action for instance:
https://github.com/dunglas/DunglasApiBundle/blob/master/Action/PostCollectionAction.php
In this implementation I also rely a lof on kernel events to be able
to plug and play some sort of logic (persistence, validation...) in a
decoupled manner but it's out of scope.

MVC - How to pass data to service

I'm a bit confused on how to perform insert and update statements using MVC.
Is it ok to create an instance of an object in your controller and pass it to your service to save it or do you pass data to your service and handle everything else in there?
Insert
In my controller something like:
$userservice->insert("myname","mypassword");
In my UserService:
function insert($username,$password){
$user = ORM::for_table('user')->create();
$user->username= $username;
$user->password= $password;
$user->save();
}
Update
In my controller something like:
$userservice->update("myname","mypassword",1);
In my UserService:
function insert($username,$password,$id){
$user = ORM::for_table('user')->find($id);
$user->username= $username;
$user->password= $password;
$user->save();
}
Is this good practice?
Because I see a lot of these answers where for example a user is being created in the controller and passed to a repository to save it:
Proper Repository Pattern Design in PHP?
But I don't like the idea of creating a user in the controller...
Controllers belongs to application layer and controlls only activity. In your example the activities are Create- and Update for an existing or for a new User. These operations belongs to the Domain Layer, which contains services. Thus services encapsulate the domain as a gatekeeper and provides operations for resolving domain like a facade.
Is it ok to create an instance of an object in your controller and pass it to your service to save it or do you pass data to your service and handle everything else in there?
The service should provide a method to pass a ValueObject. ValueObjects are better to encapsulate lot of data (Property values for User). Inside the service, the ValueObject should be delegated to Filter and Validator. If validation didn't fail the ValueObject will be delegated to a DataMapper. The DataMapper will map the properties of ValueObject to a data-model for the UserRepository (ORM). Repositories often need another model of data, e.g. Objects versus storage mediums based on RDBMS like MySQL.
This approach should be strict to seperate the concerns between layers to improve maintainabilty and interchangeabilty. Services should be thin and acts as a delegator to Domain Objects (Filter, Validator, etc.), for example see Service Layer Pattern.
So, where should be a value object created?
I would prefer that the service provides a method for this: getEntityPrototype() by using the prototype pattern.
Be careful with naming. ValueObject is an object which have no identity. Entity is an object with identity (here id of User). For an existing User you will have have a method like getUserById($id), which should return an UserEntity. If User does not exist for given id, it should return a NullObject. To create a new User getEntityPrototype() will return an UserEntity which have no identity yet, so you will call it ValueObject or better Prototype of Entity. After setting properties (e.g. by a FormObject) and persisting this object is a real entity. In a Factory for this service you can set the EntityPrototype.
What you should think about in this case is if the classes have only one responsibility.
Controller decides about the flow of the action. If there's a need for registering a user then it registers him, but it should not define how to do it, but ask a service to complete this task and get the result.
On the other hand you should have some kind of UserManager which updates, creates and fetches users - is this single responsibility? Kinda, yes - it's managing them in a broad sense.
There's a slight problem you have with your methods' names though. You should have registerUser not insert since it's way easier to tell what it actually does.
You should Pass Data to Model. MVC is all about dividing tasks Controller - Handles Application Flow, Model - Contains all the business login Database etc and View - here you decide how to show. Basically the UI part is stored here
So the Controller should send data to Model and model decides what to do with the data. The advantage of coding this way is that in future if you want to change something in the code you know where to look, or if you ask a designer to redesign your website you only have to give him the VIEW part of code . If the designer does something that caused an error , correcting that wont take that much time. If you follow MVC properly Adding,Updating or Maintaining functionality wont be a problem

Symfony user framework design problem

I'm looking for advice on how to tackle a design problem I've came up with. I'm currently using Symfony framework so I'll be using the names of Symfony classes.
When a user becomes "authenticated" or their "credentials" change in the Symfony user class, a regenerate() gets called on the currently used storage class. The store class extends sfStorage.
Now, when this regenerate() command is ran, we need to do some business logic. The following are options I've came up with so far:
Modify the three functions that addCredential, removeCredential, setAuthenticated and tell them to dispatch an event (setAuthenticated already does) so we know to do our business logic.
Second option would be to extend the sfSessionStorage class and tell it to throw an event on each regenerate. The problem I have with this is that sfUser asks for the interface sfStorage. Unless we modify sfStorage then if someone passed any kind of class that extends sfStorage that didn't know to add the event, it wouldn't work.
The third option would be the second option, but we would still extend the user object to say that we require the interface of a custom sfStorage abstract class that sends out a notification on regenerate. Then we would know for sure that any class that passes through would follow this notification method.
Anyone have any suggestions?
I would go with the second option and extend the sfSessionStorage class, and then use the class by inserting it into the factories.yml.
This shouldn't cause any issues with the sfUser though as your custom storage class will extend from sfStorage by proxy.

How to access my singletons without using global state?

I know that Singleton pattern is bad because it uses global state. But in most applications, you need to have a single instance of a class, like a database connection.
So I designed my Database object without using the singleton pattern but I instanciate it only once.
My question is, how can I access my object in the low level classes (deep in the object graph) without passing it all over the place?
Let's say I have an application controller which instanciates (ask a factory to instanciate it actually) a page controller which instaciates a User model which requires the database object.
Neither my app controller nor my page controller need to know about the database object but the User class does. How am I suppose to pass the object to it?
Thanks for your time!
Consider using a global container:
You register the objects that are indeed relevant to the several subsystems of the application.
You then request that container those objects.
This approach is very popular in dependency injection frameworks (see Symfony DI, Yadif).
Singleton is bad, no doubt about it.
In the case you describe, the database object is an implementation detail of the User object. The layers above need only know about the User, not the database object.
This becomes much more apparent if you hide the user object behind an interface and only consume that interface from the layers above.
So the page controller should deal only with the interface, not the concrete class that depends on the database object, but how does in create new instances? It uses an injected Abstract Factory to create instances of the interface. It can deal with any implementation of that interface, not only the one that relies on a database object.
Once more, you hide the page controller behind an interface. This means that the concrete implementation's reliance on the Abstract Factory becomes another implementation detail. The Application Controller only consumes the page controller interface.
You can keep wrapping objects like that like without ever needing to pass around instances. Only in the Composition Root do you need to wire all dependencies together.
See here for a related answer with examples in C#: Is it better to create a singleton to access unity container or pass it through the application?
The way I've always accomplished this is to implement a static getInstance function that will return a reference to the single instance of that class. As long as you make sure that the only way you access the object is through that method, you can still ensure that you only have one instance of the singleton. For example:
class deeply_nested_class {
public function some_function() {
$singleton = Singleton::getInstance();
}
}
There are two main objects involved in loading/saving a user using the database: the user and the repository.
You seem to have implemented the functionality on the User, but I think it belongs on the Repository. You should pass the user to the Repository to save it.
But, how do you get hold of the Repository? This is created once at the top level and passed into services that need it.
The construction dependency graph and the call dependency graph are not the same thing.
Given the example you outlined, you are almost there. You are already using a factory to instantiate your page controller, but your page controller is instantiating the users directly and as your User needs to know the database.
What you want to do is use a factory to instantiate your User objects. That way the factory can know about the database and can create User instances which know about it too. You will probably be better off making interfaces for all the dependencies, which will help with testing and will mean your code is nicely decoupled.
Create an IUserFactory which creates IUser implementations and pass this into your PageControllerFactory, then your ApplicationController only needs to know about the PageControllerFactory, it doesn't need to know anything about the IUserFactory or the database.
Then in your application start up you can create all of your dependencies and inject them in to each other through the constructors.

Categories