annotate vendor/consolidation/output-formatters/src/Transformations/ReorderFields.php @ 0:4c8ae668cc8c

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