Overview

Namespaces

  • Deimos
    • CLI
      • Exceptions
  • PHP

Classes

  • Deimos\CLI\CLI
  • Deimos\CLI\Tokenizer
  • Deimos\CLI\Variable

Interfaces

  • Deimos\CLI\InterfaceVariable
  • Throwable

Exceptions

  • Deimos\CLI\Exceptions\CLIRun
  • Deimos\CLI\Exceptions\Required
  • Deimos\CLI\Exceptions\UndefinedAlias
  • Deimos\CLI\Exceptions\UndefinedVariable
  • Exception
  • InvalidArgumentException
  • LogicException
  • Overview
  • Namespace
  • Class
  • Tree
  • Deprecated
  • Todo
  1: <?php
  2: 
  3: namespace Deimos\CLI;
  4: 
  5: use Deimos\CLI\Exceptions\CLIRun;
  6: use Deimos\CLI\Exceptions\Required;
  7: use Deimos\CLI\Exceptions\UndefinedVariable;
  8: 
  9: class CLI
 10: {
 11: 
 12:     /**
 13:      * @var array
 14:      */
 15:     protected $argv;
 16: 
 17:     /**
 18:      * @var array
 19:      */
 20:     protected $variables = [];
 21: 
 22:     /**
 23:      * @var array
 24:      */
 25:     protected $aliases;
 26: 
 27:     /**
 28:      * @var array
 29:      */
 30:     protected $requiredList;
 31: 
 32:     /**
 33:      * @var array
 34:      */
 35:     protected $storage;
 36: 
 37:     /**
 38:      * @var array
 39:      */
 40:     protected $commands = [];
 41: 
 42:     /**
 43:      * @var bool
 44:      */
 45:     protected $run;
 46: 
 47:     /**
 48:      * CLI constructor.
 49:      *
 50:      * @param array $argv
 51:      */
 52:     public function __construct(array $argv)
 53:     {
 54:         $this->argv = $argv;
 55: 
 56:         if (!empty($this->argv))
 57:         {
 58:             // remove element [0] *.php
 59:             array_shift($this->argv);
 60:         }
 61:     }
 62: 
 63:     /**
 64:      * @param string $name
 65:      *
 66:      * @return InterfaceVariable
 67:      */
 68:     public function variable($name)
 69:     {
 70:         return ($this->variables[$name] = new Variable($name));
 71:     }
 72: 
 73:     /**
 74:      * @return string
 75:      */
 76:     protected function init()
 77:     {
 78:         $this->aliases      = [];
 79:         $this->requiredList = [];
 80: 
 81:         /**
 82:          * @var $variable Variable
 83:          */
 84:         foreach ($this->variables as $variable)
 85:         {
 86:             if ($variable->isRequired())
 87:             {
 88:                 $this->requiredList[] = $variable->name();
 89:             }
 90: 
 91:             // init aliases
 92:             foreach ($variable->aliases() as $alias)
 93:             {
 94:                 $this->aliases[$alias] = $variable;
 95:             }
 96:         }
 97: 
 98:         return implode(' ', $this->argv);
 99:     }
100: 
101:     /**
102:      * @param $data
103:      *
104:      * @return array|mixed
105:      */
106:     protected function value($data)
107:     {
108:         return is_array($data) && isset($data[1]) ? $data[1] : $data;
109:     }
110: 
111:     /**
112:      * @param array $array
113:      */
114:     protected function initStorage(array &$array)
115:     {
116:         foreach ($array as $item)
117:         {
118:             $value = $this->value($item);
119: 
120:             if (in_array($value, ['-', '--'], false))
121:             {
122:                 break;
123:             }
124: 
125:             $data = array_shift($array);
126: 
127:             if ($value !== ' ')
128:             {
129:                 $this->storage[] = $this->value($data);
130:             }
131:         }
132:     }
133: 
134:     /**
135:      * @param array $array
136:      *
137:      * @throws UndefinedVariable
138:      */
139:     protected function initVariable(array &$array)
140:     {
141:         $isAlias = false;
142:         $isKey   = false;
143:         $key     = null;
144: 
145:         foreach ($array as $item)
146:         {
147:             $item  = array_shift($array);
148:             $value = $this->value($item);
149: 
150:             if ($value === ' ')
151:             {
152:                 continue;
153:             }
154: 
155:             if (!$isKey && in_array($value, ['-', '--'], true))
156:             {
157:                 $isAlias = $value === '-';
158:                 $isKey   = true;
159:                 continue;
160:             }
161: 
162:             if ($isKey)
163:             {
164:                 $key   = $value;
165:                 $isKey = false;
166: 
167:                 if ($isAlias && !isset($this->aliases[$key]))
168:                 {
169:                     throw new UndefinedVariable('Not found alias \'' . $key . '\'');
170:                 }
171: 
172:                 $this->commands[$key] = [];
173:                 continue;
174:             }
175: 
176:             $stringValue = '';
177: 
178:             while ($value !== ' ')
179:             {
180:                 if ($value === null)
181:                 {
182:                     break;
183:                 }
184: 
185:                 $stringValue .= $value;
186: 
187:                 $item  = array_shift($array);
188:                 $value = $this->value($item);
189:             }
190: 
191:             if (strlen($stringValue) > 0)
192:             {
193:                 $this->commands[$key][] = $stringValue;
194:             }
195: 
196:         }
197:     }
198: 
199:     /**
200:      * @return bool
201:      * @throws Required
202:      */
203:     protected function initRequired()
204:     {
205:         foreach ($this->requiredList as $name)
206:         {
207:             /**
208:              * @var Variable $variable
209:              * @var array    $aliasList
210:              */
211:             $variable  = $this->variables[$name];
212:             $aliasList = $variable->aliases();
213: 
214:             if (!isset($this->commands[$name]))
215:             {
216:                 $keys = array_keys($this->commands);
217:                 foreach ($aliasList as $alias)
218:                 {
219:                     if (in_array($alias, $keys, true))
220:                     {
221:                         continue 2;
222:                     }
223:                 }
224: 
225:                 throw new Required('Not found required argument \'' . $name . '\'');
226:             }
227: 
228:             continue;
229: 
230:         }
231: 
232:         return true;
233:     }
234: 
235:     /**
236:      * @throws UndefinedVariable
237:      */
238:     protected function initUndefined()
239:     {
240:         foreach ($this->commands as $command => &$data)
241:         {
242:             if (!isset($this->variables[$command]) && !isset($this->aliases[$command]))
243:             {
244:                 throw new UndefinedVariable('Not found variable \'' . $command . '\'');
245:             }
246:         }
247:     }
248: 
249:     protected function loadCommand(array $commands)
250:     {
251:         $this->commands = [];
252: 
253:         foreach ($commands as $name => $value)
254:         {
255:             /**
256:              * @var Variable $variable
257:              */
258:             $variable = $this->aliases[$name];
259: 
260:             if ($variable === null)
261:             {
262:                 $variable = $this->variables[$name];
263:             }
264: 
265:             if (count($value))
266:             {
267:                 if ($variable->isBoolType())
268:                 {
269:                     $value = $value[0];
270:                 }
271: 
272:                 $variable->setValue($value);
273:             }
274:             else if ($variable->isBoolType())
275:             {
276:                 $variable->setValue(true);
277:             }
278: 
279:             $this->commands[$variable->name()] = $variable->isBoolType()
280:                 ? (bool)$variable->value() :
281:                 $variable->value();
282:         }
283: 
284:         foreach ($this->variables as $variable)
285:         {
286:             if (!isset($this->commands[$variable->name()]))
287:             {
288:                 $this->commands[$variable->name()] = $variable->value();
289:             }
290:         }
291: 
292:         $this->run = true;
293:     }
294: 
295:     protected function &commands()
296:     {
297:         if (!$this->run)
298:         {
299:             throw new CLIRun('Start the run method');
300:         }
301: 
302:         return $this->commands;
303:     }
304: 
305:     /**
306:      * @return array
307:      */
308:     public function storage()
309:     {
310:         return $this->storage;
311:     }
312: 
313:     /**
314:      * @return array
315:      *
316:      * @throws CLIRun
317:      */
318:     public function asArray()
319:     {
320:         return $this->commands();
321:     }
322: 
323:     /**
324:      * @param $name
325:      *
326:      * @return mixed
327:      *
328:      * @throws CLIRun
329:      */
330:     public function __get($name)
331:     {
332:         if (isset($this->aliases[$name]))
333:         {
334:             /**
335:              * @var Variable $variable
336:              */
337:             $variable = $this->aliases[$name];
338:             $name     = $variable->name();
339:         }
340: 
341:         $commands = &$this->commands();
342: 
343:         return $commands[$name];
344:     }
345: 
346:     /**
347:      * @param $name
348:      * @param $value
349:      *
350:      * @throws \InvalidArgumentException
351:      */
352:     final public function __set($name, $value)
353:     {
354:         throw new \InvalidArgumentException(__METHOD__);
355:     }
356: 
357:     /**
358:      * @param $name
359:      *
360:      * @return bool
361:      *
362:      * @throws CLIRun
363:      */
364:     public function __isset($name)
365:     {
366:         $commands = &$this->commands();
367: 
368:         return isset($commands[$name]);
369:     }
370: 
371:     /**
372:      * @throws Required
373:      * @throws UndefinedVariable
374:      * @throws \InvalidArgumentException
375:      */
376:     public function run()
377:     {
378:         if ($this->run)
379:         {
380:             throw new \InvalidArgumentException(__METHOD__);
381:         }
382: 
383:         $string    = $this->init();
384:         $tokenizer = new Tokenizer($string);
385: 
386:         $storage = $tokenizer->run();
387:         $this->initStorage($storage);
388:         $this->initVariable($storage);
389:         $this->initRequired();
390:         $this->initUndefined();
391:         $this->loadCommand($this->commands);
392:     }
393: 
394: }
API documentation generated by ApiGen