GNUsocial.php 8.0 KB

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