Code Coverage
 
Classes and Traits
Functions and Methods
Lines
Total
n/a
0 / 0
n/a
0 / 0
CRAP
n/a
0 / 0
GNUsocial
n/a
0 / 0
n/a
0 / 0
10
n/a
0 / 0
 __construct
n/a
0 / 0
1
n/a
0 / 0
 initialize
n/a
0 / 0
3
n/a
0 / 0
 onKernelRequest
n/a
0 / 0
4
n/a
0 / 0
 onCommand
n/a
0 / 0
1
n/a
0 / 0
 getSubscribedEvents
n/a
0 / 0
1
n/a
0 / 0
1<?php
2
3// {{{ License
4
5// This file is part of GNU social - https://www.gnu.org/software/social
6//
7// GNU social is free software: you can redistribute it and/or modify
8// it under the terms of the GNU Affero General Public License as published by
9// the Free Software Foundation, either version 3 of the License, or
10// (at your option) any later version.
11//
12// GNU social is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15// GNU Affero General Public License for more details.
16//
17// You should have received a copy of the GNU Affero General Public License
18// along with GNU social.  If not, see <http://www.gnu.org/licenses/>.
19
20// }}}
21
22/**
23 * Main GNU social entry point
24 *
25 * @package   GNUsocial
26 * @category  Framework
27 *
28 * StatusNet and GNU social 1
29 *
30 * @author    Refer to CREDITS.md
31 * @copyright 2010 Free Software Foundation, Inc http://www.fsf.org
32 *
33 * GNU social 2
34 * @author    Bruno Casteleiro <brunoccast@fc.up.pt>
35 * @author    Diogo Cordeiro <diogo@fc.up.pt>
36 *
37 * GNU social 3
38 * @author    Hugo Sales <hugo@hsal.es>
39 * @copyright 2018-2021 Free Software Foundation, Inc http://www.fsf.org
40 * @license   https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
41 */
42
43namespace App\Core;
44
45use App\Core\DB\DB;
46use App\Core\I18n\I18n;
47use App\Core\Queue\Queue;
48use App\Core\Router\Router;
49use App\Security\EmailVerifier;
50use App\Util\Common;
51use App\Util\Exception\ConfigurationException;
52use App\Util\Formatting;
53use Doctrine\ORM\EntityManagerInterface;
54use HtmlSanitizer\SanitizerInterface;
55use Psr\Log\LoggerInterface;
56use Symfony\Component\Console\Event\ConsoleCommandEvent;
57use Symfony\Component\DependencyInjection\ParameterBag\ContainerBagInterface;
58use Symfony\Component\EventDispatcher\EventDispatcherInterface;
59use Symfony\Component\EventDispatcher\EventSubscriberInterface;
60use Symfony\Component\Form\FormFactoryInterface;
61use Symfony\Component\HttpFoundation\Request;
62use Symfony\Component\HttpFoundation\RequestStack;
63use Symfony\Component\HttpFoundation\Session\SessionInterface;
64use Symfony\Component\HttpKernel\Event\RequestEvent;
65use Symfony\Component\HttpKernel\KernelEvents;
66use Symfony\Component\Mailer\MailerInterface;
67use Symfony\Component\Messenger\MessageBusInterface;
68use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
69use Symfony\Component\Routing\RouterInterface;
70use Symfony\Component\Security\Core\Security as SSecurity;
71use Symfony\Component\Security\Http\Util\TargetPathTrait;
72use Symfony\Contracts\HttpClient\HttpClientInterface;
73use Symfony\Contracts\Translation\TranslatorInterface;
74use SymfonyCasts\Bundle\ResetPassword\ResetPasswordHelperInterface;
75use SymfonyCasts\Bundle\VerifyEmail\VerifyEmailHelperInterface;
76use Twig\Environment;
77
78/**
79 * @codeCoverageIgnore
80 */
81class GNUsocial implements EventSubscriberInterface
82{
83    use TargetPathTrait;
84
85    protected bool $initialized = false;
86    protected LoggerInterface $logger;
87    protected TranslatorInterface $translator;
88    protected EntityManagerInterface $entity_manager;
89    protected RouterInterface $router;
90    protected UrlGeneratorInterface $url_generator;
91    protected FormFactoryInterface $form_factory;
92    protected MessageBusInterface $message_bus;
93    protected EventDispatcherInterface $event_dispatcher;
94    protected SessionInterface $session;
95    protected SSecurity $security;
96    protected ModuleManager $module_manager;
97    protected HttpClientInterface $client;
98    protected SanitizerInterface $sanitizer;
99    protected ContainerBagInterface $config;
100    protected Environment $twig;
101    protected ?Request $request;
102    protected MailerInterface $mailer_helper;
103    protected VerifyEmailHelperInterface $email_verify_helper;
104    protected ResetPasswordHelperInterface $reset_password_helper;
105
106    /**
107     * Symfony dependency injection gives us access to these services
108     */
109    public function __construct(LoggerInterface $logger,
110                                TranslatorInterface $trans,
111                                EntityManagerInterface $em,
112                                RouterInterface $router,
113                                UrlGeneratorInterface $url_gen,
114                                FormFactoryInterface $ff,
115                                MessageBusInterface $mb,
116                                EventDispatcherInterface $ed,
117                                SessionInterface $sess,
118                                SSecurity $sec,
119                                ModuleManager $mm,
120                                HttpClientInterface $cl,
121                                SanitizerInterface $san,
122                                ContainerBagInterface $conf,
123                                Environment $twig,
124                                RequestStack $request_stack,
125                                MailerInterface $mailer,
126                                VerifyEmailHelperInterface $email_verify_helper,
127                                ResetPasswordHelperInterface $reset_helper)
128    {
129        $this->logger                = $logger;
130        $this->translator            = $trans;
131        $this->entity_manager        = $em;
132        $this->router                = $router;
133        $this->url_generator         = $url_gen;
134        $this->form_factory          = $ff;
135        $this->message_bus           = $mb;
136        $this->event_dispatcher      = $ed;
137        $this->session               = $sess;
138        $this->security              = $sec;
139        $this->module_manager        = $mm;
140        $this->client                = $cl;
141        $this->sanitizer             = $san;
142        $this->config                = $conf;
143        $this->twig                  = $twig;
144        $this->request               = $request_stack->getCurrentRequest();
145        $this->mailer_helper         = $mailer;
146        $this->email_verify_helper   = $email_verify_helper;
147        $this->reset_password_helper = $reset_helper;
148
149        $this->initialize();
150    }
151
152    /**
153     * Store these services to be accessed statically and load modules
154     *
155     * @throws ConfigurationException
156     */
157    public function initialize(): void
158    {
159        if (!$this->initialized) {
160            Common::setupConfig($this->config);
161            if (!is_null($this->request)) {
162                Common::setRequest($this->request);
163            }
164            Log::setLogger($this->logger);
165            Event::setDispatcher($this->event_dispatcher);
166            I18n::setTranslator($this->translator);
167            DB::setManager($this->entity_manager);
168            Form::setFactory($this->form_factory);
169            Queue::setMessageBus($this->message_bus);
170            Security::setHelper($this->security, $this->sanitizer);
171            Router::setRouter($this->router, $this->url_generator);
172            HTTPClient::setClient($this->client);
173            Formatting::setTwig($this->twig);
174            Cache::setupCache();
175            EmailVerifier::setEmailHelpers($this->mailer_helper, $this->email_verify_helper, $this->reset_password_helper);
176
177            DB::initTableMap();
178
179            // Events are proloaded on compilation, but set at runtime
180            $this->module_manager->loadModules();
181
182            $this->initialized = true;
183        }
184    }
185
186    /**
187     * Event very early on in the Symfony HTTP lifecycle, but after everything is registered
188     * where we get access to the event dispatcher
189     *
190     * @param RequestEvent $event
191     *
192     * @return RequestEvent
193     */
194    public function onKernelRequest(RequestEvent $event): RequestEvent
195    {
196        $this->request = $event->getRequest();
197
198        // Save the target path, so we can redirect back after logging in
199        if (!(!$event->isMasterRequest() || $this->request->isXmlHttpRequest() || Common::isRoute(['login', 'register', 'logout']))) {
200            $this->saveTargetPath($this->session, 'main', $this->request->getBaseUrl());
201        }
202
203        $this->initialize();
204        return $event;
205    }
206
207    /**
208     * Event after everything is initialized when using the `bin/console` command
209     *
210     * @param ConsoleCommandEvent $event
211     *
212     * @throws ConfigurationException
213     *
214     * @return ConsoleCommandEvent
215     */
216    public function onCommand(ConsoleCommandEvent $event): ConsoleCommandEvent
217    {
218        $this->initialize();
219        return $event;
220    }
221
222    /**
223     * Tell Symfony which events we want to listen to, which Symfony detects and auto-wires
224     * due to this implementing the `EventSubscriberInterface`
225     *
226     */
227    public static function getSubscribedEvents(): array
228    {
229        return [
230            KernelEvents::REQUEST => 'onKernelRequest',
231            'console.command'     => 'onCommand',
232        ];
233    }
234}