Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
57.50% covered (warning)
57.50%
23 / 40
50.00% covered (danger)
50.00%
1 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
BoundedContextHashmapFactory
57.50% covered (warning)
57.50%
23 / 40
50.00% covered (danger)
50.00%
1 / 2
10.76
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 create
56.41% covered (warning)
56.41%
22 / 39
0.00% covered (danger)
0.00%
0 / 1
8.98
1<?php
2namespace Apie\Common\Wrappers;
3
4use Apie\Common\Config\Configuration;
5use Apie\Common\Events\RegisterBoundedContexts;
6use Apie\Common\ValueObjects\EntityNamespace;
7use Apie\Core\ApieLib;
8use Apie\Core\BoundedContext\BoundedContext;
9use Apie\Core\BoundedContext\BoundedContextHashmap;
10use Apie\Core\BoundedContext\BoundedContextId;
11use Apie\Core\Entities\EntityInterface;
12use Psr\EventDispatcher\EventDispatcherInterface;
13use Symfony\Component\Finder\Finder;
14
15/**
16 * Creates a BoundedContextHashmap instance from the ApieBundle configuration.
17 *
18 * @see Configuration in apie/apie-bundle for Symfony
19 * @see resources/apie.php in apie/laravel-apie for Laravel
20 */
21final class BoundedContextHashmapFactory
22{
23    /**
24     * @param array<string, mixed> $boundedContexts
25     * @param array<string, string> $scanBoundedContexts
26     */
27    public function __construct(
28        private readonly array $boundedContexts,
29        private readonly array $scanBoundedContexts,
30        private readonly EventDispatcherInterface $eventDispatcher
31    ) {
32    }
33
34    public function create(): BoundedContextHashmap
35    {
36        $result = [];
37        $entities = [];
38        foreach ($this->boundedContexts as $boundedContextId => $boundedContextConfig) {
39            $contextId = new BoundedContextId($boundedContextId);
40            $namespace = new EntityNamespace($boundedContextConfig['entities_namespace']);
41            $classes = $namespace->getClasses($boundedContextConfig['entities_folder']);
42            $entities = array_merge($entities, $classes->toStringArray());
43            $namespace = new EntityNamespace($boundedContextConfig['actions_namespace']);
44            $methods = $namespace->getMethods($boundedContextConfig['actions_folder']);
45            $result[$boundedContextId] = new BoundedContext(
46                $contextId,
47                $classes,
48                $methods
49            );
50        }
51        ApieLib::registerAlias(EntityInterface::class, implode('|', $entities));
52        if (!empty($this->scanBoundedContexts['search_path'])
53            && !empty($this->scanBoundedContexts['search_namespace'])
54            && is_dir($this->scanBoundedContexts['search_path'])
55        ) {
56            $paths = Finder::create()
57                ->in($this->scanBoundedContexts['search_path'])
58                ->depth(0)
59                ->directories();
60            $namespace = new EntityNamespace($this->scanBoundedContexts['search_namespace']);
61            foreach ($paths as $path) {
62                $contextId = new BoundedContextId(strtolower($path->getBasename()));
63                $pathNamespace = $namespace->getChildNamespace($path->getBasename());
64                $resourceNamespace = $pathNamespace->getChildNamespace('Resources');
65                $classes = $resourceNamespace->getClasses($path . '/Resources');
66                $methodNamespace = $pathNamespace->getChildNamespace('Actions');
67                $methods = $methodNamespace->getMethods($path . '/Actions');
68                $result[$contextId->toNative()] = new BoundedContext(
69                    $contextId,
70                    $classes,
71                    $methods
72                );
73            }
74        }
75        $map = new BoundedContextHashmap($result);
76        $event = new RegisterBoundedContexts($map);
77        $this->eventDispatcher->dispatch($event);
78        return $event->hashmap;
79    }
80}