Completed
Push — master ( f62bdf...e30c7e )
by Alexis
01:32
created

SilexUserServiceProvider::validateOptions()   B

Complexity

Conditions 5
Paths 4

Size

Total Lines 14
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 14
rs 8.8571
cc 5
eloc 7
nc 4
nop 1
1
<?php
2
3
namespace AWurth\SilexUser\Provider;
4
5
use AWurth\SilexUser\Controller\AuthController;
6
use AWurth\SilexUser\Controller\RegistrationController;
7
use AWurth\SilexUser\Entity\UserManager;
8
use AWurth\SilexUser\EventListener\AuthenticationListener;
9
use AWurth\SilexUser\EventListener\EmailConfirmationListener;
10
use AWurth\SilexUser\EventListener\FlashListener;
11
use AWurth\SilexUser\Mailer\TwigSwiftMailer;
12
use AWurth\SilexUser\Security\LoginManager;
13
use LogicException;
14
use Pimple\Container;
15
use Pimple\ServiceProviderInterface;
16
use Silex\Api\BootableProviderInterface;
17
use Silex\Api\ControllerProviderInterface;
18
use Silex\Api\EventListenerProviderInterface;
19
use Silex\Application;
20
use Silex\ControllerCollection;
21
use Silex\ServiceControllerResolver;
22
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
23
use Symfony\Component\Translation\Loader\PhpFileLoader;
24
use Symfony\Component\Translation\Translator;
25
26
/**
27
 * Silex User Service Provider.
28
 *
29
 * @author Alexis Wurth <[email protected]>
30
 */
31
class SilexUserServiceProvider implements ServiceProviderInterface, BootableProviderInterface, ControllerProviderInterface, EventListenerProviderInterface
32
{
33
    protected static $defaultOptions = [
34
        'use_routes' => true,
35
        'use_templates' => true,
36
        'use_translations' => true,
37
        'use_flash_notifications' => true,
38
        'use_authentication_listener' => false,
39
        'registration.confirmation.enabled' => false,
40
        'registration.confirmation.from_email' => ''
41
    ];
42
43
    protected static $dependencies = [
44
        'twig' => 'TwigServiceProvider',
45
        'session' => 'SessionServiceProvider',
46
        'translator' => 'TranslationServiceProvider',
47
        'validator' => 'ValidatorServiceProvider',
48
        'form.factory' => 'FormServiceProvider',
49
        'orm.em' => 'DoctrineOrmServiceProvider',
50
        'security.token_storage' => 'SecurityServiceProvider'
51
    ];
52
53
    /**
54
     * {@inheritdoc}
55
     */
56
    public function register(Container $app)
57
    {
58
        if (!$app['resolver'] instanceof ServiceControllerResolver) {
59
            throw new LogicException('You must register the ServiceControllerServiceProvider to use the SilexUserServiceProvider');
60
        }
61
62
        foreach (self::$dependencies as $key => $provider) {
63
            if (!isset($app[$key])) {
64
                throw new LogicException('You must register the ' . $provider . ' to use the SilexUserServiceProvider');
65
            }
66
        }
67
68
        $app['silex_user.options'] = [];
69
70
        // Services
71
        $app['silex_user.user_manager'] = function ($app) {
72
            return new UserManager($app);
73
        };
74
75
        $app['silex_user.login_manager'] = function ($app) {
76
            return new LoginManager(
77
                $app['security.token_storage'],
78
                $app['security.user_checker'],
79
                $app['security.session_strategy'],
80
                $app['request_stack']
81
            );
82
        };
83
84
        $app['silex_user.user_provider.username'] = function ($app) {
85
            return new UserProvider($app['silex_user.user_manager']);
86
        };
87
88
        $app['silex_user.user_provider.username_email'] = function ($app) {
89
            return new EmailUserProvider($app['silex_user.user_manager']);
90
        };
91
92
        $app['silex_user.mailer'] = function ($app) {
93
            if (isset($app['mailer']) && get_class($app['mailer']) === 'Swift_Mailer') {
94
                $parameters = [
95
                    'from_email' => [
96
                        'confirmation' => $this->getOption($app, 'registration.confirmation.from_email')
97
                    ]
98
                ];
99
100
                return new TwigSwiftMailer($app['mailer'], $app['twig'], $app['url_generator'], $parameters);
101
            }
102
103
            return null;
104
        };
105
106
        // Controllers
107
        $app['auth.controller'] = function ($app) {
108
            return new AuthController($app);
109
        };
110
111
        $app['registration.controller'] = function ($app) {
112
            return new RegistrationController($app);
113
        };
114
    }
115
116
    /**
117
     * {@inheritdoc}
118
     */
119
    public function boot(Application $app)
120
    {
121
        $app['silex_user.options'] = array_replace(self::$defaultOptions, $app['silex_user.options']);
122
123
        $this->validateOptions($app);
124
125
        if (true === $this->getOption($app, 'use_templates')) {
126
            $app['twig.loader.filesystem']->addPath(dirname(__DIR__) . '/Resources/views/');
127
        }
128
129
        if (true === $this->getOption($app, 'use_translations')) {
130
            /** @var Translator $translator */
131
            $translator = $app['translator'];
132
            $translationsDir = dirname(__DIR__) . '/Resources/translations';
133
134
            $translator->addLoader('php', new PhpFileLoader());
135
136
            $translator->addResource('php', $translationsDir . '/silex_user.en.php', 'en', 'silex_user');
137
            $translator->addResource('php', $translationsDir . '/silex_user.fr.php', 'fr', 'silex_user');
138
            $translator->addResource('php', $translationsDir . '/validators.en.php', 'en', 'validators');
139
            $translator->addResource('php', $translationsDir . '/validators.fr.php', 'fr', 'validators');
140
        }
141
142
        if (true === $this->getOption($app, 'use_routes')) {
143
            $app->mount('/', $this->connect($app));
0 ignored issues
show
Documentation introduced by
$this->connect($app) is of type object<Silex\ControllerCollection>, but the function expects a callable.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
144
        }
145
    }
146
147
    /**
148
     * {@inheritdoc}
149
     */
150
    public function connect(Application $app)
151
    {
152
        /** @var ControllerCollection $controllers */
153
        $controllers = $app['controllers_factory'];
154
155
        $controllers->get('/login', 'auth.controller:loginAction')
156
            ->bind('silex_user.login');
157
158
        $controllers->method('GET|POST')
159
            ->match('/login_check')
160
            ->bind('silex_user.login_check');
161
162
        $controllers->method('GET|POST')
163
            ->match('/logout')
164
            ->bind('silex_user.logout');
165
166
        $controllers->method('GET|POST')
167
            ->match('/register', 'registration.controller:registerAction')
168
            ->bind('silex_user.register');
169
170
        $controllers->get('/register/confirmed', 'registration.controller:confirmedAction')
171
            ->bind('silex_user.registration_confirmed');
172
173
        if (true === $this->getOption($app, 'registration.confirmation.enabled')) {
174
            $controllers->get('/register/check-email', 'registration.controller:checkEmailAction')
175
                ->bind('silex_user.registration_check_email');
176
177
            $controllers->get('/register/confirm/{token}', 'registration.controller:confirmAction')
178
                ->bind('silex_user.registration_confirm');
179
        }
180
181
        return $controllers;
182
    }
183
184
    /**
185
     * {@inheritdoc}
186
     */
187
    public function subscribe(Container $app, EventDispatcherInterface $dispatcher)
188
    {
189
        if (true === $this->getOption($app, 'use_authentication_listener')) {
190
            $dispatcher->addSubscriber(new AuthenticationListener($app['silex_user.login_manager'], $app['silex_user.options']['firewall_name']));
191
        }
192
193
        if (true === $this->getOption($app, 'use_flash_notifications')) {
194
            $dispatcher->addSubscriber(new FlashListener($app['session'], $app['translator']));
195
        }
196
197
        if (true === $this->getOption($app, 'registration.confirmation.enabled')) {
198
            if (null === $app['silex_user.mailer']) {
199
                throw new LogicException('You must configure a mailer to enable email notifications');
200
            }
201
202
            $dispatcher->addSubscriber(new EmailConfirmationListener($app['silex_user.mailer'], $app['url_generator'], $app['session']));
203
        }
204
    }
205
206
    /**
207
     * Gets an option or its default value if it is not set.
208
     *
209
     * @param Container $app
210
     * @param string $name
211
     *
212
     * @return mixed
213
     */
214
    protected function getOption(Container $app, $name)
215
    {
216
        if (isset($app['silex_user.options'][$name])) {
217
            return $app['silex_user.options'][$name];
218
        } else {
219
            return self::$defaultOptions[$name];
220
        }
221
    }
222
223
    /**
224
     * Checks if options are set correctly.
225
     *
226
     * @param Application $app
227
     */
228
    protected function validateOptions(Application $app)
229
    {
230
        if (empty($app['silex_user.options']['user_class'])) {
231
            throw new LogicException('The "user_class" option must be set');
232
        }
233
234
        if (empty($app['silex_user.options']['firewall_name'])) {
235
            throw new LogicException('The "firewall_name" option must be set');
236
        }
237
238
        if (true === $this->getOption($app, 'registration.confirmation.enabled') && empty($this->getOption($app, 'registration.confirmation.from_email'))) {
239
            throw new LogicException('The "registration.confirmation.from_email" option must be set');
240
        }
241
    }
242
}
243