1<?php 2/** 3 * Helper Class for the DAVCard plugin 4 * This helper does the actual work. 5 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 6 * @author Andreas Böhler <dev@aboehler.at> 7 */ 8 9// must be run within Dokuwiki 10if(!defined('DOKU_INC')) die(); 11 12class helper_plugin_davcard extends DokuWiki_Plugin { 13 14 protected $sqlite = null; 15 16 17 /** 18 * Constructor to load the configuration 19 */ 20 public function helper_plugin_davcard() { 21 22 } 23 24 /** Establish and initialize the database if not already done 25 * @return sqlite interface or false 26 */ 27 private function getDB() 28 { 29 if($this->sqlite === null) 30 { 31 $this->sqlite = plugin_load('helper', 'sqlite'); 32 if(!$this->sqlite) 33 { 34 dbglog('This plugin requires the sqlite plugin. Please install it.'); 35 msg('This plugin requires the sqlite plugin. Please install it.', -1); 36 return false; 37 } 38 if(!$this->sqlite->init('davcard', DOKU_PLUGIN.'davcard/db/')) 39 { 40 $this->sqlite = null; 41 dbglog('Error initialising the SQLite DB for davcard'); 42 return false; 43 } 44 } 45 return $this->sqlite; 46 } 47 48 /** 49 * Retrieve a contact by specifying details like the name 50 * 51 * @param int $id The address book ID 52 * @param string $type The type to look for 53 * @param array $params The parameter array 54 * 55 * @return array An array containing the results 56 */ 57 private function getContactByDetails($id, $type, $params = array()) 58 { 59 $write = false; 60 if(strpos($id, 'webdav://') === 0) 61 { 62 $wdc =& plugin_load('helper', 'webdavclient'); 63 if(is_null($wdc)) 64 return $this->getLang('no_wdc'); 65 $connectionId = str_replace('webdav://', '', $id); 66 $settings = $wdc->getConnection($connectionId); 67 68 if($settings === false) 69 return array('formattedname' => $this->getLang('settings_not_found'), 'result' => false); 70 if($settings['type'] !== 'contacts') 71 return array('formattedname' => $this->getLang('wrong_type'), 'result' => false); 72 73 $entries = $wdc->getAddressbookEntries($connectionId); 74 $write = $settings['write']; 75 } 76 else 77 { 78 $acl = auth_quickaclcheck($id); 79 if($acl > AUTH_READ) 80 { 81 $write = true; 82 } 83 elseif($acl < AUTH_READ) 84 { 85 return array('formattedname' => $this->getLang('no_permission'), 'result' => false); 86 } 87 else 88 { 89 $write = false; 90 } 91 $addressbookid = $this->getAddressbookIdForPage($id); 92 $entries = $this->getAddressbookEntries($addressbookid); 93 } 94 foreach($entries as $entry) 95 { 96 switch($type) 97 { 98 case 'structuredname': 99 $contactdata = explode(';', strtolower($entry['structuredname'])); 100 if(count($contactdata) < 2) // We need at least first and last name 101 return array('formattedname' => sprintf($this->getLang('contact_not_found'), $params['firstname']. ' '.$params['lastname']), 'result' => false); 102 if(($params['lastname'] != '') && 103 ($contactdata[0] === $params['lastname']) 104 || $params['lastname'] === '') 105 { 106 // last name matched or no last name given 107 if(($params['firstname'] != '') && 108 ($contactdata[1] === $params['firstname']) 109 || $params['firstname'] === '') 110 { 111 // first name matched too or no first name given 112 $info = $this->parseVcard($entry['contactdata'], $entry['uri'], $write); 113 return $info; 114 } 115 } 116 break; 117 case 'formattedname': 118 if(trim(strtolower($entry['formattedname'])) == $params['formattedname']) 119 { 120 $info = $this->parseVcard($entry['contactdata'], $entry['uri'], $write); 121 return $info; 122 } 123 break; 124 case 'email': 125 $info = $this->parseVcard($entry['contactdata'], $entry['uri'], $write); 126 foreach($info['mail'] as $data) 127 { 128 if(trim(strtolower($data['mail'])) === $params['email']) 129 return $info; 130 } 131 break; 132 } 133 } 134 return array('formattedname' => sprintf($this->getLang('contact_not_found'), $this->getLang('invalid_options')), 'result' => false); 135 } 136 137 138 /** 139 * Retreive all address book entries 140 * 141 * @param int $id The addressbook ID to retrieve 142 * 143 * @return array All address book entries 144 */ 145 public function getAddressbookEntries($id) 146 { 147 $sqlite = $this->getDB(); 148 if(!$sqlite) 149 return false; 150 $query = "SELECT contactdata, uri, formattedname, structuredname FROM addressbookobjects WHERE addressbookid = ? ORDER BY formattedname ASC"; 151 $res = $sqlite->query($query, $id); 152 return $sqlite->res2arr($res); 153 } 154 155 /** 156 * Retrieve a contact by the structured name 157 * 158 * @param string $id The addressbook ID to work with 159 * @param string $firstname The contact's first name 160 * @param string $lastname The contact's last name 161 * 162 * @return array The contact's details 163 */ 164 public function getContactByStructuredName($id, $firstname = '', $lastname = '') 165 { 166 return $this->getContactByDetails($id, 'structuredname', 167 array('firstname' => strtolower($firstname), 'lastname' => strtolower($lastname))); 168 } 169 170 /** 171 * Retrieve a contact by e-mail address 172 * 173 * @param string $id The address book ID 174 * @param string $email The E-Mail address 175 * 176 * @return array The contact's details 177 */ 178 public function getContactByEmail($id, $email) 179 { 180 // FIXME: Maybe it's a good idea to save the e-mail in the database as well! 181 return $this->getContactByDetails($id, 'email', array('email' => strtolower($email))); 182 } 183 184 /** 185 * Retrieve a contact by formatted name 186 * 187 * @param string $id The address book ID 188 * @param string $name The contact's formatted name 189 * 190 * @return array The contact's details 191 */ 192 public function getContactByFormattedName($id, $name) 193 { 194 return $this->getContactByDetails($id, 'formattedname', array('formattedname' => strtolower($name))); 195 } 196 197 /** 198 * Retrieve a contact object by its URI 199 * 200 * @param string $ID The address book ID 201 * @param string $uri The object URI 202 * 203 * @return array An array containing the result 204 */ 205 public function getContactByUri($id, $uri) 206 { 207 $write = false; 208 if(strpos($id, 'webdav://') === 0) 209 { 210 $wdc =& plugin_load('helper', 'webdavclient'); 211 if(is_null($wdc)) 212 return $this->getLang('no_wdc'); 213 $connectionId = str_replace('webdav://', '', $id); 214 $settings = $wdc->getConnection($connectionId); 215 216 if($settings === false) 217 return array('formattedname' => $this->getLang('settings_not_found'), 'result' => false); 218 if($settings['type'] !== 'contacts') 219 return array('formattedname' => $this->getLang('wrong_type'), 'result' => false); 220 221 $row = $wdc->getAddressbookEntryByUri($connectionId, $uri); 222 $write = $settings['write']; 223 } 224 else 225 { 226 $acl = auth_quickaclcheck($id); 227 if($acl > AUTH_READ) 228 { 229 $write = true; 230 } 231 elseif($acl < AUTH_READ) 232 { 233 return array('formattedname' => $this->getLang('no_permission'), 'result' => false); 234 } 235 else 236 { 237 $write = false; 238 } 239 $addressbookid = $this->getAddressbookIdForPage($id); 240 $row = $this->getAddressbookEntryByUri($addressbookid, $uri); 241 } 242 243 if($row === false) 244 return array('formattedname' => sprintf($this->getLang('contact_not_found'), 'ID='.$id.' URI='.$uri), 'result' => false); 245 $info = $this->parseVcard($row['contactdata'], $row['uri'], $write); 246 $info['result'] = true; 247 return $info; 248 } 249 250 /** 251 * Retrieve an address book entry by URI (low-level version) 252 * 253 * @param int $id The address book ID 254 * @param string $uri The object URI 255 * 256 * @return array The contact's details 257 */ 258 private function getAddressbookEntryByUri($id, $uri) 259 { 260 $sqlite = $this->getDB(); 261 if(!$sqlite) 262 return false; 263 $query = "SELECT contactdata, addressbookid, etag, uri, formattedname, structuredname FROM addressbookobjects WHERE addressbookid = ? AND uri = ?"; 264 $res = $sqlite->query($query, $id, $uri); 265 return $sqlite->res2row($res); 266 } 267 268 /** 269 * Set the addressbook name for a given page 270 * 271 * @param string $name The name to set 272 * @param string $description The address book description 273 * @param int $id (optional) The page ID 274 * @param string $userid (optional) The user's ID 275 * 276 * @return boolean true on success, otherwise false 277 */ 278 public function setAddressbookNameForPage($name, $description, $id = null, $userid = null) 279 { 280 if(is_null($id)) 281 { 282 global $ID; 283 $id = $ID; 284 } 285 if(is_null($userid)) 286 { 287 if(isset($_SERVER['REMOTE_USER']) && !is_null($_SERVER['REMOTE_USER'])) 288 { 289 $userid = $_SERVER['REMOTE_USER']; 290 } 291 else 292 { 293 $userid = uniqid('davcard-'); 294 } 295 } 296 $bookid = $this->getAddressbookIdForPage($id); 297 if($bookid === false) 298 return $this->createAddressbookForPage($name, $description, $id, $userid); 299 300 $sqlite = $this->getDB(); 301 if(!$sqlite) 302 return false; 303 $query = "UPDATE addressbooks SET displayname = ?, description = ? WHERE id = ?"; 304 $res = $sqlite->query($query, $name, $description, $bookid); 305 if($res !== false) 306 return true; 307 return false; 308 } 309 310 /** 311 * Get the address book ID associated with a given page 312 * 313 * @param string $id (optional) The page ID 314 * 315 * @return mixed The address book ID or false 316 */ 317 public function getAddressbookIdForPage($id = null) 318 { 319 if(is_null($id)) 320 { 321 global $ID; 322 $id = $ID; 323 } 324 325 $sqlite = $this->getDB(); 326 if(!$sqlite) 327 return false; 328 329 $query = "SELECT addressbookid FROM pagetoaddressbookmapping WHERE page = ?"; 330 $res = $sqlite->query($query, $id); 331 $row = $sqlite->res2row($res); 332 if(isset($row['addressbookid'])) 333 { 334 $addrbkid = $row['addressbookid']; 335 return $addrbkid; 336 } 337 return false; 338 } 339 340 /** 341 * Create a new address book for a given page 342 * 343 * @param string $name The name of the new address book 344 * @param string $description The address book's description 345 * @param string $id (optional) The page ID 346 * @param string $userid (optional) The user's ID 347 * 348 * @return boolean True on success, otherwise false 349 */ 350 public function createAddressbookForPage($name, $description, $id = null, $userid = null) 351 { 352 if(is_null($id)) 353 { 354 global $ID; 355 $id = $ID; 356 } 357 if(is_null($userid)) 358 { 359 if(isset($_SERVER['REMOTE_USER']) && !is_null($_SERVER['REMOTE_USER'])) 360 { 361 $userid = $_SERVER['REMOTE_USER']; 362 } 363 else 364 { 365 $userid = uniqid('davcard-'); 366 } 367 } 368 369 $sqlite = $this->getDB(); 370 if(!$sqlite) 371 return false; 372 373 $values = array('principals/'.$userid, 374 $name, 375 str_replace(array('/', ' ', ':'), '_', $id), 376 $description, 377 1); 378 $query = "INSERT INTO addressbooks (principaluri, displayname, uri, description, synctoken) ". 379 "VALUES (?, ?, ?, ?, ?)"; 380 $res = $sqlite->query($query, $values); 381 if($res === false) 382 return false; 383 384 // Get the new addressbook ID 385 $query = "SELECT id FROM addressbooks WHERE principaluri = ? AND displayname = ? AND ". 386 "uri = ? AND description = ? AND synctoken = ?"; 387 $res = $sqlite->query($query, $values); 388 $row = $sqlite->res2row($res); 389 390 // Update the pagetocalendarmapping table with the new calendar ID 391 if(isset($row['id'])) 392 { 393 $query = "INSERT INTO pagetoaddressbookmapping (page, addressbookid) VALUES (?, ?)"; 394 $res = $sqlite->query($query, $id, $row['id']); 395 return ($res !== false); 396 } 397 398 return false; 399 } 400 401 /** 402 * Delete a contact entry from an address book by URI 403 * 404 * @param string $id The address book ID 405 * @param string $user The user's ID 406 * @param string $uri The object URI to delete 407 * 408 * @return boolean True on success, otherwise false 409 */ 410 public function deleteContactEntryToAddressbookForPage($id, $user, $uri) 411 { 412 if(strpos($id, 'webdav://') === 0) 413 { 414 $wdc =& plugin_load('helper', 'webdavclient'); 415 if(is_null($wdc)) 416 return $this->getLang('no_wdc'); 417 $connectionId = str_replace('webdav://', '', $id); 418 $settings = $wdc->getConnection($connectionId); 419 420 if($settings === false) 421 return array('formattedname' => $this->getLang('settings_not_found'), 'result' => false); 422 if($settings['type'] !== 'contacts') 423 return array('formattedname' => $this->getLang('wrong_type'), 'result' => false); 424 425 return $wdc->deleteAddressbookEntry($connectionId, $uri); 426 } 427 428 $sqlite = $this->getDB(); 429 if(!$sqlite) 430 return false; 431 432 $addressbookid = $this->getAddressbookIdForPage($id); 433 $query = "DELETE FROM addressbookobjects WHERE uri = ? AND addressbookid = ?"; 434 435 $res = $sqlite->query($query, $uri, $addressbookid); 436 if($res !== false) 437 { 438 $this->updateSyncTokenLog($addressbookid, $uri, 'deleted'); 439 return true; 440 } 441 return false; 442 } 443 444 /** 445 * Edit a contact for a given address book 446 * 447 * @param string $id The address book ID 448 * @param string $user The user name 449 * @param string $uri The object URI 450 * @param array $params The new address book parameters 451 * 452 * @return boolean True on success, otherwise false 453 */ 454 public function editContactEntryToAddressbookForPage($id, $user, $uri, $params) 455 { 456 require_once(DOKU_PLUGIN.'davcard/vendor/autoload.php'); 457 458 if(strpos($id, 'webdav://') === 0) 459 { 460 $wdc =& plugin_load('helper', 'webdavclient'); 461 if(is_null($wdc)) 462 return $this->getLang('no_wdc'); 463 $connectionId = str_replace('webdav://', '', $id); 464 $settings = $wdc->getConnection($connectionId); 465 466 if($settings === false) 467 return array('formattedname' => $this->getLang('settings_not_found'), 'result' => false); 468 if($settings['type'] !== 'contacts') 469 return array('formattedname' => $this->getLang('wrong_type'), 'result' => false); 470 471 $row = $wdc->getAddressbookEntryByUri($connectionId, $uri); 472 } 473 else 474 { 475 $addressbookid = $this->getAddressbookIdForPage($id); 476 $row = $this->getAddressbookEntryByUri($addressbookid, $uri); 477 } 478 $vcard = \Sabre\VObject\Reader::read($row['contactdata']); 479 480 $vcard->remove('ADR'); 481 $vcard->remove('TEL'); 482 $vcard->remove('EMAIL'); 483 484 if(isset($params['phones'])) 485 { 486 foreach($params['phones'] as $data) 487 { 488 $vcard->add('TEL', $data['number'], array('type' => $data['type'])); 489 } 490 } 491 492 if(isset($params['email'])) 493 { 494 foreach($params['email'] as $data) 495 { 496 $vcard->add('EMAIL', $data['mail'], array('type' => $data['type'])); 497 } 498 } 499 500 if(isset($params['addresses'])) 501 { 502 foreach($params['addresses'] as $data) 503 { 504 $vcard->add('ADR', array('', '', $data['street'], $data['city'], '', $data['zipcode'], $data['country']), array('type' => $data['type'])); 505 } 506 } 507 508 $structuredname = explode(';', (string)$vcard->N); 509 $structuredname[0] = $params['lastname']; 510 $structuredname[1] = $params['firstname']; 511 $formattedname = $params['firstname'].' '.$params['lastname']; // FIXME: Make this configurable? 512 $vcard->N = $structuredname; 513 $vcard->FN = $formattedname; 514 515 $contactdata = $vcard->serialize(); 516 517 if(strpos($id, 'webdav://') === 0) 518 { 519 return $wdc->editAddressbookEntry($connectionId, $uri, $contactdata); 520 } 521 else 522 { 523 $sqlite = $this->getDB(); 524 if(!$sqlite) 525 return false; 526 $now = new \DateTime(); 527 $query = "UPDATE addressbookobjects SET contactdata = ?, lastmodified = ?, etag = ?, size = ?, formattedname = ?, structuredname = ? WHERE addressbookid = ? AND uri = ?"; 528 $res = $sqlite->query($query, 529 $contactdata, 530 $now->getTimestamp(), 531 md5($contactdata), 532 strlen($contactdata), 533 $formattedname, 534 implode(';', $structuredname), 535 $addressbookid, 536 $uri 537 ); 538 if($res !== false) 539 { 540 $this->updateSyncTokenLog($addressbookid, $uri, 'modified'); 541 return true; 542 } 543 } 544 return false; 545 } 546 547 /** 548 * Add a new contact entry to an address book page 549 * 550 * @param string $id The page ID 551 * @param string $user The user ID 552 * @param array $params The entry's parameters 553 * 554 * @return boolean True on success, otherwise false 555 */ 556 public function addContactEntryToAddressbookForPage($id, $user, $params) 557 { 558 require_once(DOKU_PLUGIN.'davcard/vendor/autoload.php'); 559 $vcard = new \Sabre\VObject\Component\VCard(); 560 $formattedname = $params['firstname'].' '.$params['lastname']; // FIXME: Make this configurable? 561 $structuredname = array($params['lastname'], $params['firstname'], '', '', ''); 562 $vcard->FN = $formattedname; 563 $vcard->N = $structuredname; 564 565 if(isset($params['phones'])) 566 { 567 foreach($params['phones'] as $data) 568 { 569 $vcard->add('TEL', $data['number'], array('type' => $data['type'])); 570 } 571 } 572 if(isset($params['email'])) 573 { 574 foreach($params['email'] as $data) 575 { 576 $vcard->add('EMAIL', $data['mail'], array('type' => $data['type'])); 577 } 578 } 579 if(isset($params['addresses'])) 580 { 581 foreach($params['addresses'] as $data) 582 { 583 $vcard->add('ADR', array('', '', $data['street'], $data['city'], '', $data['zipcode'], $data['country']), array('type' => $data['type'])); 584 } 585 } 586 587 $contactdata = $vcard->serialize(); 588 589 if(strpos($id, 'webdav://') === 0) 590 { 591 $wdc =& plugin_load('helper', 'webdavclient'); 592 if(is_null($wdc)) 593 return false; 594 $connectionId = str_replace('webdav://', '', $id); 595 return $wdc->addAddressbookEntry($connectionId, $contactdata); 596 } 597 else 598 { 599 $sqlite = $this->getDB(); 600 if(!$sqlite) 601 return false; 602 $addressbookid = $this->getAddressbookIdForPage($id); 603 $uri = uniqid('dokuwiki-').'.vcf'; 604 $now = new \DateTime(); 605 $query = "INSERT INTO addressbookobjects (contactdata, uri, addressbookid, lastmodified, etag, size, formattedname, structuredname) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"; 606 $res = $sqlite->query($query, 607 $contactdata, 608 $uri, 609 $addressbookid, 610 $now->getTimestamp(), 611 md5($contactdata), 612 strlen($contactdata), 613 $formattedname, 614 implode(';', $structuredname) 615 ); 616 // If successfully, update the sync token database 617 if($res !== false) 618 { 619 $this->updateSyncTokenLog($addressbookid, $uri, 'added'); 620 return true; 621 } 622 } 623 return false; 624 } 625 626 /** 627 * Parse a VCard and extract important contact information 628 * 629 * @param string $card The VCard data 630 * @param string $uri The object URI 631 * @param boolean $write Writable 632 * 633 * @return array An array with parsed data 634 */ 635 public function parseVcard($card, $uri, $write) 636 { 637 require_once(DOKU_PLUGIN.'davcard/vendor/autoload.php'); 638 639 $vObject = \Sabre\VObject\Reader::read($card); 640 641 $formattedname = ''; 642 $structuredname = ''; 643 $tel = array(); 644 $addr = array(); 645 $mail = array(); 646 $photo = array(); 647 $birthday = ''; 648 $note = ''; 649 $title = ''; 650 $url = ''; 651 652 if(isset($vObject->FN)) 653 $formattedname = (string)$vObject->FN; 654 655 if(isset($vObject->N)) 656 $structuredname = join(';', $vObject->N->getParts()); 657 658 if(isset($vObject->TEL)) 659 { 660 foreach($vObject->TEL as $number) 661 { 662 if(isset($number['TYPE'])) 663 $tel[] = array('type' => strtolower((string)$number['TYPE']), 'number' => (string)$number); 664 else 665 $tel[] = array('number' => (string)$number); 666 } 667 } 668 669 if(isset($vObject->ADR)) 670 { 671 foreach($vObject->ADR as $adr) 672 { 673 if(isset($adr['TYPE'])) 674 $addr[] = array('type' => strtolower((string)$adr['TYPE']), 'address' => $adr->getParts()); 675 else 676 $addr[] = array('address' => $adr->getParts()); 677 } 678 } 679 680 if(isset($vObject->EMAIL)) 681 { 682 foreach($vObject->EMAIL as $email) 683 { 684 if(isset($email['TYPE'])) 685 $mail[] = array('type' => strtolower((string)$email['TYPE']), 'mail' => (string)$email); 686 else 687 $mail[] = array('mail' => (string)$email); 688 } 689 } 690 691 if(isset($vObject->PHOTO)) 692 { 693 if(isset($vObject->PHOTO['TYPE'])) 694 { 695 $photo[] = array('type' => strtolower((string)$vObject->PHOTO['TYPE']), 'photo' => (string)$vObject->PHOTO); 696 } 697 else 698 $photo[] = array('photo' => (string)$vObject->PHOTO); 699 } 700 701 if(isset($vObject->BDAY)) 702 { 703 $birthday = (string)$vObject->BDAY; 704 $birthday = str_replace('-', '', $birthday); 705 } 706 707 if(isset($vObject->NOTE)) 708 { 709 $note = (string)$vObject->NOTE; 710 } 711 712 if(isset($vObject->TITLE)) 713 { 714 $title = (string)$vObject->TITLE; 715 } 716 717 if(isset($vObject->URL)) 718 { 719 $url = (string)$vObject->URL; 720 } 721 722 return array( 723 'formattedname' => $formattedname, 724 'structuredname' => $structuredname, 725 'tel' => $tel, 726 'mail' => $mail, 727 'addr' => $addr, 728 'uri' => $uri, 729 'photo' => $photo, 730 'birthday' => $birthday, 731 'note' => $note, 732 'title' => $title, 733 'url' => $url, 734 'result' => true, 735 'write' => $write 736 ); 737 } 738 739 /** 740 * Retrieve the settings of a given address book 741 * 742 * @param int $addressbookid The addressbook's ID 743 * 744 * @return array The settings 745 */ 746 public function getAddressbookSettings($addressbookid) 747 { 748 $sqlite = $this->getDB(); 749 if(!$sqlite) 750 return false; 751 $query = "SELECT id, principaluri, displayname, uri, description, synctoken FROM addressbooks WHERE id= ? "; 752 $res = $sqlite->query($query, $addressbookid); 753 $row = $sqlite->res2row($res); 754 return $row; 755 } 756 757 /** 758 * Retrieve the current synctoken for an address book 759 * 760 * @param int $addressbookid The addressbook's ID 761 * 762 * @return string The current synctoken 763 */ 764 public function getSyncTokenForAddressbook($addressbookid) 765 { 766 $row = $this->getAddressbookSettings($addressbookid); 767 if(isset($row['synctoken'])) 768 return $row['synctoken']; 769 return false; 770 } 771 772 /** 773 * Helper function to convert the operation name to 774 * an operation code as stored in the database 775 * 776 * @param string $operationName The operation name 777 * 778 * @return mixed The operation code or false 779 */ 780 public function operationNameToOperation($operationName) 781 { 782 switch($operationName) 783 { 784 case 'added': 785 return 1; 786 break; 787 case 'modified': 788 return 2; 789 break; 790 case 'deleted': 791 return 3; 792 break; 793 } 794 return false; 795 } 796 797 /** 798 * Update the synctoken log for a given address book 799 * 800 * @param string $addressbookid The addressbook ID to work with 801 * @param string $uri The object URI that was modified 802 * @param string $operation The operation that was performed 803 * 804 * @return boolean True on success, otherwise false 805 */ 806 private function updateSyncTokenLog($addressbookid, $uri, $operation) 807 { 808 $currentToken = $this->getSyncTokenForAddressbook($addressbookid); 809 $operationCode = $this->operationNameToOperation($operation); 810 if(($operationCode === false) || ($currentToken === false)) 811 return false; 812 $values = array($uri, 813 $currentToken, 814 $addressbookid, 815 $operationCode 816 ); 817 $sqlite = $this->getDB(); 818 if(!$sqlite) 819 return false; 820 $query = "INSERT INTO addressbookchanges (uri, synctoken, addressbookid, operation) VALUES(?, ?, ?, ?)"; 821 $res = $sqlite->query($query, $uri, $currentToken, $addressbookid, $operationCode); 822 if($res === false) 823 return false; 824 $currentToken++; 825 $query = "UPDATE addressbooks SET synctoken = ? WHERE id = ?"; 826 $res = $sqlite->query($query, $currentToken, $addressbookid); 827 return ($res !== false); 828 } 829 830 /** 831 * Check the permission of a user for a given addressbook ID 832 * 833 * @param string $id The addressbook ID to check 834 * @return int AUTH_* constants 835 */ 836 public function checkAddressbookPermission($id) 837 { 838 if(strpos($id, 'webdav://') === 0) 839 { 840 $wdc =& plugin_load('helper', 'webdavclient'); 841 if(is_null($wdc)) 842 return AUTH_NONE; 843 $connectionId = str_replace('webdav://', '', $id); 844 $settings = $wdc->getConnection($connectionId); 845 if($settings === false) 846 return AUTH_NONE; 847 if($settings['write'] === '1') 848 return AUTH_CREATE; 849 return AUTH_READ; 850 } 851 else 852 { 853 $addr = $this->getAddressbookIdForPage($id); 854 // We return AUTH_READ if the calendar does not exist. This makes 855 // davcard happy when there are just included addressbooks 856 if($addr === false) 857 return AUTH_READ; 858 return auth_quickaclcheck($id); 859 } 860 } 861 862} 863