1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 | <?php /** * Classe qui utilise l'API de Google Book pour aller chercher des informations sur un livre en particulier ou faire des recherches par mot clé. * * @author Olivier Arteau * * Les deux principales méthodes sont : * * getBooksByKeyword * - retourne un tableau de livre * * getBookByISBN * - retourne le livre ou null si le livre n'existe pas * * La structure d'un livres est la suivante : * * array( * 'auteur' => '', // Auteur(s) du livre * 'date' => 0, // Date de publication au format timestamp * 'identifier' => array( * 'ISBN' => '', // ISBN de 10 chiffres * 'ISBN2' => '', // ISBN de 13 chiffres * 'googleid' => '' // Id Google du livre * ), * 'titre' => '', // Titre du livre * 'editeur' => '', // Éditeur du livre * 'image' => '' // Lien vers une image miniature du livre * ); * * Note: Les index sont absent pour les données qui ne sont pas disponible */ class BookSearcher { private $xpp; public function __construct() { } /** * Recherche de livre(s) par mot(s) clé(s). Retourne la liste des livres trouvés * avec leur information. * * @param (string) keyword(s) **/ public function getBooksByKeyword($keyword) { $this->xpp = new XMLReader(); $books = array(); if ($this->xpp->open('http://books.google.com/books/feeds/volumes?q=' . urlencode($keyword))) { $this->moveToEntry(); $books = array(); while ($this->xpp->name == "entry") { $books[] = $this->parseBook(); } } return $books; } /** * Cherche un livre par son ISBN et retourne un tableau contenant * les informations relatives au livre * * @param (string) ISBN **/ public function getBookByISBN($isbn) { $this->xpp = new XMLReader(); if ($this->xpp->open('http://books.google.com/books/feeds/volumes?q=' . urlencode($isbn))) { $this->moveToEntry(); $found = false; while ($this->xpp->name == "entry") { $book = $this->parseBook(); // Si le livre est trouvé // if (isset($book['identifier']) && (strlen($isbn) == 10 && isset($book['identifier']['ISBN']) && $book['identifier']['ISBN'] == $isbn) || // ISBN (strlen($isbn) == 13 && isset($book['identifier']['ISBN2']) && $book['identifier']['ISBN2'] == $isbn)) // ISBN2 { $found = true; break; } } } return (!isset($book) || !$found) ? null : $book; } private function parseBook() { $book = array(); while ($this->xpp->read() && $this->xpp->name != "entry") { if ($this->xpp->name{0} == "#") continue; switch($this->xpp->name) { case 'dc:creator': if (!isset($book['auteur'])) $book['auteur'] = ''; else $book['auteur'] .= ', '; $book['auteur'] .= $this->parseAuthor(); break; case 'dc:date': $dt = explode('-', $this->parseDate()); $book['date'] = mktime(0,0,0, (isset($dt[2]) ? $dt[2] : 1), (isset($dt[1]) ? $dt[1] : 1), $dt[0]); break; case 'dc:identifier': if (!isset($book['identifier'])) { $book['identifier'] = array(); } $dt = $this->parseIdentifier(); $book['identifier'][$dt['type']] = $dt['data']; break; case 'dc:title': if (!isset($book['titre'])) $book['titre'] = ''; else $book['titre'] .= ', '; $book['titre'] .= $this->parseTitle(); break; case 'dc:publisher': $book['editeur'] = $this->parsePublisher(); break; case 'link' : $dt = $this->parseLink(); if ($dt['name'] == 'thumbnail') { $book['image'] = $dt['href']; } break; } } $this->xpp->read(); return $book; } private function parsePublisher() { $this->xpp->read(); $val = $this->xpp->value; $this->xpp->read(); return $val; } private function parseAuthor() { $this->xpp->read(); $val = $this->xpp->value; $this->xpp->read(); return $val; } private function parseDate() { $this->xpp->read(); $val = $this->xpp->value; $this->xpp->read(); return $val; } private function parseTitle() { $this->xpp->read(); $val = $this->xpp->value; $this->xpp->read(); return $val; } private function parseLink() { $dt = array(); $dt['type'] = $this->xpp->getAttribute('type'); $dt['name'] = substr($this->xpp->getAttribute('rel'), strrpos($this->xpp->getAttribute('rel'), '/') + 1); $dt['href'] = html_entity_decode($this->xpp->getAttribute('href')); return $dt; } private function parseIdentifier() { $this->xpp->read(); $val = $this->xpp->value; $this->xpp->read(); $dt = array(); if (substr($val,0,5) == 'ISBN:') { $dt['type'] = 'ISBN'; $dt['data'] = trim(substr($val,5)); if (strlen($dt['data']) == 13) $dt['type'] .= '2'; } else { $dt['type'] = 'googleid'; $dt['data'] = $val; } return $dt; } private function moveToEntry() { // Positionne au début des entrées // while($this->xpp->name != "entry") { if (!$this->xpp->read()) break; } } } ?> |
PD9waHAKLyoqCiogQ2xhc3NlIHF1aSB1dGlsaXNlIGwnQVBJIGRlIEdvb2dsZSBCb29rIHBvdXIgYWxsZXIgY2hlcmNoZXIgZGVzIGluZm9ybWF0aW9ucyBzdXIgdW4gbGl2cmUgZW4gcGFydGljdWxpZXIgb3UgZmFpcmUgZGVzIHJlY2hlcmNoZXMgcGFyIG1vdCBjbMOpLgoqICAKKiBAYXV0aG9yIE9saXZpZXIgQXJ0ZWF1CiogCiogTGVzIGRldXggcHJpbmNpcGFsZXMgbcOpdGhvZGVzIHNvbnQgOgoqIAoqIGdldEJvb2tzQnlLZXl3b3JkCiogCS0gcmV0b3VybmUgdW4gdGFibGVhdSBkZSBsaXZyZQoqIAkKKiBnZXRCb29rQnlJU0JOCiogCS0gcmV0b3VybmUgbGUgbGl2cmUgb3UgbnVsbCBzaSBsZSBsaXZyZSBuJ2V4aXN0ZSBwYXMKKiAKKiBMYSBzdHJ1Y3R1cmUgZCd1biBsaXZyZXMgZXN0IGxhIHN1aXZhbnRlIDoKKgoqIGFycmF5KAoqIAknYXV0ZXVyJyA9PiAnJywgLy8gQXV0ZXVyKHMpIGR1IGxpdnJlIAoqIAknZGF0ZScgPT4gMCwgLy8gRGF0ZSBkZSBwdWJsaWNhdGlvbiBhdSBmb3JtYXQgdGltZXN0YW1wCiogCSdpZGVudGlmaWVyJyA9PiBhcnJheSgKKiAJCSdJU0JOJyA9PiAnJywgLy8gSVNCTiBkZSAxMCBjaGlmZnJlcwoqIAkJJ0lTQk4yJyA9PiAnJywgLy8gSVNCTiBkZSAxMyBjaGlmZnJlcwoqIAkJJ2dvb2dsZWlkJyA9PiAnJyAvLyBJZCBHb29nbGUgZHUgbGl2cmUKKiAJKSwKKiAJJ3RpdHJlJyA9PiAnJywgLy8gVGl0cmUgZHUgbGl2cmUKKiAJJ2VkaXRldXInID0+ICcnLCAvLyDDiWRpdGV1ciBkdSBsaXZyZQoqIAknaW1hZ2UnID0+ICcnIC8vIExpZW4gdmVycyB1bmUgaW1hZ2UgbWluaWF0dXJlIGR1IGxpdnJlCiogKTsKKiAKKiBOb3RlOiBMZXMgaW5kZXggc29udCBhYnNlbnQgcG91ciBsZXMgZG9ubsOpZXMgcXVpIG5lIHNvbnQgcGFzIGRpc3BvbmlibGUKICovCmNsYXNzIEJvb2tTZWFyY2hlciB7Cglwcml2YXRlICR4cHA7CgkKCXB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgpIHsKCQkKCX0KCQoJLyoqCgkgKiBSZWNoZXJjaGUgZGUgbGl2cmUocykgcGFyIG1vdChzKSBjbMOpKHMpLiBSZXRvdXJuZSBsYSBsaXN0ZSBkZXMgbGl2cmVzIHRyb3V2w6lzIAoJICogYXZlYyBsZXVyIGluZm9ybWF0aW9uLgoJICogCgkgKiBAcGFyYW0gKHN0cmluZykga2V5d29yZChzKQoJICoqLwoJCgkKCXB1YmxpYyBmdW5jdGlvbiBnZXRCb29rc0J5S2V5d29yZCgka2V5d29yZCkgewoJCSR0aGlzLT54cHAgPSBuZXcgWE1MUmVhZGVyKCk7CgkJJGJvb2tzID0gYXJyYXkoKTsKCQkKCQlpZiAoJHRoaXMtPnhwcC0+b3BlbignaHR0cDovL2Jvb2tzLmdvb2dsZS5jb20vYm9va3MvZmVlZHMvdm9sdW1lcz9xPScgLiB1cmxlbmNvZGUoJGtleXdvcmQpKSkgewoJCQkkdGhpcy0+bW92ZVRvRW50cnkoKTsKCQkJJGJvb2tzID0gYXJyYXkoKTsKCQkJCgkJCXdoaWxlICgkdGhpcy0+eHBwLT5uYW1lID09ICJlbnRyeSIpIHsKCQkJCSRib29rc1tdID0gJHRoaXMtPnBhcnNlQm9vaygpOwoJCQl9CgkJfQoJCQoJCXJldHVybiAkYm9va3M7Cgl9CgkKCS8qKgoJICogQ2hlcmNoZSB1biBsaXZyZSBwYXIgc29uIElTQk4gZXQgcmV0b3VybmUgdW4gdGFibGVhdSBjb250ZW5hbnQgCgkgKiBsZXMgaW5mb3JtYXRpb25zIHJlbGF0aXZlcyBhdSBsaXZyZQoJICogCgkgKiBAcGFyYW0gKHN0cmluZykgSVNCTgoJICoqLwoJCglwdWJsaWMgZnVuY3Rpb24gZ2V0Qm9va0J5SVNCTigkaXNibikgewoJCSR0aGlzLT54cHAgPSBuZXcgWE1MUmVhZGVyKCk7CgkJCgkJaWYgKCR0aGlzLT54cHAtPm9wZW4oJ2h0dHA6Ly9ib29rcy5nb29nbGUuY29tL2Jvb2tzL2ZlZWRzL3ZvbHVtZXM/cT0nIC4gdXJsZW5jb2RlKCRpc2JuKSkpIHsKCQkJJHRoaXMtPm1vdmVUb0VudHJ5KCk7CgkJCQoJCQkkZm91bmQgPSBmYWxzZTsKCQkJd2hpbGUgKCR0aGlzLT54cHAtPm5hbWUgPT0gImVudHJ5IikgewoJCQkJJGJvb2sgPSAkdGhpcy0+cGFyc2VCb29rKCk7CgkJCQkKCQkJCS8vIFNpIGxlIGxpdnJlIGVzdCB0cm91dsOpIC8vCgkJCQlpZiAoaXNzZXQoJGJvb2tbJ2lkZW50aWZpZXInXSkgJiYKCQkJCQkoc3RybGVuKCRpc2JuKSA9PSAxMCAmJiBpc3NldCgkYm9va1snaWRlbnRpZmllciddWydJU0JOJ10pICYmICAkYm9va1snaWRlbnRpZmllciddWydJU0JOJ10gPT0gJGlzYm4pIHx8IC8vIElTQk4KCQkJCQkoc3RybGVuKCRpc2JuKSA9PSAxMyAmJiBpc3NldCgkYm9va1snaWRlbnRpZmllciddWydJU0JOMiddKSAmJiAgJGJvb2tbJ2lkZW50aWZpZXInXVsnSVNCTjInXSA9PSAkaXNibikpIC8vIElTQk4yCgkJCQl7CgkJCQkJJGZvdW5kID0gdHJ1ZTsKCQkJCQlicmVhazsKCQkJCX0KCQkJfQoJCX0KCQkKCQlyZXR1cm4gKCFpc3NldCgkYm9vaykgfHwgISRmb3VuZCkgPyBudWxsIDogJGJvb2s7Cgl9CgkKCXByaXZhdGUgZnVuY3Rpb24gcGFyc2VCb29rKCkgewoJCSRib29rID0gYXJyYXkoKTsKCQkJCgkJd2hpbGUgKCR0aGlzLT54cHAtPnJlYWQoKSAmJiAkdGhpcy0+eHBwLT5uYW1lICE9ICJlbnRyeSIpIHsKCQkJaWYgKCR0aGlzLT54cHAtPm5hbWV7MH0gPT0gIiMiKQoJCQkJY29udGludWU7CgkJCQkKCQkJc3dpdGNoKCR0aGlzLT54cHAtPm5hbWUpIHsKCQkJCWNhc2UgJ2RjOmNyZWF0b3InOgoJCQkJCWlmICghaXNzZXQoJGJvb2tbJ2F1dGV1ciddKSkKCQkJCQkJJGJvb2tbJ2F1dGV1ciddID0gJyc7CgkJCQkJZWxzZQoJCQkJCQkkYm9va1snYXV0ZXVyJ10gLj0gJywgJzsKCQkJCQkkYm9va1snYXV0ZXVyJ10gLj0gJHRoaXMtPnBhcnNlQXV0aG9yKCk7CgkJCQkJYnJlYWs7CgkJCQljYXNlICdkYzpkYXRlJzoKCQkJCQkkZHQgPSBleHBsb2RlKCctJywgJHRoaXMtPnBhcnNlRGF0ZSgpKTsKCQkJCQkKCQkJCQkkYm9va1snZGF0ZSddID0gbWt0aW1lKDAsMCwwLCAoaXNzZXQoJGR0WzJdKSA/ICRkdFsyXSA6IDEpLCAoaXNzZXQoJGR0WzFdKSA/ICRkdFsxXSA6IDEpLCAkZHRbMF0pOwoJCQkJCWJyZWFrOwoJCQkJY2FzZSAnZGM6aWRlbnRpZmllcic6CgkJCQkJaWYgKCFpc3NldCgkYm9va1snaWRlbnRpZmllciddKSkgewoJCQkJCQkkYm9va1snaWRlbnRpZmllciddID0gYXJyYXkoKTsKCQkJCQl9CgkJCQkJJGR0ID0gJHRoaXMtPnBhcnNlSWRlbnRpZmllcigpOwoJCQkJCSRib29rWydpZGVudGlmaWVyJ11bJGR0Wyd0eXBlJ11dID0gJGR0WydkYXRhJ107CgkJCQkJYnJlYWs7CgkJCQljYXNlICdkYzp0aXRsZSc6CgkJCQkJaWYgKCFpc3NldCgkYm9va1sndGl0cmUnXSkpCgkJCQkJCSRib29rWyd0aXRyZSddID0gJyc7CgkJCQkJZWxzZQoJCQkJCQkkYm9va1sndGl0cmUnXSAuPSAnLCAnOwoJCQkJCSRib29rWyd0aXRyZSddIC49ICR0aGlzLT5wYXJzZVRpdGxlKCk7CgkJCQkJYnJlYWs7CgkJCQljYXNlICdkYzpwdWJsaXNoZXInOgoJCQkJCSRib29rWydlZGl0ZXVyJ10gPSAkdGhpcy0+cGFyc2VQdWJsaXNoZXIoKTsKCQkJCQlicmVhazsKCQkJCWNhc2UgJ2xpbmsnIDoKCQkJCQkkZHQgPSAkdGhpcy0+cGFyc2VMaW5rKCk7CgkJCQkJCgkJCQkJaWYgKCRkdFsnbmFtZSddID09ICd0aHVtYm5haWwnKSB7CgkJCQkJCSRib29rWydpbWFnZSddID0gJGR0WydocmVmJ107CgkJCQkJfQoJCQkJCWJyZWFrOwoJCQl9CgkJfQoJCQoJCSR0aGlzLT54cHAtPnJlYWQoKTsKCQkKCQlyZXR1cm4gJGJvb2s7Cgl9CgkKCXByaXZhdGUgZnVuY3Rpb24gcGFyc2VQdWJsaXNoZXIoKSB7CgkJJHRoaXMtPnhwcC0+cmVhZCgpOwoJCSR2YWwgPSAkdGhpcy0+eHBwLT52YWx1ZTsKCQkkdGhpcy0+eHBwLT5yZWFkKCk7CgkJcmV0dXJuICR2YWw7Cgl9CgkKCXByaXZhdGUgZnVuY3Rpb24gcGFyc2VBdXRob3IoKSB7CgkJJHRoaXMtPnhwcC0+cmVhZCgpOwoJCSR2YWwgPSAkdGhpcy0+eHBwLT52YWx1ZTsKCQkkdGhpcy0+eHBwLT5yZWFkKCk7CgkJcmV0dXJuICR2YWw7Cgl9CgoJcHJpdmF0ZSBmdW5jdGlvbiBwYXJzZURhdGUoKSB7CgkJJHRoaXMtPnhwcC0+cmVhZCgpOwoJCSR2YWwgPSAkdGhpcy0+eHBwLT52YWx1ZTsKCQkkdGhpcy0+eHBwLT5yZWFkKCk7CgkJcmV0dXJuICR2YWw7Cgl9CgkKCXByaXZhdGUgZnVuY3Rpb24gcGFyc2VUaXRsZSgpIHsKCQkkdGhpcy0+eHBwLT5yZWFkKCk7CgkJJHZhbCA9ICR0aGlzLT54cHAtPnZhbHVlOwoJCSR0aGlzLT54cHAtPnJlYWQoKTsKCQlyZXR1cm4gJHZhbDsKCX0KCQoJcHJpdmF0ZSBmdW5jdGlvbiBwYXJzZUxpbmsoKSB7CgkJJGR0ID0gYXJyYXkoKTsKCQkkZHRbJ3R5cGUnXSA9ICR0aGlzLT54cHAtPmdldEF0dHJpYnV0ZSgndHlwZScpOwoJCSRkdFsnbmFtZSddID0gc3Vic3RyKCR0aGlzLT54cHAtPmdldEF0dHJpYnV0ZSgncmVsJyksIHN0cnJwb3MoJHRoaXMtPnhwcC0+Z2V0QXR0cmlidXRlKCdyZWwnKSwgJy8nKSArIDEpOwoJCSRkdFsnaHJlZiddID0gaHRtbF9lbnRpdHlfZGVjb2RlKCR0aGlzLT54cHAtPmdldEF0dHJpYnV0ZSgnaHJlZicpKTsKCQkKCQlyZXR1cm4gJGR0OwoJfQoJCglwcml2YXRlIGZ1bmN0aW9uIHBhcnNlSWRlbnRpZmllcigpIHsKCQkkdGhpcy0+eHBwLT5yZWFkKCk7CgkJJHZhbCA9ICR0aGlzLT54cHAtPnZhbHVlOwoJCSR0aGlzLT54cHAtPnJlYWQoKTsKCQkKCQkkZHQgPSBhcnJheSgpOwoJCWlmIChzdWJzdHIoJHZhbCwwLDUpID09ICdJU0JOOicpIHsKCQkJJGR0Wyd0eXBlJ10gPSAnSVNCTic7CgkJCSRkdFsnZGF0YSddID0gdHJpbShzdWJzdHIoJHZhbCw1KSk7CgkJCQoJCQlpZiAoc3RybGVuKCRkdFsnZGF0YSddKSA9PSAxMykKCQkJCSRkdFsndHlwZSddIC49ICcyJzsKCQl9IGVsc2UgewoJCQkkZHRbJ3R5cGUnXSA9ICdnb29nbGVpZCc7CgkJCSRkdFsnZGF0YSddID0gJHZhbDsKCQl9CgkJCgkJcmV0dXJuICRkdDsKCX0KCQoJcHJpdmF0ZSBmdW5jdGlvbiBtb3ZlVG9FbnRyeSgpIHsKCQkvLyBQb3NpdGlvbm5lIGF1IGTDqWJ1dCBkZXMgZW50csOpZXMgLy8KCQl3aGlsZSgkdGhpcy0+eHBwLT5uYW1lICE9ICJlbnRyeSIpIHsKCQkJaWYgKCEkdGhpcy0+eHBwLT5yZWFkKCkpCgkJCQlicmVhazsKCQl9Cgl9Cn0KPz4=


