2 namespace Consolidation\OutputFormatters\Transformations;
4 use Symfony\Component\Finder\Glob;
5 use Consolidation\OutputFormatters\Exception\UnknownFieldException;
8 * Reorder the field labels based on the user-selected fields
14 * Given a simple list of user-supplied field keys or field labels,
15 * return a reordered version of the field labels matching the
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.
25 public function reorder($fields, $fieldLabels, $data)
27 $firstRow = reset($data);
29 $firstRow = $fieldLabels;
31 if (empty($fieldLabels) && !empty($data)) {
32 $fieldLabels = array_combine(array_keys($firstRow), array_map('ucfirst', array_keys($firstRow)));
34 $fields = $this->getSelectedFieldKeys($fields, $fieldLabels);
36 return array_intersect_key($fieldLabels, $firstRow);
38 return $this->reorderFieldLabels($fields, $fieldLabels, $data);
41 protected function reorderFieldLabels($fields, $fieldLabels, $data)
44 $firstRow = reset($data);
46 $firstRow = $fieldLabels;
48 foreach ($fields as $field) {
49 if (array_key_exists($field, $firstRow)) {
50 if (array_key_exists($field, $fieldLabels)) {
51 $result[$field] = $fieldLabels[$field];
58 protected function getSelectedFieldKeys($fields, $fieldLabels)
60 if (empty($fieldLabels)) {
63 if (is_string($fields)) {
64 $fields = explode(',', $fields);
67 foreach ($fields as $field) {
68 $matchedFields = $this->matchFieldInLabelMap($field, $fieldLabels);
69 if (empty($matchedFields)) {
70 throw new UnknownFieldException($field);
72 $selectedFields = array_merge($selectedFields, $matchedFields);
74 return $selectedFields;
77 protected function matchFieldInLabelMap($field, $fieldLabels)
79 $fieldRegex = $this->convertToRegex($field);
82 array_keys($fieldLabels),
83 function ($key) use ($fieldRegex, $fieldLabels) {
84 $value = $fieldLabels[$key];
85 return preg_match($fieldRegex, $value) || preg_match($fieldRegex, $key);
91 * Convert the provided string into a regex suitable for use in
94 * Matching occurs in the same way as the Symfony Finder component:
95 * http://symfony.com/doc/current/components/finder.html#file-name
97 protected function convertToRegex($str)
99 return $this->isRegex($str) ? $str : Glob::toRegex($str);
103 * Checks whether the string is a regex. This function is copied from
104 * MultiplePcreFilterIterator in the Symfony Finder component.
108 * @return bool Whether the given string is a regex
110 protected function isRegex($str)
112 if (preg_match('/^(.{3,}?)[imsxuADU]*$/', $str, $m)) {
113 $start = substr($m[1], 0, 1);
114 $end = substr($m[1], -1);
116 if ($start === $end) {
117 return !preg_match('/[*?[:alnum:] \\\\]/', $start);
120 foreach (array(array('{', '}'), array('(', ')'), array('[', ']'), array('<', '>')) as $delimiters) {
121 if ($start === $delimiters[0] && $end === $delimiters[1]) {