GithubHelp home page GithubHelp logo

msgphp / symfony-demo-app Goto Github PK

View Code? Open in Web Editor NEW
0.0 0.0 0.0 884 KB

A Symfony demo application with basic user management

Home Page: https://github.com/msgphp/msgphp

License: MIT License

PHP 78.17% Shell 5.69% Makefile 3.04% Dockerfile 3.14% Twig 9.97%
symfony message-driven domain-driven-design user-management entity-attribute-value symfony-application eav doctrine twig uuid

symfony-demo-app's Introduction

NOT ACTIVELY SUPPORTED ANY MORE!!

msgphp/* repositories are not actively developed/supported anymore.

Use in production on your own risks.

If you want to do some hotfixes - please do PR directly in target repository instead of this monorepository.

Message Driven PHP

Build Status Code Coverage

MsgPHP is a project that aims to provide reusable domain layers for your application. It has a low development time overhead and avoids being overly opinionated.

It follows Semantic Versioning, yet during development phase a package can be marked @experimental to indicate "BC breaks" could be introduced.

Domain Layers

The domain layer is a collection of entity objects and related business logic that is designed to represent the enterprise business model. The major scope of this layer is to create a standardized and federated set of objects, that could be potentially reused within different projects. (source)

Currently supported domain layers are:

On the roadmap are:

  • Organization
  • File
  • Taxonomy
  • ...

Design-Time Considerations

  • The base domain package (msgphp/domain) integrates with YOUR domain layer (it's dependency free by design)
  • You inherit from the default domain layers, if used
  • The first-class supported ORM is Doctrine ORM
  • The first-class supported message bus is Symfony Messenger

Message Based

Each domain layer provides a set of messages to consume it. Typically the messages are categorized into command-, event- and query-messages.

The main advantage is we can intuitively create an independent flow of business logic. It provides consistency in handling our business logic by dispatching the same message in e.g. web as well as CLI.

$anyMessageBus->dispatch(new CreateSomething(['field' => 'value']));

A command-message is dispatched and picked up by its handler to do the work. This handler on itself dispatches a new event-message (e.g. SomethingCreated) to notify the work is done.

A custom handler can subscribe to the SomethingCreated event to further finalize the business requirements (e.g. dispatch another commmand-message).

class MakeSomethingWork
{
    private $bus;

    public function __construct(YourFavoriteBus $bus)
    {
        $this->bus = $bus;
    }

    public function __invoke(SomethingCreated $event)
    {
        // do work, or better delegate work:
        $this->bus->dispatch(new LetSomethingWork($event->something));
    }
}

Documentation

Contributing

See CONTRIBUTING.md

symfony-demo-app's People

symfony-demo-app's Issues

security.authentication.provider.dao.api_login dependency on a non-existent

#31 and comment #issuecomment-378317327
I check and I don't see this class resource: https://github.com/msgphp/user-bundle/blob/master/Resources/config/security.php#L38 :)


vagrant@vagrant-ubuntu-trusty-64:/var/www/app/freshpay$ bin/console debug:autowiring

Autowirable Services
====================

 The following classes & interfaces can be used as type-hints when autowiring:

 ------------------------------------------------------------------------------------------------ 
 [..]                                
  App\Controller\User\MyAccountController                                                         
  App\Controller\User\RegisterController                                                          
  App\Controller\User\ResetPasswordController                                                     
  App\DataFixtures\ORM\Users                                                                      
  App\EventSubscriber\ClearPasswordResetToken                                                     
  App\EventSubscriber\EnableConfirmedUser                                                         
  App\EventSubscriber\LocaleSubscriber                                                            
  App\EventSubscriber\SendEmailConfirmationUrl                                                    
  App\EventSubscriber\SendPasswordResetUrl                                                        
  App\EventSubscriber\SendRegistrationConfirmationUrl                                             
  App\EventSubscriber\UserLocaleSubscriber                                                        
  App\Form\User\AddEmailType                                                                      
  App\Form\User\BasicSettingForm                                                                  
  App\Form\User\ChangePasswordType                                                                
  App\Form\User\ForgotPasswordType                                                                
  App\Form\User\InfoSettingForm                                                                   
  App\Form\User\LoginForm                                                                         
  App\Form\User\RegisterForm                                                                      
  App\Form\User\ResetPasswordType                                                                                                                   
  App\Security\JwtTokenSubscriber                                                                 
  App\Security\PasswordConfirmation                                                               
  App\Security\UserChecker                                                                        
  App\Security\UserRolesProvider                                                                  
  Doctrine\Common\Annotations\Reader                                                              
      alias to annotations.cached_reader                                                          
  Doctrine\Common\Persistence\ManagerRegistry                                                     
      alias to doctrine                                                                           
  Doctrine\Common\Persistence\ObjectManager                                                       
      alias to doctrine.orm.default_entity_manager                                                
  Doctrine\DBAL\Connection                                                                        
      alias to doctrine.dbal.default_connection                                                   
  Doctrine\DBAL\Driver\Connection                                                                 
      alias to doctrine.dbal.default_connection                                                   
  Doctrine\ORM\EntityManagerInterface                                                             
      alias to doctrine.orm.default_entity_manager                                                
  FOS\RestBundle\Request\ParamFetcherInterface                                                    
      alias to fos_rest.request.param_fetcher                                                     
  FOS\RestBundle\View\ViewHandlerInterface                                                        
      alias to fos_rest.view_handler.default                                                      
  JMS\Serializer\ArrayTransformerInterface                                                        
      alias to jms_serializer.serializer                                                          
  JMS\Serializer\SerializerInterface                                                              
      alias to jms_serializer.serializer                                                          
  Lexik\Bundle\JWTAuthenticationBundle\Encoder\JWTEncoderInterface                                
      alias to lexik_jwt_authentication.encoder.default                                           
  Lexik\Bundle\JWTAuthenticationBundle\Security\Http\Authentication\AuthenticationFailureHandler  
      alias to lexik_jwt_authentication.handler.authentication_failure                            
  Lexik\Bundle\JWTAuthenticationBundle\Security\Http\Authentication\AuthenticationSuccessHandler  
      alias to lexik_jwt_authentication.handler.authentication_success                            
  Lexik\Bundle\JWTAuthenticationBundle\Services\JWSProvider\JWSProviderInterface                  
      alias to lexik_jwt_authentication.jws_provider.default                                      
  Lexik\Bundle\JWTAuthenticationBundle\Services\JWTTokenInterface                                 
      alias to lexik_jwt_authentication.jwt_manager                                               
  Lexik\Bundle\JWTAuthenticationBundle\Services\JWTTokenManagerInterface                          
      alias to lexik_jwt_authentication.jwt_manager                                               
  Lexik\Bundle\JWTAuthenticationBundle\TokenExtractor\TokenExtractorInterface                     
      alias to lexik_jwt_authentication.extractor.chain_extractor                                 
  MsgPhp\Domain\DomainIdentityHelper                                                              
  MsgPhp\Domain\DomainIdentityMappingInterface                                                    
      alias to MsgPhp\Domain\Infra\Doctrine\DomainIdentityMapping                                 
  MsgPhp\Domain\Factory\ClassMappingObjectFactory                                                 
  MsgPhp\Domain\Factory\DomainObjectFactory                                                       
      alias to MsgPhp\Domain\Factory\ClassMappingObjectFactory                                    
  MsgPhp\Domain\Factory\DomainObjectFactoryInterface                                              
      alias to MsgPhp\Domain\Factory\ClassMappingObjectFactory                                    
  MsgPhp\Domain\Factory\EntityAwareFactory                                                        
      alias to MsgPhp\Domain\Infra\Doctrine\EntityAwareFactory                                    
  MsgPhp\Domain\Factory\EntityAwareFactoryInterface                                               
      alias to MsgPhp\Domain\Infra\Doctrine\EntityAwareFactory                                    
  MsgPhp\Domain\Infra\Console\Context\ClassContextElementFactory                                  
  MsgPhp\Domain\Infra\Console\Context\ClassContextElementFactoryInterface                         
      alias to MsgPhp\Domain\Infra\Console\Context\ClassContextElementFactory                     
  MsgPhp\Domain\Infra\Console\Context\ClassContextFactory                                         
  MsgPhp\Domain\Infra\Doctrine\DomainIdentityMapping                                              
  MsgPhp\Domain\Infra\Doctrine\EntityAwareFactory                                                 
  MsgPhp\Domain\Infra\Doctrine\Event\ObjectFieldMappingListener                                   
  MsgPhp\Domain\Infra\Doctrine\MappingCacheWarmer                                                 
  MsgPhp\Domain\Infra\SimpleBus\DomainMessageBus                                                  
  MsgPhp\Domain\Message\DomainMessageBusInterface                                                 
      alias to MsgPhp\Domain\Infra\SimpleBus\DomainMessageBus                                     
  MsgPhp\Eav\Infra\Doctrine\EntityFieldsMapping                                                   
  MsgPhp\Eav\Infra\Doctrine\Repository\AttributeRepository                                        
  MsgPhp\Eav\Repository\AttributeRepositoryInterface                                              
      alias to MsgPhp\Eav\Infra\Doctrine\Repository\AttributeRepository                           
  MsgPhp\UserBundle\Twig\GlobalVariables                                                          
  MsgPhp\User\Command\Handler\AddUserAttributeValueHandler                                        
  MsgPhp\User\Command\Handler\AddUserEmailHandler                                                 
  MsgPhp\User\Command\Handler\AddUserRoleHandler                                                  
  MsgPhp\User\Command\Handler\ChangeUserAttributeValueHandler                                     
  MsgPhp\User\Command\Handler\ChangeUserCredentialHandler                                         
  MsgPhp\User\Command\Handler\ConfirmUserEmailHandler                                             
  MsgPhp\User\Command\Handler\ConfirmUserHandler                                                  
  MsgPhp\User\Command\Handler\CreateUserHandler                                                   
  MsgPhp\User\Command\Handler\DeleteUserAttributeValueHandler                                     
  MsgPhp\User\Command\Handler\DeleteUserEmailHandler                                              
  MsgPhp\User\Command\Handler\DeleteUserHandler                                                   
  MsgPhp\User\Command\Handler\DeleteUserRoleHandler                                               
  MsgPhp\User\Command\Handler\DisableUserHandler                                                  
  MsgPhp\User\Command\Handler\EnableUserHandler                                                   
  MsgPhp\User\Command\Handler\RequestUserPasswordHandler                                          
  MsgPhp\User\Infra\Console\Command\AddUserRoleCommand                                            
  MsgPhp\User\Infra\Console\Command\ChangeUserCredentialCommand                                   
  MsgPhp\User\Infra\Console\Command\ConfirmUserCommand                                            
  MsgPhp\User\Infra\Console\Command\CreateUserCommand                                             
  MsgPhp\User\Infra\Console\Command\DeleteUserCommand                                             
  MsgPhp\User\Infra\Console\Command\DeleteUserRoleCommand                                         
  MsgPhp\User\Infra\Console\Command\DisableUserCommand                                            
  MsgPhp\User\Infra\Console\Command\EnableUserCommand                                             
  MsgPhp\User\Infra\Console\Command\SynchronizeUsernamesCommand                                   
  MsgPhp\User\Infra\Doctrine\EntityFieldsMapping                                                  
  MsgPhp\User\Infra\Doctrine\Event\UsernameListener                                               
  MsgPhp\User\Infra\Doctrine\Repository\RoleRepository                                            
  MsgPhp\User\Infra\Doctrine\Repository\UserAttributeValueRepository                              
  MsgPhp\User\Infra\Doctrine\Repository\UserEmailRepository                                       
  MsgPhp\User\Infra\Doctrine\Repository\UserRepository                                            
  MsgPhp\User\Infra\Doctrine\Repository\UserRoleRepository                                        
  MsgPhp\User\Infra\Doctrine\Repository\UsernameRepository                                        
  MsgPhp\User\Infra\Form\Type\HashedPasswordType                                                  
  MsgPhp\User\Infra\Security\PasswordHashing                                                      
  MsgPhp\User\Infra\Security\SecurityUserProvider                                                 
  MsgPhp\User\Infra\Security\UserParamConverter                                                   
  MsgPhp\User\Infra\Security\UserRolesProviderInterface                                           
      alias to App\Security\UserRolesProvider                                                     
  MsgPhp\User\Infra\Security\UserValueResolver                                                    
  MsgPhp\User\Infra\Validator\ExistingUsernameValidator                                           
  MsgPhp\User\Infra\Validator\UniqueUsernameValidator                                             
  MsgPhp\User\Password\PasswordHashing                                                            
  MsgPhp\User\Password\PasswordHashingInterface                                                   
      alias to MsgPhp\User\Infra\Security\PasswordHashing                                         
  MsgPhp\User\Repository\RoleRepositoryInterface                                                  
      alias to MsgPhp\User\Infra\Doctrine\Repository\RoleRepository                               
  MsgPhp\User\Repository\UserAttributeValueRepositoryInterface                                    
      alias to MsgPhp\User\Infra\Doctrine\Repository\UserAttributeValueRepository                 
  MsgPhp\User\Repository\UserEmailRepositoryInterface                                             
      alias to MsgPhp\User\Infra\Doctrine\Repository\UserEmailRepository                          
  MsgPhp\User\Repository\UserRepositoryInterface                                                  
      alias to MsgPhp\User\Infra\Doctrine\Repository\UserRepository                               
  MsgPhp\User\Repository\UserRoleRepositoryInterface                                              
      alias to MsgPhp\User\Infra\Doctrine\Repository\UserRoleRepository                           
  MsgPhp\User\Repository\UsernameRepositoryInterface                                              
      alias to MsgPhp\User\Infra\Doctrine\Repository\UsernameRepository                           
  Psr\Cache\CacheItemPoolInterface                                                                
      alias to cache.app                                                                          
  Psr\Container\ContainerInterface                                                                
      alias to service_container                                                                  
  Psr\Log\LoggerInterface                                                                         
      alias to monolog.logger                                                                     
  SessionHandlerInterface                                                                         
      alias to session.handler.native_file                                                        
  SimpleBus\SymfonyBridge\Bus\CommandBus                                                          
      alias to simple_bus.command_bus                                                             
  SimpleBus\SymfonyBridge\Bus\EventBus                                                            
      alias to simple_bus.event_bus                                                               
  Swift_Mailer                                                                                    
      alias to swiftmailer.mailer.default                                                         
  Swift_Spool                                                                                     
      alias to swiftmailer.mailer.default.spool.memory                                            
  Swift_Transport                                                                                 
      alias to swiftmailer.mailer.default.transport.spool                                         
  Symfony\Bridge\Doctrine\RegistryInterface                                                       
      alias to doctrine                                                                           
  Symfony\Bundle\FrameworkBundle\Controller\RedirectController                                    
  Symfony\Bundle\FrameworkBundle\Controller\TemplateController                                    
  Symfony\Component\Asset\Packages                                                                
      alias to assets.packages                                                                    
  Symfony\Component\Cache\Adapter\AdapterInterface                                                
      alias to cache.app                                                                          
  Symfony\Component\DependencyInjection\ContainerInterface                                        
      alias to service_container                                                                  
  Symfony\Component\EventDispatcher\EventDispatcherInterface                                      
      alias to debug.event_dispatcher                                                             
  Symfony\Component\Filesystem\Filesystem                                                         
      alias to filesystem                                                                         
  Symfony\Component\Form\FormFactoryInterface                                                     
      alias to form.factory                                                                       
  Symfony\Component\Form\FormRegistryInterface                                                    
      alias to form.registry                                                                      
  Symfony\Component\Form\ResolvedFormTypeFactoryInterface                                         
      alias to form.resolved_type_factory                                                         
  Symfony\Component\HttpFoundation\RequestStack                                                   
      alias to request_stack                                                                      
  Symfony\Component\HttpFoundation\Session\Flash\FlashBagInterface                                
      alias to session.flash_bag                                                                  
  Symfony\Component\HttpFoundation\Session\SessionInterface                                       
      alias to session                                                                            
  Symfony\Component\HttpFoundation\Session\Storage\SessionStorageInterface                        
      alias to session.storage.native                                                             
  Symfony\Component\HttpKernel\Config\FileLocator                                                 
      alias to file_locator                                                                       
  Symfony\Component\HttpKernel\Debug\FileLinkFormatter                                            
      alias to debug.file_link_formatter                                                          
  Symfony\Component\HttpKernel\HttpKernelInterface                                                
      alias to http_kernel                                                                        
  Symfony\Component\HttpKernel\KernelInterface                                                    
      alias to kernel                                                                             
  Symfony\Component\PropertyAccess\PropertyAccessorInterface                                      
      alias to property_accessor                                                                  
  Symfony\Component\Routing\Generator\UrlGeneratorInterface                                       
      alias to router.default                                                                     
  Symfony\Component\Routing\Matcher\UrlMatcherInterface                                           
      alias to router.default                                                                     
  Symfony\Component\Routing\RequestContext                                                        
      alias to router.request_context                                                             
  Symfony\Component\Routing\RequestContextAwareInterface                                          
      alias to router.default                                                                     
  Symfony\Component\Routing\RouterInterface                                                       
      alias to router.default                                                                     
  Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface                   
      alias to security.authentication.manager                                                    
  Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface              
      alias to security.token_storage                                                             
  Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface                    
      alias to debug.security.access.decision_manager                                             
  Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface                     
      alias to security.authorization_checker                                                     
  Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface                                 
      alias to security.encoder_factory.generic                                                   
  Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface                            
      alias to security.user_password_encoder.generic                                             
  Symfony\Component\Security\Core\Security                                                        
      alias to security.helper                                                                    
  Symfony\Component\Security\Csrf\CsrfTokenManagerInterface                                       
      alias to security.csrf.token_manager                                                        
  Symfony\Component\Security\Csrf\TokenGenerator\TokenGeneratorInterface                          
      alias to security.csrf.token_generator                                                      
  Symfony\Component\Security\Csrf\TokenStorage\TokenStorageInterface                              
      alias to security.csrf.token_storage                                                        
  Symfony\Component\Security\Guard\GuardAuthenticatorHandler                                      
      alias to security.authentication.guard_handler                                              
  Symfony\Component\Security\Http\Authentication\AuthenticationUtils                              
      alias to security.authentication_utils                                                      
  Symfony\Component\Security\Http\Firewall                                                        
      alias to debug.security.firewall                                                            
  Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface                  
      alias to security.authentication.session_strategy                                           
  Symfony\Component\Stopwatch\Stopwatch                                                           
      alias to debug.stopwatch                                                                    
  Symfony\Component\Translation\TranslatorInterface                                               
      alias to translator.data_collector                                                          
  Symfony\Component\Validator\Validator\ValidatorInterface                                        
      alias to debug.validator                                                                    
  Twig\Environment                                                                                
      alias to twig                                                                               
  Twig_Environment                                                                                
      alias to twig                                                                               

Documentation for implementing email confirmation

Hi,

Can we get a documentation about how to implement User Email Confirmation?
I can see it's implemented in this demo, but it would be nice to have a documentation on how to implement it to freshly installed bundle.

Move basic app code to maker commands

I discussed this briefly with @dunglas today, related to symfony/recipes#392

For top experience cloning the demo-app and go from there might not the best choice, allthough the code is easy to customize, remove, etc. Devs are also lazy, making the demo look more complex it actually is (it's super simple in fact :P).

To improve this i was thinking to leverage the new "maker" thing in SF. No experience so must be investigated.. but AFAIK it could be something like;

composer require user
bin/console make:user:registration
xdg-open http://localhost/register

And be done! Full registration working. Next you would pick features as you like:

bin/console make:user:forgot-password

Or the whole experience in one go:

bin/console make:user

Add user avatars

Possible after msgphp/msgphp#107

  • abstract underlying filesystem
  • api integration
  • my account/web integration
  • collect profile pictures from oauth
  • thumbstyles
  • perhaps some CLI infra to rebuild thumbstyles

Reconsider view on domain autoloading

I know this is controversial.. but i tend to believe writing domain layer definitions (ids, entities, projections, etc.), at least at the app level, could benefit from specialized auto-loading in terms of writing them faster.

Think

src\App\User\
  - ids.php
  - commands.php
  - entities.php
  - projections.php
  - doctrine\
     - repositories.php
src\App\Car\
  - ...

That is multiple classes per component, per file.

Creating user - returned id is incremented by one

Hi, it's me again :)

I have an issue when creating new user. After I submit the form, user is created, but the id of the $user object is incremented by one - for example I created user and I can see in the database that new redord has id = 30, but the $user->id is set to 31, and I'm getting error on line with redirect (redirecting to non-existing user).
Here is the controller function:

    /**
     * @Route(
     *     "/users/add",
     *     name = "users_add"
     * )
     * @param Request $request
     * @param PasswordHashingInterface $passwordHashing
     *
     * @return Response
     */
    public function index(Request $request, PasswordHashingInterface $passwordHashing)
    {
        $userForm = $this->createForm(UserFormType::class);
        $userForm->handleRequest($request);

        if ($userForm->isSubmitted() && $userForm->isValid()) {

            /** @var User $user */
            $user = $userForm->getData();

            $user->changePassword($passwordHashing->hash($userForm->get('password')->getData()));
            $user->changeEmail($userForm->get('email')->getData());

            $isEnabled = $userForm->get('isEnabled')->getData();
            if ($isEnabled) {
                $user->enable();
            } else {
                $user->disable();
            }

            $entityManager = $this->getDoctrine()->getManager();
            $entityManager->persist($user);
            $entityManager->flush();

            return $this->redirectToRoute('pms_users_view', [ 'id' => $user->getId() ]);
        }
        return $this->renderTemplate('user/add.html.twig', [
            'userForm' => $userForm->createView()
        ]);
    }

Here is the configureOptions function of my UserFormType:

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => User::class,
            'empty_data' => function () {
                $password = $this->passwordHashing->hash('default_password');
                return new User(new UserId(), '[email protected]', $password);
            },
            'translation_domain' => 'users',
            'attr' => [
                'novalidate' => 'novalidate'
            ]
        ]);
    }

Here is a part od my User entity related to id:

namespace App\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use MsgPhp\User\Entity\User as BaseUser;
use MsgPhp\User\UserId;
use MsgPhp\User\UserIdInterface;

/**
 * @Vich\Uploadable
 */
class User extends BaseUser
{
    /**
     * @var UserIdInterface
     */
    private $id;

    /**
     * Constructor
     *
     * @param UserIdInterface $id
     * @param string $email
     * @param string $password
     */
    public function __construct(UserIdInterface $id, string $email, string $password)
    {
        $this->id = $id;
        $this->credential = new EmailPassword($email, $password);
        $this->roles = new ArrayCollection();
        $this->settings = new ArrayCollection();
    }

    /**
     * @return UserIdInterface
     */
    public function getId(): UserIdInterface
    {
        return UserId::fromValue($this->id);
    }
}

Did I do something wrong? It was working fine, for some time I was working on other part of the application, and now noticed this... I updated composer in the meantime, so I have the latest Symfony (4.0.8) and msgphp is set to dev-master.

Thanks.

Investigate/customize OAuth flow

After #26 a few questions remain open:

  • if a user authenticates using google with email X, but email X already exists on our side i think its password needs to be re-confirmed; claiming the existing account.
  • if email X doesnt exists we create it with a random password. In that case i think we need to assign a special ROLE_OAUTH or so which we can use to enforce either a password reset or always disable changing password (nobody knows the current pass, so it cannot be confirmed either way).
  • also curious about "connect" feature: https://github.com/hwi/HWIOAuthBundle/blob/master/Resources/doc/index.md#todo i believe it allows to create custom oauth registration step, could be interesting :)
  • if data changes remotely (i.e. at google.com) how do we get in sync again?

Add custom form login using Guard

traditional form login is bound to username/password. Let's say we want a custom login in the future based on username, password and some other field. Using a custom guard this would be easy (as it scales), compared to refactoring form_login to guard.

We can also do both "for demo purposes":

  • /login
  • /login-special ? we need a use case for this (some 3rd field, next to email/password)

Otherwise im leaning to drop form_login here.

https://knpuniversity.com/screencast/new-in-symfony3/guard-authentication

API 1.0 features

Aiming to merge #28 as POC, thus reading items/collections. After that many topics remain open:

  • GET /api/me endpoint + JWT integration
  • leverage domain to document ID service
  • content / access varying based on role
  • add user resource fields like { roles: ['ROLE_X', ...], emails: ['[email protected]', ...] }
  • GET /api/users/<id>/attributes (not sure these need to be embedded)
  • auto re-index after domain writes (doctrine listener / event subscribers)
    • for being a "message driven" project we could investigate things like dispatch(new SychronizeDomainObject($entity)
  • POST /api/users/<id>/action endpoints, i.e. /confirm, /enable, etc.
  • POST /api/users endpoint (registration)
  • DELETE /api/users/<id> endpoint
    • also write endpoints could simply dispatch our domain messages
  • after #30: user avatars (file entities) could be embedded into /api/users/<id>
  • investigate projection invalidation
    • given we have file & user resources; an updated file projection might invalidate a user projection, as the latter embeds the first.
  • add filters
  • add pagination

Feature Request: Invitations

FOSUserBundle supports invitations, any chance user-bundle could add similar support, or at least documentation on how to do so?

https://symfony.com/doc/current/bundles/FOSUserBundle/adding_invitation_registration.html

I'm migrating a subscription application, and am using this opportunity to purge inactive users. My idea is to send existing subscribers an invitation, requiring them to re-register, and allow social media registration/login at that point. I've been following the demo app, but if there's a way to leverage existing code or ideas on the registration invitation, I'd prefer to use that.

Document Social Media Login

I'm a little confused about how to configure logging in with Google and Facebook.

If I deploy this on Heroku, can you help with the configuration? I realize this might be more a HWIO issue than msgphp/user-bundle, but the endpoints (on the FB/Google app setup pages) and yaml file (security, etc.) are confusing.

Or if you add a link to an article / tutorial about this.

Invalid service "data_collector.security"

Morning. :)

I just updated from 0.5 to 0.6 and getting this:
Invalid service "data_collector.security": method "MsgPhp\User\Infra\Security\DataCollector::__construct()" has no argument named "$factory". Check your service definition.
Did I miss something?

No alive nodes found in your cluster error

When running bin/reinstall it completes, but my console prints:

...
In StaticNoPingConnectionPool.php line 51:

No alive nodes found in your cluster
...

Subsequently, user registration fails with the NoNodesException:

No alive nodes found in your cluster

How do I run/install Elasticsearch to get around this error?

Error: Attempted to load trait "AttributeValueField"...

Hi again :)

I just run composer update and now getting this:


Attempted to load trait "AttributeValueField" from namespace "MsgPhp\Eav\Entity\Fields".
Did you forget a "use" statement for another namespace?
--
in UserAttributeValue.php (line 17)

My composer:

"msgphp/domain": "@dev",
"msgphp/user": "@dev",
"msgphp/user-bundle": "dev-master",

It's just a mistake, or something has changed and I have to make changes to my code?

Switch Eav\Attribute to use string identifiers

Instead of

new Attribute(
  MsgPhp\Eav\Infra\Uuid\AttributeId::fromValue(
    Attribute::GOOGLE_OAUTH_ID
  )
)

consider

new Attribute(
  MsgPhp\Eav\AttributeId::fromValue('google_oauth_id')
)

Add a User API

Basically integration with https://github.com/api-platform and perhaps some User\Infra\Api infra. Dunno :) will be the first time using API platform for me.

In general goal is to have e.g. /api/user endpoints, including docs.

Shell for user-bundle demo with bootstrap and jquery

Although my landing-bundle isn't complete yet, here are steps that will create a basic website with menus and a login form, using the msgphp user-bundle:

symfony new --full my-app && cd my-app
composer config extra.symfony.allow-contrib true

composer req survos/landing-bundle
bin/console survos:prepare --no-interaction
composer req maker --dev
composer req messenger msgphp/user-bundle -n
bin/console make:user:msgphp --no-interaction
bin/console doctrine:schema:update --force
bin/console survos:setup --no-interaction
symfony server:start 

Yarn, composer and the symfony server need to be installed, of course.

I'm jazzed about enhancing this!

Automate screenshots

Stopped updating those for now as it's real tedious to do :)

Checking out tools to automate web & CLI screenshots.

after #9

How to change the user id column?

Hi again,

Sorry for being so importunate, and may be asking for trivial things. :|
And thank you for your patience.
I came across another issue - I have to rename the id column of users table to id_users (this is a requirement from our database guy) and I wonder how I can do this.

Here is my users table mapping:

<?xml version="1.0" encoding="utf-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
                  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                  xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">

    <entity name="App\Entity\User" table="tbl_users" repository-class="App\Repository\UserRepository">

        <field name="firstName" column="first_name" type="string" length="50" nullable="true"/>
        <field name="lastName" column="last_name" type="string" length="50" nullable="true"/>
        <field name="abbreviation" column="abbreviation" type="string" length="3" nullable="true"/>
        <field name="birthDate" column="birth_date" type="date" nullable="true"/>
        <field name="phoneExtension" column="phone_extension" type="string" length="10" nullable="true"/>

        <one-to-many field="roles" target-entity="App\Entity\UserRole" mapped-by="user" orphan-removal="true" fetch="EAGER">
            <cascade>
                <cascade-persist/>
                <cascade-remove/>
            </cascade>
        </one-to-many>

    </entity>

</doctrine-mapping>

After db column name has changed the login form does not show - I can see a doctrine error, as expected.
I tried to add <id name="id" column="id_users" type="integer"/> to the doctrine mapping - and then login form shows, but after submit I can see the following error: Property "id" in "App\Entity\User" was already declared, but it must be declared only once.

Is there any possibility to change the name of id column?

Thanks much once again.

How to change the default ROLE_USER?

Hi,
I'm trying to change the default ROLE_USER to something else - for example ROLE_DEFAULT. This is because I'm taking roles from the database and there is ROLE_USER already defined, so logged user has ROLE_USER duplicated. How do I do this?

Thanks!

Multiple email login

Hi again :)

Is it possible that user has few emails and can log in using any of his emails?
One account - few emails, any can be used for login.

Question: why controllers do not check for command result?

An example code from RegisterController:

$bus->handle(new CreateUserCommand($data = $form->getData()));
$flashBag->add('success', sprintf('Hi %s, you\'re successfully registered. We\'ve send you a confirmation link.', $data['email']));
return new RedirectResponse($urlGenerator->generate('index'));

If I understand CreateUserCommand() doesn't imply an intermediate result (or throws an Exception?). And even can be handled delayed in asynchronous way, then how to deal with this situation from a web application point of view? Should controller be aware is it setup to be asynchronous or should a client request flash messages repeatedly in a separate REST call?

Add a docker-compose.yml

I think it would be nice to have a docker container optimized for this symfony-demo-app that users can just $ docker-compose up -d and immediately start working with, don't you think?

Preferably using the most lightweight images possible, using exactly what the app needs and nothing more. Like I read an article a few weeks ago about Google creating something called "distroless" images which are exactly that. Could we use that?

Multiple email: forgot password looks for email in users table...

Hi,

What about forgot password when using multiple email login feature? I entered the alternate email in the forgot password form and got Call to a member function getId() on null error. I checked the queries and I can see that system looks for users table for user with specified credential email, and it gets nothing of course because this email exists in the username table...

Multiple email - forgot password always sends email to primary email

Hello,

As far as I can see the forgot password feature sends email to user primary email, regardless of email entered into the form, right? The email entered into forgot password form is used only to find user, then email is sent to users primary email...
This may be confusing, I think.

Question: is there any point to use API platform or shouldn't Controller/User/* be built around REST resource then?

Despite the comprehensive documentation of API platform, it's not too user friendly especially for beginners. I've spend a day to figure out how to make my own custom controllers for some REST resources I had planned. And it appears for my real-life project which is far from no-brainer blog-with-comments web site API platform is just a useless dependency. Because when I build my application around REST resource concept some calls are declaratively described in API platforms decorations but some operations I have to override and put in separate controllers Creating Custom Operations and Controllers. I understand that I must keep entities slim and can't mix with controller code but if my application doesn't expose blogs & comments and majority of all REST calls are custom handlers, there's no point to use API platform at all, a FOSRestBundle will perfectly suit my needs, at least I'll have all my controller code in one place, not scattered around application.

I guess the same logic applies to your demo application, there's no need for dependency on API platform just for this:

/**
 * @ApiResource(
 *     shortName="User",
 *     collectionOperations={
 *         "get",
 *     },
 *     itemOperations={
 *         "get",
 *         "delete"={
 *             "controller"="App\Api\Endpoint\DispatchMessageEndpoint",
 *         },
 *     }
 * )
 */

because all your other controller code handling user actions lies in a completely different place and has nothing to do with API platform. I suggest either get rid of API platform or put these controllers under custom operations.

P.S. found your project because I don't like how FOSUserBundle is built and because there're no progress on it and it built on top bad technical decisions. As a Symfony developer one must either accept it or build his own user handling code with all these Oauth/JWT support etc etc reinventing bicycle all the time. I appreciate your work but vast majority of Symfony developers like me do not understand in DDD and all these domain/document/projections/buses terminology followed by the huge amount of interfacing code makes my bald scalp wrinkling and my brains boiling. I've read the blue book and DDD-php-book twice and took a little from both. Could you please be so kind to write the documentation for complete beginners like me, starting with terminology and decisions you have made. Blog posts are definitely not enough. I even do not understand why you needed the ElasticSearch in your toy example with cars and I've read your posts 5 times and things are not getting clear after studying the source code. Please don't understand me wrong, I appreciate what you are doing and ready to learn but without clear understanding I can't depend on your UserBundle in my project. And since most of php developers are uneducated like me and not coming from enterprise/java/dotnet there will be no future for msgphp project unless you take the mission of teaching us concepts of DDD from the ground up.

Separate Oauth registration from regular flow

https://github.com/msgphp/symfony-demo-app/blob/master/src/Security/OauthUserProvider.php#L59

after connecting with oauth a regular CreateUserCommand is dispatched:

$this->bus->handle(new CreateUserCommand([
'id' => $userId,
'email' => $email,
'password' => bin2hex(random_bytes(32)),
]));
$this->bus->dispatch(new ConfirmUserCommand($userId));

which will dispatch UserCreatedEvent, send an email (event subscribers), etc. The context (oauth / regular) needs to be clear, so we can act accordingly (send the mail yes/no). Perhaps a special command is needed..

relates to #27

Use API Platform + SF Messenger dedicated

https://api-platform.com/docs/core/messenger/#dispatching-a-resource-through-the-message-bus

split the write ops in https://github.com/msgphp/symfony-demo-app/blob/master/src/Api/Projection/UserProjection.php in dedicated API resources

change many controllers for endpoints to a single a message handler, serving as a proxy (route all projections as such). For generic purpose it could leverage a ApiProjectionMessageToDomainMessgage conversion, and re-dispatch.

Add object relations to entities

App\Entity\User::getRoles, App\Entity\User::getSecondaryEmails etc. with corresponding annotation mapping.

decide the return type :') getRoles(): Doctrine\Collection vs getRoles(): MsgPhp\EntityCollectionInterface

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.