Argument.php 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. <?php
  2. namespace Intervention\Image\Commands;
  3. use Intervention\Image\Exception\InvalidArgumentException;
  4. class Argument
  5. {
  6. /**
  7. * Command with arguments
  8. *
  9. * @var AbstractCommand
  10. */
  11. public $command;
  12. /**
  13. * Key of argument in array
  14. *
  15. * @var int
  16. */
  17. public $key;
  18. /**
  19. * Creates new instance from given command and key
  20. *
  21. * @param AbstractCommand $command
  22. * @param int $key
  23. */
  24. public function __construct(AbstractCommand $command, $key = 0)
  25. {
  26. $this->command = $command;
  27. $this->key = $key;
  28. }
  29. /**
  30. * Returns name of current arguments command
  31. *
  32. * @return string
  33. */
  34. public function getCommandName()
  35. {
  36. preg_match("/\\\\([\w]+)Command$/", get_class($this->command), $matches);
  37. return isset($matches[1]) ? lcfirst($matches[1]).'()' : 'Method';
  38. }
  39. /**
  40. * Returns value of current argument
  41. *
  42. * @param mixed $default
  43. * @return mixed
  44. */
  45. public function value($default = null)
  46. {
  47. $arguments = $this->command->arguments;
  48. if (is_array($arguments)) {
  49. return isset($arguments[$this->key]) ? $arguments[$this->key] : $default;
  50. }
  51. return $default;
  52. }
  53. /**
  54. * Defines current argument as required
  55. *
  56. * @return \Intervention\Image\Commands\Argument
  57. */
  58. public function required()
  59. {
  60. if ( ! array_key_exists($this->key, $this->command->arguments)) {
  61. throw new InvalidArgumentException(
  62. sprintf("Missing argument %d for %s", $this->key + 1, $this->getCommandName())
  63. );
  64. }
  65. return $this;
  66. }
  67. /**
  68. * Determines that current argument must be of given type
  69. *
  70. * @return \Intervention\Image\Commands\Argument
  71. */
  72. public function type($type)
  73. {
  74. $valid = true;
  75. $value = $this->value();
  76. if ($value === null) {
  77. return $this;
  78. }
  79. switch (strtolower($type)) {
  80. case 'bool':
  81. case 'boolean':
  82. $valid = \is_bool($value);
  83. $message = '%s accepts only boolean values as argument %d.';
  84. break;
  85. case 'int':
  86. case 'integer':
  87. $valid = \is_int($value);
  88. $message = '%s accepts only integer values as argument %d.';
  89. break;
  90. case 'num':
  91. case 'numeric':
  92. $valid = is_numeric($value);
  93. $message = '%s accepts only numeric values as argument %d.';
  94. break;
  95. case 'str':
  96. case 'string':
  97. $valid = \is_string($value);
  98. $message = '%s accepts only string values as argument %d.';
  99. break;
  100. case 'array':
  101. $valid = \is_array($value);
  102. $message = '%s accepts only array as argument %d.';
  103. break;
  104. case 'closure':
  105. $valid = is_a($value, '\Closure');
  106. $message = '%s accepts only Closure as argument %d.';
  107. break;
  108. case 'digit':
  109. $valid = $this->isDigit($value);
  110. $message = '%s accepts only integer values as argument %d.';
  111. break;
  112. }
  113. if (! $valid) {
  114. $commandName = $this->getCommandName();
  115. $argument = $this->key + 1;
  116. if (isset($message)) {
  117. $message = sprintf($message, $commandName, $argument);
  118. } else {
  119. $message = sprintf('Missing argument for %d.', $argument);
  120. }
  121. throw new InvalidArgumentException(
  122. $message
  123. );
  124. }
  125. return $this;
  126. }
  127. /**
  128. * Determines that current argument value must be numeric between given values
  129. *
  130. * @return \Intervention\Image\Commands\Argument
  131. */
  132. public function between($x, $y)
  133. {
  134. $value = $this->type('numeric')->value();
  135. if (is_null($value)) {
  136. return $this;
  137. }
  138. $alpha = min($x, $y);
  139. $omega = max($x, $y);
  140. if ($value < $alpha || $value > $omega) {
  141. throw new InvalidArgumentException(
  142. sprintf('Argument %d must be between %s and %s.', $this->key, $x, $y)
  143. );
  144. }
  145. return $this;
  146. }
  147. /**
  148. * Determines that current argument must be over a minimum value
  149. *
  150. * @return \Intervention\Image\Commands\Argument
  151. */
  152. public function min($value)
  153. {
  154. $v = $this->type('numeric')->value();
  155. if (is_null($v)) {
  156. return $this;
  157. }
  158. if ($v < $value) {
  159. throw new InvalidArgumentException(
  160. sprintf('Argument %d must be at least %s.', $this->key, $value)
  161. );
  162. }
  163. return $this;
  164. }
  165. /**
  166. * Determines that current argument must be under a maxiumum value
  167. *
  168. * @return \Intervention\Image\Commands\Argument
  169. */
  170. public function max($value)
  171. {
  172. $v = $this->type('numeric')->value();
  173. if (is_null($v)) {
  174. return $this;
  175. }
  176. if ($v > $value) {
  177. throw new InvalidArgumentException(
  178. sprintf('Argument %d may not be greater than %s.', $this->key, $value)
  179. );
  180. }
  181. return $this;
  182. }
  183. /**
  184. * Checks if value is "PHP" integer (120 but also 120.0)
  185. *
  186. * @param mixed $value
  187. * @return boolean
  188. */
  189. private function isDigit($value)
  190. {
  191. return is_numeric($value) ? intval($value) == $value : false;
  192. }
  193. }