This commit is contained in:
Xes
2025-08-14 22:41:49 +02:00
parent 2de81ccc46
commit 8ce45119b6
39774 changed files with 4309466 additions and 0 deletions

View File

@@ -0,0 +1,50 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\DependencyInjection\Compiler;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Flex\Recipe;
/**
* Checks to see if the mailer service exists.
*
* @author Ryan Weaver <ryan@knpuniversity.com>
*/
class CheckForMailerPass implements CompilerPassInterface
{
/**
* {@inheritdoc}
*/
public function process(ContainerBuilder $container)
{
// if the mailer isn't needed, then no error needed
if (!$container->has('fos_user.mailer')) {
return;
}
// the mailer exists, so all is good
if ($container->has('mailer')) {
return;
}
if ($container->findDefinition('fos_user.mailer')->hasTag('fos_user.requires_swift')) {
$message = 'A feature you activated in FOSUserBundle requires the "mailer" service to be available.';
if (class_exists(Recipe::class)) {
$message .= ' Run "composer require swiftmailer-bundle" to install SwiftMailer or configure a different mailer in "config/packages/fos_user.yaml".';
}
throw new \LogicException($message);
}
}
}

View File

@@ -0,0 +1,40 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\DependencyInjection\Compiler;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Flex\Recipe;
/**
* Checks to see if the session service exists.
*
* @author Ryan Weaver <ryan@knpuniversity.com>
*/
class CheckForSessionPass implements CompilerPassInterface
{
/**
* {@inheritdoc}
*/
public function process(ContainerBuilder $container)
{
if ($container->has('fos_user.session') && !$container->has('session')) {
$message = 'FOSUserBundle requires the "session" service to be available.';
if (class_exists(Recipe::class)) {
$message .= ' Uncomment the "session" section in "config/packages/framework.yaml" to activate it.';
}
throw new \LogicException($message);
}
}
}

View File

@@ -0,0 +1,39 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\DependencyInjection\Compiler;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
/**
* Inject RememberMeServices into LoginManager.
*
* @author Vasily Khayrulin <sirianru@gmail.com>
*/
class InjectRememberMeServicesPass implements CompilerPassInterface
{
/**
* {@inheritdoc}
*/
public function process(ContainerBuilder $container)
{
$firewallName = $container->getParameter('fos_user.firewall_name');
$loginManager = $container->getDefinition('fos_user.security.login_manager');
if ($container->hasDefinition('security.authentication.rememberme.services.persistent.'.$firewallName)) {
$loginManager->replaceArgument(4, new Reference('security.authentication.rememberme.services.persistent.'.$firewallName));
} elseif ($container->hasDefinition('security.authentication.rememberme.services.simplehash.'.$firewallName)) {
$loginManager->replaceArgument(4, new Reference('security.authentication.rememberme.services.simplehash.'.$firewallName));
}
}
}

View File

@@ -0,0 +1,37 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\DependencyInjection\Compiler;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
/**
* Injects firewall's UserChecker into LoginManager.
*
* @author Gocha Ossinkine <ossinkine@ya.ru>
*/
class InjectUserCheckerPass implements CompilerPassInterface
{
/**
* {@inheritdoc}
*/
public function process(ContainerBuilder $container)
{
$firewallName = $container->getParameter('fos_user.firewall_name');
$loginManager = $container->findDefinition('fos_user.security.login_manager');
if ($container->has('security.user_checker.'.$firewallName)) {
$loginManager->replaceArgument(1, new Reference('security.user_checker.'.$firewallName));
}
}
}

View File

@@ -0,0 +1,44 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\DependencyInjection\Compiler;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
/**
* Registers the additional validators according to the storage.
*
* @author Christophe Coevoet <stof@notk.org>
*/
class ValidationPass implements CompilerPassInterface
{
/**
* {@inheritdoc}
*/
public function process(ContainerBuilder $container)
{
if (!$container->hasParameter('fos_user.storage')) {
return;
}
$storage = $container->getParameter('fos_user.storage');
if ('custom' === $storage) {
return;
}
$validationFile = __DIR__.'/../../Resources/config/storage-validation/'.$storage.'.xml';
$container->getDefinition('validator.builder')
->addMethodCall('addXmlMapping', array($validationFile));
}
}

View File

@@ -0,0 +1,277 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\DependencyInjection;
use FOS\UserBundle\Form\Type;
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;
/**
* This class contains the configuration information for the bundle.
*
* This information is solely responsible for how the different configuration
* sections are normalized, and merged.
*
* @author Christophe Coevoet <stof@notk.org>
*/
class Configuration implements ConfigurationInterface
{
/**
* {@inheritdoc}
*/
public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root('fos_user');
$supportedDrivers = array('orm', 'mongodb', 'couchdb', 'custom');
$rootNode
->children()
->scalarNode('db_driver')
->validate()
->ifNotInArray($supportedDrivers)
->thenInvalid('The driver %s is not supported. Please choose one of '.json_encode($supportedDrivers))
->end()
->cannotBeOverwritten()
->isRequired()
->cannotBeEmpty()
->end()
->scalarNode('user_class')->isRequired()->cannotBeEmpty()->end()
->scalarNode('firewall_name')->isRequired()->cannotBeEmpty()->end()
->scalarNode('model_manager_name')->defaultNull()->end()
->booleanNode('use_authentication_listener')->defaultTrue()->end()
->booleanNode('use_listener')->defaultTrue()->end()
->booleanNode('use_flash_notifications')->defaultTrue()->end()
->booleanNode('use_username_form_type')->defaultTrue()->end()
->arrayNode('from_email')
->isRequired()
->children()
->scalarNode('address')->isRequired()->cannotBeEmpty()->end()
->scalarNode('sender_name')->isRequired()->cannotBeEmpty()->end()
->end()
->end()
->end()
// Using the custom driver requires changing the manager services
->validate()
->ifTrue(function ($v) {
return 'custom' === $v['db_driver'] && 'fos_user.user_manager.default' === $v['service']['user_manager'];
})
->thenInvalid('You need to specify your own user manager service when using the "custom" driver.')
->end()
->validate()
->ifTrue(function ($v) {
return 'custom' === $v['db_driver'] && !empty($v['group']) && 'fos_user.group_manager.default' === $v['group']['group_manager'];
})
->thenInvalid('You need to specify your own group manager service when using the "custom" driver.')
->end();
$this->addProfileSection($rootNode);
$this->addChangePasswordSection($rootNode);
$this->addRegistrationSection($rootNode);
$this->addResettingSection($rootNode);
$this->addServiceSection($rootNode);
$this->addGroupSection($rootNode);
return $treeBuilder;
}
/**
* @param ArrayNodeDefinition $node
*/
private function addProfileSection(ArrayNodeDefinition $node)
{
$node
->children()
->arrayNode('profile')
->addDefaultsIfNotSet()
->canBeUnset()
->children()
->arrayNode('form')
->addDefaultsIfNotSet()
->fixXmlConfig('validation_group')
->children()
->scalarNode('type')->defaultValue(Type\ProfileFormType::class)->end()
->scalarNode('name')->defaultValue('fos_user_profile_form')->end()
->arrayNode('validation_groups')
->prototype('scalar')->end()
->defaultValue(array('Profile', 'Default'))
->end()
->end()
->end()
->end()
->end()
->end();
}
/**
* @param ArrayNodeDefinition $node
*/
private function addRegistrationSection(ArrayNodeDefinition $node)
{
$node
->children()
->arrayNode('registration')
->addDefaultsIfNotSet()
->canBeUnset()
->children()
->arrayNode('confirmation')
->addDefaultsIfNotSet()
->children()
->booleanNode('enabled')->defaultFalse()->end()
->scalarNode('template')->defaultValue('@FOSUser/Registration/email.txt.twig')->end()
->arrayNode('from_email')
->canBeUnset()
->children()
->scalarNode('address')->isRequired()->cannotBeEmpty()->end()
->scalarNode('sender_name')->isRequired()->cannotBeEmpty()->end()
->end()
->end()
->end()
->end()
->arrayNode('form')
->addDefaultsIfNotSet()
->children()
->scalarNode('type')->defaultValue(Type\RegistrationFormType::class)->end()
->scalarNode('name')->defaultValue('fos_user_registration_form')->end()
->arrayNode('validation_groups')
->prototype('scalar')->end()
->defaultValue(array('Registration', 'Default'))
->end()
->end()
->end()
->end()
->end()
->end();
}
/**
* @param ArrayNodeDefinition $node
*/
private function addResettingSection(ArrayNodeDefinition $node)
{
$node
->children()
->arrayNode('resetting')
->addDefaultsIfNotSet()
->canBeUnset()
->children()
->scalarNode('retry_ttl')->defaultValue(7200)->end()
->scalarNode('token_ttl')->defaultValue(86400)->end()
->arrayNode('email')
->addDefaultsIfNotSet()
->children()
->scalarNode('template')->defaultValue('@FOSUser/Resetting/email.txt.twig')->end()
->arrayNode('from_email')
->canBeUnset()
->children()
->scalarNode('address')->isRequired()->cannotBeEmpty()->end()
->scalarNode('sender_name')->isRequired()->cannotBeEmpty()->end()
->end()
->end()
->end()
->end()
->arrayNode('form')
->addDefaultsIfNotSet()
->children()
->scalarNode('type')->defaultValue(Type\ResettingFormType::class)->end()
->scalarNode('name')->defaultValue('fos_user_resetting_form')->end()
->arrayNode('validation_groups')
->prototype('scalar')->end()
->defaultValue(array('ResetPassword', 'Default'))
->end()
->end()
->end()
->end()
->end()
->end();
}
/**
* @param ArrayNodeDefinition $node
*/
private function addChangePasswordSection(ArrayNodeDefinition $node)
{
$node
->children()
->arrayNode('change_password')
->addDefaultsIfNotSet()
->canBeUnset()
->children()
->arrayNode('form')
->addDefaultsIfNotSet()
->children()
->scalarNode('type')->defaultValue(Type\ChangePasswordFormType::class)->end()
->scalarNode('name')->defaultValue('fos_user_change_password_form')->end()
->arrayNode('validation_groups')
->prototype('scalar')->end()
->defaultValue(array('ChangePassword', 'Default'))
->end()
->end()
->end()
->end()
->end()
->end();
}
/**
* @param ArrayNodeDefinition $node
*/
private function addServiceSection(ArrayNodeDefinition $node)
{
$node
->addDefaultsIfNotSet()
->children()
->arrayNode('service')
->addDefaultsIfNotSet()
->children()
->scalarNode('mailer')->defaultValue('fos_user.mailer.default')->end()
->scalarNode('email_canonicalizer')->defaultValue('fos_user.util.canonicalizer.default')->end()
->scalarNode('token_generator')->defaultValue('fos_user.util.token_generator.default')->end()
->scalarNode('username_canonicalizer')->defaultValue('fos_user.util.canonicalizer.default')->end()
->scalarNode('user_manager')->defaultValue('fos_user.user_manager.default')->end()
->end()
->end()
->end()
->end();
}
/**
* @param ArrayNodeDefinition $node
*/
private function addGroupSection(ArrayNodeDefinition $node)
{
$node
->children()
->arrayNode('group')
->canBeUnset()
->children()
->scalarNode('group_class')->isRequired()->cannotBeEmpty()->end()
->scalarNode('group_manager')->defaultValue('fos_user.group_manager.default')->end()
->arrayNode('form')
->addDefaultsIfNotSet()
->fixXmlConfig('validation_group')
->children()
->scalarNode('type')->defaultValue(Type\GroupFormType::class)->end()
->scalarNode('name')->defaultValue('fos_user_group_form')->end()
->arrayNode('validation_groups')
->prototype('scalar')->end()
->defaultValue(array('Registration', 'Default'))
->end()
->end()
->end()
->end()
->end()
->end();
}
}

View File

@@ -0,0 +1,302 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\DependencyInjection;
use Symfony\Component\Config\Definition\Processor;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
class FOSUserExtension extends Extension
{
/**
* @var array
*/
private static $doctrineDrivers = array(
'orm' => array(
'registry' => 'doctrine',
'tag' => 'doctrine.event_subscriber',
),
'mongodb' => array(
'registry' => 'doctrine_mongodb',
'tag' => 'doctrine_mongodb.odm.event_subscriber',
),
'couchdb' => array(
'registry' => 'doctrine_couchdb',
'tag' => 'doctrine_couchdb.event_subscriber',
'listener_class' => 'FOS\UserBundle\Doctrine\CouchDB\UserListener',
),
);
private $mailerNeeded = false;
private $sessionNeeded = false;
/**
* {@inheritdoc}
*/
public function load(array $configs, ContainerBuilder $container)
{
$processor = new Processor();
$configuration = new Configuration();
$config = $processor->processConfiguration($configuration, $configs);
$loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
if ('custom' !== $config['db_driver']) {
if (isset(self::$doctrineDrivers[$config['db_driver']])) {
$loader->load('doctrine.xml');
$container->setAlias('fos_user.doctrine_registry', new Alias(self::$doctrineDrivers[$config['db_driver']]['registry'], false));
} else {
$loader->load(sprintf('%s.xml', $config['db_driver']));
}
$container->setParameter($this->getAlias().'.backend_type_'.$config['db_driver'], true);
}
if (isset(self::$doctrineDrivers[$config['db_driver']])) {
$definition = $container->getDefinition('fos_user.object_manager');
$definition->setFactory(array(new Reference('fos_user.doctrine_registry'), 'getManager'));
}
foreach (array('validator', 'security', 'util', 'mailer', 'listeners', 'commands') as $basename) {
$loader->load(sprintf('%s.xml', $basename));
}
if (!$config['use_authentication_listener']) {
$container->removeDefinition('fos_user.listener.authentication');
}
if ($config['use_flash_notifications']) {
$this->sessionNeeded = true;
$loader->load('flash_notifications.xml');
}
$container->setAlias('fos_user.util.email_canonicalizer', $config['service']['email_canonicalizer']);
$container->setAlias('fos_user.util.username_canonicalizer', $config['service']['username_canonicalizer']);
$container->setAlias('fos_user.util.token_generator', $config['service']['token_generator']);
$container->setAlias('fos_user.user_manager', new Alias($config['service']['user_manager'], true));
if ($config['use_listener'] && isset(self::$doctrineDrivers[$config['db_driver']])) {
$listenerDefinition = $container->getDefinition('fos_user.user_listener');
$listenerDefinition->addTag(self::$doctrineDrivers[$config['db_driver']]['tag']);
if (isset(self::$doctrineDrivers[$config['db_driver']]['listener_class'])) {
$listenerDefinition->setClass(self::$doctrineDrivers[$config['db_driver']]['listener_class']);
}
}
if ($config['use_username_form_type']) {
$loader->load('username_form_type.xml');
}
$this->remapParametersNamespaces($config, $container, array(
'' => array(
'db_driver' => 'fos_user.storage',
'firewall_name' => 'fos_user.firewall_name',
'model_manager_name' => 'fos_user.model_manager_name',
'user_class' => 'fos_user.model.user.class',
),
));
if (!empty($config['profile'])) {
$this->loadProfile($config['profile'], $container, $loader);
}
if (!empty($config['registration'])) {
$this->loadRegistration($config['registration'], $container, $loader, $config['from_email']);
}
if (!empty($config['change_password'])) {
$this->loadChangePassword($config['change_password'], $container, $loader);
}
if (!empty($config['resetting'])) {
$this->loadResetting($config['resetting'], $container, $loader, $config['from_email']);
}
if (!empty($config['group'])) {
$this->loadGroups($config['group'], $container, $loader, $config['db_driver']);
}
if ($this->mailerNeeded) {
$container->setAlias('fos_user.mailer', $config['service']['mailer']);
}
if ($this->sessionNeeded) {
// Use a private alias rather than a parameter, to avoid leaking it at runtime (the private alias will be removed)
$container->setAlias('fos_user.session', new Alias('session', false));
}
}
/**
* {@inheritdoc}
*/
public function getNamespace()
{
return 'http://friendsofsymfony.github.io/schema/dic/user';
}
/**
* @param array $config
* @param ContainerBuilder $container
* @param array $map
*/
protected function remapParameters(array $config, ContainerBuilder $container, array $map)
{
foreach ($map as $name => $paramName) {
if (array_key_exists($name, $config)) {
$container->setParameter($paramName, $config[$name]);
}
}
}
/**
* @param array $config
* @param ContainerBuilder $container
* @param array $namespaces
*/
protected function remapParametersNamespaces(array $config, ContainerBuilder $container, array $namespaces)
{
foreach ($namespaces as $ns => $map) {
if ($ns) {
if (!array_key_exists($ns, $config)) {
continue;
}
$namespaceConfig = $config[$ns];
} else {
$namespaceConfig = $config;
}
if (is_array($map)) {
$this->remapParameters($namespaceConfig, $container, $map);
} else {
foreach ($namespaceConfig as $name => $value) {
$container->setParameter(sprintf($map, $name), $value);
}
}
}
}
/**
* @param array $config
* @param ContainerBuilder $container
* @param XmlFileLoader $loader
*/
private function loadProfile(array $config, ContainerBuilder $container, XmlFileLoader $loader)
{
$loader->load('profile.xml');
$this->remapParametersNamespaces($config, $container, array(
'form' => 'fos_user.profile.form.%s',
));
}
/**
* @param array $config
* @param ContainerBuilder $container
* @param XmlFileLoader $loader
* @param array $fromEmail
*/
private function loadRegistration(array $config, ContainerBuilder $container, XmlFileLoader $loader, array $fromEmail)
{
$loader->load('registration.xml');
$this->sessionNeeded = true;
if ($config['confirmation']['enabled']) {
$this->mailerNeeded = true;
$loader->load('email_confirmation.xml');
}
if (isset($config['confirmation']['from_email'])) {
// overwrite the global one
$fromEmail = $config['confirmation']['from_email'];
unset($config['confirmation']['from_email']);
}
$container->setParameter('fos_user.registration.confirmation.from_email', array($fromEmail['address'] => $fromEmail['sender_name']));
$this->remapParametersNamespaces($config, $container, array(
'confirmation' => 'fos_user.registration.confirmation.%s',
'form' => 'fos_user.registration.form.%s',
));
}
/**
* @param array $config
* @param ContainerBuilder $container
* @param XmlFileLoader $loader
*/
private function loadChangePassword(array $config, ContainerBuilder $container, XmlFileLoader $loader)
{
$loader->load('change_password.xml');
$this->remapParametersNamespaces($config, $container, array(
'form' => 'fos_user.change_password.form.%s',
));
}
/**
* @param array $config
* @param ContainerBuilder $container
* @param XmlFileLoader $loader
* @param array $fromEmail
*/
private function loadResetting(array $config, ContainerBuilder $container, XmlFileLoader $loader, array $fromEmail)
{
$this->mailerNeeded = true;
$loader->load('resetting.xml');
if (isset($config['email']['from_email'])) {
// overwrite the global one
$fromEmail = $config['email']['from_email'];
unset($config['email']['from_email']);
}
$container->setParameter('fos_user.resetting.email.from_email', array($fromEmail['address'] => $fromEmail['sender_name']));
$this->remapParametersNamespaces($config, $container, array(
'' => array(
'retry_ttl' => 'fos_user.resetting.retry_ttl',
'token_ttl' => 'fos_user.resetting.token_ttl',
),
'email' => 'fos_user.resetting.email.%s',
'form' => 'fos_user.resetting.form.%s',
));
}
/**
* @param array $config
* @param ContainerBuilder $container
* @param XmlFileLoader $loader
* @param string $dbDriver
*/
private function loadGroups(array $config, ContainerBuilder $container, XmlFileLoader $loader, $dbDriver)
{
$loader->load('group.xml');
if ('custom' !== $dbDriver) {
if (isset(self::$doctrineDrivers[$dbDriver])) {
$loader->load('doctrine_group.xml');
} else {
$loader->load(sprintf('%s_group.xml', $dbDriver));
}
}
$container->setAlias('fos_user.group_manager', new Alias($config['group_manager'], true));
$container->setAlias('FOS\UserBundle\Model\GroupManagerInterface', new Alias('fos_user.group_manager', false));
$this->remapParametersNamespaces($config, $container, array(
'' => array(
'group_class' => 'fos_user.model.group.class',
),
'form' => 'fos_user.group.form.%s',
));
}
}