11<?php
22
33namespace DatabaseFactory {
4-
4+
55 use DatabaseFactory \Helpers ;
66 use DatabaseFactory \Facades ;
77 use DatabaseFactory \Exceptions ;
88 use DatabaseFactory \Collections ;
9-
9+
1010 /**
1111 * The main Query Builder class. Objects initialized from this
1212 * class are responsible for building queries and handling the
@@ -27,14 +27,14 @@ class Builder
2727 * @var string|null $query
2828 */
2929 private ?string $ query = '' ;
30-
30+
3131 /**
3232 * PDO Connection
3333 *
3434 * @var \PDO $connection
3535 */
3636 private \PDO $ connection ;
37-
37+
3838 /**
3939 * Module collection
4040 *
@@ -52,6 +52,7 @@ class Builder
5252 'delete ' => null ,
5353 'insert ' => null ,
5454 'offset ' => null ,
55+ 'custom ' => null ,
5556 'select ' => null ,
5657 'orLike ' => null ,
5758 'count ' => null ,
@@ -62,7 +63,7 @@ class Builder
6263 'and ' => null ,
6364 'or ' => null ,
6465 ];
65-
66+
6667 /**
6768 * Constructor
6869 *
@@ -74,7 +75,7 @@ public function __construct(private readonly string $table, private readonly str
7475 // connection string
7576 $ this ->connection = Facades \DB ::connection ();
7677 }
77-
78+
7879 /**
7980 * Check to see if the module used for a query exists within the
8081 * $modules array, extends the correct class, and implements the
@@ -92,40 +93,45 @@ public function __construct(private readonly string $table, private readonly str
9293 */
9394 public function __call (string $ module = null , mixed $ arguments = null ): Builder
9495 {
96+ $ currentModule = null ;
97+ $ config = new $ this ->config ();
98+
9599 // let's ensure that the $name passed through lives within
96- // the $modules array
97- if (!Helpers \Arr::hasKey ($ module , $ this ->modules )) {
100+ // the $modules arrays
101+ if (Helpers \Arr::hasKey ($ module , $ this ->modules )) {
102+ $ currentModule = $ this ->modules [$ module ] = $ config ->modules ()[$ module ];
103+ } elseif (Helpers \Arr::hasKey ($ module , $ config ->modules ())) {
104+ $ this ->modules = [];
105+ $ currentModule = $ this ->modules [$ module ] = $ config ->modules ()[$ module ];
106+ } else {
98107 // if not, let's throw an error
99108 throw new Exceptions \InvalidModuleException (
100109 $ module . ' must exist within the $modules array '
101110 );
102111 }
103-
104- // if it does, let's set it as the current module
105- $ currentModule = $ this ->modules [$ module ] = (new $ this ->config ())->modules ()[$ module ];
106-
112+
107113 // let's see if that module extends the base builder
108114 if (!Helpers \Cls::extends ($ currentModule , Config \BaseBuilder::class)) {
109115 throw new Exceptions \InvalidModuleException (
110116 $ module . ' module must extend ' . Config \BaseBuilder::class
111117 );
112118 }
113-
119+
114120 // let's see if it also conforms to the correct contract
115121 if (!Helpers \Cls::implements ($ currentModule , Contracts \SQLStatementInterface::class)) {
116122 throw new Exceptions \InvalidModuleException (
117123 $ module . ' must implement ' . Contracts \SQLStatementInterface::class
118124 );
119125 }
120-
126+
121127 // generate the query returned and assign it to $query
122128 // for execution
123129 $ this ->query .= (new $ currentModule ())->statement ($ this ->table , ...$ arguments );
124-
130+
125131 // allow for method chaining of queries
126132 return $ this ;
127133 }
128-
134+
129135 /**
130136 * Execute a query and return a PDOStatement
131137 *
@@ -140,18 +146,18 @@ public function execute(array $params = null): \PDOStatement
140146 if ($ params ) {
141147 // prepare the statement
142148 $ statement = $ this ->prepare ($ this ->toSQL ());
143-
149+
144150 // execute the prepared statement
145151 $ statement ->execute ($ params );
146-
152+
147153 /// unset the query and the prepared statement
148154 unset($ statement , $ this ->query );
149155 }
150-
156+
151157 // without binding parameters to a prepared statement
152158 return $ this ->query ($ this ->toSQL ());
153159 }
154-
160+
155161 /**
156162 * Generates a prepared PDO statement
157163 * using a trimmed query string
@@ -164,7 +170,7 @@ private function prepare(string $query): \PDOStatement|false
164170 {
165171 return $ this ->connection ->prepare (trim ($ query ));
166172 }
167-
173+
168174 /**
169175 * Generates a PDO query
170176 *
@@ -176,7 +182,7 @@ private function query(string $query): \PDOStatement|false
176182 {
177183 return $ this ->connection ->query (trim ($ query ));
178184 }
179-
185+
180186 /**
181187 * Close the PDO connection
182188 *
@@ -186,7 +192,7 @@ public function close(): void
186192 {
187193 unset($ this ->query , $ this ->connection );
188194 }
189-
195+
190196 /**
191197 * Return the results as an array
192198 *
@@ -196,7 +202,7 @@ private function get(): ?array
196202 {
197203 return $ this ->execute ()->fetchAll (\PDO ::FETCH_ASSOC );
198204 }
199-
205+
200206 /**
201207 * Wrapper for $this->get()
202208 *
@@ -210,7 +216,7 @@ public function toArray(): array
210216 {
211217 return (new Collections \ToArray ($ this ->get ()))->collection ();
212218 }
213-
219+
214220 /**
215221 * Return the results as a JSON string
216222 *
@@ -222,10 +228,11 @@ public function toArray(): array
222228 public function toJSON (): string |false
223229 {
224230 return json_encode (
225- (new Collections \ToJSON ($ this ->get ())), JSON_THROW_ON_ERROR | JSON_PRETTY_PRINT
231+ (new Collections \ToJSON ($ this ->get ())),
232+ JSON_THROW_ON_ERROR | JSON_PRETTY_PRINT
226233 );
227234 }
228-
235+
229236 /**
230237 * Returns the trimmed string value of
231238 * $query
@@ -238,7 +245,7 @@ public function toSQL(): string
238245 {
239246 return trim ($ this ->query );
240247 }
241-
248+
242249 /**
243250 * __toString() implementation
244251 *
@@ -250,7 +257,7 @@ public function __toString(): string
250257 {
251258 return $ this ->toSQL ();
252259 }
253-
260+
254261 /**
255262 * Destructor
256263 *
0 commit comments