/library/Zend/Validator/Barcode/AbstractAdapter.php

https://github.com/christeredvartsen/zf2 · PHP · 315 lines · 179 code · 36 blank · 100 comment · 38 complexity · 30e06ce9f266a5b2fe5d21983305eff6 MD5 · raw file

  1. <?php
  2. /**
  3. * Zend Framework (http://framework.zend.com/)
  4. *
  5. * @link http://github.com/zendframework/zf2 for the canonical source repository
  6. * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
  7. * @license http://framework.zend.com/license/new-bsd New BSD License
  8. * @package Zend_Validator
  9. */
  10. namespace Zend\Validator\Barcode;
  11. /**
  12. * @category Zend
  13. * @package Zend_Validator
  14. */
  15. abstract class AbstractAdapter implements AdapterInterface
  16. {
  17. /**
  18. * Allowed options for this adapter
  19. * @var array
  20. */
  21. protected $options = array(
  22. 'length' => null, // Allowed barcode lengths, integer, array, string
  23. 'characters' => null, // Allowed barcode characters
  24. 'checksum' => null, // Callback to checksum function
  25. 'useChecksum' => true, // Is a checksum value included?, boolean
  26. );
  27. /**
  28. * Checks the length of a barcode
  29. *
  30. * @param string $value The barcode to check for proper length
  31. * @return bool
  32. */
  33. public function hasValidLength($value)
  34. {
  35. if (!is_string($value)) {
  36. return false;
  37. }
  38. $fixum = strlen($value);
  39. $found = false;
  40. $length = $this->getLength();
  41. if (is_array($length)) {
  42. foreach ($length as $value) {
  43. if ($fixum == $value) {
  44. $found = true;
  45. }
  46. if ($value == -1) {
  47. $found = true;
  48. }
  49. }
  50. } elseif ($fixum == $length) {
  51. $found = true;
  52. } elseif ($length == -1) {
  53. $found = true;
  54. } elseif ($length == 'even') {
  55. $count = $fixum % 2;
  56. $found = ($count == 0) ? true : false;
  57. } elseif ($length == 'odd') {
  58. $count = $fixum % 2;
  59. $found = ($count == 1) ? true : false;
  60. }
  61. return $found;
  62. }
  63. /**
  64. * Checks for allowed characters within the barcode
  65. *
  66. * @param string $value The barcode to check for allowed characters
  67. * @return bool
  68. */
  69. public function hasValidCharacters($value)
  70. {
  71. if (!is_string($value)) {
  72. return false;
  73. }
  74. $characters = $this->getCharacters();
  75. if ($characters == 128) {
  76. for ($x = 0; $x < 128; ++$x) {
  77. $value = str_replace(chr($x), '', $value);
  78. }
  79. } else {
  80. $chars = str_split($characters);
  81. foreach ($chars as $char) {
  82. $value = str_replace($char, '', $value);
  83. }
  84. }
  85. if (strlen($value) > 0) {
  86. return false;
  87. }
  88. return true;
  89. }
  90. /**
  91. * Validates the checksum
  92. *
  93. * @param string $value The barcode to check the checksum for
  94. * @return bool
  95. */
  96. public function hasValidChecksum($value)
  97. {
  98. $checksum = $this->getChecksum();
  99. if (!empty($checksum)) {
  100. if (method_exists($this, $checksum)) {
  101. return $this->$checksum($value);
  102. }
  103. }
  104. return false;
  105. }
  106. /**
  107. * Returns the allowed barcode length
  108. *
  109. * @return int|array
  110. */
  111. public function getLength()
  112. {
  113. return $this->options['length'];
  114. }
  115. /**
  116. * Returns the allowed characters
  117. *
  118. * @return integer|string|array
  119. */
  120. public function getCharacters()
  121. {
  122. return $this->options['characters'];
  123. }
  124. /**
  125. * Returns the checksum function name
  126. *
  127. */
  128. public function getChecksum()
  129. {
  130. return $this->options['checksum'];
  131. }
  132. /**
  133. * Sets the checksum validation method
  134. *
  135. * @param callable $checksum Checksum method to call
  136. * @return AbstractAdapter
  137. */
  138. protected function setChecksum($checksum)
  139. {
  140. $this->options['checksum'] = $checksum;
  141. return $this;
  142. }
  143. /**
  144. * Sets the checksum validation, if no value is given, the actual setting is returned
  145. *
  146. * @param bool $check
  147. * @return AbstractAdapter|bool
  148. */
  149. public function useChecksum($check = null)
  150. {
  151. if ($check === null) {
  152. return $this->options['useChecksum'];
  153. }
  154. $this->options['useChecksum'] = (bool) $check;
  155. return $this;
  156. }
  157. /**
  158. * Sets the length of this barcode
  159. *
  160. * @param int|array $length
  161. * @return AbstractAdapter
  162. */
  163. protected function setLength($length)
  164. {
  165. $this->options['length'] = $length;
  166. return $this;
  167. }
  168. /**
  169. * Sets the allowed characters of this barcode
  170. *
  171. * @param integer $characters
  172. * @return AbstractAdapter
  173. */
  174. protected function setCharacters($characters)
  175. {
  176. $this->options['characters'] = $characters;
  177. return $this;
  178. }
  179. /**
  180. * Validates the checksum (Modulo 10)
  181. * GTIN implementation factor 3
  182. *
  183. * @param string $value The barcode to validate
  184. * @return bool
  185. */
  186. protected function gtin($value)
  187. {
  188. $barcode = substr($value, 0, -1);
  189. $sum = 0;
  190. $length = strlen($barcode) - 1;
  191. for ($i = 0; $i <= $length; $i++) {
  192. if (($i % 2) === 0) {
  193. $sum += $barcode[$length - $i] * 3;
  194. } else {
  195. $sum += $barcode[$length - $i];
  196. }
  197. }
  198. $calc = $sum % 10;
  199. $checksum = ($calc === 0) ? 0 : (10 - $calc);
  200. if ($value[$length + 1] != $checksum) {
  201. return false;
  202. }
  203. return true;
  204. }
  205. /**
  206. * Validates the checksum (Modulo 10)
  207. * IDENTCODE implementation factors 9 and 4
  208. *
  209. * @param string $value The barcode to validate
  210. * @return bool
  211. */
  212. protected function identcode($value)
  213. {
  214. $barcode = substr($value, 0, -1);
  215. $sum = 0;
  216. $length = strlen($value) - 2;
  217. for ($i = 0; $i <= $length; $i++) {
  218. if (($i % 2) === 0) {
  219. $sum += $barcode[$length - $i] * 4;
  220. } else {
  221. $sum += $barcode[$length - $i] * 9;
  222. }
  223. }
  224. $calc = $sum % 10;
  225. $checksum = ($calc === 0) ? 0 : (10 - $calc);
  226. if ($value[$length + 1] != $checksum) {
  227. return false;
  228. }
  229. return true;
  230. }
  231. /**
  232. * Validates the checksum (Modulo 10)
  233. * CODE25 implementation factor 3
  234. *
  235. * @param string $value The barcode to validate
  236. * @return bool
  237. */
  238. protected function code25($value)
  239. {
  240. $barcode = substr($value, 0, -1);
  241. $sum = 0;
  242. $length = strlen($barcode) - 1;
  243. for ($i = 0; $i <= $length; $i++) {
  244. if (($i % 2) === 0) {
  245. $sum += $barcode[$i] * 3;
  246. } else {
  247. $sum += $barcode[$i];
  248. }
  249. }
  250. $calc = $sum % 10;
  251. $checksum = ($calc === 0) ? 0 : (10 - $calc);
  252. if ($value[$length + 1] != $checksum) {
  253. return false;
  254. }
  255. return true;
  256. }
  257. /**
  258. * Validates the checksum ()
  259. * POSTNET implementation
  260. *
  261. * @param string $value The barcode to validate
  262. * @return bool
  263. */
  264. protected function postnet($value)
  265. {
  266. $checksum = substr($value, -1, 1);
  267. $values = str_split(substr($value, 0, -1));
  268. $check = 0;
  269. foreach ($values as $row) {
  270. $check += $row;
  271. }
  272. $check %= 10;
  273. $check = 10 - $check;
  274. if ($check == $checksum) {
  275. return true;
  276. }
  277. return false;
  278. }
  279. }