11<?php declare (strict_types=1 );
22
3- namespace Salient \Sli \Command \ Concept ;
3+ namespace Salient \Sli \Command ;
44
55use Salient \Cli \Exception \CliInvalidArgumentsException ;
66use Salient \Cli \CliCommand ;
7- use Salient \Contract \Core \ProviderInterface ;
87use Salient \Core \Exception \FilesystemErrorException ;
98use Salient \Core \Utility \Env ;
109use Salient \Core \Utility \File ;
1110use Salient \Core \Utility \Get ;
1211use Salient \Core \Utility \Json ;
13- use Salient \Sli \Catalog \EnvVar ;
12+ use Salient \Core \Utility \Test ;
13+ use Salient \Sli \EnvVar ;
1414use JsonException ;
1515
1616/**
1717 * Base class for sli commands
1818 */
19- abstract class Command extends CliCommand
19+ abstract class AbstractCommand extends CliCommand
2020{
2121 /**
2222 * Normalise a user-supplied class name, optionally assigning its base name
@@ -25,23 +25,36 @@ abstract class Command extends CliCommand
2525 * @return class-string|''
2626 */
2727 protected function getFqcnOptionValue (
28+ string $ valueName ,
2829 string $ value ,
2930 ?string $ namespaceEnvVar = null ,
3031 ?string &$ class = null ,
3132 ?string &$ namespace = null
3233 ): string {
34+ if ($ value === '' ) {
35+ return '' ;
36+ }
37+
3338 $ namespace = null ;
3439 if ($ namespaceEnvVar !== null ) {
3540 $ namespace = Env::get ($ namespaceEnvVar , null );
3641 }
37- if ($ namespace === null ) {
38- $ namespace = Env::get (EnvVar::NS_DEFAULT , null );
39- }
40- if ($ namespace !== null && trim ($ value ) && strpos ($ value , '\\' ) === false ) {
42+ $ namespace ??= Env::get (EnvVar::NS_DEFAULT , null );
43+
44+ if ($ namespace !== null && strpos ($ value , '\\' ) === false ) {
4145 $ fqcn = trim ($ namespace , '\\' ) . "\\$ value " ;
4246 } else {
4347 $ fqcn = ltrim ($ value , '\\' );
4448 }
49+
50+ if (!Test::isFqcn ($ fqcn )) {
51+ throw new CliInvalidArgumentsException (sprintf (
52+ 'invalid %s: %s ' ,
53+ $ valueName ,
54+ $ value ,
55+ ));
56+ }
57+
4558 $ class = Get::basename ($ fqcn );
4659 $ namespace = Get::namespace ($ fqcn );
4760
@@ -54,85 +67,88 @@ protected function getFqcnOptionValue(
5467 *
5568 * @return class-string
5669 */
57- protected function getRequiredFqcnOptionValue (
70+ protected function requireFqcnOptionValue (
5871 string $ valueName ,
5972 string $ value ,
6073 ?string $ namespaceEnvVar = null ,
6174 ?string &$ class = null ,
6275 ?string &$ namespace = null
6376 ): string {
64- $ fqcn = $ this ->getFqcnOptionValue ($ value , $ namespaceEnvVar , $ class , $ namespace );
65-
77+ $ fqcn = $ this ->getFqcnOptionValue ($ valueName , $ value , $ namespaceEnvVar , $ class , $ namespace );
6678 if ($ fqcn === '' ) {
6779 throw new CliInvalidArgumentsException (sprintf ('invalid %s: %s ' , $ valueName , $ value ));
6880 }
69-
7081 return $ fqcn ;
7182 }
7283
7384 /**
74- * Normalise mandatory user-supplied class names
85+ * Normalise an array of user-supplied class names
7586 *
7687 * @param string[] $values
7788 * @return array<class-string>
7889 */
79- protected function requireMultipleFqcnValues (
90+ protected function requireFqcnOptionValues (
8091 string $ valueName ,
8192 array $ values ,
8293 ?string $ namespaceEnvVar = null
8394 ): array {
8495 $ fqcn = [];
8596 foreach ($ values as $ value ) {
86- $ fqcn [] = $ this ->getRequiredFqcnOptionValue ($ valueName , $ value , $ namespaceEnvVar );
97+ $ fqcn [] = $ this ->requireFqcnOptionValue ($ valueName , $ value , $ namespaceEnvVar );
8798 }
8899 return $ fqcn ;
89100 }
90101
91102 /**
92- * Resolve a user-supplied provider name to a concrete instance
103+ * Normalise a user-supplied class name and resolve it to a concrete
104+ * instance of a given class
93105 *
94- * @template TBaseProvider of ProviderInterface
95- * @template TProvider of TBaseProvider
106+ * @template TClass of object
96107 *
97- * @param class-string<TProvider> $provider
98- * @param class-string<TBaseProvider> $class
99- * @return TProvider
108+ * @param class-string<TClass> $class
109+ * @return TClass
100110 */
101- protected function getProvider (string $ provider , string $ class = ProviderInterface::class): ProviderInterface
102- {
103- $ provider = $ this ->getFqcnOptionValue ($ provider , EnvVar::NS_PROVIDER );
104- if (is_a ($ provider , $ class , true )) {
105- return $ this ->App ->get ($ provider );
111+ protected function getFqcnOptionInstance (
112+ string $ valueName ,
113+ string $ value ,
114+ string $ class ,
115+ ?string $ namespaceEnvVar = null
116+ ) {
117+ $ value = $ this ->getFqcnOptionValue ($ valueName , $ value , $ namespaceEnvVar );
118+ if (is_a ($ value , $ class , true )) {
119+ return $ this ->App ->get ($ value );
106120 }
107-
108- throw class_exists ($ provider )
109- ? new CliInvalidArgumentsException ("not a subclass of $ class: $ provider " )
110- : new CliInvalidArgumentsException ("class does not exist: $ provider " );
121+ throw new CliInvalidArgumentsException (
122+ class_exists ($ value ) ? sprintf (
123+ 'class does not inherit %s: %s ' ,
124+ $ class ,
125+ $ value ,
126+ ) : sprintf (
127+ 'class does not exist: %s ' ,
128+ $ value ,
129+ )
130+ );
111131 }
112132
113133 /**
114134 * Get data from a user-supplied JSON file, optionally assigning the file's
115- * "friendly pathname" to a variable before returning
135+ * "friendly pathname" to a variable passed by reference
116136 *
117137 * @return mixed
118138 */
119139 protected function getJson (string $ file , ?string &$ path = null , bool $ associative = true )
120140 {
121- $ _file = $ file ;
122141 if ($ file === '- ' ) {
123142 $ file = 'php://stdin ' ;
124143 } else {
125144 try {
126- $ file = File::realpath ( $ file );
145+ $ path = File::relativeToParent ( $ file , $ this -> App -> getBasePath (), $ file );
127146 } catch (FilesystemErrorException $ ex ) {
128147 throw new CliInvalidArgumentsException (sprintf (
129148 'file not found: %s ' ,
130- $ _file ,
149+ $ file ,
131150 ));
132151 }
133-
134- $ relative = File::relativeToParent ($ file , $ this ->App ->getBasePath ());
135- $ path = $ relative === null ? $ file : "./ {$ relative }" ;
136152 }
137153
138154 $ json = File::getContents ($ file );
@@ -144,7 +160,7 @@ protected function getJson(string $file, ?string &$path = null, bool $associativ
144160 } catch (JsonException $ ex ) {
145161 throw new CliInvalidArgumentsException (sprintf (
146162 "invalid JSON in '%s': %s " ,
147- $ _file ,
163+ $ file ,
148164 $ ex ->getMessage (),
149165 ));
150166 }
0 commit comments