Completed
Pull Request — 8.x-3.x (#525)
by Philipp
02:12
created

StringHelper::parseType()   C

Complexity

Conditions 8
Paths 6

Size

Total Lines 23
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
eloc 13
nc 6
nop 1
dl 0
loc 23
rs 6.1403
c 0
b 0
f 0
1
<?php
2
3
namespace Drupal\graphql\Utility;
4
5
class StringHelper {
6
7
  /**
8
   * Turn a list of machine names into a camel-cased string.
9
   *
10
   * @return string
11
   *   A camel-cased concatenation of the input components.
12
   *
13
   * @throws \InvalidArgumentException
14
   *   If the provided input does can't be converted to a specification compliant
15
   *   string representation for field or type names.
16
   */
17
  public static function camelCase() {
18
    $components = func_get_args();
19
    $string = is_array($components) ? implode('_', $components) : $components;
20
    $filtered = preg_replace('/^[^_a-zA-Z]+/', '', $string);
21
    $components = array_filter(preg_split('/[^a-zA-Z0-9]/', $filtered));
22
23
    if (!count($components)) {
24
      throw new \InvalidArgumentException(sprintf("Failed to create a specification compliant string representation for '%s'.", $string));
25
    }
26
27
    return implode('', array_map('ucfirst', $components));
28
  }
29
30
  /**
31
   * Turn a list of machine names into a property-cased string.
32
   *
33
   * @return string
34
   *   A camel-cased concatenation of the input components.
35
   */
36
  public static function propCase() {
37
    $result = call_user_func_array([static::class, 'camelCase'], func_get_args());
38
    return ctype_upper($result) ? strtolower($result) : lcfirst($result);
39
  }
40
41
  /**
42
   * Wraps a type string in brackets declaring it as a list.
43
   *
44
   * @param string $type
45
   *   The type to declare as a list.
46
   *
47
   * @return string
48
   *   The decorated type string.
49
   */
50
  public static function listType($type) {
51
    return "[$type]";
52
  }
53
54
  /**
55
   * Appends an exclamation mark to a type string declaring it as non-null.
56
   *
57
   * @param string $type
58
   *   The type to declare as non-null.
59
   *
60
   * @return string
61
   *   The decorated type string.
62
   */
63
  public static function nonNullType($type) {
64
    return "$type!";
65
  }
66
67
  /**
68
   * Decorates a type as non-null and/or as a list.
69
   *
70
   * @param string $type
71
   *   The type to declare as non-null.
72
   * @param bool $list
73
   *   Whether to mark the type as a list.
74
   * @param bool $required
75
   *   Whether to mark the type as required.
76
   *
77
   * @return string
78
   *   The decorated type.
79
   */
80
  public static function decorateType($type, $list = FALSE, $required = FALSE) {
81
    if (!empty($list)) {
82
      $type = static::listType($type);
83
    }
84
85
    if (!empty($required)) {
86
      $type = static::nonNullType($type);
87
    }
88
89
    return $type;
90
  }
91
92
  /**
93
   * Parses a type definition from a string and properly decorates it.
94
   *
95
   * Converts type strings (e.g. [Foo!]) to their object representations.
96
   *
97
   * @param string $type
98
   *   The type string to parse.
99
   *
100
   * @return array
101
   *   The extracted type with the type decorators.
102
   */
103
  public static function parseType($type) {
104
    $decorators = [];
105
    $unwrapped = $type;
106
    $matches = NULL;
107
108
    while (preg_match('/[\[\]!]/', $unwrapped) && preg_match_all('/^(\[?)(.*?)(\]?)(!*?)$/', $unwrapped, $matches)) {
109
      if ($unwrapped === $matches[2][0] || empty($matches[1][0]) !== empty($matches[3][0])) {
110
        throw new \InvalidArgumentException(sprintf("Invalid type declaration '%s'.", $type));
111
      }
112
113
      if (!empty($matches[4][0])) {
114
        array_unshift($decorators, ['GraphQL\Type\Definition\Type', 'nonNull']);
115
      }
116
117
      if (!empty($matches[1][0]) && !empty($matches[3][0])) {
118
        array_unshift($decorators, ['GraphQL\Type\Definition\Type', 'listOf']);
119
      }
120
121
      $unwrapped = $matches[2][0];
122
    }
123
124
    return [$unwrapped, $decorators];
125
  }
126
127
}