Issues (5)

src/Client.php (1 issue)

1
<?php
2
3
namespace DMT\WebservicesNl\Client;
4
5
use Composer\Autoload\ClassLoader;
6
use DMT\WebservicesNl\Client\Request\RequestInterface;
7
use DMT\WebservicesNl\Client\Response\ResponseInterface;
8
use JMS\Serializer\Naming\CamelCaseNamingStrategy;
9
use JMS\Serializer\Naming\SerializedNameAnnotationStrategy;
10
use JMS\Serializer\SerializerBuilder;
11
use League\Tactician\CommandBus;
12
13
/**
14
 * Class Client
15
 *
16
 * @package DMT\WebservicesNl\Client
17
 */
18
class Client
19
{
20
    /**
21
     * @var CommandBus
22
     */
23
    protected $commandBus;
24
25
    /**
26
     * Client constructor.
27
     *
28
     * @param CommandBus $commandBus
29
     */
30 6
    public function __construct(CommandBus $commandBus)
31
    {
32 6
        $this->commandBus = $commandBus;
33 6
    }
34
35
    /**
36
     * @param RequestInterface $request
37
     *
38
     * @return ResponseInterface|null
39
     */
40 2
    public function execute(RequestInterface $request): ?ResponseInterface
41
    {
42 2
        return $this->commandBus->handle($request);
43
    }
44
45
    /**
46
     * Call a service method with arguments.
47
     *
48
     * @param string $method
49
     * @param array $arguments
50
     *
51
     * @return object|null
52
     * @throws \BadMethodCallException
53
     */
54 3
    public function __call(string $method, array $arguments = []): ?\stdClass
55
    {
56 3
        if (count($arguments) === 1) {
57 1
            $arguments = array_pop($arguments);
58
        }
59
60 3
        $serializer = SerializerBuilder::create()
61 3
            ->setPropertyNamingStrategy(new SerializedNameAnnotationStrategy(new CamelCaseNamingStrategy()))
62 3
            ->addDefaultHandlers()
63 3
            ->build();
64
65 3
        $response = $this->execute($serializer->fromArray($arguments, $this->getRequestClassForMethod($method)));
66
67 1
        return $response ? json_decode($serializer->serialize($response, 'json')) : null;
68
    }
69
70
    /**
71
     * Get all the installed (available) services.
72
     *
73
     * @return array
74
     */
75 2
    protected function getInstalledServices(): array
76
    {
77 2
        $reflection = new \ReflectionObject(new ClassLoader());
78 2
        $psr4File = dirname($reflection->getFileName()) . '/autoload_psr4.php';
79
80 2
        $psr4Prefixes = include $psr4File;
81 2
        $installedServices = preg_filter(
82 2
            '~^DMT\\\WebservicesNl\\\((?!Client).+)\\\~', '$1',
83 2
            array_keys((array) $psr4Prefixes)
84
        );
85
86 2
        return $installedServices;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $installedServices could return the type null|string which is incompatible with the type-hinted return array. Consider adding an additional type-check to rule them out.
Loading history...
87
    }
88
89
    /**
90
     * Get the request that corresponds to the service method.
91
     *
92
     * @param string $method
93
     *
94
     * @return string
95
     * @throws \BadMethodCallException
96
     */
97 3
    protected function getRequestClassForMethod(string $method): string
98
    {
99 3
        if (in_array($method, ['login', 'logout'])) {
100 1
            return sprintf('DMT\\WebservicesNl\\Client\\Request\\%sRequest', ucfirst($method));
101
        }
102
103 2
        foreach ($this->getInstalledServices() as $service) {
104
            if (stripos($method, $service) !== 0) {
105
                continue;
106
            }
107
108
            $requestClass = sprintf(
109
                'DMT\\WebservicesNl\\%s\\Request\\%sRequest',
110
                $service,
111
                substr($method, strlen($service))
112
            );
113
114
            if (class_exists($requestClass)) {
115
                return $requestClass;
116
            }
117
        }
118
119 2
        throw new \BadMethodCallException("Function `$method` is not a valid method for this service");
120
    }
121
}
122