ValidGenerator.php 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. <?php
  2. namespace Faker;
  3. use Faker\Extension\Extension;
  4. /**
  5. * Proxy for other generators, to return only valid values. Works with
  6. * Faker\Generator\Base->valid()
  7. *
  8. * @mixin Generator
  9. */
  10. class ValidGenerator
  11. {
  12. protected $generator;
  13. protected $validator;
  14. protected $maxRetries;
  15. /**
  16. * @param Extension|Generator $generator
  17. * @param callable|null $validator
  18. * @param int $maxRetries
  19. */
  20. public function __construct($generator, $validator = null, $maxRetries = 10000)
  21. {
  22. if (null === $validator) {
  23. $validator = static function () {
  24. return true;
  25. };
  26. } elseif (!is_callable($validator)) {
  27. throw new \InvalidArgumentException('valid() only accepts callables as first argument');
  28. }
  29. $this->generator = $generator;
  30. $this->validator = $validator;
  31. $this->maxRetries = $maxRetries;
  32. }
  33. public function ext(string $id)
  34. {
  35. return new self($this->generator->ext($id), $this->validator, $this->maxRetries);
  36. }
  37. /**
  38. * Catch and proxy all generator calls but return only valid values
  39. *
  40. * @param string $attribute
  41. *
  42. * @deprecated Use a method instead.
  43. */
  44. public function __get($attribute)
  45. {
  46. trigger_deprecation('fakerphp/faker', '1.14', 'Accessing property "%s" is deprecated, use "%s()" instead.', $attribute, $attribute);
  47. return $this->__call($attribute, []);
  48. }
  49. /**
  50. * Catch and proxy all generator calls with arguments but return only valid values
  51. *
  52. * @param string $name
  53. * @param array $arguments
  54. */
  55. public function __call($name, $arguments)
  56. {
  57. $i = 0;
  58. do {
  59. $res = call_user_func_array([$this->generator, $name], $arguments);
  60. ++$i;
  61. if ($i > $this->maxRetries) {
  62. throw new \OverflowException(sprintf('Maximum retries of %d reached without finding a valid value', $this->maxRetries));
  63. }
  64. } while (!call_user_func($this->validator, $res));
  65. return $res;
  66. }
  67. }