Skip to content

Commit

Permalink
Merge pull request #24276 from totten/master-basic-svc
Browse files Browse the repository at this point in the history
Autoload services based on interfaces/annotations. Convert APIv4 services.
  • Loading branch information
colemanw authored Sep 16, 2022
2 parents 83cb873 + 420474e commit 5d37888
Show file tree
Hide file tree
Showing 87 changed files with 1,320 additions and 188 deletions.
77 changes: 0 additions & 77 deletions CRM/Api4/Services.php

This file was deleted.

9 changes: 9 additions & 0 deletions CRM/Extension/Manager.php
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,9 @@ public function replace($tmpCodeDir) {
}

$this->refresh();
// It might be useful to reset the container, but (given dev/core#3686) that's not likely to do much.
// \Civi::reset();
// \CRM_Core_Config::singleton(TRUE, TRUE);
CRM_Core_Invoke::rebuildMenuAndCaches(TRUE);
}

Expand Down Expand Up @@ -311,6 +314,8 @@ public function install($keys, $mode = 'install') {
$this->statuses = NULL;
$this->mapper->refresh();
if (!CRM_Core_Config::isUpgradeMode()) {
\Civi::reset();
\CRM_Core_Config::singleton(TRUE, TRUE);
CRM_Core_Invoke::rebuildMenuAndCaches(TRUE);

$schema = new CRM_Logging_Schema();
Expand Down Expand Up @@ -422,6 +427,8 @@ public function disable($keys) {

$this->statuses = NULL;
$this->mapper->refresh();
\Civi::reset();
\CRM_Core_Config::singleton(TRUE, TRUE);
CRM_Core_Invoke::rebuildMenuAndCaches(TRUE);

$this->popProcess($keys);
Expand Down Expand Up @@ -480,6 +487,8 @@ public function uninstall($keys) {

$this->statuses = NULL;
$this->mapper->refresh();
// At the analogous step of `install()` or `disable()`, it would reset the container.
// But here, the extension goes from "disabled=>uninstall". All we really need is to reconcile mgd's.
CRM_Core_Invoke::rebuildMenuAndCaches(TRUE);
$this->popProcess($keys);
}
Expand Down
5 changes: 4 additions & 1 deletion Civi/Api4/Event/Subscriber/ActivitySchemaMapSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@
use Civi\Api4\Service\Schema\Joinable\Joinable;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class ActivitySchemaMapSubscriber implements EventSubscriberInterface {
/**
* @service civi.api4.activitySchema
*/
class ActivitySchemaMapSubscriber extends \Civi\Core\Service\AutoService implements EventSubscriberInterface {

/**
* @return array
Expand Down
5 changes: 4 additions & 1 deletion Civi/Api4/Event/Subscriber/ContactSchemaMapSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@
use Civi\Api4\Service\Schema\Joinable\Joinable;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class ContactSchemaMapSubscriber implements EventSubscriberInterface {
/**
* @service civi.api4.contactSchema
*/
class ContactSchemaMapSubscriber extends \Civi\Core\Service\AutoService implements EventSubscriberInterface {

/**
* @return array
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
use Civi\API\Event\PrepareEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

abstract class AbstractPrepareSubscriber implements EventSubscriberInterface {
abstract class AbstractPrepareSubscriber extends \Civi\Core\Service\AutoService implements EventSubscriberInterface {

/**
* @return array
Expand Down
1 change: 1 addition & 0 deletions Civi/Api4/Event/Subscriber/IsCurrentSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
/**
* @deprecated
* @see \Civi\Api4\Generic\Traits\IsCurrentTrait
* @service civi.api4.isCurrent
*/
class IsCurrentSubscriber extends Generic\AbstractPrepareSubscriber {

Expand Down
4 changes: 3 additions & 1 deletion Civi/Api4/Event/Subscriber/PermissionCheckSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@
* For any API requests that correspond to a Doctrine entity
* ($apiRequest['doctrineClass']), check permissions specified in
* Civi\API\Annotation\Permission.
*
* @service civi.api4.permissionCheck
*/
class PermissionCheckSubscriber implements EventSubscriberInterface {
class PermissionCheckSubscriber extends \Civi\Core\Service\AutoService implements EventSubscriberInterface {

/**
* @return array
Expand Down
2 changes: 2 additions & 0 deletions Civi/Api4/Event/Subscriber/ValidateFieldsSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@

/**
* Validate field inputs based on annotations in the action class
*
* @service civi.api4.validateFields
*/
class ValidateFieldsSubscriber extends Generic\AbstractPrepareSubscriber {

Expand Down
5 changes: 4 additions & 1 deletion Civi/Api4/Provider/ActionObjectProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,15 @@
use Civi\API\Events;
use Civi\Api4\Utils\ReflectionUtils;
use Civi\Core\Event\GenericHookEvent;
use Civi\Core\Service\AutoService;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

/**
* Accept $apiRequests based on \Civi\API\Action
*
* @service action_object_provider
*/
class ActionObjectProvider implements EventSubscriberInterface, ProviderInterface {
class ActionObjectProvider extends AutoService implements EventSubscriberInterface, ProviderInterface {

/**
* @return array
Expand Down
75 changes: 75 additions & 0 deletions Civi/Api4/Service/LegacySpecScanner.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?php

namespace Civi\Api4\Service;

use Civi\Core\Service\AutoDefinition;
use Civi\Core\Service\AutoServiceInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;

/**
* This provides transitional support for extensions that implemented 'SpecProviderInterface'.
* Compare these contracts:
*
* - For v5.19-v5.53, an extension could create a class in '$EXT/Civi/Api4/Service/Spec/Provider'
* which implements 'SpecProviderInterface'. This would be auto-registered as a Symfony service
* and tagged with 'spec_provider'.
* - For v5.54+, an extension can enable `scan-classes@1`. Any classes in `$EXT/Civi` or `$EXT/CRM`
* will be scanned and registered, provided that they implement AutoServiceInterface and
* enable `scan-classes@1`.
*
* The 5.54+ scanner supports more interfaces and more options. However, it won't necessarily detect
* spec-providers from 5.19-5.53 (because they don't have `scan-classes@1` and they don't
* implement `AutoServiceInterface`).
*/
class LegacySpecScanner implements AutoServiceInterface {

public static function buildContainer(ContainerBuilder $container): void {
$classNames = static::findClasses('Civi\Api4\Service\Spec\Provider', $container);
foreach ($classNames as $className) {
$class = new \ReflectionClass($className);
if ($class->implementsInterface(AutoServiceInterface::class)) {
// This is already handled by the main scanner.
continue;
}
$container->addResource(new \Symfony\Component\Config\Resource\FileResource($class->getFileName()));
$name = $class->getName(); /* str_replace('\\', '_', $class->getName()); */
$definition = AutoDefinition::create($className)->addTag('internal');
$container->setDefinition($name, $definition);
}
}

/**
* Scan all extensions for files in a certain namespace.
*
* @param string $namespace
* @param \Symfony\Component\DependencyInjection\ContainerBuilder $container
* @return array
*/
protected static function findClasses($namespace, $container): array {
$classes = [];

$namespace = \CRM_Utils_File::addTrailingSlash($namespace, '\\');
$locations = array_merge([\Civi::paths()->getPath('[civicrm.root]/Civi.php')],
array_column(\CRM_Extension_System::singleton()->getMapper()->getActiveModuleFiles(), 'filePath')
);
foreach ($locations as $location) {
$path = \CRM_Utils_File::addTrailingSlash(dirname($location)) . str_replace('\\', DIRECTORY_SEPARATOR, $namespace);
if (!file_exists($path) || !is_dir($path)) {
$resource = new \Symfony\Component\Config\Resource\FileExistenceResource($path);
$container->addResource($resource);
}
else {
$resource = new \Symfony\Component\Config\Resource\DirectoryResource($path, ';\.php$;');
$container->addResource($resource);
foreach (glob("$path*.php") as $file) {
$matches = [];
preg_match('/(\w*)\.php$/', $file, $matches);
$classes[] = $namespace . array_pop($matches);
}
}
}

return $classes;
}

}
8 changes: 7 additions & 1 deletion Civi/Api4/Service/Schema/SchemaMapBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,14 @@
use Civi\Api4\Service\Schema\Joinable\CustomGroupJoinable;
use Civi\Api4\Service\Schema\Joinable\Joinable;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Civi\Core\Service\AutoService;
use CRM_Core_DAO_AllCoreTables as AllCoreTables;

class SchemaMapBuilder {
/**
* @service schema_map_builder
*/
class SchemaMapBuilder extends AutoService {

/**
* @var \Symfony\Component\EventDispatcher\EventDispatcherInterface
*/
Expand All @@ -32,6 +37,7 @@ class SchemaMapBuilder {

/**
* @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $dispatcher
* @inject dispatcher
*/
public function __construct(EventDispatcherInterface $dispatcher) {
$this->dispatcher = $dispatcher;
Expand Down
6 changes: 5 additions & 1 deletion Civi/Api4/Service/Spec/Provider/ACLCreationSpecProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@

use Civi\Api4\Service\Spec\RequestSpec;

class ACLCreationSpecProvider implements Generic\SpecProviderInterface {
/**
* @service
* @internal
*/
class ACLCreationSpecProvider extends \Civi\Core\Service\AutoService implements Generic\SpecProviderInterface {

/**
* @inheritDoc
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@

use Civi\Api4\Service\Spec\RequestSpec;

class ACLEntityRoleCreationSpecProvider implements Generic\SpecProviderInterface {
/**
* @service
* @internal
*/
class ACLEntityRoleCreationSpecProvider extends \Civi\Core\Service\AutoService implements Generic\SpecProviderInterface {

/**
* @inheritDoc
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@

use Civi\Api4\Service\Spec\RequestSpec;

class ActionScheduleCreationSpecProvider implements Generic\SpecProviderInterface {
/**
* @service
* @internal
*/
class ActionScheduleCreationSpecProvider extends \Civi\Core\Service\AutoService implements Generic\SpecProviderInterface {

/**
* @inheritDoc
Expand Down
6 changes: 5 additions & 1 deletion Civi/Api4/Service/Spec/Provider/ActivitySpecProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@
use Civi\Api4\Service\Spec\FieldSpec;
use Civi\Api4\Service\Spec\RequestSpec;

class ActivitySpecProvider implements Generic\SpecProviderInterface {
/**
* @service
* @internal
*/
class ActivitySpecProvider extends \Civi\Core\Service\AutoService implements Generic\SpecProviderInterface {

/**
* @inheritDoc
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@

use Civi\Api4\Service\Spec\RequestSpec;

class AddressCreationSpecProvider implements Generic\SpecProviderInterface {
/**
* @service
* @internal
*/
class AddressCreationSpecProvider extends \Civi\Core\Service\AutoService implements Generic\SpecProviderInterface {

/**
* @param \Civi\Api4\Service\Spec\RequestSpec $spec
Expand Down
6 changes: 5 additions & 1 deletion Civi/Api4/Service/Spec/Provider/AddressGetSpecProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@
use Civi\Api4\Service\Spec\FieldSpec;
use Civi\Api4\Service\Spec\RequestSpec;

class AddressGetSpecProvider implements Generic\SpecProviderInterface {
/**
* @service
* @internal
*/
class AddressGetSpecProvider extends \Civi\Core\Service\AutoService implements Generic\SpecProviderInterface {

/**
* @param \Civi\Api4\Service\Spec\RequestSpec $spec
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@

use Civi\Api4\Service\Spec\RequestSpec;

class BatchCreationSpecProvider implements Generic\SpecProviderInterface {
/**
* @service
* @internal
*/
class BatchCreationSpecProvider extends \Civi\Core\Service\AutoService implements Generic\SpecProviderInterface {

/**
* @inheritDoc
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@

use Civi\Api4\Service\Spec\RequestSpec;

class CampaignCreationSpecProvider implements Generic\SpecProviderInterface {
/**
* @service
* @internal
*/
class CampaignCreationSpecProvider extends \Civi\Core\Service\AutoService implements Generic\SpecProviderInterface {

/**
* @inheritDoc
Expand Down
Loading

0 comments on commit 5d37888

Please sign in to comment.