1212use PDPhilip \Elasticsearch \DSL \Results ;
1313use RuntimeException ;
1414
15+ use function array_replace_recursive ;
16+
1517/**
1618 * @method bool indexModify(array $settings)
1719 * @method bool indexCreate(array $settings = [])
@@ -46,7 +48,10 @@ class Connection extends BaseConnection
4648{
4749 const VALID_AUTH_TYPES = ['http ' , 'cloud ' ];
4850
49- protected Client $ client ;
51+ /**
52+ * The Elasticsearch connection handler.
53+ */
54+ protected ?Client $ client ;
5055
5156 protected string $ index = '' ;
5257
@@ -81,7 +86,10 @@ public function __construct(array $config)
8186
8287 $ this ->config = $ config ;
8388
84- $ this ->setOptions ($ config );
89+ $ this ->_sanitizeConfig ();
90+ $ this ->_validateConnection ();
91+
92+ $ this ->setOptions ();
8593
8694 $ this ->client = $ this ->buildConnection ();
8795
@@ -92,46 +100,31 @@ public function __construct(array $config)
92100 $ this ->useDefaultQueryGrammar ();
93101 }
94102
95- public function setOptions ($ config ): void
103+ public function setOptions (): void
96104 {
97- $ this ->indexPrefix = $ config ['index_prefix ' ] ?? '' ;
105+ $ this ->indexPrefix = $ this -> config ['index_prefix ' ] ?? '' ;
98106
99- if (isset ($ config ['options ' ]['allow_id_sort ' ])) {
100- $ this ->allowIdSort = $ config ['options ' ]['allow_id_sort ' ];
107+ if (isset ($ this -> config ['options ' ]['allow_id_sort ' ])) {
108+ $ this ->allowIdSort = $ this -> config ['options ' ]['allow_id_sort ' ];
101109 }
102- if (isset ($ config ['options ' ]['ssl_verification ' ])) {
103- $ this ->sslVerification = $ config ['options ' ]['ssl_verification ' ];
110+ if (isset ($ this -> config ['options ' ]['ssl_verification ' ])) {
111+ $ this ->sslVerification = $ this -> config ['options ' ]['ssl_verification ' ];
104112 }
105- if (! empty ($ config ['options ' ]['retires ' ])) {
106- $ this ->retires = $ config ['options ' ]['retires ' ];
113+ if (! empty ($ this -> config ['options ' ]['retires ' ])) {
114+ $ this ->retires = $ this -> config ['options ' ]['retires ' ];
107115 }
108- if (isset ($ config ['options ' ]['meta_header ' ])) {
109- $ this ->elasticMetaHeader = $ config ['options ' ]['meta_header ' ];
116+ if (isset ($ this -> config ['options ' ]['meta_header ' ])) {
117+ $ this ->elasticMetaHeader = $ this -> config ['options ' ]['meta_header ' ];
110118 }
111119
112- if (! empty ($ config ['error_log_index ' ])) {
120+ if (! empty ($ this -> config ['error_log_index ' ])) {
113121 $ this ->errorLoggingIndex = $ this ->indexPrefix
114- ? $ this ->indexPrefix .'_ ' .$ config ['error_log_index ' ]
115- : $ config ['error_log_index ' ];
122+ ? $ this ->indexPrefix .'_ ' .$ this -> config ['error_log_index ' ]
123+ : $ this -> config ['error_log_index ' ];
116124 }
117125
118126 }
119127
120- protected function buildConnection (): Client
121- {
122- $ type = strtolower (config ('database.connections.elasticsearch.auth_type ' , '' ));
123- $ this ->validateAuthType ($ type );
124-
125- return $ this ->{'_ ' .$ type .'Connection ' }();
126- }
127-
128- private function validateAuthType (string $ type ): void
129- {
130- if (! in_array ($ type , self ::VALID_AUTH_TYPES )) {
131- throw new RuntimeException ('Invalid [auth_type] in database config. Must be: http, cloud or api ' );
132- }
133- }
134-
135128 /** {@inheritdoc} */
136129 public function getTablePrefix (): ?string
137130 {
@@ -197,7 +190,7 @@ public function getSchemaBuilder(): Schema\Builder
197190 /** {@inheritdoc} */
198191 public function disconnect (): void
199192 {
200- unset( $ this ->connection ) ;
193+ $ this ->client = null ;
201194 }
202195
203196 /** {@inheritdoc} */
@@ -211,7 +204,7 @@ public function rebuildConnection(): void
211204 $ this ->rebuild = true ;
212205 }
213206
214- public function getClient (): Client
207+ public function getClient (): ? Client
215208 {
216209 return $ this ->client ;
217210 }
@@ -251,10 +244,6 @@ protected function getDefaultPostProcessor(): Query\Processor
251244 return new Query \Processor ;
252245 }
253246
254- //----------------------------------------------------------------------
255- // Connection Builder
256- //----------------------------------------------------------------------
257-
258247 /** {@inheritdoc} */
259248 protected function getDefaultQueryGrammar (): Query \Grammar
260249 {
@@ -267,25 +256,95 @@ protected function getDefaultSchemaGrammar(): Schema\Grammar
267256 return new Schema \Grammar ;
268257 }
269258
270- protected function _httpConnection (): Client
259+ /**
260+ * Sanitizes the configuration array by merging it with a predefined array of default configuration settings.
261+ * This ensures that all required configuration keys exist, even if they are set to null or default values.
262+ */
263+ private function _sanitizeConfig (): void
271264 {
272- $ hosts = config ('database.connections. ' .$ this ->connectionName .'.hosts ' ) ?? null ;
273- $ username = config ('database.connections. ' .$ this ->connectionName .'.username ' ) ?? null ;
274- $ pass = config ('database.connections. ' .$ this ->connectionName .'.password ' ) ?? null ;
275- $ apiId = config ('database.connections. ' .$ this ->connectionName .'.api_id ' ) ?? null ;
276- $ apiKey = config ('database.connections. ' .$ this ->connectionName .'.api_key ' ) ?? null ;
277- $ cb = ClientBuilder::create ()->setHosts ($ hosts );
265+
266+ $ this ->config = array_replace_recursive (
267+ [
268+ 'name ' => null ,
269+ 'auth_type ' => '' ,
270+ 'cloud_id ' => null ,
271+ 'hosts ' => [],
272+ 'username ' => null ,
273+ 'password ' => null ,
274+ 'api_key ' => null ,
275+ 'api_id ' => null ,
276+ 'index_prefix ' => null ,
277+ 'ssl_cert ' => null ,
278+ 'options ' => [
279+ 'allow_id_sort ' => null ,
280+ 'ssl_verification ' => null ,
281+ 'retires ' => null ,
282+ 'error_log_index ' => null ,
283+ 'meta_header ' => null ,
284+ ],
285+ 'ssl ' => [
286+ 'key ' => null ,
287+ 'password ' => null ,
288+ 'cert ' => null ,
289+ 'cert_password ' => null ,
290+ ],
291+ ],
292+ $ this ->config
293+ );
294+
295+ $ this ->config ['auth_type ' ] = strtolower ($ this ->config ['auth_type ' ]);
296+
297+ }
298+
299+ //----------------------------------------------------------------------
300+ // Connection Builder
301+ //----------------------------------------------------------------------
302+
303+ protected function buildConnection (): Client
304+ {
305+
306+ $ this ->_validateConnection ();
307+
308+ $ cb = ClientBuilder::create ();
309+
310+ // Set the connection type
311+ if ($ this ->config ['auth_type ' ] === 'http ' ) {
312+ $ cb = $ cb ->setHosts ($ this ->config ['hosts ' ]);
313+ } else {
314+ $ cb = $ cb ->setElasticCloudId ($ this ->config ['cloud_id ' ]);
315+ }
316+
317+ // Set Builder options
278318 $ cb = $ this ->_builderOptions ($ cb );
279- if ($ username && $ pass ) {
280- $ cb ->setBasicAuthentication ($ username , $ pass );
319+
320+ // Set Authentication
321+ if ($ this ->config ['username ' ] && $ this ->config ['password ' ]) {
322+ $ cb ->setBasicAuthentication ($ this ->config ['username ' ], $ this ->config ['password ' ]);
281323 }
282- if ($ apiKey ) {
283- $ cb ->setApiKey ($ apiKey , $ apiId );
324+
325+ if ($ this ->config ['api_key ' ]) {
326+ $ cb ->setApiKey ($ this ->config ['api_key ' ], $ this ->config ['api_id ' ]);
284327 }
285328
286329 return $ cb ->build ();
287330 }
288331
332+ private function _validateConnection (): void
333+ {
334+ if (! in_array ($ this ->config ['auth_type ' ], self ::VALID_AUTH_TYPES )) {
335+ throw new RuntimeException ('Invalid [auth_type] in database config. Must be: http or cloud ' );
336+ }
337+
338+ if ($ this ->config ['auth_type ' ] === 'cloud ' && ! $ this ->config ['cloud_id ' ]) {
339+ throw new RuntimeException ('auth_type of `cloud` requires `cloud_id` to be set ' );
340+ }
341+
342+ if ($ this ->config ['auth_type ' ] === 'http ' && ! $ this ->config ['hosts ' ]) {
343+ throw new RuntimeException ('auth_type of `http` requires `hosts` to be set ' );
344+ }
345+
346+ }
347+
289348 protected function _builderOptions ($ cb )
290349 {
291350 $ cb ->setSSLVerification ($ this ->sslVerification );
@@ -296,45 +355,19 @@ protected function _builderOptions($cb)
296355 if (isset ($ this ->retires )) {
297356 $ cb ->setRetries ($ this ->retires );
298357 }
299- $ caBundle = config ('database.connections. ' .$ this ->connectionName .'.ssl_cert ' ) ?? null ;
300- if ($ caBundle ) {
301- $ cb ->setCABundle ($ caBundle );
302- }
303- $ sslCert = config ('database.connections. ' .$ this ->connectionName .'.ssl.cert ' ) ?? null ;
304- $ sslCertPassword = config ('database.connections. ' .$ this ->connectionName .'.ssl.cert_password ' ) ?? null ;
305- $ sslKey = config ('database.connections. ' .$ this ->connectionName .'.ssl.key ' ) ?? null ;
306- $ sslKeyPassword = config ('database.connections. ' .$ this ->connectionName .'.ssl.key_password ' ) ?? null ;
307- if ($ sslCert ) {
308- $ cb ->setSSLCert ($ sslCert , $ sslCertPassword );
309- }
310- if ($ sslKey ) {
311- $ cb ->setSSLKey ($ sslKey , $ sslKeyPassword );
312- }
313-
314- return $ cb ;
315- }
316358
317- //----------------------------------------------------------------------
318- // Dynamic call routing to DSL bridge
319- //----------------------------------------------------------------------
320-
321- protected function _cloudConnection (): Client
322- {
323- $ cloudId = config ('database.connections. ' .$ this ->connectionName .'.cloud_id ' ) ?? null ;
324- $ username = config ('database.connections. ' .$ this ->connectionName .'.username ' ) ?? null ;
325- $ pass = config ('database.connections. ' .$ this ->connectionName .'.password ' ) ?? null ;
326- $ apiId = config ('database.connections. ' .$ this ->connectionName .'.api_id ' ) ?? null ;
327- $ apiKey = config ('database.connections. ' .$ this ->connectionName .'.api_key ' ) ?? null ;
359+ if ($ this ->config ['ssl_cert ' ]) {
360+ $ cb ->setCABundle ($ this ->config ['ssl_cert ' ]);
361+ }
328362
329- $ cb = ClientBuilder::create ()->setElasticCloudId ($ cloudId );
330- $ cb = $ this ->_builderOptions ($ cb );
331- if ($ username && $ pass ) {
332- $ cb ->setBasicAuthentication ($ username , $ pass );
363+ if ($ this ->config ['ssl ' ]['cert ' ]) {
364+ $ cb ->setSSLCert ($ this ->config ['ssl ' ]['cert ' ], $ this ->config ['ssl ' ]['cert_password ' ]);
333365 }
334- if ($ apiKey ) {
335- $ cb ->setApiKey ($ apiKey , $ apiId );
366+
367+ if ($ this ->config ['ssl ' ]['key ' ]) {
368+ $ cb ->setSSLKey ($ this ->config ['ssl ' ]['key ' ], $ this ->config ['ssl ' ]['key_password ' ]);
336369 }
337370
338- return $ cb-> build () ;
371+ return $ cb ;
339372 }
340373}
0 commit comments