Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
<?php
namespace Opf;
use DI\ContainerBuilder;
use Exception;
use Opf\Handlers\HttpErrorHandler;
use Opf\Util\Util;
use Slim\App;
use Slim\Factory\AppFactory;
class ScimServer
{
/**
* @var string $scimServerPhpRoot The root of the project using
* OPF as a dependency. This is needed for autoloading purposes,
* such that all classes of the project using OPF can be made
* visible to OPF.
*/
private string $scimServerPhpRoot;
/**
* A container builder which is used to configure and create a
* DI container, used by the Slim application
*/
private ContainerBuilder $containerBuilder;
/**
* The Slim application to configure and run as a server, exposing
* the SCIM API
*/
private App $app;
/**
* @var array $dependencies An array holding dependency definitions,
* passed to the DI ContainerBuilder for configuring the DI container
*/
private array $dependencies;
/**
* @var array $middleware Any custom middleware that needs to be added
* to the Slim application (e.g., custom auth middleware)
*/
private array $middleware;
/**
* ScimServer class constructor
*
* @param string $scimServerPhpRoot The root of the project using
* the OPF library. Needed for autoloading. See more in description
* of the dedicated class property of the same name
*/
public function __construct(string $scimServerPhpRoot)
{
$this->scimServerPhpRoot = $scimServerPhpRoot;
/**
* Once we have the root directory of the project that's using
* OPF, we include its autoload file, so that we don't run into
* autoloading issues.
*/
require $this->scimServerPhpRoot . '/vendor/autoload.php';
}
public function setConfig(string $configFilePath)
{
if (!isset($configFilePath) || empty($configFilePath)) {
throw new Exception("Config file path must be supplied");
}
Util::setConfigFile($configFilePath);
}
public function setDependencies(array $dependencies = array())
{
$baseDependencies = require __DIR__ . '/Dependencies/dependencies.php';
$this->dependencies = array_merge($baseDependencies, $dependencies);
}
public function setMiddleware(array $middleware = array())
{
$this->middleware = $middleware;
}
public function run()
{
session_start();
// Instantiate the PHP-DI ContainerBuilder
$containerBuilder = new ContainerBuilder();
$config = Util::getConfigFile();
if ($config['isInProduction']) {
$containerBuilder->enableCompilation(__DIR__ . '/../var/cache');
}
// Set up a few Slim-related settings
$settings = [
'settings' => [
'determineRouteBeforeAppMiddleware' => false,
'displayErrorDetails' => true, // set to false in production
'addContentLengthHeader' => false, // Allow the web server to send the content-length header
]
];
$containerBuilder->addDefinitions($settings);
// Set all necessary dependencies which are provided in this class'
// $dependencies attribute
$containerBuilder->addDefinitions($this->dependencies);
// Build PHP-DI Container instance
$container = $containerBuilder->build();
// Instantiate the app
AppFactory::setContainer($container);
$this->app = AppFactory::create();
// Set our app's base path if it's configured
if (isset($config['basePath']) && !empty($config['basePath'])) {
$this->app->setBasePath($config['basePath']);
}
// Register routes
$routes = require __DIR__ . '/routes.php';
$routes($this->app);
// Iterate through the custom middleware (if any) and set it
if (isset($this->middleware) && !empty($this->middleware)) {
foreach ($this->middleware as $middleware) {
$this->app->addMiddleware($this->app->getContainer()->get($middleware));
}
}
// Add Routing Middleware
$this->app->addRoutingMiddleware();
$this->app->addBodyParsingMiddleware();
$callableResolver = $this->app->getCallableResolver();
$responseFactory = $this->app->getResponseFactory();
// Instantiate our custom Http error handler that we need further down below
$errorHandler = new HttpErrorHandler($callableResolver, $responseFactory);
// Add error middleware
$errorMiddleware = $this->app->addErrorMiddleware(
$config['isInProduction'] ? false : true,
true,
true
);
$errorMiddleware->setDefaultErrorHandler($errorHandler);
// Run app
$this->app->run();
}
}