2525 */
2626class ConfigurationManager
2727{
28- /**
29- * @var string
30- */
31- public const CONFIG_FILE_NAME = 'propel ' ;
32-
3328 /**
3429 * @var int
3530 */
@@ -72,6 +67,8 @@ public function __construct(?string $path = null, ?array $extraConf = [])
7267 }
7368
7469 /**
70+ * @deprecated Use aptly named {@see ConfigurationManager::getConfig()}
71+ *
7572 * Return the whole configuration array
7673 *
7774 * @return array
@@ -82,6 +79,18 @@ public function get(): array
8279 }
8380
8481 /**
82+ * Return the whole configuration array
83+ *
84+ * @return array
85+ */
86+ public function getConfig (): array
87+ {
88+ return $ this ->config ;
89+ }
90+
91+ /**
92+ * @deprecated Access config props (including full sections) through {@see static::getConfigProperty()}
93+ *
8594 * Return a specific section of the configuration array.
8695 * It ca be useful to get, in example, only 'generator' values.
8796 *
@@ -106,28 +115,77 @@ public function getSection(string $section): ?array
106115 * is expressed by:
107116 * <code>'database.adapter.mysql.tableType</code>
108117 *
109- * @param string $name The name of property, expressed as a dot separated level hierarchy
118+ * @psalm-return ($isRequired ? array|int|bool|string : array|scalar|null)
119+ *
120+ * @param string $path The name of property, expressed as a dot separated level hierarchy
121+ * @param bool $isRequired
110122 *
123+ * @throws \Propel\Common\Config\Exception\InvalidConfigurationException
111124 * @throws \Propel\Common\Config\Exception\InvalidArgumentException
112125 *
113- * @return mixed The configuration property
126+ * @return array|string|int|bool|null The configuration property
114127 */
115- public function getConfigProperty (string $ name )
128+ public function getConfigProperty (string $ path , bool $ isRequired = false ): array | int | bool | string | null
116129 {
117- if ($ name === '' ) {
130+ if ($ path === '' ) {
118131 throw new InvalidArgumentException ('Invalid empty configuration property name. ' );
119132 }
120133
121- $ keys = explode ('. ' , $ name );
122- $ output = $ this ->get ();
134+ $ keys = explode ('. ' , $ path );
135+ $ section = $ this ->getConfig ();
123136 foreach ($ keys as $ key ) {
124- if (!array_key_exists ($ key , $ output )) {
125- return null ;
137+ if (array_key_exists ($ key , $ section )) {
138+ $ section = $ section [$ key ];
139+
140+ continue ;
126141 }
127- $ output = $ output [$ key ];
142+
143+ if ($ isRequired ) {
144+ throw new InvalidConfigurationException ("Cannot resolve config property ' $ path': No value at ' $ key' " );
145+ }
146+
147+ return null ;
128148 }
129149
130- return $ output ;
150+ if ($ isRequired && ($ section === null || $ section === '' )) {
151+ throw new InvalidConfigurationException ("Required config property ' $ path' cannot be empty, but is: " . var_export ($ section , true ));
152+ }
153+
154+ return $ section ;
155+ }
156+
157+ /**
158+ * Type-safe access of {@see static::getConfigProperty()}.
159+ *
160+ * @psalm-return ($isRequired ? string : string|null)
161+ *
162+ * @param string $path The name of property, expressed as a dot separated level hierarchy
163+ * @param bool $isRequired
164+ *
165+ * @throws \Propel\Common\Config\Exception\InvalidConfigurationException
166+ *
167+ * @return string|null The configuration property
168+ */
169+ public function getConfigPropertyString (string $ path , bool $ isRequired = false ): string |null
170+ {
171+ $ val = $ this ->getConfigProperty ($ path , $ isRequired );
172+ if ($ val === null || is_string ($ val )) {
173+ return $ val ;
174+ }
175+
176+ throw new InvalidConfigurationException ("Configuration item ` $ path` is expected to contain a string, but is " . var_export ($ val , true ));
177+ }
178+
179+ /**
180+ * Return a specific configuration property.
181+ *
182+ * @param string $path The name of property, expressed as a dot separated level hierarchy
183+ *
184+ * @return array|string|int|bool The configuration property
185+ */
186+ public function getConfigPropertyRequired (string $ path ): array |int |bool |string
187+ {
188+ return $ this ->getConfigProperty ($ path , true ) ?? '' ;
131189 }
132190
133191 /**
@@ -215,7 +273,7 @@ protected function process(array $extraConf = []): void
215273 try {
216274 $ this ->config = $ processor ->processConfiguration ($ configuration , $ this ->config );
217275 } catch (SymfonyInvalidConfigurationException $ e ) {
218- throw new InvalidConfigurationException ('Could not process configuration. Please check the property in error message : ' . $ e ->getMessage ());
276+ throw new InvalidConfigurationException ('Invalid configuration: ' . $ e ->getMessage ());
219277 }
220278 $ this ->cleanupSlaveConnections ();
221279 $ this ->cleanupConnections ();
@@ -239,11 +297,16 @@ private function getConfigFileNamesFromDirectory(string $path): array
239297 ];
240298 $ dirs = array_filter ($ dirs , 'is_dir ' );
241299
242- $ fileGlob = self :: CONFIG_FILE_NAME . ' .{php,inc,ini,properties,yaml,yml,xml,json}{,.dist} ' ;
300+ $ fileGlob = ' p{rope,erp}l .{php,inc,ini,properties,yaml,yml,xml,json}{,.dist} ' ;
243301 $ finder = new Finder ();
244302 $ finder ->in ($ dirs )->depth (0 )->files ()->name ($ fileGlob );
245303 $ orderedConfigFileNames = [];
246304 foreach ($ finder as $ file ) {
305+ $ realPath = $ file ->getRealPath ();
306+ $ isExecutable = array_any (['propel ' , 'perpl ' ], fn ($ cmd ) => str_ends_with ($ realPath , "/bin/ {$ cmd }.php " ));
307+ if ($ isExecutable ) {
308+ continue ;
309+ }
247310 $ precedence = ($ file ->getExtension () === 'dist ' ) ? self ::PRECEDENCE_DIST : self ::PRECEDENCE_NORMAL ;
248311 if (isset ($ orderedConfigFileNames [$ precedence ])) {
249312 $ messageSplits = [
0 commit comments