Upgraded drupal core with security updates
[yaffs-website] / vendor / psy / psysh / src / Psy / Input / FilterOptions.php
1 <?php
2
3 /*
4  * This file is part of Psy Shell.
5  *
6  * (c) 2012-2017 Justin Hileman
7  *
8  * For the full copyright and license information, please view the LICENSE
9  * file that was distributed with this source code.
10  */
11
12 namespace Psy\Input;
13
14 use Psy\Exception\RuntimeException;
15 use Symfony\Component\Console\Input\InputInterface;
16 use Symfony\Component\Console\Input\InputOption;
17
18 /**
19  * Parse, validate and match --grep, --insensitive and --invert command options.
20  */
21 class FilterOptions
22 {
23     private $filter = false;
24     private $pattern;
25     private $insensitive;
26     private $invert;
27
28     /**
29      * Get input option definitions for filtering.
30      *
31      * @return InputOption[]
32      */
33     public static function getOptions()
34     {
35         return array(
36             new InputOption('grep',        'G', InputOption::VALUE_REQUIRED, 'Limit to items matching the given pattern (string or regex).'),
37             new InputOption('insensitive', 'i', InputOption::VALUE_NONE,     'Case-insensitive search (requires --grep).'),
38             new InputOption('invert',      'v', InputOption::VALUE_NONE,     'Inverted search (requires --grep).'),
39         );
40     }
41
42     /**
43      * Bind input and prepare filter.
44      *
45      * @param InputInterface $input
46      */
47     public function bind(InputInterface $input)
48     {
49         $this->validateInput($input);
50
51         if (!$pattern = $input->getOption('grep')) {
52             $this->filter = false;
53
54             return;
55         }
56
57         if (!$this->stringIsRegex($pattern)) {
58             $pattern = '/' . preg_quote($pattern, '/') . '/';
59         }
60
61         if ($insensitive = $input->getOption('insensitive')) {
62             $pattern .= 'i';
63         }
64
65         $this->validateRegex($pattern);
66
67         $this->filter      = true;
68         $this->pattern     = $pattern;
69         $this->insensitive = $insensitive;
70         $this->invert      = $input->getOption('invert');
71     }
72
73     /**
74      * Check whether the bound input has filter options.
75      *
76      * @return bool
77      */
78     public function hasFilter()
79     {
80         return $this->filter;
81     }
82
83     /**
84      * Check whether a string matches the current filter options.
85      *
86      * @param string $string
87      * @param array  $matches
88      *
89      * @return bool
90      */
91     public function match($string, array &$matches = null)
92     {
93         return $this->filter === false || (preg_match($this->pattern, $string, $matches) xor $this->invert);
94     }
95
96     /**
97      * Validate that grep, invert and insensitive input options are consistent.
98      *
99      * @param InputInterface $input
100      *
101      * @return bool
102      */
103     private function validateInput(InputInterface $input)
104     {
105         if (!$input->getOption('grep')) {
106             foreach (array('invert', 'insensitive') as $option) {
107                 if ($input->getOption($option)) {
108                     throw new RuntimeException('--' . $option . ' does not make sense without --grep');
109                 }
110             }
111         }
112     }
113
114     /**
115      * Check whether a string appears to be a regular expression.
116      *
117      * @param string $string
118      *
119      * @return bool
120      */
121     private function stringIsRegex($string)
122     {
123         return substr($string, 0, 1) === '/' && substr($string, -1) === '/' && strlen($string) >= 3;
124     }
125
126     /**
127      * Validate that $pattern is a valid regular expression.
128      *
129      * @param string $pattern
130      *
131      * @return bool
132      */
133     private function validateRegex($pattern)
134     {
135         set_error_handler(array('Psy\Exception\ErrorException', 'throwException'));
136         try {
137             preg_match($pattern, '');
138         } catch (ErrorException $e) {
139             throw new RuntimeException(str_replace('preg_match(): ', 'Invalid regular expression: ', $e->getRawMessage()));
140         }
141         restore_error_handler();
142     }
143 }