From 3c006cb86e14568cf533f9534e98e77c817170e2 Mon Sep 17 00:00:00 2001 From: Seamus Lee <seamuslee001@gmail.com> Date: Sun, 24 May 2020 07:25:13 +1000 Subject: [PATCH] WIP allow for installation on Symfony 4.4 --- Civi/Api4/services.xml | 8 ++-- Civi/Core/CiviEventDispatcher.php | 75 ++++++++++++++++++++++++++++++- Civi/Core/Container.php | 52 ++++++++++----------- composer.json | 12 ++--- composer.lock | 2 +- tests/phpunit/api/v4/services.xml | 2 +- 6 files changed, 111 insertions(+), 40 deletions(-) diff --git a/Civi/Api4/services.xml b/Civi/Api4/services.xml index 3d8a2fcab1..630a646326 100644 --- a/Civi/Api4/services.xml +++ b/Civi/Api4/services.xml @@ -4,21 +4,21 @@ <services> - <service id="spec_gatherer" class="Civi\Api4\Service\Spec\SpecGatherer"/> + <service id="spec_gatherer" class="Civi\Api4\Service\Spec\SpecGatherer" public="true"/> <service id="schema_map_builder" class="Civi\Api4\Service\Schema\SchemaMapBuilder" public="false"> <argument type="service" id="dispatcher" /> </service> - <service id="schema_map" class="Civi\Api4\Service\Schema\SchemaMap"> + <service id="schema_map" class="Civi\Api4\Service\Schema\SchemaMap" public="true"> <factory service="schema_map_builder" method="build"/> </service> - <service id="joiner" class="Civi\Api4\Service\Schema\Joiner"> + <service id="joiner" class="Civi\Api4\Service\Schema\Joiner" public="true"> <argument type="service" id="schema_map"/> </service> - <service id="action_object_provider" class="Civi\Api4\Provider\ActionObjectProvider"> + <service id="action_object_provider" class="Civi\Api4\Provider\ActionObjectProvider" public="true"> <tag name="event_subscriber"/> </service> diff --git a/Civi/Core/CiviEventDispatcher.php b/Civi/Core/CiviEventDispatcher.php index 18d8aa3043..f6f6479b96 100644 --- a/Civi/Core/CiviEventDispatcher.php +++ b/Civi/Core/CiviEventDispatcher.php @@ -2,7 +2,7 @@ namespace Civi\Core; -use Symfony\Component\EventDispatcher\ContainerAwareEventDispatcher; +use Symfony\Component\EventDispatcher\EventDispatcher; use Symfony\Component\EventDispatcher\Event; /** @@ -15,7 +15,7 @@ use Symfony\Component\EventDispatcher\Event; * * @see \CRM_Utils_Hook */ -class CiviEventDispatcher extends ContainerAwareEventDispatcher { +class CiviEventDispatcher extends EventDispatcher { const DEFAULT_HOOK_PRIORITY = -100; @@ -172,6 +172,7 @@ class CiviEventDispatcher extends ContainerAwareEventDispatcher { */ protected function bindPatterns($eventName) { if ($eventName !== NULL && !isset($this->autoListeners[$eventName])) { + $this->lazyLoad($eventName); $this->autoListeners[$eventName] = 1; if ($this->isHookEvent($eventName)) { // WISHLIST: For native extensions (and possibly D6/D7/D8/BD), enumerate @@ -183,6 +184,11 @@ class CiviEventDispatcher extends ContainerAwareEventDispatcher { ], self::DEFAULT_HOOK_PRIORITY); } } + elseif (NULL === $eventName) { + foreach ($this->listenerIds as $serviceEventName => $args) { + $this->lazyLoad($serviceEventName); + } + } } /** @@ -250,4 +256,69 @@ class CiviEventDispatcher extends ContainerAwareEventDispatcher { return 'fail'; } + public function addListenerService($eventName, $callback, $priority = 0) { + if (!\is_array($callback) || 2 !== \count($callback)) { + throw new \InvalidArgumentException('Expected an array("service", "method") argument'); + } + $this->listenerIds[$eventName][] = array( + $callback[0], + $callback[1], + $priority, + ); + } + + public function addSubscriberService($serviceId, $class) { + foreach ($class::getSubscribedEvents() as $eventName => $params) { + if (\is_string($params)) { + $this->listenerIds[$eventName][] = array( + $serviceId, + $params, + 0, + ); + } + elseif (\is_string($params[0])) { + $this->listenerIds[$eventName][] = array( + $serviceId, + $params[0], + isset($params[1]) ? $params[1] : 0, + ); + } + else { + foreach ($params as $listener) { + $this->listenerIds[$eventName][] = array( + $serviceId, + $listener[0], + isset($listener[1]) ? $listener[1] : 0, + ); + } + } + } + } + + /** + * Lazily loads listeners for this event from the dependency injection + * container. + * + * @param string $eventName The name of the event to dispatch. The name of + * the event is the name of the method that is + * invoked on listeners. + */ + protected function lazyLoad($eventName) { + if (isset($this->listenerIds[$eventName])) { + foreach ($this->listenerIds[$eventName] as list($serviceId, $method, $priority)) { + $listener = \Civi\Core\Container::singleton()->get($serviceId); + $key = $serviceId . '.' . $method; + if (!isset($this->listeners[$eventName][$key])) { + $this->addListener($eventName, array($listener, $method), $priority); + } + elseif ($this->listeners[$eventName][$key] !== $listener) { + parent::removeListener($eventName, array($this->listeners[$eventName][$key], $method)); + $this->addListener($eventName, array($listener, $method), $priority); + } + + $this->listeners[$eventName][$key] = $listener; + } + } + } + } diff --git a/Civi/Core/Container.php b/Civi/Core/Container.php index 5e064cae44..15c7860a9d 100644 --- a/Civi/Core/Container.php +++ b/Civi/Core/Container.php @@ -121,32 +121,32 @@ class Container { 'Civi\Angular\Manager', [] )) - ->setFactory([new Reference(self::SELF), 'createAngularManager']); + ->setFactory([new Reference(self::SELF), 'createAngularManager'])->setPublic(TRUE); $container->setDefinition('dispatcher', new Definition( 'Civi\Core\CiviEventDispatcher', [new Reference('service_container')] )) - ->setFactory([new Reference(self::SELF), 'createEventDispatcher']); + ->setFactory([new Reference(self::SELF), 'createEventDispatcher'])->setPublic(TRUE); $container->setDefinition('magic_function_provider', new Definition( 'Civi\API\Provider\MagicFunctionProvider', [] - )); + ))->setPublic(TRUE); $container->setDefinition('civi_api_kernel', new Definition( 'Civi\API\Kernel', [new Reference('dispatcher'), new Reference('magic_function_provider')] )) - ->setFactory([new Reference(self::SELF), 'createApiKernel']); + ->setFactory([new Reference(self::SELF), 'createApiKernel'])->setPublic(TRUE); $container->setDefinition('cxn_reg_client', new Definition( 'Civi\Cxn\Rpc\RegistrationClient', [] )) - ->setFactory('CRM_Cxn_BAO_Cxn::createRegistrationClient'); + ->setFactory('CRM_Cxn_BAO_Cxn::createRegistrationClient')->setPublic(TRUE); - $container->setDefinition('psr_log', new Definition('CRM_Core_Error_Log', [])); + $container->setDefinition('psr_log', new Definition('CRM_Core_Error_Log', []))->setPublic(TRUE); $basicCaches = [ 'js_strings' => 'js_strings', @@ -176,7 +176,7 @@ class Container { $container->setDefinition("cache.{$cacheSvc}", new Definition( 'CRM_Utils_Cache_Interface', [$definitionParams] - ))->setFactory('CRM_Utils_Cache::create'); + ))->setFactory('CRM_Utils_Cache::create')->setPublic(TRUE); } // PrevNextCache cannot use memory or array cache at the moment because the @@ -189,22 +189,22 @@ class Container { 'type' => ['SqlGroup'], ], ] - ))->setFactory('CRM_Utils_Cache::create'); + ))->setFactory('CRM_Utils_Cache::create')->setPublic(TRUE); $container->setDefinition('sql_triggers', new Definition( 'Civi\Core\SqlTriggers', [] - )); + ))->setPublic(TRUE); $container->setDefinition('asset_builder', new Definition( 'Civi\Core\AssetBuilder', [] - )); + ))->setPublic(TRUE); $container->setDefinition('themes', new Definition( 'Civi\Core\Themes', [] - )); + ))->setPublic(TRUE); $container->setDefinition('pear_mail', new Definition('Mail')) ->setFactory('CRM_Utils_Mail::createMailer'); @@ -228,47 +228,47 @@ class Container { $container->setDefinition($name, new Definition( $class )) - ->setFactory([$class, 'singleton']); + ->setFactory([$class, 'singleton'])->setPublic(TRUE); } $container->setAlias('cache.short', 'cache.default'); $container->setDefinition('resources', new Definition( 'CRM_Core_Resources', [new Reference('service_container')] - ))->setFactory([new Reference(self::SELF), 'createResources']); + ))->setFactory([new Reference(self::SELF), 'createResources'])->setPublic(TRUE); $container->setDefinition('prevnext', new Definition( 'CRM_Core_PrevNextCache_Interface', [new Reference('service_container')] - ))->setFactory([new Reference(self::SELF), 'createPrevNextCache']); + ))->setFactory([new Reference(self::SELF), 'createPrevNextCache'])->setPublic(TRUE); $container->setDefinition('prevnext.driver.sql', new Definition( 'CRM_Core_PrevNextCache_Sql', [] - )); + ))->setPublic(TRUE); $container->setDefinition('prevnext.driver.redis', new Definition( 'CRM_Core_PrevNextCache_Redis', [new Reference('cache_config')] - )); + ))->setPublic(TRUE); $container->setDefinition('cache_config', new Definition('ArrayObject')) - ->setFactory([new Reference(self::SELF), 'createCacheConfig']); + ->setFactory([new Reference(self::SELF), 'createCacheConfig'])->setPublic(TRUE); $container->setDefinition('civi.mailing.triggers', new Definition( 'Civi\Core\SqlTrigger\TimestampTriggers', ['civicrm_mailing', 'Mailing'] - ))->addTag('kernel.event_listener', ['event' => 'hook_civicrm_triggerInfo', 'method' => 'onTriggerInfo']); + ))->addTag('kernel.event_listener', ['event' => 'hook_civicrm_triggerInfo', 'method' => 'onTriggerInfo'])->setPublic(TRUE); $container->setDefinition('civi.activity.triggers', new Definition( 'Civi\Core\SqlTrigger\TimestampTriggers', ['civicrm_activity', 'Activity'] - ))->addTag('kernel.event_listener', ['event' => 'hook_civicrm_triggerInfo', 'method' => 'onTriggerInfo']); + ))->addTag('kernel.event_listener', ['event' => 'hook_civicrm_triggerInfo', 'method' => 'onTriggerInfo'])->setPublic(TRUE); $container->setDefinition('civi.case.triggers', new Definition( 'Civi\Core\SqlTrigger\TimestampTriggers', ['civicrm_case', 'Case'] - ))->addTag('kernel.event_listener', ['event' => 'hook_civicrm_triggerInfo', 'method' => 'onTriggerInfo']); + ))->addTag('kernel.event_listener', ['event' => 'hook_civicrm_triggerInfo', 'method' => 'onTriggerInfo'])->setPublic(TRUE); $container->setDefinition('civi.case.staticTriggers', new Definition( 'Civi\Core\SqlTrigger\StaticTriggers', @@ -291,22 +291,22 @@ class Container { ], ] )) - ->addTag('kernel.event_listener', ['event' => 'hook_civicrm_triggerInfo', 'method' => 'onTriggerInfo']); + ->addTag('kernel.event_listener', ['event' => 'hook_civicrm_triggerInfo', 'method' => 'onTriggerInfo'])->setPublic(TRUE); $container->setDefinition('civi_token_compat', new Definition( 'Civi\Token\TokenCompatSubscriber', [] - ))->addTag('kernel.event_subscriber'); + ))->addTag('kernel.event_subscriber')->setPublic(TRUE); $container->setDefinition("crm_mailing_action_tokens", new Definition( "CRM_Mailing_ActionTokens", [] - ))->addTag('kernel.event_subscriber'); + ))->addTag('kernel.event_subscriber')->setPublic(TRUE); foreach (['Activity', 'Contribute', 'Event', 'Mailing', 'Member'] as $comp) { $container->setDefinition("crm_" . strtolower($comp) . "_tokens", new Definition( "CRM_{$comp}_Tokens", [] - ))->addTag('kernel.event_subscriber'); + ))->addTag('kernel.event_subscriber')->setPublic(TRUE); } \CRM_Api4_Services::hook_container($container); @@ -325,10 +325,10 @@ class Container { /** * @param \Symfony\Component\DependencyInjection\ContainerInterface $container - * @return \Symfony\Component\EventDispatcher\ContainerAwareEventDispatcher + * @return \Symfony\Component\EventDispatcher\EventDispatcher */ public function createEventDispatcher($container) { - $dispatcher = new CiviEventDispatcher($container); + $dispatcher = new CiviEventDispatcher(); if (\CRM_Core_Config::isUpgradeMode()) { $dispatcher->setDispatchPolicy(\CRM_Upgrade_DispatchPolicy::get('upgrade.main')); } diff --git a/composer.json b/composer.json index 6e414e4c66..00be366247 100644 --- a/composer.json +++ b/composer.json @@ -46,14 +46,14 @@ "cache/integration-tests": "~0.16.0", "dompdf/dompdf" : "0.8.*", "electrolinux/phpquery": "^0.9.6", - "symfony/config": "^2.8.50 || ~3.0", + "symfony/config": "^2.8.50 || ~3.0 || ~4.4", "symfony/polyfill-iconv": "~1.0", - "symfony/dependency-injection": "^2.8.50 || ~3.0", - "symfony/event-dispatcher": "^2.8.50 || ~3.0", - "symfony/filesystem": "^2.8.50 || ~3.0", - "symfony/process": "^2.8.50 || ~3.0", + "symfony/dependency-injection": "^2.8.50 || ~3.0 || ~4.4", + "symfony/event-dispatcher": "^2.8.50 || ~3.0 || ~4.4", + "symfony/filesystem": "^2.8.50 || ~3.0 || ~4.4", + "symfony/process": "^2.8.50 || ~3.0 || ~4.4", "psr/log": "~1.0", - "symfony/finder": "^2.8.50 || ~3.0", + "symfony/finder": "^2.8.50 || ~3.0 || ~4.4", "tecnickcom/tcpdf" : "6.2.*", "totten/ca-config": "~17.05", "zetacomponents/base": "1.9.*", diff --git a/composer.lock b/composer.lock index 42f872a30d..4b4be4b0cd 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "00d8b8be8e838f8ff098162f88af562c", + "content-hash": "1d40b2baf2c31338ed7e628dfbba3d2a", "packages": [ { "name": "adrienrn/php-mimetyper", diff --git a/tests/phpunit/api/v4/services.xml b/tests/phpunit/api/v4/services.xml index 3310b03e93..e5e9c69035 100644 --- a/tests/phpunit/api/v4/services.xml +++ b/tests/phpunit/api/v4/services.xml @@ -3,7 +3,7 @@ xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> <services> - <service id="test.param_provider" class="api\v4\Service\TestCreationParameterProvider"> + <service id="test.param_provider" class="api\v4\Service\TestCreationParameterProvider" public="true"> <argument type="service" id="spec_gatherer"/> </service> </services> -- 2.25.1