BCGisbn.barcode.php 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. <?php
  2. /**
  3. *--------------------------------------------------------------------
  4. *
  5. * Sub-Class - ISBN-10 and ISBN-13
  6. *
  7. * You can provide an ISBN with 10 digits with or without the checksum.
  8. * You can provide an ISBN with 13 digits with or without the checksum.
  9. * Calculate the ISBN based on the EAN-13 encoding.
  10. *
  11. * The checksum is always displayed.
  12. *
  13. *--------------------------------------------------------------------
  14. * Copyright (C) Jean-Sebastien Goupil
  15. * http://www.barcodephp.com
  16. */
  17. include_once('BCGParseException.php');
  18. include_once('BCGArgumentException.php');
  19. include_once('BCGean13.barcode.php');
  20. class BCGisbn extends BCGean13 {
  21. const GS1_AUTO = 0;
  22. const GS1_PREFIX978 = 1;
  23. const GS1_PREFIX979 = 2;
  24. private $gs1;
  25. /**
  26. * Constructor.
  27. *
  28. * @param int $gs1
  29. */
  30. public function __construct($gs1 = self::GS1_AUTO) {
  31. parent::__construct();
  32. $this->setGS1($gs1);
  33. }
  34. /**
  35. * Adds the default label.
  36. */
  37. protected function addDefaultLabel() {
  38. if ($this->isDefaultEanLabelEnabled()) {
  39. $isbn = $this->createISBNText();
  40. $font = $this->font;
  41. $topLabel = new BCGLabel($isbn, $font, BCGLabel::POSITION_TOP, BCGLabel::ALIGN_CENTER);
  42. $this->addLabel($topLabel);
  43. }
  44. parent::addDefaultLabel();
  45. }
  46. /**
  47. * Sets the first numbers of the barcode.
  48. * - GS1_AUTO: Adds 978 before the code
  49. * - GS1_PREFIX978: Adds 978 before the code
  50. * - GS1_PREFIX979: Adds 979 before the code
  51. *
  52. * @param int $gs1
  53. */
  54. public function setGS1($gs1) {
  55. $gs1 = (int)$gs1;
  56. if ($gs1 !== self::GS1_AUTO && $gs1 !== self::GS1_PREFIX978 && $gs1 !== self::GS1_PREFIX979) {
  57. throw new BCGArgumentException('The GS1 argument must be BCGisbn::GS1_AUTO, BCGisbn::GS1_PREFIX978, or BCGisbn::GS1_PREFIX979', 'gs1');
  58. }
  59. $this->gs1 = $gs1;
  60. }
  61. /**
  62. * Check chars allowed.
  63. */
  64. protected function checkCharsAllowed() {
  65. $c = strlen($this->text);
  66. // Special case, if we have 10 digits, the last one can be X
  67. if ($c === 10) {
  68. if (array_search($this->text[9], $this->keys) === false && $this->text[9] !== 'X') {
  69. throw new BCGParseException('isbn', 'The character \'' . $this->text[9] . '\' is not allowed.');
  70. }
  71. // Drop the last char
  72. $this->text = substr($this->text, 0, 9);
  73. }
  74. return parent::checkCharsAllowed();
  75. }
  76. /**
  77. * Check correct length.
  78. */
  79. protected function checkCorrectLength() {
  80. $c = strlen($this->text);
  81. // If we have 13 chars just flush the last one
  82. if ($c === 13) {
  83. $this->text = substr($this->text, 0, 12);
  84. } elseif ($c === 9 || $c === 10) {
  85. if ($c === 10) {
  86. // Before dropping it, we check if it's legal
  87. if (array_search($this->text[9], $this->keys) === false && $this->text[9] !== 'X') {
  88. throw new BCGParseException('isbn', 'The character \'' . $this->text[9] . '\' is not allowed.');
  89. }
  90. $this->text = substr($this->text, 0, 9);
  91. }
  92. if ($this->gs1 === self::GS1_AUTO || $this->gs1 === self::GS1_PREFIX978) {
  93. $this->text = '978' . $this->text;
  94. } elseif ($this->gs1 === self::GS1_PREFIX979) {
  95. $this->text = '979' . $this->text;
  96. }
  97. } elseif ($c !== 12) {
  98. throw new BCGParseException('isbn', 'The code parsed must be 9, 10, 12, or 13 digits long.');
  99. }
  100. }
  101. /**
  102. * Creates the ISBN text.
  103. *
  104. * @return string
  105. */
  106. private function createISBNText() {
  107. $isbn = '';
  108. if (!empty($this->text)) {
  109. // We try to create the ISBN Text... the hyphen really depends the ISBN agency.
  110. // We just put one before the checksum and one after the GS1 if present.
  111. $c = strlen($this->text);
  112. if ($c === 12 || $c === 13) {
  113. // If we have 13 characters now, just transform it temporarily to find the checksum...
  114. // Further in the code we take care of that anyway.
  115. $lastCharacter = '';
  116. if ($c === 13) {
  117. $lastCharacter = $this->text[12];
  118. $this->text = substr($this->text, 0, 12);
  119. }
  120. $checksum = $this->processChecksum();
  121. $isbn = 'ISBN ' . substr($this->text, 0, 3) . '-' . substr($this->text, 3, 9) . '-' . $checksum;
  122. // Put the last character back
  123. if ($c === 13) {
  124. $this->text .= $lastCharacter;
  125. }
  126. } elseif ($c === 9 || $c === 10) {
  127. $checksum = 0;
  128. for ($i = 10; $i >= 2; $i--) {
  129. $checksum += $this->text[10 - $i] * $i;
  130. }
  131. $checksum = 11 - $checksum % 11;
  132. if ($checksum === 10) {
  133. $checksum = 'X'; // Changing type
  134. }
  135. $isbn = 'ISBN ' . substr($this->text, 0, 9) . '-' . $checksum;
  136. }
  137. }
  138. return $isbn;
  139. }
  140. }
  141. ?>