Validator.php 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. <?php
  2. namespace Gedmo\Uploadable\Mapping;
  3. use Doctrine\ORM\Mapping\ClassMetadataInfo;
  4. use Gedmo\Exception\InvalidMappingException;
  5. use Gedmo\Exception\UploadableCantWriteException;
  6. use Gedmo\Exception\UploadableInvalidPathException;
  7. use Doctrine\ORM\Mapping\ClassMetadata;
  8. /**
  9. * This class is used to validate mapping information
  10. *
  11. * @author Gustavo Falco <comfortablynumb84@gmail.com>
  12. * @author Gediminas Morkevicius <gediminas.morkevicius@gmail.com>
  13. * @package Gedmo.Uploadable.Mapping
  14. * @subpackage Validator
  15. * @link http://www.gediminasm.org
  16. * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
  17. */
  18. class Validator
  19. {
  20. const UPLOADABLE_FILE_MIME_TYPE = 'UploadableFileMimeType';
  21. const UPLOADABLE_FILE_PATH = 'UploadableFilePath';
  22. const UPLOADABLE_FILE_SIZE = 'UploadableFileSize';
  23. const FILENAME_GENERATOR_SHA1 = 'SHA1';
  24. const FILENAME_GENERATOR_ALPHANUMERIC = 'ALPHANUMERIC';
  25. const FILENAME_GENERATOR_NONE = 'NONE';
  26. /**
  27. * Determines if we should throw an exception in the case the "allowedTypes" and
  28. * "disallowedTypes" options are BOTH set. Useful for testing purposes
  29. *
  30. * @var bool
  31. */
  32. public static $enableMimeTypesConfigException = true;
  33. /**
  34. * List of types which are valid for UploadableFileMimeType field
  35. *
  36. * @var array
  37. */
  38. public static $validFileMimeTypeTypes = array(
  39. 'string'
  40. );
  41. /**
  42. * List of types which are valid for UploadableFilePath field
  43. *
  44. * @var array
  45. */
  46. public static $validFilePathTypes = array(
  47. 'string'
  48. );
  49. /**
  50. * List of types which are valid for UploadableFileSize field
  51. *
  52. * @var array
  53. */
  54. public static $validFileSizeTypes = array(
  55. 'decimal'
  56. );
  57. public static function validateFileMimeTypeField(ClassMetadataInfo $meta, $field)
  58. {
  59. self::validateField($meta, $field, self::UPLOADABLE_FILE_MIME_TYPE, self::$validFileMimeTypeTypes);
  60. }
  61. public static function validateFilePathField(ClassMetadataInfo $meta, $field)
  62. {
  63. self::validateField($meta, $field, self::UPLOADABLE_FILE_PATH, self::$validFilePathTypes);
  64. }
  65. public static function validateFileSizeField(ClassMetadataInfo $meta, $field)
  66. {
  67. self::validateField($meta, $field, self::UPLOADABLE_FILE_SIZE, self::$validFileSizeTypes);
  68. }
  69. public static function validateField($meta, $field, $uploadableField, $validFieldTypes)
  70. {
  71. $fieldMapping = $meta->getFieldMapping($field);
  72. if (!in_array($fieldMapping['type'], $validFieldTypes)) {
  73. $msg = 'Field "%s" to work as an "%s" field must be of one of the following types: "%s".';
  74. throw new InvalidMappingException(sprintf($msg,
  75. $field,
  76. $uploadableField,
  77. implode(', ', $validFieldTypes)
  78. ));
  79. }
  80. }
  81. public static function validatePath($path)
  82. {
  83. if (!is_string($path) || $path === '') {
  84. throw new UploadableInvalidPathException('Path must be a string containing the path to a valid directory.');
  85. }
  86. if (!is_dir($path) || !is_writable($path)) {
  87. throw new UploadableCantWriteException(sprintf('Directory "%s" does not exist or is not writable',
  88. $path
  89. ));
  90. }
  91. }
  92. public static function validateConfiguration(ClassMetadata $meta, array &$config)
  93. {
  94. if (!$config['filePathField']) {
  95. throw new InvalidMappingException(sprintf('Class "%s" must have an UploadableFilePath field.',
  96. $meta->name
  97. ));
  98. }
  99. $refl = $meta->getReflectionClass();
  100. if ($config['pathMethod'] !== '' && !$refl->hasMethod($config['pathMethod'])) {
  101. throw new InvalidMappingException(sprintf('Class "%s" doesn\'t have method "%s"!',
  102. $meta->name,
  103. $config['pathMethod']
  104. ));
  105. }
  106. if ($config['callback'] !== '' && !$refl->hasMethod($config['callback'])) {
  107. throw new InvalidMappingException(sprintf('Class "%s" doesn\'t have method "%s"!',
  108. $meta->name,
  109. $config['callback']
  110. ));
  111. }
  112. $config['maxSize'] = (double) $config['maxSize'];
  113. if ($config['maxSize'] < 0) {
  114. throw new InvalidMappingException(sprintf('Option "maxSize" must be a number >= 0 for class "%s".',
  115. $meta->name
  116. ));
  117. }
  118. if (self::$enableMimeTypesConfigException && ($config['allowedTypes'] !== '' && $config['disallowedTypes'] !== '')) {
  119. $msg = 'You\'ve set "allowedTypes" and "disallowedTypes" options. You must set only one in class "%s".';
  120. throw new InvalidMappingException(sprintf($msg,
  121. $meta->name
  122. ));
  123. }
  124. $config['allowedTypes'] = $config['allowedTypes'] ? (strpos($config['allowedTypes'], ',') !== false ?
  125. explode(',', $config['allowedTypes']) : array($config['allowedTypes'])) : false;
  126. $config['disallowedTypes'] = $config['disallowedTypes'] ? (strpos($config['disallowedTypes'], ',') !== false ?
  127. explode(',', $config['disallowedTypes']) : array($config['disallowedTypes'])) : false;
  128. if ($config['fileMimeTypeField']) {
  129. self::validateFileMimeTypeField($meta, $config['fileMimeTypeField']);
  130. }
  131. if ($config['fileSizeField']) {
  132. self::validateFileSizeField($meta, $config['fileSizeField']);
  133. }
  134. switch ((string) $config['filenameGenerator']) {
  135. case self::FILENAME_GENERATOR_ALPHANUMERIC:
  136. case self::FILENAME_GENERATOR_SHA1:
  137. case self::FILENAME_GENERATOR_NONE:
  138. break;
  139. default:
  140. $ok = false;
  141. if (class_exists($config['filenameGenerator'])) {
  142. $refl = new \ReflectionClass($config['filenameGenerator']);
  143. if ($refl->implementsInterface('Gedmo\Uploadable\FilenameGenerator\FilenameGeneratorInterface')) {
  144. $ok = true;
  145. }
  146. }
  147. if (!$ok) {
  148. $msg = 'Class "%s" needs a valid value for filenameGenerator. It can be: SHA1, ALPHANUMERIC, NONE or ';
  149. $msg .= 'a class implementing FileGeneratorInterface.';
  150. throw new InvalidMappingException(sprintf($msg,
  151. $meta->name
  152. ));
  153. }
  154. }
  155. self::validateFilePathField($meta, $config['filePathField']);
  156. }
  157. }