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 (is_string($fields)) {
61 $fields = explode(',', $fields);
64 foreach ($fields as $field) {
65 $matchedFields = $this->matchFieldInLabelMap($field, $fieldLabels);
66 if (empty($matchedFields)) {
67 throw new UnknownFieldException($field);
69 $selectedFields = array_merge($selectedFields, $matchedFields);
71 return $selectedFields;
74 protected function matchFieldInLabelMap($field, $fieldLabels)
76 $fieldRegex = $this->convertToRegex($field);
79 array_keys($fieldLabels),
80 function ($key) use ($fieldRegex, $fieldLabels) {
81 $value = $fieldLabels[$key];
82 return preg_match($fieldRegex, $value) || preg_match($fieldRegex, $key);
88 * Convert the provided string into a regex suitable for use in
91 * Matching occurs in the same way as the Symfony Finder component:
92 * http://symfony.com/doc/current/components/finder.html#file-name
94 protected function convertToRegex($str)
96 return $this->isRegex($str) ? $str : Glob::toRegex($str);
100 * Checks whether the string is a regex. This function is copied from
101 * MultiplePcreFilterIterator in the Symfony Finder component.
105 * @return bool Whether the given string is a regex
107 protected function isRegex($str)
109 if (preg_match('/^(.{3,}?)[imsxuADU]*$/', $str, $m)) {
110 $start = substr($m[1], 0, 1);
111 $end = substr($m[1], -1);
113 if ($start === $end) {
114 return !preg_match('/[*?[:alnum:] \\\\]/', $start);
117 foreach (array(array('{', '}'), array('(', ')'), array('[', ']'), array('<', '>')) as $delimiters) {
118 if ($start === $delimiters[0] && $end === $delimiters[1]) {