* @link http://www.codeitnow.in * @package https://github.com/codeitnowin/barcode-generator */ namespace CodeItNow\BarcodeBundle\Generator; use CodeItNow\BarcodeBundle\Generator\CINParseException; use CodeItNow\BarcodeBundle\Generator\CINArgumentException; use CodeItNow\BarcodeBundle\Generator\CINean13; class CINisbn extends CINean13 { const GS1_AUTO = 0; const GS1_PREFIX978 = 1; const GS1_PREFIX979 = 2; private $gs1; /** * Constructor. * * @param int $gs1 */ public function __construct($gs1 = self::GS1_AUTO) { parent::__construct(); $this->setGS1($gs1); } /** * Adds the default label. */ protected function addDefaultLabel() { if ($this->isDefaultEanLabelEnabled()) { $isbn = $this->createISBNText(); $font = $this->font; $topLabel = new CINLabel($isbn, $font, CINLabel::POSITION_TOP, CINLabel::ALIGN_CENTER); $this->addLabel($topLabel); } parent::addDefaultLabel(); } /** * Sets the first numbers of the barcode. * - GS1_AUTO: Adds 978 before the code * - GS1_PREFIX978: Adds 978 before the code * - GS1_PREFIX979: Adds 979 before the code * * @param int $gs1 */ public function setGS1($gs1) { $gs1 = (int)$gs1; if ($gs1 !== self::GS1_AUTO && $gs1 !== self::GS1_PREFIX978 && $gs1 !== self::GS1_PREFIX979) { throw new CINArgumentException('The GS1 argument must be CINisbn::GS1_AUTO, CINisbn::GS1_PREFIX978, or CINisbn::GS1_PREFIX979', 'gs1'); } $this->gs1 = $gs1; } /** * Check chars allowed. */ protected function checkCharsAllowed() { $c = strlen($this->text); // Special case, if we have 10 digits, the last one can be X if ($c === 10) { if (array_search($this->text[9], $this->keys) === false && $this->text[9] !== 'X') { throw new CINParseException('isbn', 'The character \'' . $this->text[9] . '\' is not allowed.'); } // Drop the last char $this->text = substr($this->text, 0, 9); } return parent::checkCharsAllowed(); } /** * Check correct length. */ protected function checkCorrectLength() { $c = strlen($this->text); // If we have 13 chars just flush the last one if ($c === 13) { $this->text = substr($this->text, 0, 12); } elseif ($c === 9 || $c === 10) { if ($c === 10) { // Before dropping it, we check if it's legal if (array_search($this->text[9], $this->keys) === false && $this->text[9] !== 'X') { throw new CINParseException('isbn', 'The character \'' . $this->text[9] . '\' is not allowed.'); } $this->text = substr($this->text, 0, 9); } if ($this->gs1 === self::GS1_AUTO || $this->gs1 === self::GS1_PREFIX978) { $this->text = '978' . $this->text; } elseif ($this->gs1 === self::GS1_PREFIX979) { $this->text = '979' . $this->text; } } elseif ($c !== 12) { throw new CINParseException('isbn', 'The code parsed must be 9, 10, 12, or 13 digits long.'); } } /** * Creates the ISBN text. * * @return string */ private function createISBNText() { $isbn = ''; if (!empty($this->text)) { // We try to create the ISBN Text... the hyphen really depends the ISBN agency. // We just put one before the checksum and one after the GS1 if present. $c = strlen($this->text); if ($c === 12 || $c === 13) { // If we have 13 characters now, just transform it temporarily to find the checksum... // Further in the code we take care of that anyway. $lastCharacter = ''; if ($c === 13) { $lastCharacter = $this->text[12]; $this->text = substr($this->text, 0, 12); } $checksum = $this->processChecksum(); $isbn = 'ISBN ' . substr($this->text, 0, 3) . '-' . substr($this->text, 3, 9) . '-' . $checksum; // Put the last character back if ($c === 13) { $this->text .= $lastCharacter; } } elseif ($c === 9 || $c === 10) { $checksum = 0; for ($i = 10; $i >= 2; $i--) { $checksum += $this->text[10 - $i] * $i; } $checksum = 11 - $checksum % 11; if ($checksum === 10) { $checksum = 'X'; // Changing type } $isbn = 'ISBN ' . substr($this->text, 0, 9) . '-' . $checksum; } } return $isbn; } } ?>