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 <[email protected]> |
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
|
|
|
// {{{ ISBN_Exception |
83
|
|
|
/** |
84
|
|
|
* ISBN_Exception class |
85
|
|
|
* |
86
|
|
|
* @category Pending |
87
|
|
|
* @package ISBN |
88
|
|
|
* @author Tom Klingenberg <[email protected]> |
89
|
|
|
* @copyright 2006-2007 Tom Klingenberg |
90
|
|
|
* @license LGPL http://www.gnu.org/licenses/lgpl.txt |
91
|
|
|
* @link http://isbn.lastflood.com/ |
92
|
|
|
* @since Class available since Release 0.1.3 |
93
|
|
|
*/ |
94
|
|
|
class ISBN_Exception |
95
|
|
|
{ |
96
|
|
|
function __construct($message, $e = null) { |
97
|
|
|
$this->message = $message; |
|
|
|
|
98
|
|
|
$this->e = $e; |
|
|
|
|
99
|
|
|
} |
100
|
|
|
|
101
|
|
|
function getMessage() { |
102
|
|
|
return $this->message; |
103
|
|
|
} |
104
|
|
|
} |
105
|
|
|
// }}} |
106
|
|
|
|
107
|
|
|
// {{{ ISBN |
108
|
|
|
/** |
109
|
|
|
* ISBN class |
110
|
|
|
* |
111
|
|
|
* Class to Handle, Convert and Validate ISBN Numbers |
112
|
|
|
* |
113
|
|
|
* @category Pending |
114
|
|
|
* @package ISBN |
115
|
|
|
* @author Tom Klingenberg <[email protected]> |
116
|
|
|
* @copyright 2006-2007 Tom Klingenberg |
117
|
|
|
* @license LGPL http://www.gnu.org/licenses/lgpl.txt |
118
|
|
|
* @link http://isbn.lastflood.com/ |
119
|
|
|
* @since Class available since Release 0.0.0 |
120
|
|
|
*/ |
121
|
|
|
class ISBN |
122
|
|
|
{ |
123
|
|
|
var $groups_csv = "data/groups.csv"; |
124
|
|
|
|
125
|
|
|
/** |
126
|
|
|
* @var string ISBN Registration Group |
127
|
|
|
*/ |
128
|
|
|
var $isbn_group = ''; |
129
|
|
|
/** |
130
|
|
|
* @var string ISBN Publisher |
131
|
|
|
*/ |
132
|
|
|
var $isbn_publisher = ''; |
133
|
|
|
/** |
134
|
|
|
* @var string ISBN Title |
135
|
|
|
*/ |
136
|
|
|
var $isbn_title = ''; |
137
|
|
|
|
138
|
|
|
/** |
139
|
|
|
* @var mixed ISBN number version |
140
|
|
|
*/ |
141
|
|
|
var $ver = ISBN_VERSION_NONE; |
142
|
|
|
|
143
|
|
|
/** |
144
|
|
|
* @var array ISBN Groups Data acting as cache |
145
|
|
|
* @see _getISBN10Groups() |
146
|
|
|
*/ |
147
|
|
|
var $varISBN10Groups = array(); |
148
|
|
|
|
149
|
|
|
// {{{ __construct |
150
|
|
|
/** |
151
|
|
|
* Constructor |
152
|
|
|
* |
153
|
|
|
* @param array $isbn String of ISBN Value to use |
154
|
|
|
* @param mixed $ver Optional Version Constant |
155
|
|
|
* |
156
|
|
|
* @access public |
157
|
|
|
* |
158
|
|
|
* @throws ISBN_Exception in case it fails |
159
|
|
|
*/ |
160
|
|
|
function __construct($isbn = '', $ver = ISBN_DEFAULT_INPUTVERSION) |
161
|
|
|
{ |
162
|
|
|
/* validate & handle optional isbn parameter */ |
163
|
|
|
if (is_string($isbn) == false ) { |
|
|
|
|
164
|
|
|
return new ISBN_Exception('ISBN parameter must be a string'); |
|
|
|
|
165
|
|
|
} |
166
|
|
|
if (strlen($isbn) == 0) { |
167
|
|
|
$this->setISBN($isbn); |
168
|
|
|
return; |
169
|
|
|
} |
170
|
|
|
|
171
|
|
|
/* validate version parameter */ |
172
|
|
|
if (ISBN::_isbnVersionIs($ver) == false) { |
|
|
|
|
173
|
|
|
return new ISBN_Exception( |
|
|
|
|
174
|
|
|
'ISBN Version parameter is not an ISBN Version' |
175
|
|
|
); |
176
|
|
|
} |
177
|
|
|
|
178
|
|
|
/* ISBN has been passed, check the version now: |
179
|
|
|
* if it is unknown, try to dertine it, if this fails |
180
|
|
|
* throw an exception |
181
|
|
|
*/ |
182
|
|
|
if ($ver == ISBN_VERSION_UNKNOWN) { |
183
|
|
|
$verguess = ISBN::_isbnVersionGuess($isbn); |
184
|
|
|
if (ISBN::_isbnVersionIsValid($verguess)) { |
185
|
|
|
$ver = $verguess; |
186
|
|
|
} else { |
187
|
|
|
/* throw new ISBN_Exception( |
188
|
|
|
*'ISBN Version couldn\'t determined.'); |
189
|
|
|
*/ |
190
|
|
|
$ver = ISBN_VERSION_NONE; |
191
|
|
|
} |
192
|
|
|
} |
193
|
|
|
/* version determined */ |
194
|
|
|
$this->ver = $ver; |
195
|
|
|
|
196
|
|
|
/* handle a complete invalid ISBN of which a version could |
197
|
|
|
* not be determined. */ |
198
|
|
|
if ($ver === ISBN_VERSION_NONE) { |
199
|
|
|
$this->setISBN(''); |
200
|
|
|
return; |
201
|
|
|
} |
202
|
|
|
|
203
|
|
|
$e = $this->setISBN($isbn); |
204
|
|
|
if ("ISBN_Exception" == get_class($e)) { |
205
|
|
|
/* the isbn is invalid and not set, sothat this |
206
|
|
|
* ISBN object will be set to a blank value. */ |
207
|
|
|
$this->setISBN(''); |
208
|
|
|
} |
209
|
|
|
|
210
|
|
|
} |
211
|
|
|
// }}} |
212
|
|
|
|
213
|
|
|
// {{{ _extractCheckdigit() |
214
|
|
|
/** |
215
|
|
|
* extract Checkdigit of an ISBN-Number |
216
|
|
|
* |
217
|
|
|
* @param string $isbnn normalized ISBN string |
218
|
|
|
* |
219
|
|
|
* @return string|false ISBN-Body or false if failed |
220
|
|
|
* |
221
|
|
|
*/ |
222
|
|
|
function _extractCheckdigit($isbnn) |
223
|
|
|
{ |
224
|
|
|
$checkdigit = false; |
|
|
|
|
225
|
|
|
$checkdigit = substr($isbnn, -1); |
226
|
|
|
return (string) $checkdigit; |
227
|
|
|
} |
228
|
|
|
// }}} |
229
|
|
|
|
230
|
|
|
// {{{ _extractEANPrefix() |
231
|
|
|
/** |
232
|
|
|
* extracts EAN-Prefix of a normalized isbn string |
233
|
|
|
* |
234
|
|
|
* @param string $isbnn normalized isbn string |
235
|
|
|
* |
236
|
|
|
* @return string|false Prefix or false if failed |
237
|
|
|
*/ |
238
|
|
|
function _extractEANPrefix($isbnn) |
239
|
|
|
{ |
240
|
|
|
$r = settype($isbnn, 'string'); |
241
|
|
|
if ($r === false) { |
242
|
|
|
return false; |
243
|
|
|
} |
244
|
|
|
if (strlen($isbnn) < 3) { |
245
|
|
|
return false; |
246
|
|
|
} |
247
|
|
|
$prefix = substr($isbnn, 0, 3); |
248
|
|
|
return $prefix; |
249
|
|
|
} |
250
|
|
|
// }}} |
251
|
|
|
|
252
|
|
|
// {{{ _extractGroup() |
253
|
|
|
/** |
254
|
|
|
* extract Registration Group of an ISBN-Body |
255
|
|
|
* |
256
|
|
|
* @param string $isbnbody ISBN-Body |
257
|
|
|
* |
258
|
|
|
* @return integer|false Registration Group or false if failed |
259
|
|
|
*/ |
260
|
|
|
function _extractGroup($isbnbody) |
261
|
|
|
{ |
262
|
|
|
$group = ''; |
263
|
|
|
$subbody = ''; |
264
|
|
|
|
265
|
|
|
$r = ISBN::_isbnBodyParts($isbnbody, $group, $subbody); |
266
|
|
|
if ($r === false) { |
267
|
|
|
return false; |
268
|
|
|
} |
269
|
|
|
return $group; |
270
|
|
|
} |
271
|
|
|
// }}} |
272
|
|
|
|
273
|
|
|
// {{{ _extractISBNBody() |
274
|
|
|
/** |
275
|
|
|
* extract ISBN-Body of an ISBN-Number |
276
|
|
|
* |
277
|
|
|
* @param string $isbnn normalized ISBN string |
278
|
|
|
* |
279
|
|
|
* @return string|false ISBN-Body or false if failed |
280
|
|
|
*/ |
281
|
|
|
function _extractISBNBody($isbnn) |
282
|
|
|
{ |
283
|
|
|
/* extract */ |
284
|
|
|
$body = false; |
|
|
|
|
285
|
|
|
$isbnn = (string) $isbnn; |
286
|
|
|
|
287
|
|
|
$l = strlen($isbnn); |
288
|
|
|
if ($l == 10) { |
289
|
|
|
$body = substr($isbnn, 0, -1); |
290
|
|
|
} elseif ($l == 13) { |
291
|
|
|
$body = substr($isbnn, 3, -1); |
292
|
|
|
} else { |
293
|
|
|
return false; |
294
|
|
|
} |
295
|
|
|
/* verify */ |
296
|
|
|
$r = settype($body, 'string'); |
297
|
|
|
if ($r === false) { |
298
|
|
|
return false; |
299
|
|
|
} |
300
|
|
|
if (strlen($body) != 9) { |
301
|
|
|
return false; |
302
|
|
|
} |
303
|
|
|
if (ctype_digit($body) === false) { |
304
|
|
|
return false; |
305
|
|
|
} |
306
|
|
|
return $body; |
307
|
|
|
} |
308
|
|
|
// }}} |
309
|
|
|
|
310
|
|
|
// {{{ _isbnBodyParts() |
311
|
|
|
/** |
312
|
|
|
* Get the 2 Parts of the ISBN-Body (ISBN-10/ISBN-13-978) |
313
|
|
|
* |
314
|
|
|
* @param string $isbnbody ISBN-Body |
315
|
|
|
* @param string &$registrationgroup Registration Group |
316
|
|
|
* @param string &$isbnsubbody ISBN-Subbody |
317
|
|
|
* |
318
|
|
|
* @return boolean False if failed, True on success |
319
|
|
|
* |
320
|
|
|
* @access private |
321
|
|
|
*/ |
322
|
|
|
function _isbnBodyParts($isbnbody, |
323
|
|
|
&$registrationgroup, |
324
|
|
|
&$isbnsubbody) |
325
|
|
|
{ |
326
|
|
|
/* validate input (should not be needed, @access private) */ |
327
|
|
|
$r = settype($isbnbody, 'string'); |
328
|
|
|
if ($r === false) { |
329
|
|
|
return false; |
330
|
|
|
} |
331
|
|
|
if (strlen($isbnbody) != 9) { |
332
|
|
|
return false; |
333
|
|
|
} |
334
|
|
|
if (ctype_digit($isbnbody) === false) { |
335
|
|
|
return false; |
336
|
|
|
} |
337
|
|
|
/* extract registraion group |
338
|
|
|
* boundaries see p.13 2005 handbook |
339
|
|
|
*/ |
340
|
|
|
$boundaries = array(); |
341
|
|
|
|
342
|
|
|
$boundaries[] = array( 0, 59999, 1); |
343
|
|
|
$boundaries[] = array(60000, 60099, 3); // Iran 2006-12-05 |
344
|
|
|
$boundaries[] = array(60100, 69999, 0); |
345
|
|
|
$boundaries[] = array(70000, 79999, 1); |
346
|
|
|
$boundaries[] = array(80000, 94999, 2); |
347
|
|
|
$boundaries[] = array(95000, 98999, 3); |
348
|
|
|
$boundaries[] = array(99000, 99899, 4); |
349
|
|
|
$boundaries[] = array(99900, 99999, 5); |
350
|
|
|
/* segment value */ |
351
|
|
|
$segment = substr($isbnbody, 0, 5); |
352
|
|
|
$segmentvalue = intval($segment); |
353
|
|
|
/* test segment value against boundaries */ |
354
|
|
|
$r = false; |
355
|
|
|
foreach ($boundaries as $boundary) { |
356
|
|
|
if ($segmentvalue >= $boundary[0] && $segmentvalue <= $boundary[1]) { |
357
|
|
|
$r = $boundary[2]; |
358
|
|
|
} |
359
|
|
|
} |
360
|
|
|
if ($r === false) { |
361
|
|
|
return false; |
362
|
|
|
} |
363
|
|
|
/* $r is 0 when the boundary is not defined */ |
364
|
|
|
if ($r === 0) { |
365
|
|
|
return false; |
366
|
|
|
} |
367
|
|
|
$registrationgroup = substr($isbnbody, 0, $r); |
368
|
|
|
$isbnsubbody = substr($isbnbody, $r); |
369
|
|
|
return true; |
370
|
|
|
} |
371
|
|
|
// }}} |
372
|
|
|
|
373
|
|
|
// {{{ _isbnSubbodyParts() |
374
|
|
|
/** |
375
|
|
|
* Get the 2 Parts of the ISBN-Subbody (ISBN-10/ISBN-13) |
376
|
|
|
* |
377
|
|
|
* @param string $isbnsubbody ISBN-Subbody |
378
|
|
|
* @param integer $groupid Registrationgroup |
379
|
|
|
* @param string &$registrant Registrant |
380
|
|
|
* @param string &$publication Publication |
381
|
|
|
* |
382
|
|
|
* @return boolean False if failed, true on success |
383
|
|
|
* |
384
|
|
|
* @access private |
385
|
|
|
*/ |
386
|
|
|
function _isbnSubbodyParts($isbnsubbody, |
387
|
|
|
$groupid, |
388
|
|
|
&$registrant, |
389
|
|
|
&$publication) |
390
|
|
|
{ |
391
|
|
|
/* validate input (should not be needed, @access private) */ |
392
|
|
|
$r = settype($isbnsubbody, 'string'); |
393
|
|
|
if ($r === false) { |
394
|
|
|
return false; |
395
|
|
|
} |
396
|
|
|
$l = strlen($isbnsubbody); |
397
|
|
|
if ( $l < 1 || $l > 8) { |
398
|
|
|
return false; |
399
|
|
|
} |
400
|
|
|
if (ctype_digit($isbnsubbody) === false) { |
401
|
|
|
return false; |
402
|
|
|
} |
403
|
|
|
$r = settype($groupid, 'integer'); |
404
|
|
|
if ($r === false) { |
405
|
|
|
return false; |
406
|
|
|
} |
407
|
|
|
if ($groupid < 0 || $groupid > 99999) { |
408
|
|
|
return false; |
409
|
|
|
} |
410
|
|
|
/* extract registrant based on group and registrant range |
411
|
|
|
* parse this specific group format: |
412
|
|
|
* array( |
413
|
|
|
* 'English speaking area', |
414
|
|
|
* '00-09;10-19;200-699;7000-8499;85000-89999;' . |
415
|
|
|
* '900000-949999;9500000-9999999' |
416
|
|
|
* ); |
417
|
|
|
*/ |
418
|
|
|
|
419
|
|
|
$group = ISBN::_getISBN10Group($groupid); |
420
|
|
|
if ($group === false) { |
421
|
|
|
return false; |
422
|
|
|
} |
423
|
|
|
|
424
|
|
|
$len = ISBN::_getRegistrantLength($isbnsubbody, $group[1]); |
425
|
|
|
if ($len === false) { |
426
|
|
|
return false; |
427
|
|
|
} |
428
|
|
|
$registrant = substr($isbnsubbody, 0, $len); |
429
|
|
|
$publication = substr($isbnsubbody, $len); |
430
|
|
|
return true; |
431
|
|
|
} |
432
|
|
|
// }}} |
433
|
|
|
|
434
|
|
|
// {{{ _getRegistrantLength() |
435
|
|
|
/** |
436
|
|
|
* Return Length of Registrant part within an ISBNSubbody in a specific |
437
|
|
|
* grouprange in this specific format: |
438
|
|
|
* |
439
|
|
|
* '00-09;10-19;200-699;7000-8499;85000-89999;900000-949999;9500000-9999999' |
440
|
|
|
* |
441
|
|
|
* Info: This function is compatible with Groupranges formatted in the |
442
|
|
|
* .js file and might become obsolete if new formats are more fitting. |
443
|
|
|
* |
444
|
|
|
* @param string $isbnsubbody ISBN-Subbody |
445
|
|
|
* @param string $grouprange Grouprange in the Format '#a1-#z1;#a2-z2[...]' |
446
|
|
|
* |
447
|
|
|
* @return boolean|int False if failed or Length (in chars) of Registrant |
448
|
|
|
* |
449
|
|
|
* @access private |
450
|
|
|
*/ |
451
|
|
|
function _getRegistrantLength($isbnsubbody, $grouprange) |
452
|
|
|
{ |
453
|
|
|
$r = settype($grouprange, 'string'); |
454
|
|
|
if ($r === false) { |
455
|
|
|
return false; |
456
|
|
|
} |
457
|
|
|
if (strlen($grouprange) < 3) { |
458
|
|
|
return false; |
459
|
|
|
} |
460
|
|
|
|
461
|
|
|
$sl = strlen($isbnsubbody); |
462
|
|
|
$ranges = explode(';', $grouprange); |
463
|
|
|
foreach ($ranges as $range) { |
464
|
|
|
$range = trim($range); |
465
|
|
|
$fromto = explode('-', $range); |
466
|
|
|
if (count($fromto) !== 2) { |
467
|
|
|
return false; |
468
|
|
|
} |
469
|
|
|
/* validation: |
470
|
|
|
* from and to need to be in the same class, |
471
|
|
|
* having the same length. |
472
|
|
|
* registrant can not be bigger or same then the |
473
|
|
|
* whole subbody, at least there is one digit for |
474
|
|
|
* the publication. |
475
|
|
|
*/ |
476
|
|
|
|
477
|
|
|
$l = strlen($fromto[0]); |
478
|
|
|
if ($l != strlen($fromto[1])) { |
479
|
|
|
return false; |
480
|
|
|
} |
481
|
|
|
if ($l >= $sl) { |
482
|
|
|
return false; |
483
|
|
|
} |
484
|
|
|
|
485
|
|
|
/* check that from/to values are in order */ |
486
|
|
|
if (strcmp($fromto[0], $fromto[1]) >= 0) { |
487
|
|
|
return false; |
488
|
|
|
} |
489
|
|
|
|
490
|
|
|
/* compare and fire if matched */ |
491
|
|
|
$comparec = substr($isbnsubbody, 0, $l); |
492
|
|
|
|
493
|
|
|
if (strcmp($fromto[0], $comparec) < 1 && |
494
|
|
|
strcmp($fromto[1], $comparec) > -1) { |
495
|
|
|
return $l; |
496
|
|
|
} |
497
|
|
|
} |
498
|
|
|
return false; |
499
|
|
|
} |
500
|
|
|
// }}} |
501
|
|
|
|
502
|
|
|
// {{{ _getISBN10Group() |
503
|
|
|
/** |
504
|
|
|
* Get ISBN-10 Registration Group Data by its numeric ID |
505
|
|
|
* |
506
|
|
|
* @param integer $id Registration Group Identifier |
507
|
|
|
* |
508
|
|
|
* @return mixed array: group array |
509
|
|
|
* boolean: False if failed |
510
|
|
|
*/ |
511
|
|
|
function _getISBN10Group($id) |
512
|
|
|
{ |
513
|
|
|
$r = settype($id, 'integer'); |
514
|
|
|
if ($r === false) { |
515
|
|
|
return false; |
516
|
|
|
} |
517
|
|
|
$groups = ISBN::_getISBN10Groups(); |
518
|
|
|
if ($groups === false) { |
519
|
|
|
return false; |
520
|
|
|
} |
521
|
|
|
if (isset($groups[$id]) === false) { |
522
|
|
|
return false; |
523
|
|
|
} |
524
|
|
|
$group = $groups[$id]; |
525
|
|
|
return $group; |
526
|
|
|
} |
527
|
|
|
// }}} |
528
|
|
|
|
529
|
|
|
// {{{ _getISBN10Groups() |
530
|
|
|
/** |
531
|
|
|
* Get all ISBN-10 Registration Groups |
532
|
|
|
* |
533
|
|
|
* @return array groups array |
534
|
|
|
* |
535
|
|
|
* Info: This function connects outer world data into this class logic |
536
|
|
|
* which can be generated with the supplied tools. |
537
|
|
|
* A user should not alter the array data. This data should be altered |
538
|
|
|
* together with the international ISBN Agency only. |
539
|
|
|
*/ |
540
|
|
|
function _getISBN10Groups() |
541
|
|
|
{ |
542
|
|
|
/* check if data has been already loaded */ |
543
|
|
|
if (sizeof($this->varISBN10Groups) > 0 ) { |
544
|
|
|
return $this->varISBN10Groups; |
545
|
|
|
} |
546
|
|
|
|
547
|
|
|
/* load external data */ |
548
|
|
|
$t = file_get_contents($this->groups_csv); |
549
|
|
|
/* parse external data */ |
550
|
|
|
$groups = array(); |
551
|
|
|
$tls = explode("\n", $t); |
552
|
|
|
$line = 0; |
553
|
|
|
foreach ($tls as $tl) { |
554
|
|
|
$line++; |
555
|
|
|
$tlp = explode(',', $tl); |
556
|
|
|
if (sizeof($tlp) == 3) { |
557
|
|
|
$index = intval($tlp[0]); |
558
|
|
|
if (isset($groups[$index])) { |
559
|
|
|
return 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[$index] = array($tlp[1],$tlp[2]); |
567
|
|
|
} else { |
568
|
|
|
return 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) == 0 ) { |
577
|
|
|
return new ISBN_Exception( |
578
|
|
|
'ISBN Groups Data does not contain any valid data.' |
579
|
|
|
); |
580
|
|
|
} |
581
|
|
|
|
582
|
|
|
$this->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
|
|
|
function _getVersion($isbn) |
601
|
|
|
{ |
602
|
|
|
$ver = ISBN::_isbnVersionGuess($isbn); |
603
|
|
|
$r = ISBN::_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|false Checkdigit [0-9,X] or false if failed |
616
|
|
|
* |
617
|
|
|
* @access private |
618
|
|
|
*/ |
619
|
|
|
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
|
|
View Code Duplication |
for ($i = 0; $i < 10; $i++) { |
635
|
|
|
$v = intval(substr($isbnbody, $i, 1)); |
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|false Checkdigit [0-9] or false if failed |
659
|
|
|
* |
660
|
|
|
* @access private |
661
|
|
|
*/ |
662
|
|
|
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
|
|
View Code Duplication |
for ($i = 0; $i < 13; $i++) { |
677
|
|
|
$ii = 1 - $ii; |
678
|
|
|
$sum += intval(substr($t, $i, 1)) * ($ii * 2 + 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
|
|
|
function _isIsbnValid($isbn, $ver = ISBN_DEFAULT_INPUTVERSION) |
719
|
|
|
{ |
720
|
|
|
/* version handling */ |
721
|
|
|
$r = ISBN::_isbnVersionIs($ver); |
722
|
|
|
if ($r === false) { |
723
|
|
|
return false; |
724
|
|
|
} |
725
|
|
|
if ($ver === ISBN_VERSION_UNKNOWN) { |
|
|
|
|
726
|
|
|
$ver = ISBN::_isbnVersionGuess($isbn); |
727
|
|
|
} |
728
|
|
|
if (ISBN::_isbnVersionIsValid($ver) === false) { |
729
|
|
|
return false; |
730
|
|
|
} |
731
|
|
|
/* since a version is available now, normalise the ISBN input */ |
732
|
|
|
$isbnn = ISBN::_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 = ISBN::_extractISBNBody($isbnn); |
743
|
|
|
$check = ISBN::_extractCheckdigit($isbnn); |
744
|
|
|
if ($check === false) { |
745
|
|
|
return false; |
746
|
|
|
} |
747
|
|
|
$checkdigit = ISBN::_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 = ISBN::_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 = ISBN::_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 = ISBN::_extractEANPrefix($isbnn); |
786
|
|
|
if ($ean !== '978') { |
787
|
|
|
return false; |
788
|
|
|
} |
789
|
|
|
|
790
|
|
|
/* check syntax against checkdigit */ |
791
|
|
|
$isbnbody = ISBN::_extractISBNBody($isbnn); |
792
|
|
|
$check = ISBN::_extractCheckdigit($isbnn); |
793
|
|
|
if ($check === false) { |
794
|
|
|
return false; |
795
|
|
|
} |
796
|
|
|
$checkdigit = ISBN::_checkdigitISBN13($isbnbody); |
|
|
|
|
797
|
|
|
if ($checkdigit === false) { |
798
|
|
|
return false; |
799
|
|
|
} |
800
|
|
|
if ($check !== $checkdigit) { |
801
|
|
|
return false; |
802
|
|
|
} |
803
|
|
|
|
804
|
|
|
/* validate group */ |
805
|
|
|
$isbnbody = ISBN::_extractISBNBody($isbnn); |
806
|
|
|
if ($isbnbody === false) { |
807
|
|
|
return false; |
808
|
|
|
} |
809
|
|
|
|
810
|
|
|
$registrationgroup = false; |
811
|
|
|
$subbody = false; |
812
|
|
|
|
813
|
|
|
$r = ISBN::_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 = ISBN::_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|false Version Value or false (ISBN_VERSION_NONE) if failed |
850
|
|
|
* @access private |
851
|
|
|
*/ |
852
|
|
|
function _isbnVersionGuess($isbn) |
853
|
|
|
{ |
854
|
|
|
$isbn = ISBN::_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
|
|
|
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
|
|
|
function _isbnVersionIsValid($ver) |
908
|
|
|
{ |
909
|
|
|
$r = ISBN::_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|false normalised ISBN Number or false if the function was |
936
|
|
|
* not able to normalise the input |
937
|
|
|
* |
938
|
|
|
* @access private |
939
|
|
|
*/ |
940
|
|
|
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 = ISBN::_normaliseISBNremoveLangSpecific($isbn); |
954
|
|
|
|
955
|
|
|
/* remove ISBN-10: or ISBN-13: prefix (if any) */ |
956
|
|
|
if (strlen($isbn > 8)) { |
957
|
|
|
$prefix = substr($isbn, 0, 8); |
958
|
|
|
if ($prefix == 'ISBN-10:' || $prefix == 'ISBN-13:') { |
959
|
|
|
$isbn = substr($isbn, 8); |
960
|
|
|
$isbn = ltrim($isbn); |
961
|
|
|
} |
962
|
|
|
} |
963
|
|
|
|
964
|
|
|
/* remove lang specific prefix again (if any) */ |
965
|
|
|
$isbn = ISBN::_normaliseISBNremoveLangSpecific($isbn); |
966
|
|
|
|
967
|
|
|
/* remove "ISBN" prefix (if any)*/ |
968
|
|
|
if (substr($isbn, 0, 4) == 'ISBN') { |
969
|
|
|
$isbn = substr($isbn, 4); |
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
|
|
|
function _normaliseISBNremoveLangSpecific($isbn) |
1005
|
|
|
{ |
1006
|
|
|
$lang = strtoupper(ISBN_DEFAULT_PRINT_LANG_SPECIFIC_PREFIX); |
1007
|
|
|
$l = strlen($lang); |
1008
|
|
|
if ($l > 0 ) { |
1009
|
|
|
if (substr($isbn, 0, $l) == $lang) { |
1010
|
|
|
$isbn = substr($isbn, $l); |
1011
|
|
|
} |
1012
|
|
|
} |
1013
|
|
|
return $isbn; |
1014
|
|
|
} |
1015
|
|
|
// }}} |
1016
|
|
|
|
1017
|
|
|
// {{{ convert() |
1018
|
|
|
/** |
1019
|
|
|
* converts an ISBN number from one version to another |
1020
|
|
|
* can convert ISBN-10 to ISBN-13 and ISBN-13 to ISBN-10 |
1021
|
|
|
* |
1022
|
|
|
* @param string $isbnin ISBN to convert, must be a valid ISBN Number |
1023
|
|
|
* @param integer $verfrom version value of the input ISBN |
1024
|
|
|
* @param integer $verto version value to convert to |
1025
|
|
|
* |
1026
|
|
|
* @return string|false converted ISBN Number or false if conversion failed |
1027
|
|
|
*/ |
1028
|
|
|
function convert($isbnin, $verfrom = ISBN_VERSION_ISBN_10, |
1029
|
|
|
$verto = ISBN_VERSION_ISBN_13) |
1030
|
|
|
{ |
1031
|
|
|
/* validate input */ |
1032
|
|
|
if (!ISBN::_isbnVersionIsValid($verfrom)) { |
1033
|
|
|
return false; |
1034
|
|
|
} |
1035
|
|
|
if (!ISBN::_isbnVersionIsValid($verto)) { |
1036
|
|
|
return false; |
1037
|
|
|
} |
1038
|
|
|
$r = ISBN::validate($isbnin, $verfrom); |
1039
|
|
|
if ($r === false) { |
1040
|
|
|
return false; |
1041
|
|
|
} |
1042
|
|
|
/* normalize input */ |
1043
|
|
|
$isbnn = ISBN::_normaliseISBN($isbnin); |
1044
|
|
|
/* input is ok now, let's convert */ |
1045
|
|
|
switch(true) { |
1046
|
|
View Code Duplication |
case $verfrom == ISBN_VERSION_ISBN_10 && $verto == ISBN_VERSION_ISBN_13: |
1047
|
|
|
/* convert 10 to 13 */ |
1048
|
|
|
$isbnbody = ISBN::_extractISBNBody($isbnn); |
|
|
|
|
1049
|
|
|
if ($isbnbody === false) { |
1050
|
|
|
return false; |
1051
|
|
|
} |
1052
|
|
|
$isbnout = '978' . $isbnbody . ISBN::_checkdigitISBN13($isbnbody); |
1053
|
|
|
return $isbnout; |
1054
|
|
View Code Duplication |
case $verfrom == ISBN_VERSION_ISBN_13 && $verto == ISBN_VERSION_ISBN_10: |
1055
|
|
|
/* convert 13 to 10 */ |
1056
|
|
|
$isbnbody = ISBN::_extractISBNBody($isbnn); |
|
|
|
|
1057
|
|
|
if ($isbnbody === false) { |
1058
|
|
|
return false; |
1059
|
|
|
} |
1060
|
|
|
$isbnout = $isbnbody . ISBN::_checkdigitISBN10($isbnbody); |
1061
|
|
|
return $isbnout; |
1062
|
|
|
case $verfrom == $verto: |
1063
|
|
|
/* version is the same so there is no need to convert */ |
1064
|
|
|
/* hej, praktisch! */ |
1065
|
|
|
return $isbnn; |
1066
|
|
|
} |
1067
|
|
|
return false; |
1068
|
|
|
} |
1069
|
|
|
// }}} |
1070
|
|
|
|
1071
|
|
|
// {{{ getCheckdigit() |
1072
|
|
|
/** |
1073
|
|
|
* Get the Checkdigit Part of ISBN Number |
1074
|
|
|
* |
1075
|
|
|
* @return string|false Checkdigit or false if failed |
1076
|
|
|
*/ |
1077
|
|
|
function getCheckdigit() |
1078
|
|
|
{ |
1079
|
|
|
$ver = $this->getVersion(); |
1080
|
|
|
$check = false; |
1081
|
|
|
|
1082
|
|
|
switch ($ver) { |
1083
|
|
|
case ISBN_VERSION_ISBN_10: |
1084
|
|
|
$check = ISBN::_checkdigitISBN10($this->_getISBNBody()); |
1085
|
|
|
break; |
1086
|
|
|
|
1087
|
|
|
case ISBN_VERSION_ISBN_13: |
1088
|
|
|
$check = ISBN::_checkdigitISBN13($this->_getISBNBody()); |
1089
|
|
|
break; |
1090
|
|
|
|
1091
|
|
|
} |
1092
|
|
|
|
1093
|
|
|
return $check; |
1094
|
|
|
} |
1095
|
|
|
// }}} |
1096
|
|
|
|
1097
|
|
|
// {{{ getEAN() |
1098
|
|
|
/** |
1099
|
|
|
* Get the EAN Prefix of ISBN Number (ISBN-13) |
1100
|
|
|
* |
1101
|
|
|
* @return string|false EAN Prefix or false if failed |
1102
|
|
|
*/ |
1103
|
|
|
function getEAN() |
1104
|
|
|
{ |
1105
|
|
|
$ver = $this->getVersion(); |
1106
|
|
|
if ($ver === false ) { |
1107
|
|
|
return false; |
1108
|
|
|
} |
1109
|
|
|
if ($ver == ISBN_VERSION_ISBN_13_978) { |
1110
|
|
|
return '978'; |
1111
|
|
|
} |
1112
|
|
|
if ($ver == ISBN_VERSION_ISBN_13_979) { |
1113
|
|
|
return '979'; |
1114
|
|
|
} |
1115
|
|
|
return ''; |
1116
|
|
|
} |
1117
|
|
|
// }}} |
1118
|
|
|
|
1119
|
|
|
// {{{ getGroup() |
1120
|
|
|
/** |
1121
|
|
|
* Get the Registrationgroup Part of the ISBN Number |
1122
|
|
|
* |
1123
|
|
|
* @return string|false Group Identifier or false if failed |
1124
|
|
|
*/ |
1125
|
|
|
function getGroup() |
1126
|
|
|
{ |
1127
|
|
|
return $this->isbn_group; |
1128
|
|
|
} |
1129
|
|
|
// }}} |
1130
|
|
|
|
1131
|
|
|
// {{{ _setGroup() |
1132
|
|
|
/** |
1133
|
|
|
* Setter for the Registrationgroup Part of the ISBN Number |
1134
|
|
|
* |
1135
|
|
|
* @param string $group Registrationsgroup to set |
1136
|
|
|
* |
1137
|
|
|
* @return void |
1138
|
|
|
* |
1139
|
|
|
* @throws ISBN_Exception in case it fails |
1140
|
|
|
*/ |
1141
|
|
|
function _setGroup($group) |
1142
|
|
|
{ |
1143
|
|
|
if (is_string($group) == false) { |
|
|
|
|
1144
|
|
|
return new ISBN_Exception('Wrong Vartype'); |
1145
|
|
|
} |
1146
|
|
|
$l = strlen($group); |
1147
|
|
|
if ($l < 1 || $l > 5) { |
1148
|
|
|
return new ISBN_Exception('Wrong Group Length (' . $l . ')'); |
1149
|
|
|
} |
1150
|
|
|
$testbody = substr($group . '000000000', 0, 9); |
1151
|
|
|
$testgroup = ISBN::_extractGroup($testbody); |
1152
|
|
|
if ($testgroup === false ) { |
1153
|
|
|
return new ISBN_Exception('Invalid Group'); |
1154
|
|
|
} |
1155
|
|
|
if ($testgroup != $group) { |
1156
|
|
|
return new ISBN_Exception('Invalid Group'); |
1157
|
|
|
} |
1158
|
|
|
$this->isbn_group = $group; |
1159
|
|
|
} |
1160
|
|
|
|
1161
|
|
|
// {{{ getISBN() |
1162
|
|
|
/** |
1163
|
|
|
* Get whole ISBN Number |
1164
|
|
|
* |
1165
|
|
|
* @return string ISBN Number (unformatted); empty string if this is |
1166
|
|
|
* not a valid ISBN |
1167
|
|
|
*/ |
1168
|
|
|
function getISBN() |
1169
|
|
|
{ |
1170
|
|
|
$ver = $this->getVersion(); |
1171
|
|
|
if ($ver === false ) { |
1172
|
|
|
return ''; |
1173
|
|
|
} |
1174
|
|
|
|
1175
|
|
|
$isbn = ''; |
1176
|
|
|
|
1177
|
|
|
$r = ISBN::_isbnVersionIsValid($ver); |
1178
|
|
|
if ($r === false ) { |
1179
|
|
|
return $isbn; |
1180
|
|
|
} |
1181
|
|
|
|
1182
|
|
|
$isbn .= $this->getEAN(); |
1183
|
|
|
$isbn .= $this->_getISBNBody(); |
1184
|
|
|
$isbn .= $this->getCheckdigit(); |
1185
|
|
|
|
1186
|
|
|
return $isbn; |
1187
|
|
|
} |
1188
|
|
|
// }}} |
1189
|
|
|
|
1190
|
|
|
// {{{ getISBNDisplayable() |
1191
|
|
|
/** |
1192
|
|
|
* Get whole ISBN Number in a displayable fashion (see Handbook p. 15) |
1193
|
|
|
* |
1194
|
|
|
* @param string $format Formatstring 1-4 Chars: |
1195
|
|
|
* each character is a control char: |
1196
|
|
|
* #1 i or not: use international pre-prefix |
1197
|
|
|
* #2 i or not: "ISBN" in front or v: incl. version |
1198
|
|
|
* #3 : or not: insert a ":" |
1199
|
|
|
* #4 - or not: use - after EAN (ISBN 13 only) |
1200
|
|
|
* #4 or =: use - between each ISBN part |
1201
|
|
|
* Example 1: |
1202
|
|
|
* ' --' 978-0-385-33941-4 |
1203
|
|
|
* classic displayable ISBN |
1204
|
|
|
* Example 2: |
1205
|
|
|
* ' v:-' ISBN-13: 978-0385339414 |
1206
|
|
|
* ISBN-Format used by amazon |
1207
|
|
|
* Example 3: |
1208
|
|
|
* 'iv:=' ISBN-13: 978-0-385-33941-4 |
1209
|
|
|
* full blown: more is more! |
1210
|
|
|
* |
1211
|
|
|
* @return string ISBN Number (formatted); empty string if this is |
1212
|
|
|
* not a valid ISBN |
1213
|
|
|
*/ |
1214
|
|
|
function getISBNDisplayable($format = '') |
1215
|
|
|
{ |
1216
|
|
|
if ( strlen($format)==0 ) { |
1217
|
|
|
$format = 'iv:='; //edit $this->ISBNFormatstring; |
1218
|
|
|
} |
1219
|
|
|
$format = substr($format . ' ', 0, 4); |
1220
|
|
|
|
1221
|
|
|
$ver = $this->getVersion(); |
1222
|
|
|
if ($ver === false ) { |
1223
|
|
|
return ''; |
1224
|
|
|
} |
1225
|
|
|
|
1226
|
|
|
$isbn = ''; |
1227
|
|
|
|
1228
|
|
|
$r = ISBN::_isbnVersionIsValid($ver); |
1229
|
|
|
if ($r === false ) { |
1230
|
|
|
return $isbn; |
1231
|
|
|
} |
1232
|
|
|
|
1233
|
|
|
if ($format[0] == 'i') { |
1234
|
|
|
$isbn .= ISBN_DEFAULT_PRINT_LANG_SPECIFIC_PREFIX; |
1235
|
|
|
if (strlen($isbn)) $isbn .= ' '; |
1236
|
|
|
} |
1237
|
|
|
|
1238
|
|
|
if ($format[1] == 'i' || $format[1] == 'v') { |
1239
|
|
|
$isbn .= 'ISBN'; |
1240
|
|
|
if ($format[1] == 'v') { |
1241
|
|
|
switch ($ver) { |
1242
|
|
|
case ISBN_VERSION_ISBN_10: |
1243
|
|
|
$isbn .= '-10'; |
1244
|
|
|
break; |
1245
|
|
|
case ISBN_VERSION_ISBN_13: |
1246
|
|
|
$isbn .= '-13'; |
1247
|
|
|
break; |
1248
|
|
|
} |
1249
|
|
|
} |
1250
|
|
|
} |
1251
|
|
|
|
1252
|
|
|
if ($format[2] == ':') { |
1253
|
|
|
$isbn .= ':'; |
1254
|
|
|
} |
1255
|
|
|
|
1256
|
|
|
if (strlen($isbn)) { |
1257
|
|
|
$isbn .= ' '; |
1258
|
|
|
} |
1259
|
|
|
|
1260
|
|
|
if ($ver == ISBN_VERSION_ISBN_13_978 || $ver == ISBN_VERSION_ISBN_13_979) { |
1261
|
|
|
$isbn .= $this->getEAN(); |
1262
|
|
|
if ($format[3] == '-' || $format[3] == '=') { |
1263
|
|
|
$isbn .= ISBN_DEFAULT_COSMETIC_SEPERATOR; |
1264
|
|
|
} |
1265
|
|
|
} |
1266
|
|
|
|
1267
|
|
|
$seperator = ($format[3] == '=') ? ISBN_DEFAULT_COSMETIC_SEPERATOR : ''; |
1268
|
|
|
|
1269
|
|
|
$isbn .= $this->getGroup() . $seperator; |
1270
|
|
|
$isbn .= $this->getPublisher() . $seperator; |
1271
|
|
|
$isbn .= $this->getTitle() . $seperator; |
1272
|
|
|
$isbn .= $this->getCheckdigit(); |
1273
|
|
|
|
1274
|
|
|
return $isbn; |
1275
|
|
|
|
1276
|
|
|
} |
1277
|
|
|
// }}} |
1278
|
|
|
|
1279
|
|
|
// {{{ setISBN() |
1280
|
|
|
/** |
1281
|
|
|
* Setter for ISBN |
1282
|
|
|
* |
1283
|
|
|
* @param string $isbn ISBN Number |
1284
|
|
|
* this is a valid ISBN Number or it is an Empty string |
1285
|
|
|
* which will reset the class |
1286
|
|
|
* |
1287
|
|
|
* @return void |
1288
|
|
|
* |
1289
|
|
|
* @throws ISBN_Exception in case it fails |
1290
|
|
|
* |
1291
|
|
|
*/ |
1292
|
|
|
function setISBN($isbn) |
1293
|
|
|
{ |
1294
|
|
|
if ($isbn == '') { |
1295
|
|
|
$this->ver = ISBN_VERSION_NONE; |
1296
|
|
|
$this->isbn_group = ''; |
1297
|
|
|
$this->isbn_publisher = ''; |
1298
|
|
|
$this->isbn_title = ''; |
1299
|
|
|
} else { |
1300
|
|
|
$isbnn = ISBN::_normaliseISBN($isbn); |
1301
|
|
|
$ver = ISBN::_getVersion($isbnn); |
|
|
|
|
1302
|
|
|
if ($ver === false) { |
1303
|
|
|
return new ISBN_Exception('Invalid ISBN'); |
1304
|
|
|
} |
1305
|
|
|
if ($ver != $this->ver && $this->ver !== ISBN_VERSION_NONE) { |
1306
|
|
|
return new ISBN_Exception( |
1307
|
|
|
'ISBN Version of passed ISBN (' . $ver . ') '. |
1308
|
|
|
'does not match existing (' . $this->ver . ').' |
1309
|
|
|
); |
1310
|
|
|
} elseif ($this->ver === ISBN_VERSION_NONE) { |
1311
|
|
|
$this->ver = $ver; |
1312
|
|
|
} |
1313
|
|
|
$body = ISBN::_extractISBNBody($isbnn); |
|
|
|
|
1314
|
|
|
if ($body === false) { |
1315
|
|
|
return new ISBN_Exception('Invalid ISBN (could not extract body)'); |
1316
|
|
|
} |
1317
|
|
|
$e = $this->_setISBNBody($body); |
1318
|
|
|
if ("ISBN_Exception" == get_class($e)) { |
1319
|
|
|
return 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
|
|
|
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
|
|
|
function _setISBNBody($body) |
1355
|
|
|
{ |
1356
|
|
|
/* validate parameter */ |
1357
|
|
|
if (is_string($body) == false) { |
|
|
|
|
1358
|
|
|
return new ISBN_Exception('Not a Body: wrong variabletype'); |
1359
|
|
|
} |
1360
|
|
|
if (strlen($body) != 9) { |
1361
|
|
|
return new ISBN_Exception('Not a Body: wrong body length'); |
1362
|
|
|
} |
1363
|
|
|
if (ctype_digit($body) !== true) { |
1364
|
|
|
return 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 = ISBN::_isbnBodyParts($body, $group, $subbody); |
1372
|
|
|
if ($r == false) { |
|
|
|
|
1373
|
|
|
return new ISBN_Exception('Invalid Body'); |
1374
|
|
|
} |
1375
|
|
|
|
1376
|
|
|
$e = $this->_setGroup($group); |
1377
|
|
|
if ("ISBN_Exception" == get_class($e)) { |
1378
|
|
|
return new ISBN_Exception('Invalid Body: Group is invalid', $e); |
1379
|
|
|
} |
1380
|
|
|
|
1381
|
|
|
$e = $this->_setISBNSubbody($subbody); |
1382
|
|
|
if ("ISBN_Exception" == get_class($e)) { |
1383
|
|
|
return new ISBN_Exception( |
1384
|
|
|
'Invalid Body: Subbody is invalid (' . $e->getMessage() . ')', $e |
1385
|
|
|
); |
1386
|
|
|
} |
1387
|
|
|
} |
1388
|
|
|
// }}} |
1389
|
|
|
|
1390
|
|
|
// {{{ _getISBNSubbody() |
1391
|
|
|
/** |
1392
|
|
|
* Get ISBNSubbody () |
1393
|
|
|
* |
1394
|
|
|
* @return ISBN Subbody |
1395
|
|
|
*/ |
1396
|
|
|
function _getISBNSubbody() |
1397
|
|
|
{ |
1398
|
|
|
$subbody = ''; |
1399
|
|
|
$subbody .= $this->getPublisher(); |
1400
|
|
|
$subbody .= $this->getTitle(); |
1401
|
|
|
return $subbody; |
1402
|
|
|
} |
1403
|
|
|
// }}} |
1404
|
|
|
|
1405
|
|
|
// {{{ _setISBNSubbody() |
1406
|
|
|
/** |
1407
|
|
|
* _setISBNSubbody |
1408
|
|
|
* |
1409
|
|
|
* Setter for the ISBN Subbody |
1410
|
|
|
* |
1411
|
|
|
* @param string $subbody ISBN Subbody |
1412
|
|
|
* |
1413
|
|
|
* @return void |
1414
|
|
|
* |
1415
|
|
|
* @throws ISBN_Exception in case it fails |
1416
|
|
|
*/ |
1417
|
|
|
function _setISBNSubbody($subbody) |
1418
|
|
|
{ |
1419
|
|
|
/* validate parameter */ |
1420
|
|
|
if (is_string($subbody) == false) { |
|
|
|
|
1421
|
|
|
return new ISBN_Exception('Wrong Vartype'); |
1422
|
|
|
} |
1423
|
|
|
$l = strlen($subbody); |
1424
|
|
|
if ( $l < 4 || $l > 8) { |
1425
|
|
|
return new ISBN_Exception('Not a Subbody by length'); |
1426
|
|
|
} |
1427
|
|
|
/* validate by setting apart */ |
1428
|
|
|
$registrant = false; |
1429
|
|
|
$publication = false; |
1430
|
|
|
$groupid = intval($this->isbn_group); |
1431
|
|
|
|
1432
|
|
|
$r = ISBN::_isbnSubbodyParts($subbody, $groupid, $registrant, $publication); |
1433
|
|
|
if ($r === false) { |
1434
|
|
|
return new ISBN_Exception('Can\'t break'); |
1435
|
|
|
} |
1436
|
|
|
/* edit+ setter/getter for Registrant/Publisher and Title/Publication */ |
1437
|
|
|
$this->isbn_publisher = $registrant; |
1438
|
|
|
$this->isbn_title = $publication; |
1439
|
|
|
} |
1440
|
|
|
|
1441
|
|
|
// {{{ getPublisher() |
1442
|
|
|
/** |
1443
|
|
|
* Get the Publication Part of the ISBN Number |
1444
|
|
|
* |
1445
|
|
|
* @return string|false Publisher or false if failed |
1446
|
|
|
*/ |
1447
|
|
|
function getPublisher() |
1448
|
|
|
{ |
1449
|
|
|
return $this->isbn_publisher; |
1450
|
|
|
} |
1451
|
|
|
// }}} |
1452
|
|
|
|
1453
|
|
|
// {{{ getTitle() |
1454
|
|
|
/** |
1455
|
|
|
* Get the Title Part of the ISBN Number |
1456
|
|
|
* |
1457
|
|
|
* @return string|false Title or false if failed |
1458
|
|
|
*/ |
1459
|
|
|
function getTitle() |
1460
|
|
|
{ |
1461
|
|
|
return $this->isbn_title; |
1462
|
|
|
} |
1463
|
|
|
// }}} |
1464
|
|
|
|
1465
|
|
|
|
1466
|
|
|
// {{{ isValid() |
1467
|
|
|
/** |
1468
|
|
|
* Returns this ISBN validity |
1469
|
|
|
* |
1470
|
|
|
* @return boolean |
1471
|
|
|
*/ |
1472
|
|
|
function isValid() |
1473
|
|
|
{ |
1474
|
|
|
$isbn = $this->getISBN(); |
|
|
|
|
1475
|
|
|
$r = ISBN::validate($this->getISBN(), $this->getVersion()); |
1476
|
|
|
return (bool) $r; |
1477
|
|
|
} |
1478
|
|
|
|
1479
|
|
|
// {{{ validate() |
1480
|
|
|
/** |
1481
|
|
|
* Validates an ISBN |
1482
|
|
|
* |
1483
|
|
|
* @param string $isbn ISBN to validate |
1484
|
|
|
* @param integer $ver ISBN-Version to validate against |
1485
|
|
|
* |
1486
|
|
|
* @return integer|false Version value of a valid ISBN or false |
1487
|
|
|
* if it did not validate |
1488
|
|
|
*/ |
1489
|
|
|
function validate($isbn, $ver = ISBN_DEFAULT_INPUTVERSION) |
1490
|
|
|
{ |
1491
|
|
|
$r = ISBN::_isbnVersionIs($ver); |
1492
|
|
|
if ($r === false) { |
1493
|
|
|
return false; |
1494
|
|
|
} |
1495
|
|
|
if ($ver === ISBN_VERSION_UNKNOWN) { |
1496
|
|
|
$ver = ISBN::_isbnVersionGuess($isbn); |
1497
|
|
|
} |
1498
|
|
|
if (ISBN::_isbnVersionIsValid($ver) === false) { |
1499
|
|
|
return false; |
1500
|
|
|
} |
1501
|
|
|
$r = ISBN::_isIsbnValid($isbn, $ver); |
1502
|
|
|
if ($r === false) { |
1503
|
|
|
return false; |
1504
|
|
|
} |
1505
|
|
|
return $ver; |
1506
|
|
|
} |
1507
|
|
|
// }}} |
1508
|
|
|
|
1509
|
|
|
// {{{ getVersion() |
1510
|
|
|
/** |
1511
|
|
|
* Returns version of this objects ISBN |
1512
|
|
|
* |
1513
|
|
|
* @return integer|false Version value or ISBN_VERSION_NONE |
1514
|
|
|
*/ |
1515
|
|
|
function getVersion() |
1516
|
|
|
{ |
1517
|
|
|
return $this->ver; |
1518
|
|
|
} |
1519
|
|
|
|
1520
|
|
|
|
1521
|
|
|
// {{{ guessVersion() |
1522
|
|
|
/** |
1523
|
|
|
* Guesses ISBN version of passed string |
1524
|
|
|
* |
1525
|
|
|
* Note: This is not Validation. To get the validated |
1526
|
|
|
* version of an ISBN Number use ISBN::validate(); |
1527
|
|
|
* |
1528
|
|
|
* @param string $isbn ISBN Number to guess Version of |
1529
|
|
|
* |
1530
|
|
|
* @return integer|false Version Value or false if failed |
1531
|
|
|
* |
1532
|
|
|
* @see validate(); |
1533
|
|
|
*/ |
1534
|
|
|
function guessVersion($isbn) |
1535
|
|
|
{ |
1536
|
|
|
$r = ISBN::_isbnVersionGuess($isbn); |
1537
|
|
|
return $r; |
1538
|
|
|
} |
1539
|
|
|
// }}} |
1540
|
|
|
|
1541
|
|
|
} |
1542
|
|
|
|
In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:
Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion: