ISBN
[ class tree: ISBN ] [ index: ISBN ] [ all elements ]

Source for file ISBN.php

Documentation is available at ISBN.php

  1. <?php
  2. /**
  3.  * ISBN
  4.  *
  5.  * Handle, Convert and Validate ISBN Numbers
  6.  *
  7.  * PHP version 5
  8.  *
  9.  * LICENSE: LGPL (In cases LGPL is not appropriate, it is licensed under GPL)
  10.  *
  11.  * Package to handle, convert and validate ISBN numbers. It includes:
  12.  *
  13.  *  - ISBN specifics: EAN/PrefixArrayAccess (integer)
  14.  *  - ISBN specifics: Group/Registration Group [2001: Group identifier] (integer)
  15.  *  - ISBN specifics: GroupTitle/Registration Group Title (string)
  16.  *  - ISBN specifics: Publisher/Registrant [2001: Publisher identifier] (string)
  17.  *  - ISBN specifics: Title/Publication [2001: Title identifier] (string)
  18.  *  - ISBN specifics: Checkdigit (string)
  19.  *  - ISBN specifics: 'ISBNBody' (string)
  20.  *  - ISBN specifics: 'ISBNSubbody' (string)
  21.  *  - ISBN Version handling
  22.  *  - Syntactical Validation plus Validation based on real ISBN Data
  23.  *  - ISBN-10 (ISO 2108) checksum calculation
  24.  *  - Validation (ISBN-10 and ISBN-13-978)
  25.  *  - Conversion to ISBN-13-978
  26.  *  - ISBN-13-978 (2005 Handbook, ISO pending; ISBN-13)
  27.  *  - ISBN-13 checksum calculation (EAN)
  28.  *
  29.  * Based on standards published by international ISBN Agency
  30.  * http://www.isbn-international.org/
  31.  *
  32.  * @category  Pending
  33.  * @package   ISBN
  34.  * @author    Tom Klingenberg <tkli-php@lastflood.net>
  35.  * @copyright 2006-2007 Tom Klingenberg
  36.  * @license   LGPL http://www.gnu.org/licenses/lgpl.txt
  37.  * @version   v 0.1.6 CVS: <cvs_id>
  38.  * @link      http://isbn.lastflood.com online docs
  39.  * 
  40.  * @todo      License for .js file or remove it
  41.  * @todo      GroupTitle
  42.  * @todo      PEAR Package.xml
  43.  *
  44.  */
  45.  
  46. // {{{ constants
  47. /**
  48.  * ISBN Versions supported
  49.  */
  50. define('ISBN_VERSION_NONE'false);
  51. /**
  52.  * VERSION_UNKNOWN is by the caller only, this shall never
  53.  * be a value returned by a public function or getter
  54.  */
  55. define('ISBN_VERSION_UNKNOWN'0);
  56. define('ISBN_VERSION_ISBN_10'10);
  57. define('ISBN_VERSION_ISBN_13'13978);
  58. define('ISBN_VERSION_ISBN_13_978'ISBN_VERSION_ISBN_13);
  59. define('ISBN_VERSION_ISBN_13_979'13979);  /* reserved */
  60.  
  61. /*
  62.  * Default ISBN Version for class input / usage
  63.  */
  64. define('ISBN_DEFAULT_INPUTVERSION'ISBN_VERSION_UNKNOWN);
  65. /*
  66.  * Default ISBN Seperator string
  67.  */
  68. define('ISBN_DEFAULT_COSMETIC_SEPERATOR''-');
  69.  
  70. /*
  71.  * ISBN_DEFAULT_PRINT_LANG_SPECIFIC_PREFIX
  72.  *
  73.  * When printed, the ISBN is always preceded by the letters "ISBN".
  74.  * Note: In countries where the Latin alphabet is not used, an abbreviation
  75.  * in the characters of the local script may be used in addition to the
  76.  * Latin letters "ISBN".
  77.  * This can be defined as a default value wihtin this constant.
  78.  */
  79. define('ISBN_DEFAULT_PRINT_LANG_SPECIFIC_PREFIX''');
  80. // }}}
  81.  
  82. require_once 'PEAR/Exception.php';
  83.  
  84. // {{{ ISBN_Exception
  85. /**
  86.  * ISBN_Exception class
  87.  *
  88.  * @category  Pending
  89.  * @package   ISBN
  90.  * @author    Tom Klingenberg <tkli-php@lastflood.net>
  91.  * @copyright 2006-2007 Tom Klingenberg
  92.  * @license   LGPL http://www.gnu.org/licenses/lgpl.txt
  93.  * @link      http://isbn.lastflood.com/
  94.  * @since     Class available since Release 0.1.3
  95.  */
  96. class ISBN_Exception Extends PEAR_Exception
  97. {
  98. }
  99. // }}}
  100.  
  101. // {{{ ISBN
  102. /**
  103.  * ISBN class
  104.  *
  105.  * Class to Handle, Convert and Validate ISBN Numbers
  106.  *
  107.  * @category  Pending
  108.  * @package   ISBN
  109.  * @author    Tom Klingenberg <tkli-php@lastflood.net>
  110.  * @copyright 2006-2007 Tom Klingenberg
  111.  * @license   LGPL http://www.gnu.org/licenses/lgpl.txt
  112.  * @link      http://isbn.lastflood.com/
  113.  * @since     Class available since Release 0.0.0
  114.  */
  115. class ISBN
  116. {
  117.     /**
  118.      * @var string ISBN Registration Group
  119.      */
  120.     private $isbn_group '';
  121.     /**
  122.      * @var string ISBN Publisher
  123.      */
  124.     private $isbn_publisher '';
  125.     /**
  126.      * @var string ISBN Title
  127.      */
  128.     private $isbn_title '';
  129.  
  130.     /**
  131.      * @var mixed ISBN number version
  132.      */
  133.     private $ver ISBN_VERSION_NONE;
  134.     
  135.     /**
  136.      * @var array ISBN Groups Data acting as cache
  137.      * @see _getISBN10Groups()
  138.      */    
  139.     private static $varISBN10Groups array();    
  140.  
  141.     // {{{ __construct
  142.         /**
  143.      * Constructor
  144.      *
  145.      * @param array $isbn String of ISBN Value to use
  146.      * @param mixed $ver  Optional Version Constant
  147.      *
  148.      * @access public
  149.      * 
  150.      * @throws ISBN_Exception in case it fails
  151.      */
  152.     function __construct($isbn ''$ver ISBN_DEFAULT_INPUTVERSION)
  153.     {
  154.         /* validate & handle optional isbn parameter */
  155.         if (is_string($isbn== false {
  156.             throw new ISBN_Exception('ISBN parameter must be a string');
  157.         }
  158.         if (strlen($isbn== 0{
  159.             $this->setISBN($isbn);
  160.             return;
  161.         }
  162.  
  163.         /* validate version parameter */
  164.         if (self::_isbnVersionIs($ver== false{
  165.             throw new ISBN_Exception(
  166.                 'ISBN Version parameter is not an ISBN Version'
  167.             );
  168.         }
  169.  
  170.         /* ISBN has been passed, check the version now:
  171.          *  if it is unknown, try to dertine it, if this fails
  172.          *  throw an exception
  173.          */
  174.         if ($ver == ISBN_VERSION_UNKNOWN{
  175.             $verguess self::_isbnVersionGuess($isbn);
  176.             if (self::_isbnVersionIsValid($verguess)) {
  177.                 $ver $verguess;
  178.             else {
  179.                 /* throw new ISBN_Exception(
  180.                  *'ISBN Version couldn\'t determined.');
  181.                  */                                  
  182.                 $ver ISBN_VERSION_NONE;
  183.             }
  184.         }
  185.         /* version determined */
  186.         $this->ver $ver;
  187.  
  188.         /* handle a complete invalid ISBN of which a version could
  189.          * not be determined. */
  190.         if ($ver === ISBN_VERSION_NONE{
  191.             $this->setISBN('');
  192.             return;
  193.         }
  194.  
  195.         try {
  196.             $this->setISBN($isbn);
  197.         catch(Exception $e{
  198.             /* the isbn is invalid and not set, sothat this
  199.              * ISBN object will be set to a blank value. */
  200.             $this->setISBN('');
  201.         }
  202.  
  203.     }
  204.     // }}}
  205.  
  206.     // {{{ _extractCheckdigit()
  207.         /**
  208.      * extract Checkdigit of an ISBN-Number
  209.      *
  210.      * @param string $isbnn normalized ISBN string
  211.      *
  212.      * @return string|falseISBN-Body or false if failed
  213.      *
  214.      */
  215.     private static function _extractCheckdigit($isbnn)
  216.     {
  217.         $checkdigit false;
  218.         $checkdigit substr($isbnn-1);
  219.         return (string) $checkdigit;
  220.     }
  221.     // }}}
  222.  
  223.     // {{{ _extractEANPrefix()
  224.         /**
  225.      * extracts EAN-Prefix of a normalized isbn string
  226.      *
  227.      * @param string $isbnn normalized isbn string
  228.      *
  229.      * @return string|falsePrefix or false if failed
  230.      */
  231.     private static function _extractEANPrefix($isbnn)
  232.     {
  233.         $r settype($isbnn'string');
  234.         if ($r === false{
  235.             return false;
  236.         }
  237.         if (strlen($isbnn3{
  238.             return false;
  239.         }
  240.         $prefix substr($isbnn03);
  241.         return $prefix;
  242.     }
  243.     // }}}
  244.  
  245.     // {{{ _extractGroup()
  246.         /**
  247.      * extract Registration Group of an ISBN-Body
  248.      *
  249.      * @param string $isbnbody ISBN-Body
  250.      *
  251.      * @return integer|false   Registration Group or false if failed
  252.      */
  253.     private static function _extractGroup($isbnbody)
  254.     {
  255.         $group   '';
  256.         $subbody '';
  257.  
  258.         $r self::_isbnBodyParts($isbnbody$group$subbody);
  259.         if ($r === false{
  260.             return false;
  261.         }
  262.         return $group;
  263.     }
  264.     // }}}
  265.  
  266.     // {{{ _extractISBNBody()
  267.         /**
  268.      * extract ISBN-Body of an ISBN-Number
  269.      *
  270.      * @param string $isbnn normalized ISBN string
  271.      *
  272.      * @return string|falseISBN-Body or false if failed
  273.      */
  274.     private static function _extractISBNBody($isbnn)
  275.     {
  276.         /* extract */
  277.         $body  false;
  278.         $isbnn = (string) $isbnn;
  279.  
  280.         $l strlen($isbnn);
  281.         if ($l == 10{
  282.             $body =  substr($isbnn0-1);
  283.         elseif ($l == 13{
  284.             $body =  substr($isbnn3-1);
  285.         else {
  286.             return false;
  287.         }
  288.         /* verify */
  289.         $r settype($body'string');
  290.         if ($r === false{
  291.             return false;
  292.         }
  293.         if (strlen($body!= 9{
  294.             return false;
  295.         }
  296.         if (ctype_digit($body=== false{
  297.             return false;
  298.         }
  299.         return $body;
  300.     }
  301.     // }}}
  302.  
  303.     // {{{ _isbnBodyParts()
  304.         /**
  305.      * Get the 2 Parts of the ISBN-Body (ISBN-10/ISBN-13-978)
  306.      *
  307.      * @param string $isbnbody           ISBN-Body
  308.      * @param string &$registrationgroup Registration Group
  309.      * @param string &$isbnsubbody       ISBN-Subbody
  310.      *
  311.      * @return boolean  False if failed, True on success
  312.      *
  313.      * @access private
  314.      */
  315.     private static function _isbnBodyParts($isbnbody
  316.                                            &$registrationgroup
  317.                                            &$isbnsubbody)
  318.     {
  319.         /* validate input (should not be needed, @access private) */
  320.         $r settype($isbnbody'string');
  321.         if ($r === false{
  322.             return false;
  323.         }
  324.         if (strlen($isbnbody!= 9{
  325.             return false;
  326.         }
  327.         if (ctype_digit($isbnbody=== false{
  328.             return false;
  329.         }
  330.         /* extract registraion group
  331.          * boundaries see p.13 2005 handbook
  332.          */
  333.         $boundaries array();
  334.  
  335.         $boundaries[array(    0599991);
  336.         $boundaries[array(60000600993)// Iran 2006-12-05
  337.         $boundaries[array(60100699990);
  338.         $boundaries[array(70000799991);
  339.         $boundaries[array(80000949992);
  340.         $boundaries[array(95000989993);
  341.         $boundaries[array(99000998994);
  342.         $boundaries[array(99900999995);
  343.         /* segment value */
  344.         $segment      substr($isbnbody05);
  345.         $segmentvalue intval($segment);
  346.         /* test segment value against boundaries */
  347.         $r false;
  348.         foreach ($boundaries as $boundary{
  349.             if ($segmentvalue >= $boundary[0&& $segmentvalue <= $boundary[1]{
  350.                 $r $boundary[2];
  351.             }
  352.         }
  353.         if ($r === false{
  354.             return false;
  355.         }
  356.         /* $r is 0 when the boundary is not defined */
  357.         if ($r === 0{
  358.             return false;
  359.         }
  360.         $registrationgroup substr($isbnbody0$r);
  361.         $isbnsubbody       substr($isbnbody$r);
  362.         return true;
  363.     }
  364.     // }}}
  365.  
  366.     // {{{ _isbnSubbodyParts()
  367.         /**
  368.      * Get the 2 Parts of the ISBN-Subbody (ISBN-10/ISBN-13)
  369.      *
  370.      * @param string  $isbnsubbody  ISBN-Subbody
  371.      * @param integer $groupid      Registrationgroup
  372.      * @param string  &$registrant  Registrant
  373.      * @param string  &$publication Publication
  374.      *
  375.      * @return boolean  False if failed, true on success
  376.      *
  377.      * @access private
  378.      */
  379.     private static function _isbnSubbodyParts($isbnsubbody
  380.                                               $groupid
  381.                                               &$registrant
  382.                                               &$publication)
  383.     {
  384.         /* validate input (should not be needed, @access private) */
  385.         $r settype($isbnsubbody'string');
  386.         if ($r === false{
  387.             return false;
  388.         }
  389.         $l strlen($isbnsubbody);
  390.         if $l || $l 8{
  391.             return false;
  392.         }
  393.         if (ctype_digit($isbnsubbody=== false{
  394.             return false;
  395.         }
  396.         $r settype($groupid'integer');
  397.         if ($r === false{
  398.             return false;
  399.         }
  400.         if ($groupid || $groupid 99999{
  401.             return false;
  402.         }
  403.         /* extract registrant based on group and registrant range
  404.          * parse this specific group format: 
  405.          *  array(
  406.          *      'English speaking area',
  407.          *      '00-09;10-19;200-699;7000-8499;85000-89999;' .
  408.          *         '900000-949999;9500000-9999999'
  409.          *      );
  410.          */ 
  411.         
  412.         $group self::_getISBN10Group($groupid);
  413.         if ($group === false{
  414.             return false;
  415.         }
  416.  
  417.         $len self::_getRegistrantLength($isbnsubbody$group[1]);
  418.         if ($len === false{
  419.             return false;
  420.         }        
  421.         $registrant  substr($isbnsubbody0$len);
  422.         $publication substr($isbnsubbody$len);
  423.         return true;
  424.     }
  425.     // }}}
  426.  
  427.     // {{{ _getRegistrantLength()
  428.         /**
  429.      * Return Length of Registrant part within an ISBNSubbody in a specific
  430.      * grouprange in this specific format:
  431.      *
  432.      * '00-09;10-19;200-699;7000-8499;85000-89999;900000-949999;9500000-9999999'
  433.      *
  434.      * Info: This function is compatible with Groupranges formatted in the
  435.      * .js file and might become obsolete if new formats are more fitting.
  436.      *
  437.      * @param string $isbnsubbody ISBN-Subbody
  438.      * @param string $grouprange  Grouprange in the Format '#a1-#z1;#a2-z2[...]'
  439.      *
  440.      * @return boolean|int False if failed or Length (in chars) of Registrant
  441.      *
  442.      * @access private
  443.      */
  444.     private static function _getRegistrantLength($isbnsubbody$grouprange)
  445.     {
  446.         $r settype($grouprange'string');
  447.         if ($r === false{
  448.             return false;
  449.         }
  450.         if (strlen($grouprange3{
  451.             return false;
  452.         }
  453.         
  454.         $sl     strlen($isbnsubbody);
  455.         $ranges explode(';'$grouprange);
  456.         foreach ($ranges as $range{
  457.             $range  trim($range);
  458.             $fromto explode('-'$range);
  459.             if (count($fromto!== 2{
  460.                 return false;
  461.             }
  462.             /* validation:
  463.              * from and to need to be in the same class,
  464.              * having the same length.
  465.              * registrant can not be bigger or same then the
  466.              * whole subbody, at least there is one digit for
  467.              * the publication.
  468.              */
  469.  
  470.             $l strlen($fromto[0]);
  471.             if ($l != strlen($fromto[1])) {
  472.                 return false;
  473.             }
  474.             if ($l >= $sl{
  475.                 return false;
  476.             }
  477.  
  478.             /* check that from/to values are in order */
  479.             if (strcmp($fromto[0]$fromto[1]>= 0{
  480.                 return false;
  481.             }
  482.  
  483.             /* compare and fire if matched */
  484.             $comparec substr($isbnsubbody0$l);
  485.  
  486.             if (strcmp($fromto[0]$comparec&& 
  487.                 strcmp($fromto[1]$comparec> -1{
  488.                 return $l;
  489.             }
  490.         }        
  491.         return false;
  492.     }
  493.     // }}}
  494.  
  495.     // {{{ _getISBN10Group()
  496.         /**
  497.      * Get ISBN-10 Registration Group Data by its numeric ID
  498.      *
  499.      * @param integer $id Registration Group Identifier
  500.      *
  501.      * @return mixed    array:   group array
  502.      *                   boolean: False if failed
  503.      */
  504.     private static function _getISBN10Group($id)
  505.     {
  506.         $r settype($id'integer');
  507.         if ($r === false{
  508.             return false;
  509.         }
  510.         $groups self::_getISBN10Groups();
  511.         if ($groups === false{
  512.             return false;
  513.         }
  514.         if (isset($groups[$id]=== false{
  515.             return false;
  516.         }
  517.         $group $groups[$id];
  518.         return $group;
  519.     }
  520.     // }}}
  521.  
  522.     // {{{ _getISBN10Groups()
  523.         /**
  524.      * Get all ISBN-10 Registration Groups
  525.      *
  526.      * @return array    groups array
  527.      *
  528.      *  Info: This function connects outer world data into this class logic
  529.      *        which can be generated with the supplied tools.
  530.      *        A user should not alter the array data. This data should be altered
  531.      *        together with the international ISBN Agency only.
  532.      */
  533.     private static function _getISBN10Groups()
  534.     {
  535.         /* check if data has been already loaded */
  536.         if (sizeof(self::$varISBN10Groups{
  537.                 return self::$varISBN10Groups;      
  538.         }
  539.         
  540.         /* load external data */
  541.         try {       
  542.             $t file_get_contents('data/groups.csv'truenull);
  543.         catch(Exception $e{
  544.             throw new ISBN_Exception(
  545.                 'Unable to read ISBN Groups Data file.'
  546.             );          
  547.         }
  548.         
  549.         /* parse external data */
  550.         $groups array();      
  551.         $tls    split("\n"$t);
  552.         $line   0;
  553.         foreach ($tls as $tl{
  554.             $line++;            
  555.             $tlp split(','$tl);
  556.             if (sizeof($tlp== 3{
  557.                 $index intval($tlp[0]);
  558.                 if (isset($groups[$index])) {
  559.                     throw new ISBN_Exception(
  560.                         'ISBN Groups Data is invalid, Group ' .
  561.                         $index 'is a duplicate.'
  562.                     );                  
  563.                 }
  564.                 /* edit+ mature: sanitize external 
  565.                    data */
  566.                 $groups[$indexarray($tlp[1],$tlp[2]);                       
  567.             else {
  568.                 throw new ISBN_Exception(
  569.                     'ISBN Groups Data is malformed on line #' $line 
  570.                     ' (' sizeof($tlp').'
  571.                 );
  572.             }               
  573.         }
  574.         
  575.         /* verify minimum */    
  576.         if (sizeof($groups== {
  577.             throw new ISBN_Exception(
  578.                 'ISBN Groups Data does not contain any valid data.'
  579.             );          
  580.         }
  581.         
  582.         self::$varISBN10Groups $groups;
  583.         
  584.         /* return groups */
  585.         return $groups;
  586.     }
  587.     // }}}
  588.  
  589.     // {{{ _getVersion()
  590.         /**
  591.      * Get the Version of am ISBN Number
  592.      *
  593.      * @param string $isbn ISBN Number ofwhich the version to get
  594.      *
  595.      * @return mixed false for no, or fully identifyable ISBN
  596.      *                               Version Constant
  597.      *
  598.      * @access private
  599.      */
  600.     private static function _getVersion($isbn)
  601.     {
  602.         $ver self::_isbnVersionGuess($isbn);
  603.         $r   self::_isbnVersionIsValid($ver);
  604.         return $r;
  605.     }
  606.     // }}}
  607.  
  608.     // {{{ _checkdigitISBN10()
  609.           /**
  610.      * Calculate checkdigit of an ISBN-10 string (ISBN-Body)
  611.      * as documented on pp.4-5 2001 handbook.
  612.      *
  613.      * @param string $isbnbody ISBN-Body
  614.      *
  615.      * @return string|falseCheckdigit [0-9,X] or false if failed
  616.      *
  617.      * @access private
  618.      */
  619.     private static function _checkdigitISBN10($isbnbody)
  620.     {
  621.         /* The check digit is the last digit of an ISBN. It is calculated
  622.          * on a modulus 11 with weights 10-2, using X in lieu of 10 where
  623.          * ten would occur as a check digit.
  624.          * This means that each of the first nine digits of the ISBN ï¿½
  625.          * excluding the check digit itself ï¿½ is multiplied by a number
  626.          * ranging from 10 to 2 and that the resulting sum of the products,
  627.          * plus the check digit, must be divisible by 11 without a
  628.          * remainder. (pp.4-5 2001 Handbook)
  629.          */
  630.         if (strlen($isbnbody!= 9{
  631.             return false;
  632.         }
  633.         $sum 0;
  634.         for ($i 0$i 10$i++{
  635.             $v    intval(substr($isbnbody$i1));
  636.             $sum += $v (10 $i);
  637.         }
  638.         $remainder  $sum 11;
  639.         $checkdigit 11 $remainder;
  640.         if ($remainder == 0{
  641.             $checkdigit 0;
  642.         }
  643.         if ($checkdigit == 10{
  644.             $checkdigit 'X';
  645.         }
  646.         return (string) $checkdigit;
  647.     }
  648.     // }}}
  649.  
  650.     // {{{ _checkdigitISBN13()
  651.           /**
  652.      * Calculate checkdigit of an ISBN-13 string (Prefix + ISBN-Body)
  653.      * as documented on pp.10-11 2005 handbook.
  654.      *
  655.      * @param string $isbnbody ISBN-Body
  656.      * @param string $prefix   EAN-Prefix (Default 978 for ISBN13-978)
  657.      *
  658.      * @return string|falseCheckdigit [0-9] or false if failed
  659.      *
  660.      * @access private
  661.      */
  662.     private static function _checkdigitISBN13($isbnbody$prefix '978')
  663.     {
  664.         $prefixandisbnbody $prefix $isbnbody;
  665.  
  666.         $t $prefixandisbnbody;
  667.         $l strlen($t);
  668.         if ($l != 12{
  669.             return false;
  670.         }
  671.         /* Step 1: Determine the sum of the weighted products for the first 12
  672.         *  digits of the ISBN (see p.10 2005 handbook)
  673.         */
  674.         $ii 1;
  675.         $sum 0;
  676.         for ($i 0$i 13$i++{
  677.             $ii   $ii;
  678.             $sum += intval(substr($t$i1)) ($ii 1);
  679.         }
  680.         /* Step 2: Divide the sum of the weighted products of the first 12
  681.          * digits of the ISBN calculated in step 1 by 10, determining the
  682.          * remainder. (see p.11 2005 handbook)
  683.          */
  684.         $remainder $sum 10;
  685.  
  686.         /* Step 3: Subtract the remainder calculated in step 2 from 10. The
  687.          * resulting difference is the value of the check digit with one
  688.          * exception. If the remainder from step 2 is 0, the check
  689.          * digit is 0. (ebd.)
  690.          */
  691.         $checkdigit 10 $remainder;
  692.         if ($remainder == 0{
  693.             $checkdigit 0;
  694.         }
  695.         /* return string value */
  696.         if (is_int($checkdigit)) {
  697.             $checkdigit = (string) $checkdigit;
  698.         }
  699.         if (is_string($checkdigit== false{
  700.             return false;
  701.         }
  702.         return $checkdigit;
  703.     }
  704.     // }}}
  705.  
  706.     // {{{ _isIsbnValid()
  707.         /**
  708.      * Validate an ISBN value
  709.      *
  710.      * @param string $isbn Number to validate
  711.      * @param string $ver  Version to validate against
  712.      *
  713.      * @return integer|false   Returns the Version to signal validity or false if
  714.      *                             ISBN number is not valid
  715.      *
  716.      * @access private
  717.      */
  718.     private static function _isIsbnValid($isbn$ver ISBN_DEFAULT_INPUTVERSION)
  719.     {
  720.         /* version handling */
  721.         $r self::_isbnVersionIs($ver);
  722.         if ($r === false{
  723.             return false;
  724.         }
  725.         if ($ver === ISBN_VERSION_UNKNOWN{
  726.             $ver self::_isbnVersionGuess($isbn);
  727.         }
  728.         if (self::_isbnVersionIsValid($ver=== false{
  729.             return false;
  730.         }
  731.         /* since a version is available now, normalise the ISBN input */
  732.         $isbnn self::_normaliseISBN($isbn);
  733.         if ($isbnn === false{
  734.             return false;
  735.         }
  736.         /* normalzied ISBN and Version available, it's ok now
  737.          * to perform indepth checks per version */
  738.         switch ($ver{
  739.         case ISBN_VERSION_ISBN_10:
  740.  
  741.             /* check syntax against checkdigit */
  742.             $isbnbody self::_extractISBNBody($isbnn);
  743.             $check    self::_extractCheckdigit($isbnn);
  744.             if ($check === false{
  745.                 return false;
  746.             }
  747.             $checkdigit self::_checkdigitISBN10($isbnbody);
  748.             if ($checkdigit === false{
  749.                 return false;
  750.             }
  751.             if ($checkdigit !== $check{
  752.                 return false;
  753.             }
  754.  
  755.             /* check registrationgroup validity */
  756.             $registrationgroup false;
  757.             $subbody           false;
  758.  
  759.             $r self::_isbnBodyParts($isbnbody$registrationgroup$subbody);
  760.             if ($r == false{
  761.                 return false;
  762.             }
  763.  
  764.             /* check for undefined registrationgroup */
  765.             if (strlen($registrationgroup== 0{
  766.                 return false;
  767.             }
  768.  
  769.             /* check registrant validity */
  770.             $groupid     intval($registrationgroup);
  771.             $registrant  false;
  772.             $publication false;
  773.  
  774.             $r self::_isbnSubbodyParts($subbody$groupid
  775.                                          $registrant$publication);
  776.             if ($r == false{
  777.                 return false;
  778.             }
  779.             return true;
  780.  
  781.         case ISBN_VERSION_ISBN_13:
  782.         case ISBN_VERSION_ISBN_13_978:
  783.  
  784.             /* validate EAN Prefix */
  785.             $ean self::_extractEANPrefix($isbnn);
  786.             if ($ean !== '978'{
  787.                 return false;
  788.             }
  789.  
  790.             /* check syntax against checkdigit */
  791.             $isbnbody self::_extractISBNBody($isbnn);
  792.             $check    self::_extractCheckdigit($isbnn);
  793.             if ($check === false{
  794.                 return false;
  795.             }
  796.             $checkdigit self::_checkdigitISBN13($isbnbody);
  797.             if ($checkdigit === false{
  798.                 return false;
  799.             }
  800.             if ($check !== $checkdigit{
  801.                 return false;
  802.             }
  803.  
  804.             /* validate group */
  805.             $isbnbody self::_extractISBNBody($isbnn);
  806.             if ($isbnbody === false{
  807.                 return false;
  808.             }
  809.  
  810.             $registrationgroup false;
  811.             $subbody           false;
  812.  
  813.             $r self::_isbnBodyParts($isbnbody$registrationgroup$subbody);
  814.             if ($r === false{
  815.                 return false;
  816.             }
  817.  
  818.             /* check for undefined registrationgroup */
  819.             if (strlen($registrationgroup== 0{
  820.                 return false;
  821.             }
  822.  
  823.             /* validate publisher */
  824.             $registrant  false;
  825.             $publication false;
  826.  
  827.             $r self::_isbnSubbodyParts($subbody$registrationgroup
  828.                                          $registrant$publication);
  829.             if ($r === false{
  830.                 return false;
  831.             }
  832.             return $ver;
  833.  
  834.         case ISBN_VERSION_ISBN_13_979:
  835.             /* not yet standarized */
  836.             return false;
  837.  
  838.         }
  839.         return false;
  840.     }
  841.     // }}}
  842.  
  843.     // {{{ _isbnVersionGuess()
  844.         /**
  845.      * Guesses the version of an ISBN
  846.      *
  847.      * @param string $isbn ISBN Number of which the Version to guess
  848.      *
  849.      * @return integer|falseVersion Value or false (ISBN_VERSION_NONE) if failed
  850.      * @access private
  851.      */
  852.     private static function _isbnVersionGuess($isbn)
  853.     {
  854.         $isbn self::_normaliseISBN($isbn);
  855.         if ($isbn === false{
  856.             return ISBN_VERSION_NONE;
  857.         }
  858.         if strlen($isbn== 10{
  859.             return ISBN_VERSION_ISBN_10;
  860.         else {
  861.             return ISBN_VERSION_ISBN_13;
  862.         }
  863.     }
  864.     // }}}
  865.  
  866.     // {{{ _isbnVersionIs()
  867.         /**
  868.      * Validate an ISBN Version value
  869.      *
  870.      * @param mixed $ver version to be checked being a valid ISBN Version
  871.      *
  872.      * @return bool true if value is valid, false if not
  873.      *
  874.      * @access private
  875.      */
  876.     private static function _isbnVersionIs($ver)
  877.     {
  878.         if (is_bool($ver=== false && is_integer($ver=== false{
  879.             return false;
  880.         }
  881.         switch ($ver{
  882.         case ISBN_VERSION_NONE:
  883.         case ISBN_VERSION_UNKNOWN:
  884.         case ISBN_VERSION_ISBN_10:
  885.         case ISBN_VERSION_ISBN_13:
  886.         case ISBN_VERSION_ISBN_13_978:
  887.         case ISBN_VERSION_ISBN_13_979:
  888.             return true;
  889.  
  890.         default:
  891.             return false;
  892.  
  893.         }
  894.     }
  895.     // }}}
  896.  
  897.     // {{{ _isbnVersionIsValid()
  898.         /**
  899.      * Validate an ISBN value being a valid (identifyable -10 / -13) value
  900.      *
  901.      * @param mixed $ver value to be checked being a valid ISBN Version
  902.      *
  903.      * @return bool true if value is valid, false if not
  904.      *
  905.      * @access private
  906.      */
  907.     private static function _isbnVersionIsValid($ver)
  908.     {
  909.         $r self::_isbnVersionIs($ver);
  910.         if ($r === false{
  911.             return false;
  912.         }
  913.  
  914.         switch ($ver{
  915.         case ISBN_VERSION_ISBN_10:
  916.         case ISBN_VERSION_ISBN_13_978:
  917.             return true;
  918.         default:
  919.             return false;
  920.         }
  921.     }
  922.     // }}}
  923.  
  924.     // {{{ _normaliseISBN()
  925.         /**
  926.      * downformat "any" ISBN Number to the very basics
  927.      * an isbn number is a 10 or 13 digit. with the
  928.      * 10 digit string, the last digit can be 0-9 and
  929.      * X as well, all other are 0-9 only
  930.      * additionally this fucntion can be used to validate
  931.      * the isbn against correct length and chars
  932.      *
  933.      * @param string $isbn ISBN String to normalise
  934.      *
  935.      * @return string|falsenormalised ISBN Number or false if the function was
  936.      *                         not able to normalise the input
  937.      *
  938.      * @access private
  939.      */
  940.     private static function _normaliseISBN($isbn)
  941.     {
  942.         /* validate input */
  943.         $r settype($isbn'string');
  944.         if ($r === false{
  945.             return false;
  946.         }
  947.  
  948.         /* normalize (trim & case)*/
  949.         $isbn trim($isbn);
  950.         $isbn strtoupper($isbn);
  951.  
  952.         /* remove lang specific prefix (if any) */
  953.         $isbn self::_normaliseISBNremoveLangSpecific($isbn);
  954.  
  955.         /* remove ISBN-10: or ISBN-13: prefix (if any) */
  956.         if (strlen($isbn 8)) {
  957.             $prefix substr($isbn08);
  958.             if ($prefix == 'ISBN-10:' || $prefix == 'ISBN-13:'{
  959.                 $isbn substr($isbn8);
  960.                 $isbn ltrim($isbn);
  961.             }
  962.         }
  963.  
  964.         /* remove lang specific prefix again (if any) */
  965.         $isbn self::_normaliseISBNremoveLangSpecific($isbn);
  966.  
  967.         /* remove "ISBN" prefix (if any)*/
  968.         if (substr($isbn04== 'ISBN'{
  969.             $isbn substr($isbn4);
  970.         }
  971.  
  972.         /* remove cosmetic chars and different type of spaces */
  973.         $isbn str_replace(array('-'' ''\t''\n')''$isbn);
  974.  
  975.         /* take the length to check and differ between versions
  976.          * sothat a syntaxcheck can be made */
  977.         $l strlen($isbn);
  978.         if ($l != 10 && $l != 13{
  979.             return false;
  980.         elseif ($l == 10{
  981.             if (!preg_match('/^[0-9]{9}[0-9X]$/'$isbn)) {
  982.                 return false;
  983.             }
  984.         elseif ($l == 13{
  985.             if (!ctype_digit($isbn)) {
  986.                 return false;
  987.             }
  988.         }
  989.         return $isbn;
  990.     }
  991.     // }}}
  992.  
  993.     // {{{ _normaliseISBNremoveLangSpecific()
  994.         /**
  995.      * helper function for _normaliseISBN to
  996.      * remove lang sepcific ISBN prefix
  997.      *
  998.      * @param string $isbn ISBN String to check (partially normalised)
  999.      *
  1000.      * @return string   input value passed through helper
  1001.      *
  1002.      * @access private
  1003.      */
  1004.     private static function _normaliseISBNremoveLangSpecific($isbn)
  1005.     {
  1006.         $l    strlen($lang);
  1007.         if ($l {
  1008.             if (substr($isbn0$l== $lang{
  1009.                 $isbn substr($isbn$l);
  1010.             }
  1011.         }
  1012.         return $isbn;
  1013.     }
  1014.     // }}}
  1015.  
  1016.     // {{{ convert()
  1017.         /**
  1018.      * converts an ISBN number from one version to another
  1019.      * can convert ISBN-10 to ISBN-13 and ISBN-13 to ISBN-10
  1020.      * 
  1021.      * @param string  $isbnin  ISBN to convert, must be a valid ISBN Number
  1022.      * @param integer $verfrom version value of the input ISBN
  1023.      * @param integer $verto   version value to convert to
  1024.      *
  1025.      * @return string|falseconverted ISBN Number or false if conversion failed
  1026.      */
  1027.     public static function convert($isbnin$verfrom ISBN_VERSION_ISBN_10
  1028.                                    $verto ISBN_VERSION_ISBN_13)
  1029.     {
  1030.         /* validate input */
  1031.         if (!self::_isbnVersionIsValid($verfrom)) {
  1032.             return false;
  1033.         }
  1034.         if (!self::_isbnVersionIsValid($verto)) {
  1035.             return false;
  1036.         }
  1037.         $r self::validate($isbnin$verfrom);
  1038.         if ($r === false{
  1039.             return false;
  1040.         }
  1041.         /* normalize input */
  1042.         $isbnn self::_normaliseISBN($isbnin);
  1043.         /* input is ok now, let's convert */
  1044.         switch(true{
  1045.         case $verfrom == ISBN_VERSION_ISBN_10 && $verto == ISBN_VERSION_ISBN_13:
  1046.             /* convert 10 to 13 */
  1047.             $isbnbody self::_extractISBNBody($isbnn);
  1048.             if ($isbnbody === false{
  1049.                 return false;
  1050.             }
  1051.             $isbnout '978' $isbnbody self::_checkdigitISBN13($isbnbody);
  1052.             return $isbnout;
  1053.         case $verfrom == ISBN_VERSION_ISBN_13 && $verto == ISBN_VERSION_ISBN_10:
  1054.             /* convert 13 to 10 */
  1055.             $isbnbody self::_extractISBNBody($isbnn);
  1056.             if ($isbnbody === false{
  1057.                 return false;
  1058.             }
  1059.             $isbnout $isbnbody self::_checkdigitISBN10($isbnbody);
  1060.             return $isbnout;
  1061.         case $verfrom == $verto:
  1062.             /* version is the same so there is no need to convert */
  1063.             /* hej, praktisch! */           
  1064.             return $isbnn;              
  1065.         }        
  1066.         return false;
  1067.     }
  1068.     // }}}
  1069.  
  1070.     // {{{ getCheckdigit()
  1071.         /**
  1072.      * Get the Checkdigit Part of ISBN Number
  1073.      *
  1074.      * @return string|falseCheckdigit or false if failed
  1075.      */
  1076.     public function getCheckdigit()
  1077.     {
  1078.         $ver   $this->getVersion();
  1079.         $check false;
  1080.  
  1081.         switch ($ver{
  1082.         case ISBN_VERSION_ISBN_10:
  1083.             $check self::_checkdigitISBN10($this->_getISBNBody());
  1084.             break;
  1085.  
  1086.         case ISBN_VERSION_ISBN_13:
  1087.             $check self::_checkdigitISBN13($this->_getISBNBody());
  1088.             break;
  1089.  
  1090.         }
  1091.  
  1092.         return $check;
  1093.     }
  1094.     // }}}
  1095.  
  1096.     // {{{ getEAN()
  1097.         /**
  1098.      * Get the EAN Prefix of ISBN Number (ISBN-13)
  1099.      *
  1100.      * @return string|falseEAN Prefix or false if failed
  1101.      */
  1102.     public function getEAN()
  1103.     {
  1104.         $ver $this->getVersion();
  1105.         if ($ver === false {
  1106.             return false;
  1107.         }
  1108.         if ($ver == ISBN_VERSION_ISBN_13_978{
  1109.             return '978';
  1110.         }
  1111.         if ($ver == ISBN_VERSION_ISBN_13_979{
  1112.             return '979';
  1113.         }
  1114.         return '';
  1115.     }
  1116.     // }}}
  1117.  
  1118.     // {{{ getGroup()
  1119.         /**
  1120.      * Get the Registrationgroup Part of the ISBN Number
  1121.      *
  1122.      * @return string|falseGroup Identifier or false if failed
  1123.      */
  1124.     public function getGroup()
  1125.     {
  1126.         return $this->isbn_group;
  1127.     }
  1128.     // }}}
  1129.  
  1130.     // {{{ _setGroup()
  1131.         /**
  1132.      * Setter for the Registrationgroup Part of the ISBN Number
  1133.      *
  1134.      * @param string $group Registrationsgroup to set
  1135.      * 
  1136.      * @return void 
  1137.      * 
  1138.      * @throws ISBN_Exception in case it fails
  1139.      */
  1140.     private function _setGroup($group)
  1141.     {
  1142.         if (is_string($group== false{
  1143.             throw new ISBN_Exception('Wrong Vartype');
  1144.         }
  1145.         $l strlen($group);
  1146.         if ($l || $l 5{
  1147.             throw new ISBN_Exception('Wrong Group Length (' $l ')');
  1148.         }
  1149.         $testbody  substr($group '000000000'09);
  1150.         $testgroup self::_extractGroup($testbody);
  1151.         if ($testgroup === false {
  1152.             throw new ISBN_Exception('Invalid Group');
  1153.         }
  1154.         if ($testgroup != $group{
  1155.             throw new ISBN_Exception('Invalid Group');
  1156.         }        
  1157.         $this->isbn_group $group;
  1158.     }
  1159.  
  1160.     // {{{ getISBN()
  1161.         /**
  1162.      * Get whole ISBN Number
  1163.      *
  1164.      * @return string ISBN Number (unformatted); empty string if this is
  1165.      *                 not a valid ISBN
  1166.      */
  1167.     public function getISBN()
  1168.     {
  1169.         $ver $this->getVersion();
  1170.         if ($ver === false {
  1171.             return '';
  1172.         }
  1173.  
  1174.         $isbn '';
  1175.  
  1176.         $r self::_isbnVersionIsValid($ver);
  1177.         if ($r === false {
  1178.             return $isbn;
  1179.         }
  1180.  
  1181.         $isbn .= $this->getEAN();
  1182.         $isbn .= $this->_getISBNBody();
  1183.         $isbn .= $this->getCheckdigit();
  1184.  
  1185.         return $isbn;
  1186.     }
  1187.     // }}}
  1188.     
  1189.     // {{{ getISBNDisplayable()
  1190.         /**
  1191.      * Get whole ISBN Number in a displayable fashion (see Handbook p. 15)
  1192.      *
  1193.      * @param string $format Formatstring 1-4 Chars:
  1194.      *                each character is a control char:
  1195.      *                #1 i or not: use international pre-prefix
  1196.      *                #2 i or not: "ISBN" in front or v: incl. version
  1197.      *                #3 : or not: insert a ":"
  1198.      *                #4 - or not: use - after EAN (ISBN 13 only)
  1199.      *                #4 or =: use - between each ISBN part
  1200.      *                Example 1:
  1201.      *                   '   --' 978-0-385-33941-4
  1202.      *                   classic displayable ISBN
  1203.      *                Example 2:
  1204.      *                   ' v:-' ISBN-13: 978-0385339414
  1205.      *                   ISBN-Format used by amazon
  1206.      *                Example 3:
  1207.      *                   'iv:=' ISBN-13: 978-0-385-33941-4
  1208.      *                   full blown: more is more!
  1209.      *   
  1210.      * @return string ISBN Number (formatted); empty string if this is
  1211.      *                 not a valid ISBN
  1212.      */    
  1213.     public function getISBNDisplayable($format '')
  1214.     {
  1215.         if strlen($format)=={
  1216.             $format 'iv:='//edit $this->ISBNFormatstring;
  1217.         }
  1218.         $format substr($format '    '04);
  1219.         
  1220.         $ver $this->getVersion();
  1221.         if ($ver === false {
  1222.             return '';
  1223.         }
  1224.  
  1225.         $isbn '';
  1226.  
  1227.         $r self::_isbnVersionIsValid($ver);
  1228.         if ($r === false {
  1229.             return $isbn;
  1230.         }
  1231.  
  1232.         if ($format[0== 'i'{
  1233.             $isbn .= ISBN_DEFAULT_PRINT_LANG_SPECIFIC_PREFIX;
  1234.             if (strlen($isbn)) $isbn .= ' ';
  1235.         }
  1236.         
  1237.         if ($format[1== 'i' || $format[1== 'v'{
  1238.             $isbn .= 'ISBN';
  1239.             if ($format[1== 'v'{
  1240.                 switch ($ver{
  1241.                 case ISBN_VERSION_ISBN_10:
  1242.                     $isbn .= '-10';
  1243.                     break;
  1244.                 case ISBN_VERSION_ISBN_13:
  1245.                     $isbn .= '-13';
  1246.                     break;
  1247.                 }               
  1248.             }
  1249.         }
  1250.         
  1251.         if ($format[2== ':'{
  1252.             $isbn .= ':';
  1253.         }
  1254.         
  1255.         if (strlen($isbn)) {
  1256.             $isbn .= ' ';
  1257.         }
  1258.         
  1259.         if ($ver == ISBN_VERSION_ISBN_13_978 || $ver == ISBN_VERSION_ISBN_13_979{
  1260.             $isbn .= $this->getEAN();
  1261.             if ($format[3== '-' || $format[3== '='{
  1262.                 $isbn .= ISBN_DEFAULT_COSMETIC_SEPERATOR;
  1263.             }
  1264.         }
  1265.         
  1266.         $seperator ($format[3== '='ISBN_DEFAULT_COSMETIC_SEPERATOR '';
  1267.                 
  1268.         $isbn .= $this->getGroup($seperator;
  1269.         $isbn .= $this->getPublisher($seperator;
  1270.         $isbn .= $this->getTitle($seperator;        
  1271.         $isbn .= $this->getCheckdigit();
  1272.  
  1273.         return $isbn;
  1274.         
  1275.     }
  1276.     // }}}
  1277.  
  1278.     // {{{ setISBN()
  1279.         /**
  1280.      * Setter for ISBN
  1281.      *
  1282.      * @param string $isbn ISBN Number
  1283.      *           this is a valid ISBN Number or it is an Empty string
  1284.      *           which will reset the class
  1285.      * 
  1286.      * @return void 
  1287.      * 
  1288.      * @throws ISBN_Exception in case it fails
  1289.      * 
  1290.      */
  1291.     public function setISBN($isbn)
  1292.     {
  1293.         if ($isbn == ''{
  1294.             $this->ver            ISBN_VERSION_NONE;
  1295.             $this->isbn_group     '';
  1296.             $this->isbn_publisher '';
  1297.             $this->isbn_title     '';
  1298.         else {
  1299.             $isbnn self::_normaliseISBN($isbn);
  1300.             $ver   self::_getVersion($isbnn);
  1301.             if ($ver === false{
  1302.                 throw new ISBN_Exception('Invalid ISBN');
  1303.             }
  1304.             if ($ver != $this->ver and $this->ver !== ISBN_VERSION_NONE{
  1305.                 throw new ISBN_Exception(
  1306.                   'ISBN Version of passed ISBN (' $ver ') '.
  1307.                   'does not match existing (' $this->ver ').'
  1308.                 );
  1309.             elseif ($this->ver === ISBN_VERSION_NONE{
  1310.                 $this->ver $ver;
  1311.             }
  1312.             $body self::_extractISBNBody($isbnn);
  1313.             if ($body === false{
  1314.                 throw new ISBN_Exception('Invalid ISBN (could not extract body)');
  1315.             }
  1316.             try {
  1317.                 $this->_setISBNBody($body);
  1318.             catch (ISBN_Exception $e{
  1319.                 throw new ISBN_Exception(
  1320.                     'Invalid ISBN (invalid body "' $body '")'$e
  1321.                 );
  1322.             }
  1323.         }
  1324.     }
  1325.     // }}}
  1326.  
  1327.     // {{{ _getISBNBody()
  1328.         /**
  1329.      * _getISBNBody()
  1330.      *
  1331.      * @return string ISBN Body (not an offical term)
  1332.      */
  1333.     private function _getISBNBody()
  1334.     {
  1335.         $body  '';
  1336.         $body .= $this->getGroup();
  1337.         $body .= $this->_getISBNSubbody();
  1338.         return $body;
  1339.     }
  1340.     // }}}
  1341.  
  1342.     // {{{ _setISBNBody()
  1343.         /**
  1344.      * _setISBNBody()
  1345.      *
  1346.      * Setter for ISBNBody
  1347.      *
  1348.      * @param string $body ISBNBody
  1349.      * 
  1350.      * @return void 
  1351.      * 
  1352.      * @throws ISBN_Exception in case it fails
  1353.      */
  1354.     private function _setISBNBody($body)
  1355.     {
  1356.         /* validate parameter */
  1357.         if (is_string($body== false{
  1358.             throw new ISBN_Exception('Not a Body: wrong variabletype');
  1359.         }
  1360.         if (strlen($body!= 9{
  1361.             throw new ISBN_Exception('Not a Body: wrong body length');
  1362.         }
  1363.         if (ctype_digit($body!== true{
  1364.             throw new ISBN_Exception('Not a Body: syntactically not a body');
  1365.         }
  1366.  
  1367.         /* validate body by extracting and validating parts */
  1368.         $group   false;
  1369.         $subbody false;
  1370.  
  1371.         $r self::_isbnBodyParts($body$group$subbody);
  1372.         if ($r == false{
  1373.             throw new ISBN_Exception('Invalid Body');
  1374.         }
  1375.         
  1376.         try {
  1377.             $this->_setGroup($group);
  1378.         catch (ISBN_Exception $e{
  1379.             throw new Exception('Invalid Body: Group is invalid'$e);
  1380.         }
  1381.  
  1382.         try {
  1383.             $this->_setISBNSubbody($subbody);
  1384.         catch (ISBN_Exception $e{
  1385.             throw new ISBN_Exception(
  1386.                 'Invalid Body: Subbody is invalid (' $e->getMessage(')'$e
  1387.             );
  1388.         }
  1389.     }
  1390.     // }}}
  1391.  
  1392.     // {{{ _getISBNSubbody()
  1393.         /**
  1394.      * Get ISBNSubbody ()
  1395.      *
  1396.      * @return ISBN Subbody
  1397.      */
  1398.     private function _getISBNSubbody()
  1399.     {
  1400.         $subbody  '';
  1401.         $subbody .= $this->getPublisher();
  1402.         $subbody .= $this->getTitle();
  1403.         return $subbody;
  1404.     }
  1405.     // }}}
  1406.  
  1407.     // {{{ _setISBNSubbody()
  1408.         /**
  1409.      * _setISBNSubbody
  1410.      *
  1411.      * Setter for the ISBN Subbody
  1412.      *
  1413.      * @param string $subbody ISBN Subbody
  1414.      * 
  1415.      * @return void 
  1416.      * 
  1417.      * @throws ISBN_Exception in case it fails
  1418.      */
  1419.     private function _setISBNSubbody($subbody)
  1420.     {
  1421.         /* validate parameter */
  1422.         if (is_string($subbody== false{
  1423.             throw new ISBN_Exception('Wrong Vartype');
  1424.         }
  1425.         $l strlen($subbody);
  1426.         if $l || $l 8{
  1427.             throw new ISBN_Exception('Not a Subbody by length');
  1428.         }
  1429.         /* validate by setting apart */
  1430.         $registrant  false;
  1431.         $publication false;
  1432.         $groupid     intval($this->isbn_group);
  1433.         
  1434.         $r self::_isbnSubbodyParts($subbody$groupid$registrant$publication);
  1435.         if ($r === false{
  1436.             throw new ISBN_Exception('Can\'t break');
  1437.         }
  1438.         /* edit+ setter/getter for Registrant/Publisher and Title/Publication */
  1439.         $this->isbn_publisher $registrant;
  1440.         $this->isbn_title     $publication;
  1441.     }
  1442.  
  1443.     // {{{ getPublisher()
  1444.         /**
  1445.      * Get the Publication Part of the ISBN Number
  1446.      *
  1447.      * @return string|falsePublisher or false if failed
  1448.      */
  1449.     public function getPublisher()
  1450.     {
  1451.         return $this->isbn_publisher;
  1452.     }
  1453.     // }}}
  1454.  
  1455.     // {{{ getTitle()
  1456.         /**
  1457.      * Get the Title Part of the ISBN Number
  1458.      *
  1459.      * @return string|falseTitle or false if failed
  1460.      */
  1461.     public function getTitle()
  1462.     {
  1463.         return $this->isbn_title;
  1464.     }
  1465.     // }}}
  1466.  
  1467.  
  1468.     // {{{ isValid()
  1469.         /**
  1470.      * Returns this ISBN validity
  1471.      *
  1472.      * @return boolean 
  1473.      */
  1474.     public function isValid()
  1475.     {
  1476.         $isbn $this->getISBN();
  1477.         $r    self::validate($this->getISBN()$this->getVersion());
  1478.         return (bool) $r;
  1479.     }
  1480.  
  1481.     // {{{ validate()
  1482.         /**
  1483.      * Validates an ISBN
  1484.      * 
  1485.      * @param string  $isbn ISBN to validate
  1486.      * @param integer $ver  ISBN-Version to validate against
  1487.      *
  1488.      * @return integer|false   Version value of a valid ISBN or false
  1489.      *                           if it did not validate
  1490.      */
  1491.     public static function validate($isbn$ver ISBN_DEFAULT_INPUTVERSION)
  1492.     {
  1493.         $r self::_isbnVersionIs($ver);
  1494.         if ($r === false{
  1495.             return false;
  1496.         }
  1497.         if ($ver === ISBN_VERSION_UNKNOWN{
  1498.             $ver self::_isbnVersionGuess($isbn);
  1499.         }
  1500.         if (self::_isbnVersionIsValid($ver=== false{
  1501.             return false;
  1502.         }
  1503.         $r self::_isIsbnValid($isbn$ver);
  1504.         if ($r === false{
  1505.             return false;
  1506.         }
  1507.         return $ver;
  1508.     }
  1509.     // }}}
  1510.  
  1511.     // {{{ getVersion()
  1512.         /**
  1513.      * Returns version of this objects ISBN
  1514.      *
  1515.      * @return integer|false Version value or ISBN_VERSION_NONE
  1516.      */
  1517.     public function getVersion()
  1518.     {
  1519.         return $this->ver;
  1520.     }
  1521.  
  1522.  
  1523.     // {{{ guessVersion()
  1524.         /**
  1525.      * Guesses ISBN version of passed string
  1526.      *
  1527.      * Note: This is not Validation. To get the validated
  1528.      * version of an ISBN Number use self::validate();
  1529.      *     
  1530.      * @param string $isbn ISBN Number to guess Version of
  1531.      * 
  1532.      * @return integer|false   Version Value or false if failed
  1533.      * 
  1534.      * @see validate();
  1535.      */
  1536.     public static function guessVersion($isbn)
  1537.     {
  1538.         $r self::_isbnVersionGuess($isbn);
  1539.         return $r;
  1540.     }
  1541.     // }}}
  1542.  
  1543. }
  1544. ?>

Documentation generated on Tue, 06 Mar 2007 01:03:06 +0100 by phpDocumentor 1.3.1