3c98b83b6376332f407150487b1cf1542b93065e
[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", "sl", "cl", "sh"];
147
148     $num_vowels = count($vowels);
149     $num_cons = count($cons);
150     $word = '';
151
152     while (strlen($word) < $length) {
153       $word .= $cons[mt_rand(0, $num_cons - 1)] . $vowels[mt_rand(0, $num_vowels - 1)];
154     }
155
156     return substr($word, 0, $length);
157   }
158
159   /**
160    * Generates a random PHP object.
161    *
162    * @param int $size
163    *   The number of random keys to add to the object.
164    *
165    * @return \stdClass
166    *   The generated object, with the specified number of random keys. Each key
167    *   has a random string value.
168    */
169   public function object($size = 4) {
170     $object = new \stdClass();
171     for ($i = 0; $i < $size; $i++) {
172       $random_key = $this->name();
173       $random_value = $this->string();
174       $object->{$random_key} = $random_value;
175     }
176     return $object;
177   }
178
179   /**
180    * Generates sentences Latin words, often used as placeholder text.
181    *
182    * @param int $min_word_count
183    *   The minimum number of words in the return string. Total word count
184    *   can slightly exceed provided this value in order to deliver
185    *   sentences of random length.
186    * @param bool $capitalize
187    *   Uppercase all the words in the string.
188    *
189    * @return string
190    *   Nonsense latin words which form sentence(s).
191    */
192   public function sentences($min_word_count, $capitalize = FALSE) {
193     $dictionary = ["abbas", "abdo", "abico", "abigo", "abluo", "accumsan",
194       "acsi", "ad", "adipiscing", "aliquam", "aliquip", "amet", "antehabeo",
195       "appellatio", "aptent", "at", "augue", "autem", "bene", "blandit",
196       "brevitas", "caecus", "camur", "capto", "causa", "cogo", "comis",
197       "commodo", "commoveo", "consectetuer", "consequat", "conventio", "cui",
198       "damnum", "decet", "defui", "diam", "dignissim", "distineo", "dolor",
199       "dolore", "dolus", "duis", "ea", "eligo", "elit", "enim", "erat",
200       "eros", "esca", "esse", "et", "eu", "euismod", "eum", "ex", "exerci",
201       "exputo", "facilisi", "facilisis", "fere", "feugiat", "gemino",
202       "genitus", "gilvus", "gravis", "haero", "hendrerit", "hos", "huic",
203       "humo", "iaceo", "ibidem", "ideo", "ille", "illum", "immitto",
204       "importunus", "imputo", "in", "incassum", "inhibeo", "interdico",
205       "iriure", "iusto", "iustum", "jugis", "jumentum", "jus", "laoreet",
206       "lenis", "letalis", "lobortis", "loquor", "lucidus", "luctus", "ludus",
207       "luptatum", "macto", "magna", "mauris", "melior", "metuo", "meus",
208       "minim", "modo", "molior", "mos", "natu", "neo", "neque", "nibh",
209       "nimis", "nisl", "nobis", "nostrud", "nulla", "nunc", "nutus", "obruo",
210       "occuro", "odio", "olim", "oppeto", "os", "pagus", "pala", "paratus",
211       "patria", "paulatim", "pecus", "persto", "pertineo", "plaga", "pneum",
212       "populus", "praemitto", "praesent", "premo", "probo", "proprius",
213       "quadrum", "quae", "qui", "quia", "quibus", "quidem", "quidne", "quis",
214       "ratis", "refero", "refoveo", "roto", "rusticus", "saepius",
215       "sagaciter", "saluto", "scisco", "secundum", "sed", "si", "similis",
216       "singularis", "sino", "sit", "sudo", "suscipere", "suscipit", "tamen",
217       "tation", "te", "tego", "tincidunt", "torqueo", "tum", "turpis",
218       "typicus", "ulciscor", "ullamcorper", "usitas", "ut", "utinam",
219       "utrum", "uxor", "valde", "valetudo", "validus", "vel", "velit",
220       "veniam", "venio", "vereor", "vero", "verto", "vicis", "vindico",
221       "virtus", "voco", "volutpat", "vulpes", "vulputate", "wisi", "ymo",
222       "zelus"];
223     $dictionary_flipped = array_flip($dictionary);
224     $greeking = '';
225
226     if (!$capitalize) {
227       $words_remaining = $min_word_count;
228       while ($words_remaining > 0) {
229         $sentence_length = mt_rand(3, 10);
230         $words = array_rand($dictionary_flipped, $sentence_length);
231         $sentence = implode(' ', $words);
232         $greeking .= ucfirst($sentence) . '. ';
233         $words_remaining -= $sentence_length;
234       }
235     }
236     else {
237       // Use slightly different method for titles.
238       $words = array_rand($dictionary_flipped, $min_word_count);
239       $words = is_array($words) ? implode(' ', $words) : $words;
240       $greeking = ucwords($words);
241     }
242     return trim($greeking);
243   }
244
245   /**
246    * Generate paragraphs separated by double new line.
247    *
248    * @param int $paragraph_count
249    * @return string
250    */
251   public function paragraphs($paragraph_count = 12) {
252     $output = '';
253     for ($i = 1; $i <= $paragraph_count; $i++) {
254       $output .= $this->sentences(mt_rand(20, 60)) . "\n\n";
255     }
256     return $output;
257   }
258
259
260   /**
261    * Create a placeholder image.
262    *
263    * @param string $destination
264    *   The absolute file path where the image should be stored.
265    * @param int $min_resolution
266    * @param int $max_resolution
267    *
268    * @return string
269    *   Path to image file.
270    */
271   public function image($destination, $min_resolution, $max_resolution) {
272     $extension = pathinfo($destination, PATHINFO_EXTENSION);
273     $min = explode('x', $min_resolution);
274     $max = explode('x', $max_resolution);
275
276     $width = rand((int) $min[0], (int) $max[0]);
277     $height = rand((int) $min[1], (int) $max[1]);
278
279     // Make an image split into 4 sections with random colors.
280     $im = imagecreate($width, $height);
281     for ($n = 0; $n < 4; $n++) {
282       $color = imagecolorallocate($im, rand(0, 255), rand(0, 255), rand(0, 255));
283       $x = $width / 2 * ($n % 2);
284       $y = $height / 2 * (int) ($n >= 2);
285       imagefilledrectangle($im, $x, $y, $x + $width / 2, $y + $height / 2, $color);
286     }
287
288     // Make a perfect circle in the image middle.
289     $color = imagecolorallocate($im, rand(0, 255), rand(0, 255), rand(0, 255));
290     $smaller_dimension = min($width, $height);
291     imageellipse($im, $width / 2, $height / 2, $smaller_dimension, $smaller_dimension, $color);
292
293     $save_function = 'image' . ($extension == 'jpg' ? 'jpeg' : $extension);
294     $save_function($im, $destination);
295     return $destination;
296   }
297
298 }