cf3483509d73cd1cdf3d2c6f6c5d735e536a5db2
[yaffs-website] / web / core / lib / Drupal / Component / Utility / Random.php
1 <?php
2
3 namespace Drupal\Component\Utility;
4
5 /**
6  * Defines a utility class for creating random data.
7  *
8  * @ingroup utility
9  */
10 class Random {
11
12   /**
13    * The maximum number of times name() and string() can loop.
14    *
15    * This prevents infinite loops if the length of the random value is very
16    * small.
17    *
18    * @see \Drupal\Tests\Component\Utility\RandomTest
19    */
20   const MAXIMUM_TRIES = 100;
21
22   /**
23    * A list of unique strings generated by string().
24    *
25    * @var array
26    */
27   protected $strings = [];
28
29   /**
30    * A list of unique names generated by name().
31    *
32    * @var array
33    */
34   protected $names = [];
35
36   /**
37    * Generates a random string of ASCII characters of codes 32 to 126.
38    *
39    * The generated string includes alpha-numeric characters and common
40    * miscellaneous characters. Use this method when testing general input
41    * where the content is not restricted.
42    *
43    * @param int $length
44    *   Length of random string to generate.
45    * @param bool $unique
46    *   (optional) If TRUE ensures that the random string returned is unique.
47    *   Defaults to FALSE.
48    * @param callable $validator
49    *   (optional) A callable to validate the string. Defaults to NULL.
50    *
51    * @return string
52    *   Randomly generated string.
53    *
54    * @see \Drupal\Component\Utility\Random::name()
55    */
56   public function string($length = 8, $unique = FALSE, $validator = NULL) {
57     $counter = 0;
58
59     // Continue to loop if $unique is TRUE and the generated string is not
60     // unique or if $validator is a callable that returns FALSE. To generate a
61     // random string this loop must be carried out at least once.
62     do {
63       if ($counter == static::MAXIMUM_TRIES) {
64         throw new \RuntimeException('Unable to generate a unique random name');
65       }
66       $str = '';
67       for ($i = 0; $i < $length; $i++) {
68         $str .= chr(mt_rand(32, 126));
69       }
70       $counter++;
71
72       $continue = FALSE;
73       if ($unique) {
74         $continue = isset($this->strings[$str]);
75       }
76       if (!$continue && is_callable($validator)) {
77         // If the validator callback returns FALSE generate another random
78         // string.
79         $continue = !call_user_func($validator, $str);
80       }
81     } while ($continue);
82
83     if ($unique) {
84       $this->strings[$str] = TRUE;
85     }
86
87     return $str;
88   }
89
90   /**
91    * Generates a random string containing letters and numbers.
92    *
93    * The string will always start with a letter. The letters may be upper or
94    * lower case. This method is better for restricted inputs that do not
95    * accept certain characters. For example, when testing input fields that
96    * require machine readable values (i.e. without spaces and non-standard
97    * characters) this method is best.
98    *
99    * @param int $length
100    *   Length of random string to generate.
101    * @param bool $unique
102    *   (optional) If TRUE ensures that the random string returned is unique.
103    *   Defaults to FALSE.
104    *
105    * @return string
106    *   Randomly generated string.
107    *
108    * @see \Drupal\Component\Utility\Random::string()
109    */
110   public function name($length = 8, $unique = FALSE) {
111     $values = array_merge(range(65, 90), range(97, 122), range(48, 57));
112     $max = count($values) - 1;
113     $counter = 0;
114
115     do {
116       if ($counter == static::MAXIMUM_TRIES) {
117         throw new \RuntimeException('Unable to generate a unique random name');
118       }
119       $str = chr(mt_rand(97, 122));
120       for ($i = 1; $i < $length; $i++) {
121         $str .= chr($values[mt_rand(0, $max)]);
122       }
123       $counter++;
124     } while ($unique && isset($this->names[$str]));
125
126     if ($unique) {
127       $this->names[$str] = TRUE;
128     }
129
130     return $str;
131   }
132
133   /**
134    * Generate a string that looks like a word (letters only, alternating consonants and vowels).
135    *
136    * @param int $length
137    *   The desired word length.
138    *
139    * @return string
140    */
141   public function word($length) {
142     mt_srand((double) microtime() * 1000000);
143
144     $vowels = ["a", "e", "i", "o", "u"];
145     $cons = ["b", "c", "d", "g", "h", "j", "k", "l", "m", "n", "p", "r", "s", "t", "u", "v", "w", "tr",
146       "cr", "br", "fr", "th", "dr", "ch", "ph", "wr", "st", "sp", "sw", "pr",
147       "sl", "cl", "sh",
148     ];
149
150     $num_vowels = count($vowels);
151     $num_cons = count($cons);
152     $word = '';
153
154     while (strlen($word) < $length) {
155       $word .= $cons[mt_rand(0, $num_cons - 1)] . $vowels[mt_rand(0, $num_vowels - 1)];
156     }
157
158     return substr($word, 0, $length);
159   }
160
161   /**
162    * Generates a random PHP object.
163    *
164    * @param int $size
165    *   The number of random keys to add to the object.
166    *
167    * @return \stdClass
168    *   The generated object, with the specified number of random keys. Each key
169    *   has a random string value.
170    */
171   public function object($size = 4) {
172     $object = new \stdClass();
173     for ($i = 0; $i < $size; $i++) {
174       $random_key = $this->name();
175       $random_value = $this->string();
176       $object->{$random_key} = $random_value;
177     }
178     return $object;
179   }
180
181   /**
182    * Generates sentences Latin words, often used as placeholder text.
183    *
184    * @param int $min_word_count
185    *   The minimum number of words in the return string. Total word count
186    *   can slightly exceed provided this value in order to deliver
187    *   sentences of random length.
188    * @param bool $capitalize
189    *   Uppercase all the words in the string.
190    *
191    * @return string
192    *   Nonsense latin words which form sentence(s).
193    */
194   public function sentences($min_word_count, $capitalize = FALSE) {
195     $dictionary = ["abbas", "abdo", "abico", "abigo", "abluo", "accumsan",
196       "acsi", "ad", "adipiscing", "aliquam", "aliquip", "amet", "antehabeo",
197       "appellatio", "aptent", "at", "augue", "autem", "bene", "blandit",
198       "brevitas", "caecus", "camur", "capto", "causa", "cogo", "comis",
199       "commodo", "commoveo", "consectetuer", "consequat", "conventio", "cui",
200       "damnum", "decet", "defui", "diam", "dignissim", "distineo", "dolor",
201       "dolore", "dolus", "duis", "ea", "eligo", "elit", "enim", "erat",
202       "eros", "esca", "esse", "et", "eu", "euismod", "eum", "ex", "exerci",
203       "exputo", "facilisi", "facilisis", "fere", "feugiat", "gemino",
204       "genitus", "gilvus", "gravis", "haero", "hendrerit", "hos", "huic",
205       "humo", "iaceo", "ibidem", "ideo", "ille", "illum", "immitto",
206       "importunus", "imputo", "in", "incassum", "inhibeo", "interdico",
207       "iriure", "iusto", "iustum", "jugis", "jumentum", "jus", "laoreet",
208       "lenis", "letalis", "lobortis", "loquor", "lucidus", "luctus", "ludus",
209       "luptatum", "macto", "magna", "mauris", "melior", "metuo", "meus",
210       "minim", "modo", "molior", "mos", "natu", "neo", "neque", "nibh",
211       "nimis", "nisl", "nobis", "nostrud", "nulla", "nunc", "nutus", "obruo",
212       "occuro", "odio", "olim", "oppeto", "os", "pagus", "pala", "paratus",
213       "patria", "paulatim", "pecus", "persto", "pertineo", "plaga", "pneum",
214       "populus", "praemitto", "praesent", "premo", "probo", "proprius",
215       "quadrum", "quae", "qui", "quia", "quibus", "quidem", "quidne", "quis",
216       "ratis", "refero", "refoveo", "roto", "rusticus", "saepius",
217       "sagaciter", "saluto", "scisco", "secundum", "sed", "si", "similis",
218       "singularis", "sino", "sit", "sudo", "suscipere", "suscipit", "tamen",
219       "tation", "te", "tego", "tincidunt", "torqueo", "tum", "turpis",
220       "typicus", "ulciscor", "ullamcorper", "usitas", "ut", "utinam",
221       "utrum", "uxor", "valde", "valetudo", "validus", "vel", "velit",
222       "veniam", "venio", "vereor", "vero", "verto", "vicis", "vindico",
223       "virtus", "voco", "volutpat", "vulpes", "vulputate", "wisi", "ymo",
224       "zelus",
225     ];
226     $dictionary_flipped = array_flip($dictionary);
227     $greeking = '';
228
229     if (!$capitalize) {
230       $words_remaining = $min_word_count;
231       while ($words_remaining > 0) {
232         $sentence_length = mt_rand(3, 10);
233         $words = array_rand($dictionary_flipped, $sentence_length);
234         $sentence = implode(' ', $words);
235         $greeking .= ucfirst($sentence) . '. ';
236         $words_remaining -= $sentence_length;
237       }
238     }
239     else {
240       // Use slightly different method for titles.
241       $words = array_rand($dictionary_flipped, $min_word_count);
242       $words = is_array($words) ? implode(' ', $words) : $words;
243       $greeking = ucwords($words);
244     }
245     return trim($greeking);
246   }
247
248   /**
249    * Generate paragraphs separated by double new line.
250    *
251    * @param int $paragraph_count
252    * @return string
253    */
254   public function paragraphs($paragraph_count = 12) {
255     $output = '';
256     for ($i = 1; $i <= $paragraph_count; $i++) {
257       $output .= $this->sentences(mt_rand(20, 60)) . "\n\n";
258     }
259     return $output;
260   }
261
262
263   /**
264    * Create a placeholder image.
265    *
266    * @param string $destination
267    *   The absolute file path where the image should be stored.
268    * @param int $min_resolution
269    * @param int $max_resolution
270    *
271    * @return string
272    *   Path to image file.
273    */
274   public function image($destination, $min_resolution, $max_resolution) {
275     $extension = pathinfo($destination, PATHINFO_EXTENSION);
276     $min = explode('x', $min_resolution);
277     $max = explode('x', $max_resolution);
278
279     $width = rand((int) $min[0], (int) $max[0]);
280     $height = rand((int) $min[1], (int) $max[1]);
281
282     // Make an image split into 4 sections with random colors.
283     $im = imagecreate($width, $height);
284     for ($n = 0; $n < 4; $n++) {
285       $color = imagecolorallocate($im, rand(0, 255), rand(0, 255), rand(0, 255));
286       $x = $width / 2 * ($n % 2);
287       $y = $height / 2 * (int) ($n >= 2);
288       imagefilledrectangle($im, $x, $y, $x + $width / 2, $y + $height / 2, $color);
289     }
290
291     // Make a perfect circle in the image middle.
292     $color = imagecolorallocate($im, rand(0, 255), rand(0, 255), rand(0, 255));
293     $smaller_dimension = min($width, $height);
294     imageellipse($im, $width / 2, $height / 2, $smaller_dimension, $smaller_dimension, $color);
295
296     $save_function = 'image' . ($extension == 'jpg' ? 'jpeg' : $extension);
297     $save_function($im, $destination);
298     return $destination;
299   }
300
301 }