Chris@0
|
1 <?php
|
Chris@0
|
2
|
Chris@0
|
3 namespace DrupalCodeGenerator;
|
Chris@0
|
4
|
Chris@0
|
5 use Symfony\Component\Console\Question\Question;
|
Chris@0
|
6
|
Chris@0
|
7 /**
|
Chris@0
|
8 * Helper methods for code generators.
|
Chris@0
|
9 */
|
Chris@0
|
10 class Utils {
|
Chris@0
|
11
|
Chris@5
|
12 use LegacyUtilsTrait;
|
Chris@5
|
13
|
Chris@0
|
14 /**
|
Chris@0
|
15 * Creates default plugin ID.
|
Chris@0
|
16 */
|
Chris@0
|
17 public static function defaultPluginId(array $vars) {
|
Chris@0
|
18 return $vars['machine_name'] . '_' . self::human2machine($vars['plugin_label']);
|
Chris@0
|
19 }
|
Chris@0
|
20
|
Chris@0
|
21 /**
|
Chris@0
|
22 * Transforms a machine name to human name.
|
Chris@0
|
23 */
|
Chris@0
|
24 public static function machine2human($machine_name) {
|
Chris@0
|
25 return ucfirst(trim(str_replace('_', ' ', $machine_name)));
|
Chris@0
|
26 }
|
Chris@0
|
27
|
Chris@0
|
28 /**
|
Chris@0
|
29 * Transforms a human name to machine name.
|
Chris@0
|
30 */
|
Chris@0
|
31 public static function human2machine($human_name) {
|
Chris@0
|
32 return trim(preg_replace(
|
Chris@0
|
33 ['/^[0-9]+/', '/[^a-z0-9_]+/'],
|
Chris@0
|
34 '_',
|
Chris@0
|
35 strtolower($human_name)
|
Chris@0
|
36 ), '_');
|
Chris@0
|
37 }
|
Chris@0
|
38
|
Chris@0
|
39 /**
|
Chris@4
|
40 * Transforms a camelized sting to machine name.
|
Chris@4
|
41 */
|
Chris@4
|
42 public static function camel2machine($input) {
|
Chris@4
|
43 return self::human2machine(preg_replace('/[A-Z]/', ' \0', $input));
|
Chris@4
|
44 }
|
Chris@4
|
45
|
Chris@4
|
46 /**
|
Chris@0
|
47 * Camelize a string.
|
Chris@0
|
48 */
|
Chris@0
|
49 public static function camelize($string, $upper_camel = TRUE) {
|
Chris@0
|
50 $output = preg_replace('/([^A-Z])([A-Z])/', '$1 $2', $string);
|
Chris@0
|
51 $output = strtolower($output);
|
Chris@0
|
52 $output = preg_replace('/[^a-z0-9]/', ' ', $output);
|
Chris@0
|
53 $output = trim($output);
|
Chris@0
|
54 $output = ucwords($output);
|
Chris@0
|
55 $output = str_replace(' ', '', $output);
|
Chris@0
|
56 return $upper_camel ? $output : lcfirst($output);
|
Chris@0
|
57 }
|
Chris@0
|
58
|
Chris@0
|
59 /**
|
Chris@0
|
60 * Machine name validator.
|
Chris@0
|
61 */
|
Chris@0
|
62 public static function validateMachineName($value) {
|
Chris@0
|
63 if (!preg_match('/^[a-z][a-z0-9_]*[a-z0-9]$/', $value)) {
|
Chris@0
|
64 throw new \UnexpectedValueException('The value is not correct machine name.');
|
Chris@0
|
65 }
|
Chris@0
|
66 return $value;
|
Chris@0
|
67 }
|
Chris@0
|
68
|
Chris@0
|
69 /**
|
Chris@0
|
70 * Class name validator.
|
Chris@0
|
71 *
|
Chris@0
|
72 * @see http://php.net/manual/en/language.oop5.basic.php
|
Chris@0
|
73 */
|
Chris@0
|
74 public static function validateClassName($value) {
|
Chris@0
|
75 if (!preg_match('/^[A-Z][a-zA-Z0-9]+$/', $value)) {
|
Chris@0
|
76 throw new \UnexpectedValueException('The value is not correct class name.');
|
Chris@0
|
77 }
|
Chris@0
|
78 return $value;
|
Chris@0
|
79 }
|
Chris@0
|
80
|
Chris@0
|
81 /**
|
Chris@4
|
82 * Service name validator.
|
Chris@4
|
83 */
|
Chris@4
|
84 public static function validateServiceName($value) {
|
Chris@4
|
85 if ($value !== '' && !preg_match('/^[a-z][a-z0-9_\.]*[a-z0-9]$/', $value)) {
|
Chris@4
|
86 throw new \UnexpectedValueException('The value is not correct service name.');
|
Chris@4
|
87 }
|
Chris@4
|
88 return $value;
|
Chris@4
|
89 }
|
Chris@4
|
90
|
Chris@4
|
91 /**
|
Chris@0
|
92 * Required value validator.
|
Chris@0
|
93 */
|
Chris@0
|
94 public static function validateRequired($value) {
|
Chris@0
|
95 // FALSE is not considered as empty value because question helper use
|
Chris@0
|
96 // it as negative answer on confirmation questions.
|
Chris@0
|
97 if ($value === NULL || $value === '') {
|
Chris@0
|
98 throw new \UnexpectedValueException('The value is required.');
|
Chris@0
|
99 }
|
Chris@0
|
100 return $value;
|
Chris@0
|
101 }
|
Chris@0
|
102
|
Chris@0
|
103 /**
|
Chris@5
|
104 * Returns a validator for allowed options.
|
Chris@0
|
105 *
|
Chris@5
|
106 * @param array $options
|
Chris@5
|
107 * Allowed values.
|
Chris@5
|
108 *
|
Chris@5
|
109 * @return callable
|
Chris@5
|
110 * Question validator.
|
Chris@0
|
111 */
|
Chris@5
|
112 public static function getOptionsValidator(array $options) {
|
Chris@5
|
113 return function ($value) use ($options) {
|
Chris@5
|
114 if (!in_array($value, $options)) {
|
Chris@5
|
115 $options_formatted = implode(', ', $options);
|
Chris@5
|
116 $error_message = sprintf('The value should be one of the following: %s.', $options_formatted);
|
Chris@5
|
117 throw new \UnexpectedValueException($error_message);
|
Chris@0
|
118 }
|
Chris@5
|
119 return $value;
|
Chris@5
|
120 };
|
Chris@0
|
121 }
|
Chris@0
|
122
|
Chris@0
|
123 /**
|
Chris@0
|
124 * Returns default questions for module generators.
|
Chris@0
|
125 *
|
Chris@0
|
126 * @return \Symfony\Component\Console\Question\Question[]
|
Chris@5
|
127 * Array of module questions.
|
Chris@0
|
128 */
|
Chris@5
|
129 public static function moduleQuestions() {
|
Chris@0
|
130 $questions['name'] = new Question('Module name');
|
Chris@0
|
131 $questions['name']->setValidator([Utils::class, 'validateRequired']);
|
Chris@0
|
132 $questions['machine_name'] = new Question('Module machine name');
|
Chris@0
|
133 $questions['machine_name']->setValidator([Utils::class, 'validateMachineName']);
|
Chris@0
|
134 return $questions;
|
Chris@0
|
135 }
|
Chris@0
|
136
|
Chris@0
|
137 /**
|
Chris@0
|
138 * Returns default questions for plugin generators.
|
Chris@0
|
139 *
|
Chris@0
|
140 * @return \Symfony\Component\Console\Question\Question[]
|
Chris@5
|
141 * Array of plugin questions.
|
Chris@0
|
142 */
|
Chris@5
|
143 public static function pluginQuestions($class_suffix = '') {
|
Chris@0
|
144 $questions['plugin_label'] = new Question('Plugin label', 'Example');
|
Chris@0
|
145 $questions['plugin_label']->setValidator([Utils::class, 'validateRequired']);
|
Chris@0
|
146 $questions['plugin_id'] = new Question('Plugin ID', [Utils::class, 'defaultPluginId']);
|
Chris@0
|
147 $questions['plugin_id']->setValidator([Utils::class, 'validateMachineName']);
|
Chris@5
|
148 $questions['class'] = static::pluginClassQuestion($class_suffix);
|
Chris@0
|
149 return $questions;
|
Chris@0
|
150 }
|
Chris@0
|
151
|
Chris@0
|
152 /**
|
Chris@5
|
153 * Creates plugin class question.
|
Chris@5
|
154 */
|
Chris@5
|
155 public static function pluginClassQuestion($suffix = '') {
|
Chris@5
|
156 $default_class = function ($vars) use ($suffix) {
|
Chris@5
|
157 $unprefixed_plugin_id = preg_replace('/^' . $vars['machine_name'] . '_/', '', $vars['plugin_id']);
|
Chris@5
|
158 return Utils::camelize($unprefixed_plugin_id) . $suffix;
|
Chris@5
|
159 };
|
Chris@5
|
160 return new Question('Plugin class', $default_class);
|
Chris@5
|
161 }
|
Chris@5
|
162
|
Chris@5
|
163 /**
|
Chris@0
|
164 * Returns extension root.
|
Chris@0
|
165 *
|
Chris@0
|
166 * @return string|bool
|
Chris@0
|
167 * Extension root directory or false if it was not found.
|
Chris@0
|
168 */
|
Chris@0
|
169 public static function getExtensionRoot($directory) {
|
Chris@0
|
170 $extension_root = FALSE;
|
Chris@0
|
171 for ($i = 1; $i <= 5; $i++) {
|
Chris@0
|
172 $info_file = $directory . '/' . basename($directory) . '.info';
|
Chris@4
|
173 if ((file_exists($info_file) && basename($directory) !== 'drush') || file_exists($info_file . '.yml')) {
|
Chris@0
|
174 $extension_root = $directory;
|
Chris@0
|
175 break;
|
Chris@0
|
176 }
|
Chris@0
|
177 $directory = dirname($directory);
|
Chris@0
|
178 }
|
Chris@0
|
179 return $extension_root;
|
Chris@0
|
180 }
|
Chris@0
|
181
|
Chris@0
|
182 /**
|
Chris@0
|
183 * Removes a given number of lines from the beginning of the string.
|
Chris@0
|
184 */
|
Chris@0
|
185 public static function removeHeader($content, $header_size) {
|
Chris@0
|
186 return implode("\n", array_slice(explode("\n", $content), $header_size));
|
Chris@0
|
187 }
|
Chris@0
|
188
|
Chris@0
|
189 /**
|
Chris@0
|
190 * Return the user's home directory.
|
Chris@0
|
191 */
|
Chris@0
|
192 public static function getHomeDirectory() {
|
Chris@0
|
193 return isset($_SERVER['HOME']) ? $_SERVER['HOME'] : getenv('HOME');
|
Chris@0
|
194 }
|
Chris@0
|
195
|
Chris@0
|
196 /**
|
Chris@0
|
197 * Replaces all tokens in a given string with appropriate values.
|
Chris@0
|
198 *
|
Chris@0
|
199 * @param string $text
|
Chris@0
|
200 * A string potentially containing replaceable tokens.
|
Chris@0
|
201 * @param array $data
|
Chris@0
|
202 * An array where keys are token names and values are replacements.
|
Chris@0
|
203 *
|
Chris@0
|
204 * @return string
|
Chris@0
|
205 * Text with tokens replaced.
|
Chris@0
|
206 */
|
Chris@5
|
207 public static function replaceTokens($text, array $data) {
|
Chris@0
|
208 $tokens = [];
|
Chris@0
|
209 foreach ($data as $var_name => $var) {
|
Chris@0
|
210 if (is_string($var)) {
|
Chris@0
|
211 $tokens['{' . $var_name . '}'] = $var;
|
Chris@0
|
212 }
|
Chris@0
|
213 }
|
Chris@0
|
214 return str_replace(array_keys($tokens), array_values($tokens), $text);
|
Chris@0
|
215 }
|
Chris@0
|
216
|
Chris@4
|
217 /**
|
Chris@4
|
218 * Pluralizes a noun.
|
Chris@4
|
219 *
|
Chris@4
|
220 * @param string $string
|
Chris@4
|
221 * A noun to pluralize.
|
Chris@4
|
222 *
|
Chris@4
|
223 * @return string
|
Chris@4
|
224 * The pluralized noun.
|
Chris@4
|
225 */
|
Chris@4
|
226 public static function pluralize($string) {
|
Chris@4
|
227 switch (substr($string, -1)) {
|
Chris@4
|
228 case 'y':
|
Chris@4
|
229 return substr($string, 0, -1) . 'ies';
|
Chris@4
|
230
|
Chris@4
|
231 case 's':
|
Chris@4
|
232 return $string . 'es';
|
Chris@4
|
233
|
Chris@4
|
234 default:
|
Chris@4
|
235 return $string . 's';
|
Chris@4
|
236 }
|
Chris@4
|
237 }
|
Chris@4
|
238
|
Chris@4
|
239 /**
|
Chris@4
|
240 * Prepares choices.
|
Chris@4
|
241 *
|
Chris@4
|
242 * @param array $raw_choices
|
Chris@4
|
243 * The choices to be prepared.
|
Chris@4
|
244 *
|
Chris@4
|
245 * @return array
|
Chris@4
|
246 * The prepared choices.
|
Chris@4
|
247 */
|
Chris@4
|
248 public static function prepareChoices(array $raw_choices) {
|
Chris@4
|
249 // The $raw_choices can be an associative array.
|
Chris@4
|
250 $choices = array_values($raw_choices);
|
Chris@4
|
251 // Start choices list form '1'.
|
Chris@4
|
252 array_unshift($choices, NULL);
|
Chris@4
|
253 unset($choices[0]);
|
Chris@4
|
254 return $choices;
|
Chris@4
|
255 }
|
Chris@4
|
256
|
Chris@0
|
257 }
|