VideoUrl.php 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. <?php
  2. /*
  3. * Copyright (c) Alexandre Gomes Gaigalas <alganet@gmail.com>
  4. * SPDX-License-Identifier: MIT
  5. */
  6. declare(strict_types=1);
  7. namespace Respect\Validation\Rules;
  8. use Respect\Validation\Exceptions\ComponentException;
  9. use function array_keys;
  10. use function is_string;
  11. use function mb_strtolower;
  12. use function preg_match;
  13. use function sprintf;
  14. /**
  15. * Validates if the input is a video URL value.
  16. *
  17. * @author Danilo Correa <danilosilva87@gmail.com>
  18. * @author Emmerson Siqueira <emmersonsiqueira@gmail.com>
  19. * @author Henrique Moody <henriquemoody@gmail.com>
  20. * @author Ricardo Gobbo <ricardo@clicknow.com.br>
  21. */
  22. final class VideoUrl extends AbstractRule
  23. {
  24. private const SERVICES = [
  25. // phpcs:disable Generic.Files.LineLength.TooLong
  26. 'youtube' => '@^https?://(www\.)?(?:youtube\.com/(?:[^/]+/.+/|(?:v|e(?:mbed)?)/|.*[?&]v=)|youtu\.be/)([^\"&?/]{11})@i',
  27. 'vimeo' => '@^https?://(www\.)?(player\.)?(vimeo\.com/)((channels/[A-z]+/)|(groups/[A-z]+/videos/)|(video/))?([0-9]+)@i',
  28. 'twitch' => '@^https?://(((www\.)?twitch\.tv/videos/[0-9]+)|clips\.twitch\.tv/[a-zA-Z]+)$@i',
  29. // phpcs:enable Generic.Files.LineLength.TooLong
  30. ];
  31. /**
  32. * @var string|null
  33. */
  34. private $service;
  35. /**
  36. * Create a new instance VideoUrl.
  37. *
  38. * @throws ComponentException when the given service is not supported
  39. */
  40. public function __construct(?string $service = null)
  41. {
  42. if ($service !== null && !$this->isSupportedService($service)) {
  43. throw new ComponentException(sprintf('"%s" is not a recognized video service.', $service));
  44. }
  45. $this->service = $service;
  46. }
  47. /**
  48. * {@inheritDoc}
  49. */
  50. public function validate($input): bool
  51. {
  52. if (!is_string($input)) {
  53. return false;
  54. }
  55. if ($this->service !== null) {
  56. return $this->isValid($this->service, $input);
  57. }
  58. foreach (array_keys(self::SERVICES) as $service) {
  59. if (!$this->isValid($service, $input)) {
  60. continue;
  61. }
  62. return true;
  63. }
  64. return false;
  65. }
  66. private function isSupportedService(string $service): bool
  67. {
  68. return isset(self::SERVICES[mb_strtolower($service)]);
  69. }
  70. private function isValid(string $service, string $input): bool
  71. {
  72. return preg_match(self::SERVICES[mb_strtolower($service)], $input) > 0;
  73. }
  74. }