Security update for permissions_by_term
[yaffs-website] / vendor / behat / behat / src / Behat / Testwork / Output / Cli / OutputController.php
1 <?php
2
3 /*
4  * This file is part of the Behat Testwork.
5  * (c) Konstantin Kudryashov <ever.zet@gmail.com>
6  *
7  * For the full copyright and license information, please view the LICENSE
8  * file that was distributed with this source code.
9  */
10
11 namespace Behat\Testwork\Output\Cli;
12
13 use Behat\Testwork\Cli\Controller;
14 use Behat\Testwork\Output\Formatter;
15 use Behat\Testwork\Output\OutputManager;
16 use Symfony\Component\Console\Command\Command;
17 use Symfony\Component\Console\Input\InputInterface;
18 use Symfony\Component\Console\Input\InputOption;
19 use Symfony\Component\Console\Output\OutputInterface;
20
21 /**
22  * Configures formatters based on user input.
23  *
24  * @author Konstantin Kudryashov <ever.zet@gmail.com>
25  */
26 class OutputController implements Controller
27 {
28     /**
29      * @var OutputManager
30      */
31     private $manager;
32
33     /**
34      * Initializes controller.
35      *
36      * @param OutputManager $manager
37      */
38     public function __construct(OutputManager $manager)
39     {
40         $this->manager = $manager;
41     }
42
43     /**
44      * {@inheritdoc}
45      */
46     public function configure(Command $command)
47     {
48         $command
49             ->addOption(
50                 '--format', '-f', InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
51                 'How to format tests output. <comment>pretty</comment> is default.' . PHP_EOL .
52                 'Available formats are:' . PHP_EOL . $this->getFormatterDescriptions() .
53                 'You can use multiple formats at the same time.'
54             )
55             ->addOption(
56                 '--out', '-o', InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
57                 'Write format output to a file/directory instead of' . PHP_EOL .
58                 'STDOUT <comment>(output_path)</comment>. You can also provide different' . PHP_EOL .
59                 'outputs to multiple formats.'
60             )
61             ->addOption(
62                 '--format-settings', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
63                 'Set formatters parameters using json object.' . PHP_EOL .
64                 'Keys are parameter names, values are values.'
65             );
66     }
67
68     /**
69      * {@inheritdoc}
70      */
71     public function execute(InputInterface $input, OutputInterface $output)
72     {
73         $formats = $input->getOption('format');
74         $outputs = $input->getOption('out');
75
76         $this->configureFormatters($formats, $input, $output);
77         $this->configureOutputs($formats, $outputs, $output->isDecorated());
78     }
79
80     /**
81      * Configures formatters based on container, input and output configurations.
82      *
83      * @param array           $formats
84      * @param InputInterface  $input
85      * @param OutputInterface $output
86      */
87     protected function configureFormatters(array $formats, InputInterface $input, OutputInterface $output)
88     {
89         $this->enableFormatters($formats);
90         $this->setFormattersParameters($input, $output);
91     }
92
93     /**
94      * Enables formatters.
95      *
96      * @param array $formats
97      */
98     protected function enableFormatters(array $formats)
99     {
100         if (count($formats)) {
101             $this->manager->disableAllFormatters();
102             foreach ($formats as $format) {
103                 $this->manager->enableFormatter($format);
104             }
105         }
106     }
107
108     /**
109      * Sets formatters parameters based on input & output.
110      *
111      * @param InputInterface  $input
112      * @param OutputInterface $output
113      */
114     protected function setFormattersParameters(InputInterface $input, OutputInterface $output)
115     {
116         $this->manager->setFormattersParameter('output_decorate', $output->isDecorated());
117
118         if ($input->getOption('format-settings')) {
119             foreach ($input->getOption('format-settings') as $jsonSettings) {
120                 $this->loadJsonSettings($jsonSettings);
121             }
122         }
123     }
124
125     /**
126      * Locates output path from relative one.
127      *
128      * @param string $path
129      *
130      * @return string
131      */
132     protected function locateOutputPath($path)
133     {
134         if ($this->isAbsolutePath($path)) {
135             return $path;
136         }
137
138         $path = getcwd() . DIRECTORY_SEPARATOR . $path;
139
140         if (!file_exists($path)) {
141             touch($path);
142             $path = realpath($path);
143             unlink($path);
144         } else {
145             $path = realpath($path);
146         }
147
148         return $path;
149     }
150
151     /**
152      * Initializes multiple formatters with different outputs.
153      *
154      * @param array   $formats
155      * @param array   $outputs
156      * @param Boolean $decorated
157      */
158     private function configureOutputs(array $formats, array $outputs, $decorated = false)
159     {
160         if (1 == count($outputs) && !$this->isStandardOutput($outputs[0])) {
161             $outputPath = $this->locateOutputPath($outputs[0]);
162
163             $this->manager->setFormattersParameter('output_path', $outputPath);
164             $this->manager->setFormattersParameter('output_decorate', $decorated);
165
166             return;
167         }
168
169         foreach ($outputs as $i => $out) {
170             if ($this->isStandardOutput($out)) {
171                 continue;
172             }
173
174             $outputPath = $this->locateOutputPath($out);
175             if (isset($formats[$i])) {
176                 $this->manager->setFormatterParameter($formats[$i], 'output_path', $outputPath);
177                 $this->manager->setFormatterParameter($formats[$i], 'output_decorate', $decorated);
178             }
179         }
180     }
181
182     /**
183      * Checks if provided output identifier represents standard output.
184      *
185      * @param string $outputId
186      *
187      * @return Boolean
188      */
189     private function isStandardOutput($outputId)
190     {
191         return 'std' === $outputId || 'null' === $outputId || 'false' === $outputId;
192     }
193
194     /**
195      * Returns whether the file path is an absolute path.
196      *
197      * @param string $file A file path
198      *
199      * @return Boolean
200      */
201     private function isAbsolutePath($file)
202     {
203         if ($file[0] == '/' || $file[0] == '\\'
204             || (strlen($file) > 3 && ctype_alpha($file[0])
205                 && $file[1] == ':'
206                 && ($file[2] == '\\' || $file[2] == '/')
207             )
208             || null !== parse_url($file, PHP_URL_SCHEME)
209         ) {
210             return true;
211         }
212
213         return false;
214     }
215
216     /**
217      * Returns formatters description.
218      *
219      * @return string
220      */
221     private function getFormatterDescriptions()
222     {
223         return implode(
224             PHP_EOL,
225             array_map(
226                 function (Formatter $formatter) {
227                     $comment = '- <comment>' . $formatter->getName() . '</comment>: ';
228                     $comment .= $formatter->getDescription();
229
230                     return $comment;
231                 }, $this->manager->getFormatters()
232             )
233         ) . PHP_EOL;
234     }
235
236     /**
237      * Loads JSON settings as formatter parameters.
238      *
239      * @param string $jsonSettings
240      */
241     private function loadJsonSettings($jsonSettings)
242     {
243         $settings = @json_decode($jsonSettings, true);
244
245         if (!is_array($settings)) {
246             return;
247         }
248
249         foreach ($settings as $name => $value) {
250             $this->manager->setFormattersParameter($name, $value);
251         }
252     }
253 }