Updated Drupal to 8.6. This goes with the following updates because it's possible...
[yaffs-website] / vendor / consolidation / output-formatters / src / Transformations / ReorderFields.php
1 <?php
2 namespace Consolidation\OutputFormatters\Transformations;
3
4 use Symfony\Component\Finder\Glob;
5 use Consolidation\OutputFormatters\Exception\UnknownFieldException;
6
7 /**
8  * Reorder the field labels based on the user-selected fields
9  * to display.
10  */
11 class ReorderFields
12 {
13     /**
14      * Given a simple list of user-supplied field keys or field labels,
15      * return a reordered version of the field labels matching the
16      * user selection.
17      *
18      * @param string|array $fields The user-selected fields
19      * @param array $fieldLabels An associative array mapping the field
20      *   key to the field label
21      * @param array $data The data that will be rendered.
22      *
23      * @return array
24      */
25     public function reorder($fields, $fieldLabels, $data)
26     {
27         $firstRow = reset($data);
28         if (!$firstRow) {
29             $firstRow = $fieldLabels;
30         }
31         if (empty($fieldLabels) && !empty($data)) {
32             $fieldLabels = array_combine(array_keys($firstRow), array_map('ucfirst', array_keys($firstRow)));
33         }
34         $fields = $this->getSelectedFieldKeys($fields, $fieldLabels);
35         if (empty($fields)) {
36             return array_intersect_key($fieldLabels, $firstRow);
37         }
38         return $this->reorderFieldLabels($fields, $fieldLabels, $data);
39     }
40
41     protected function reorderFieldLabels($fields, $fieldLabels, $data)
42     {
43         $result = [];
44         $firstRow = reset($data);
45         if (!$firstRow) {
46             $firstRow = $fieldLabels;
47         }
48         foreach ($fields as $field) {
49             if (array_key_exists($field, $firstRow)) {
50                 if (array_key_exists($field, $fieldLabels)) {
51                     $result[$field] = $fieldLabels[$field];
52                 }
53             }
54         }
55         return $result;
56     }
57
58     protected function getSelectedFieldKeys($fields, $fieldLabels)
59     {
60         if (empty($fieldLabels)) {
61             return [];
62         }
63         if (is_string($fields)) {
64             $fields = explode(',', $fields);
65         }
66         $selectedFields = [];
67         foreach ($fields as $field) {
68             $matchedFields = $this->matchFieldInLabelMap($field, $fieldLabels);
69             if (empty($matchedFields)) {
70                 throw new UnknownFieldException($field);
71             }
72             $selectedFields = array_merge($selectedFields, $matchedFields);
73         }
74         return $selectedFields;
75     }
76
77     protected function matchFieldInLabelMap($field, $fieldLabels)
78     {
79         $fieldRegex = $this->convertToRegex($field);
80         return
81             array_filter(
82                 array_keys($fieldLabels),
83                 function ($key) use ($fieldRegex, $fieldLabels) {
84                     $value = $fieldLabels[$key];
85                     return preg_match($fieldRegex, $value) || preg_match($fieldRegex, $key);
86                 }
87             );
88     }
89
90     /**
91      * Convert the provided string into a regex suitable for use in
92      * preg_match.
93      *
94      * Matching occurs in the same way as the Symfony Finder component:
95      * http://symfony.com/doc/current/components/finder.html#file-name
96      */
97     protected function convertToRegex($str)
98     {
99         return $this->isRegex($str) ? $str : Glob::toRegex($str);
100     }
101
102     /**
103      * Checks whether the string is a regex.  This function is copied from
104      * MultiplePcreFilterIterator in the Symfony Finder component.
105      *
106      * @param string $str
107      *
108      * @return bool Whether the given string is a regex
109      */
110     protected function isRegex($str)
111     {
112         if (preg_match('/^(.{3,}?)[imsxuADU]*$/', $str, $m)) {
113             $start = substr($m[1], 0, 1);
114             $end = substr($m[1], -1);
115
116             if ($start === $end) {
117                 return !preg_match('/[*?[:alnum:] \\\\]/', $start);
118             }
119
120             foreach (array(array('{', '}'), array('(', ')'), array('[', ']'), array('<', '>')) as $delimiters) {
121                 if ($start === $delimiters[0] && $end === $delimiters[1]) {
122                     return true;
123                 }
124             }
125         }
126
127         return false;
128     }
129 }