Updated to Drupal 8.5. Core Media not yet in use.
[yaffs-website] / vendor / drupal / console-core / src / Application.php
1 <?php
2
3 namespace Drupal\Console\Core;
4
5 use Drupal\Console\Core\EventSubscriber\RemoveMessagesListener;
6 use Drupal\Console\Core\EventSubscriber\ShowGenerateCountCodeLinesListener;
7 use Drupal\Console\Core\Utils\TranslatorManagerInterface;
8 use Symfony\Component\DependencyInjection\ContainerInterface;
9 use Symfony\Component\EventDispatcher\EventDispatcher;
10 use Symfony\Component\Console\Output\OutputInterface;
11 use Symfony\Component\Console\Input\InputInterface;
12 use Symfony\Component\Console\Input\InputOption;
13 use Symfony\Component\Console\Application as BaseApplication;
14 use Symfony\Component\Console\Input\ArrayInput;
15 use Drupal\Console\Core\EventSubscriber\DefaultValueEventListener;
16 use Drupal\Console\Core\EventSubscriber\ShowGenerateChainListener;
17 use Drupal\Console\Core\EventSubscriber\ShowTipsListener;
18 use Drupal\Console\Core\EventSubscriber\ShowWelcomeMessageListener;
19 use Drupal\Console\Core\EventSubscriber\ValidateExecutionListener;
20 use Drupal\Console\Core\EventSubscriber\ShowGeneratedFilesListener;
21 use Drupal\Console\Core\EventSubscriber\ShowGenerateInlineListener;
22 use Drupal\Console\Core\EventSubscriber\CallCommandListener;
23 use Drupal\Console\Core\Utils\ConfigurationManager;
24 use Drupal\Console\Core\Style\DrupalStyle;
25 use Drupal\Console\Core\Utils\ChainDiscovery;
26 use Drupal\Console\Core\Command\Chain\ChainCustomCommand;
27 use Drupal\Console\Core\Bootstrap\DrupalInterface;
28
29 /**
30  * Class Application
31  *
32  * @package Drupal\Console
33  */
34 class Application extends BaseApplication
35 {
36     /**
37      * @var ContainerInterface
38      */
39     protected $container;
40
41     /**
42      * @var string
43      */
44     protected $commandName;
45
46     /**
47      * @var DrupalInterface
48      */
49     protected $drupal;
50
51     /**
52      * @var bool
53      */
54     protected $eventRegistered;
55
56     /**
57      * ConsoleApplication constructor.
58      *
59      * @param ContainerInterface $container
60      * @param string             $name
61      * @param string             $version
62      */
63     public function __construct(
64         ContainerInterface $container,
65         $name,
66         $version
67     ) {
68         $this->container = $container;
69         $this->eventRegistered = false;
70         parent::__construct($name, $version);
71         $this->addOptions();
72     }
73
74     /**
75      * @return TranslatorManagerInterface
76      */
77     public function getTranslator()
78     {
79         if ($this->container) {
80             return $this->container->get('console.translator_manager');
81         }
82
83         return null;
84     }
85
86     /**
87      * @param $key string
88      *
89      * @return string
90      */
91     public function trans($key)
92     {
93         if ($this->getTranslator()) {
94             return $this->getTranslator()->trans($key);
95         }
96
97         return null;
98     }
99
100     /**
101      * {@inheritdoc}
102      */
103     public function doRun(InputInterface $input, OutputInterface $output)
104     {
105         $io = new DrupalStyle($input, $output);
106         $messageManager = $this->container->get('console.message_manager');
107         $this->commandName = $this->getCommandName($input)?:'list';
108
109         $clear = $this->container->get('console.configuration_manager')
110             ->getConfiguration()
111             ->get('application.clear')?:false;
112         if ($clear === true || $clear === 'true') {
113             $output->write(sprintf("\033\143"));
114         }
115
116         $this->loadCommands();
117
118         /**
119          * @var ConfigurationManager $configurationManager
120          */
121         $configurationManager = $this->container
122             ->get('console.configuration_manager');
123
124         if (!$this->has($this->commandName)) {
125             $isValidCommand = false;
126             $config = $configurationManager->getConfiguration();
127             $mappings = $config->get('application.commands.mappings');
128
129             if (array_key_exists($this->commandName, $mappings)) {
130                 $commandNameMap = $mappings[$this->commandName];
131                 $messageManager->warning(
132                     sprintf(
133                         $this->trans('application.errors.renamed-command'),
134                         $this->commandName,
135                         $commandNameMap
136                     )
137                 );
138                 $this->add(
139                     $this->find($commandNameMap)->setAliases([$this->commandName])
140                 );
141                 $isValidCommand = true;
142             }
143
144             $drushCommand = $configurationManager->readDrushEquivalents($this->commandName);
145             if ($drushCommand) {
146                 $this->add(
147                     $this->find($drushCommand)->setAliases([$this->commandName])
148                 );
149                 $isValidCommand = true;
150                 $messageManager->warning(
151                     sprintf(
152                         $this->trans('application.errors.drush-command'),
153                         $this->commandName,
154                         $drushCommand
155                     )
156                 );
157             }
158
159             $namespaces = $this->getNamespaces();
160             if (in_array($this->commandName, $namespaces)) {
161                 $input = new ArrayInput(
162                     [
163                         'command' => 'list',
164                         'namespace' => $this->commandName
165                     ]
166                 );
167                 $this->commandName = 'list';
168                 $isValidCommand = true;
169             }
170
171             if (!$isValidCommand) {
172                 $io->error(
173                     sprintf(
174                         $this->trans('application.errors.invalid-command'),
175                         $this->commandName
176                     )
177                 );
178
179                 return 1;
180             }
181         }
182
183         $code = parent::doRun(
184             $input,
185             $output
186         );
187
188         // Propagate Drupal messages.
189         $this->addDrupalMessages($messageManager);
190
191         if ($this->showMessages($input)) {
192             $messages = $messageManager->getMessages();
193
194             foreach ($messages as $message) {
195                 $showBy = $message['showBy'];
196                 if ($showBy!=='all' && $showBy!==$this->commandName) {
197                     continue;
198                 }
199                 $type = $message['type'];
200                 $io->$type($message['message']);
201             }
202         }
203
204
205         return $code;
206     }
207
208     public function loadCommands()
209     {
210         $this->registerGenerators();
211         $this->registerCommands();
212         $this->registerEvents();
213         $this->registerExtendCommands();
214
215         /**
216          * @var ConfigurationManager $configurationManager
217          */
218         $configurationManager = $this->container
219             ->get('console.configuration_manager');
220
221         $config = $configurationManager->getConfiguration()
222             ->get('application.extras.config')?:'true';
223         if ($config === 'true') {
224             $this->registerCommandsFromAutoWireConfiguration();
225         }
226
227         $chains = $configurationManager->getConfiguration()
228             ->get('application.extras.chains')?:'true';
229         if ($chains === 'true') {
230             $this->registerChainCommands();
231         }
232     }
233
234     /**
235      * @param InputInterface $input
236      *
237      * @return bool
238      */
239     private function showMessages(InputInterface $input)
240     {
241         $format = $input->hasOption('format')?$input->getOption('format'):'txt';
242
243         if ($format !== 'txt') {
244             return false;
245         }
246
247         return true;
248     }
249
250     /**
251      * registerEvents
252      */
253     private function registerEvents()
254     {
255         if (!$this->eventRegistered) {
256             $dispatcher = new EventDispatcher();
257             $dispatcher->addSubscriber(
258                 new ValidateExecutionListener(
259                     $this->container->get('console.translator_manager'),
260                     $this->container->get('console.configuration_manager')
261                 )
262             );
263             $dispatcher->addSubscriber(
264                 new ShowWelcomeMessageListener(
265                     $this->container->get('console.translator_manager')
266                 )
267             );
268             $dispatcher->addSubscriber(
269                 new DefaultValueEventListener(
270                     $this->container->get('console.configuration_manager')
271                 )
272             );
273             $dispatcher->addSubscriber(
274                 new ShowTipsListener(
275                     $this->container->get('console.translator_manager')
276                 )
277             );
278             $dispatcher->addSubscriber(
279                 new CallCommandListener(
280                     $this->container->get('console.chain_queue')
281                 )
282             );
283             $dispatcher->addSubscriber(
284                 new ShowGeneratedFilesListener(
285                     $this->container->get('console.file_queue'),
286                     $this->container->get('console.show_file')
287                 )
288             );
289             $dispatcher->addSubscriber(
290                 new ShowGenerateInlineListener(
291                     $this->container->get('console.translator_manager')
292                 )
293             );
294             $dispatcher->addSubscriber(
295                 new ShowGenerateChainListener(
296                     $this->container->get('console.translator_manager')
297                 )
298             );
299
300             $dispatcher->addSubscriber(
301                 new ShowGenerateCountCodeLinesListener(
302                     $this->container->get('console.translator_manager'),
303                     $this->container->get('console.count_code_lines')
304                 )
305             );
306
307             $dispatcher->addSubscriber(
308                 new RemoveMessagesListener(
309                     $this->container->get('console.message_manager')
310                 )
311             );
312
313             $this->setDispatcher($dispatcher);
314             $this->eventRegistered = true;
315         }
316     }
317
318     /**
319      * addOptions
320      */
321     private function addOptions()
322     {
323         // Get the configuration from config.yml.
324         $env = $this->container
325             ->get('console.configuration_manager')
326             ->getConfiguration()
327             ->get('application.environment');
328
329         $this->getDefinition()->addOption(
330             new InputOption(
331                 '--env',
332                 '-e',
333                 InputOption::VALUE_OPTIONAL,
334                 $this->trans('application.options.env'),
335                 !empty($env) ? $env : 'prod'
336             )
337         );
338         $this->getDefinition()->addOption(
339             new InputOption(
340                 '--root',
341                 null,
342                 InputOption::VALUE_OPTIONAL,
343                 $this->trans('application.options.root')
344             )
345         );
346         $this->getDefinition()->addOption(
347             new InputOption(
348                 '--debug',
349                 null,
350                 InputOption::VALUE_NONE,
351                 $this->trans('application.options.debug')
352             )
353         );
354         $this->getDefinition()->addOption(
355             new InputOption(
356                 '--learning',
357                 null,
358                 InputOption::VALUE_NONE,
359                 $this->trans('application.options.learning')
360             )
361         );
362         $this->getDefinition()->addOption(
363             new InputOption(
364                 '--generate-chain',
365                 '-c',
366                 InputOption::VALUE_NONE,
367                 $this->trans('application.options.generate-chain')
368             )
369         );
370         $this->getDefinition()->addOption(
371             new InputOption(
372                 '--generate-inline',
373                 '-i',
374                 InputOption::VALUE_NONE,
375                 $this->trans('application.options.generate-inline')
376             )
377         );
378         $this->getDefinition()->addOption(
379             new InputOption(
380                 '--generate-doc',
381                 '-d',
382                 InputOption::VALUE_NONE,
383                 $this->trans('application.options.generate-doc')
384             )
385         );
386         $this->getDefinition()->addOption(
387             new InputOption(
388                 '--target',
389                 '-t',
390                 InputOption::VALUE_OPTIONAL,
391                 $this->trans('application.options.target')
392             )
393         );
394         $this->getDefinition()->addOption(
395             new InputOption(
396                 '--uri',
397                 '-l',
398                 InputOption::VALUE_REQUIRED,
399                 $this->trans('application.options.uri')
400             )
401         );
402         $this->getDefinition()->addOption(
403             new InputOption(
404                 '--yes',
405                 '-y',
406                 InputOption::VALUE_NONE,
407                 $this->trans('application.options.yes')
408             )
409         );
410     }
411
412     /**
413      * registerCommands
414      */
415     private function registerCommands()
416     {
417         $consoleCommands = $this->container
418             ->findTaggedServiceIds('drupal.command');
419
420         $aliases = $this->container->get('console.configuration_manager')
421             ->getConfiguration()
422             ->get('application.commands.aliases')?:[];
423
424         $invalidCommands = [];
425         if ($this->container->has('console.key_value_storage')) {
426             $invalidCommands = $this->container
427                 ->get('console.key_value_storage')
428                 ->get('invalid_commands', []);
429         }
430
431         foreach ($consoleCommands as $name => $tags) {
432             if (in_array($name, $invalidCommands)) {
433                 continue;
434             }
435
436             if (!$this->container->has($name)) {
437                 continue;
438             }
439
440             try {
441                 $command = $this->container->get($name);
442             } catch (\Exception $e) {
443                 echo $name . ' - ' . $e->getMessage() . PHP_EOL;
444
445                 continue;
446             }
447
448             if (!$command) {
449                 continue;
450             }
451
452             if (method_exists($command, 'setTranslator')) {
453                 $command->setTranslator(
454                     $this->container->get('console.translator_manager')
455                 );
456             }
457
458             if (method_exists($command, 'setContainer')) {
459                 $command->setContainer(
460                     $this->container->get('service_container')
461                 );
462             }
463
464             if (method_exists($command, 'setDrupalFinder')) {
465                 $command->setDrupalFinder(
466                     $this->container->get('console.drupal_finder')
467                 );
468             }
469
470             if (array_key_exists($command->getName(), $aliases)) {
471                 $commandAliases = $aliases[$command->getName()];
472                 if (!is_array($commandAliases)) {
473                     $commandAliases = [$commandAliases];
474                 }
475                 $commandAliases = array_merge(
476                     $command->getAliases(),
477                     $commandAliases
478                 );
479                 $command->setAliases($commandAliases);
480             }
481
482             $this->add($command);
483         }
484     }
485
486     /**
487      * registerGenerators
488      */
489     private function registerGenerators()
490     {
491         $consoleGenerators = $this->container
492             ->findTaggedServiceIds('drupal.generator');
493
494         foreach ($consoleGenerators as $name => $tags) {
495             if (!$this->container->has($name)) {
496                 continue;
497             }
498
499             try {
500                 $generator = $this->container->get($name);
501             } catch (\Exception $e) {
502                 echo $name . ' - ' . $e->getMessage() . PHP_EOL;
503
504                 continue;
505             }
506
507             if (!$generator) {
508                 continue;
509             }
510
511             if (method_exists($generator, 'setRenderer')) {
512                 $generator->setRenderer(
513                     $this->container->get('console.renderer')
514                 );
515             }
516
517             if (method_exists($generator, 'setFileQueue')) {
518                 $generator->setFileQueue(
519                     $this->container->get('console.file_queue')
520                 );
521             }
522
523             if (method_exists($generator, 'setCountCodeLines')) {
524                 $generator->setCountCodeLines(
525                     $this->container->get('console.count_code_lines')
526                 );
527             }
528
529             if (method_exists($generator, 'setDrupalFinder')) {
530                 $generator->setDrupalFinder(
531                     $this->container->get('console.drupal_finder')
532                 );
533             }
534         }
535     }
536
537     /**
538      * registerCommandsFromAutoWireConfiguration
539      */
540     private function registerCommandsFromAutoWireConfiguration()
541     {
542         $configuration = $this->container->get('console.configuration_manager')
543             ->getConfiguration();
544
545         $autoWireForcedCommands = $configuration
546             ->get('application.autowire.commands.forced');
547
548         if (!is_array($autoWireForcedCommands)) {
549             return;
550         }
551
552         foreach ($autoWireForcedCommands as $autoWireForcedCommand) {
553             try {
554                 if (!$autoWireForcedCommand['class']) {
555                     continue;
556                 }
557
558                 $reflectionClass = new \ReflectionClass(
559                     $autoWireForcedCommand['class']
560                 );
561
562                 $arguments = [];
563                 if (array_key_exists('arguments', $autoWireForcedCommand)) {
564                     foreach ($autoWireForcedCommand['arguments'] as $argument) {
565                         $argument = substr($argument, 1);
566                         $arguments[] = $this->container->get($argument);
567                     }
568                 }
569
570                 $command = $reflectionClass->newInstanceArgs($arguments);
571
572                 if (method_exists($command, 'setTranslator')) {
573                     $command->setTranslator(
574                         $this->container->get('console.translator_manager')
575                     );
576                 }
577                 if (method_exists($command, 'setContainer')) {
578                     $command->setContainer(
579                         $this->container->get('service_container')
580                     );
581                 }
582
583                 $this->add($command);
584             } catch (\Exception $e) {
585                 echo $e->getMessage() . PHP_EOL;
586                 continue;
587             }
588         }
589
590         $autoWireNameCommand = $configuration->get(
591             sprintf(
592                 'application.autowire.commands.name.%s',
593                 $this->commandName
594             )
595         );
596
597         if ($autoWireNameCommand) {
598             try {
599                 $arguments = [];
600                 if (array_key_exists('arguments', $autoWireNameCommand)) {
601                     foreach ($autoWireNameCommand['arguments'] as $argument) {
602                         $argument = substr($argument, 1);
603                         $arguments[] = $this->container->get($argument);
604                     }
605                 }
606
607                 $reflectionClass = new \ReflectionClass(
608                     $autoWireNameCommand['class']
609                 );
610                 $command = $reflectionClass->newInstanceArgs($arguments);
611
612                 if (method_exists($command, 'setTranslator')) {
613                     $command->setTranslator(
614                         $this->container->get('console.translator_manager')
615                     );
616                 }
617                 if (method_exists($command, 'setContainer')) {
618                     $command->setContainer(
619                         $this->container->get('service_container')
620                     );
621                 }
622
623                 $this->add($command);
624             } catch (\Exception $e) {
625                 echo $e->getMessage() . PHP_EOL;
626             }
627         }
628     }
629
630     /**
631      * registerChainCommands
632      */
633     public function registerChainCommands()
634     {
635         /**
636          * @var ChainDiscovery $chainDiscovery
637          */
638         $chainDiscovery = $this->container->get('console.chain_discovery');
639         $chainCommands = $chainDiscovery->getChainCommands();
640
641         foreach ($chainCommands as $name => $chainCommand) {
642             try {
643                 $file = $chainCommand['file'];
644                 $description = $chainCommand['description'];
645                 $command = new ChainCustomCommand(
646                     $name,
647                     $description,
648                     $file,
649                     $chainDiscovery
650                 );
651                 $this->add($command);
652             } catch (\Exception $e) {
653                 echo $e->getMessage() . PHP_EOL;
654             }
655         }
656     }
657
658     /**
659      * registerExtendCommands
660      */
661     private function registerExtendCommands()
662     {
663         $this->container->get('console.configuration_manager')
664             ->loadExtendConfiguration();
665     }
666
667     public function getData()
668     {
669         $singleCommands = [
670             'about',
671             'chain',
672             'check',
673             'composerize',
674             'exec',
675             'help',
676             'init',
677             'list',
678             'shell',
679             'server'
680         ];
681
682         $languages = $this->container->get('console.configuration_manager')
683             ->getConfiguration()
684             ->get('application.languages');
685
686         $data = [];
687         foreach ($singleCommands as $singleCommand) {
688             $data['commands']['misc'][] = $this->commandData($singleCommand);
689         }
690
691         $namespaces = array_filter(
692             $this->getNamespaces(), function ($item) {
693                 return (strpos($item, ':')<=0);
694             }
695         );
696         sort($namespaces);
697         array_unshift($namespaces, 'misc');
698
699         foreach ($namespaces as $namespace) {
700             $commands = $this->all($namespace);
701             usort(
702                 $commands, function ($cmd1, $cmd2) {
703                     return strcmp($cmd1->getName(), $cmd2->getName());
704                 }
705             );
706
707             foreach ($commands as $command) {
708                 if (method_exists($command, 'getModule')) {
709                     if ($command->getModule() == 'Console') {
710                         $data['commands'][$namespace][] = $this->commandData(
711                             $command->getName()
712                         );
713                     }
714                 } else {
715                     $data['commands'][$namespace][] = $this->commandData(
716                         $command->getName()
717                     );
718                 }
719             }
720         }
721
722         $input = $this->getDefinition();
723         $options = [];
724         foreach ($input->getOptions() as $option) {
725             $options[] = [
726                 'name' => $option->getName(),
727                 'description' => $this->trans('application.options.'.$option->getName())
728             ];
729         }
730         $arguments = [];
731         foreach ($input->getArguments() as $argument) {
732             $arguments[] = [
733                 'name' => $argument->getName(),
734                 'description' => $this->trans('application.arguments.'.$argument->getName())
735             ];
736         }
737
738         $data['application'] = [
739             'namespaces' => $namespaces,
740             'options' => $options,
741             'arguments' => $arguments,
742             'languages' => $languages,
743             'messages' => [
744                 'title' => $this->trans('application.gitbook.messages.title'),
745                 'note' =>  $this->trans('application.gitbook.messages.note'),
746                 'note_description' =>  $this->trans('application.gitbook.messages.note-description'),
747                 'command' =>  $this->trans('application.gitbook.messages.command'),
748                 'options' => $this->trans('application.gitbook.messages.options'),
749                 'option' => $this->trans('application.gitbook.messages.option'),
750                 'details' => $this->trans('application.gitbook.messages.details'),
751                 'arguments' => $this->trans('application.gitbook.messages.arguments'),
752                 'argument' => $this->trans('application.gitbook.messages.argument'),
753                 'examples' => $this->trans('application.gitbook.messages.examples')
754             ],
755             'examples' => []
756         ];
757
758         return $data;
759     }
760
761     private function commandData($commandName)
762     {
763         if (!$this->has($commandName)) {
764             return [];
765         }
766
767         $command = $this->find($commandName);
768
769         $input = $command->getDefinition();
770         $options = [];
771         foreach ($input->getOptions() as $option) {
772             $options[$option->getName()] = [
773                 'name' => $option->getName(),
774                 'description' => $this->trans($option->getDescription()),
775             ];
776         }
777
778         $arguments = [];
779         foreach ($input->getArguments() as $argument) {
780             $arguments[$argument->getName()] = [
781                 'name' => $argument->getName(),
782                 'description' => $this->trans($argument->getDescription()),
783             ];
784         }
785
786         $commandKey = str_replace(':', '.', $command->getName());
787
788         $examples = [];
789         for ($i = 0; $i < 5; $i++) {
790             $description = sprintf(
791                 'commands.%s.examples.%s.description',
792                 $commandKey,
793                 $i
794             );
795             $execution = sprintf(
796                 'commands.%s.examples.%s.execution',
797                 $commandKey,
798                 $i
799             );
800
801             if ($description != $this->trans($description)) {
802                 $examples[] = [
803                     'description' => $this->trans($description),
804                     'execution' => $this->trans($execution)
805                 ];
806             } else {
807                 break;
808             }
809         }
810
811         $data = [
812             'name' => $command->getName(),
813             'description' => $command->getDescription(),
814             'options' => $options,
815             'arguments' => $arguments,
816             'examples' => $examples,
817             'aliases' => $command->getAliases(),
818             'key' => $commandKey,
819             'dashed' => str_replace(':', '-', $command->getName()),
820             'messages' => [
821                 'usage' =>  $this->trans('application.gitbook.messages.usage'),
822                 'options' => $this->trans('application.gitbook.messages.options'),
823                 'option' => $this->trans('application.gitbook.messages.option'),
824                 'details' => $this->trans('application.gitbook.messages.details'),
825                 'arguments' => $this->trans('application.gitbook.messages.arguments'),
826                 'argument' => $this->trans('application.gitbook.messages.argument'),
827                 'examples' => $this->trans('application.gitbook.messages.examples')
828             ],
829         ];
830
831         return $data;
832     }
833
834     /**
835      * @return DrupalInterface
836      */
837     public function getDrupal()
838     {
839         return $this->drupal;
840     }
841
842     /**
843      * @param DrupalInterface $drupal
844      */
845     public function setDrupal($drupal)
846     {
847         $this->drupal = $drupal;
848     }
849
850     public function setContainer($container)
851     {
852         $this->container = $container;
853     }
854
855     public function getContainer()
856     {
857         return $this->container;
858     }
859
860     /**
861      * Add Drupal system messages.
862      */
863     protected function addDrupalMessages($messageManager) {
864         if (function_exists('drupal_get_messages')) {
865             $drupalMessages = drupal_get_messages();
866             foreach ($drupalMessages as $type => $messages) {
867                 foreach ($messages as $message) {
868                     $method = $this->getMessageMethod($type);
869                     $messageManager->{$method}((string)$message);
870                 }
871             }
872         }
873     }
874
875     /**
876      * Gets method name for MessageManager.
877      *
878      * @param string $type
879      *   Type of the message.
880      *
881      * @return string
882      *   Name of the method
883      */
884     protected function getMessageMethod($type) {
885         $methodName = 'info';
886         switch ($type) {
887             case 'error':
888             case 'warning':
889                 $methodName = $type;
890                 break;
891         }
892
893         return $methodName;
894     }
895
896     /**
897      * Finds a command by name or alias.
898      *
899      * @param string $name A command name or a command alias
900      *
901      * @return mixed A Command instance
902      *
903      * Override parent find method to avoid name collisions with automatically
904      * generated command abbreviations.
905      * Command name validation was previously done at doRun method.
906      */
907     public function find($name)
908     {
909         return $this->get($name);
910     }
911 }