/** * Validates the node for correctness. * * The following options are supported: * - VCard::REPAIR - If something is broken, and automatic repair may * be attempted. * - VCard::UPGRADE - If needed the vCard will be upgraded to version 3.0. * * An array is returned with warnings. * * Every item in the array has the following properties: * * level - (number between 1 and 3 with severity information) * * message - (human readable message) * * node - (reference to the offending node) * * @param int $options * @return array */ public function validate($options = 0) { $warnings = array(); if ($options & self::UPGRADE) { $this->VERSION = self::DEFAULT_VERSION; foreach ($this->children as &$property) { $this->decodeProperty($property); $this->fixPropertyParameters($property); /* What exactly was I thinking here? switch((string)$property->name) { case 'LOGO': case 'SOUND': case 'PHOTO': if(isset($property['TYPE']) && strpos((string)$property['TYPE'], '/') === false) { $property['TYPE'] = 'image/' . strtolower($property['TYPE']); } }*/ } } $version = $this->select('VERSION'); if (count($version) !== 1) { $warnings[] = array('level' => 1, 'message' => 'The VERSION property must appear in the VCARD component exactly 1 time', 'node' => $this); if ($options & self::REPAIR) { $this->VERSION = self::DEFAULT_VERSION; if (!$options & self::UPGRADE) { $options |= self::UPGRADE; } } } else { $version = (string) $this->VERSION; if ($version !== '2.1' && $version !== '3.0' && $version !== '4.0') { $warnings[] = array('level' => 1, 'message' => 'Only vcard version 4.0 (RFC6350), version 3.0 (RFC2426) or version 2.1 (icm-vcard-2.1) are supported.', 'node' => $this); if ($options & self::REPAIR) { $this->VERSION = self::DEFAULT_VERSION; if (!$options & self::UPGRADE) { $options |= self::UPGRADE; } } } } $fn = $this->select('FN'); if (count($fn) !== 1) { $warnings[] = array('level' => 1, 'message' => 'The FN property must appear in the VCARD component exactly 1 time', 'node' => $this); if ($options & self::REPAIR && count($fn) === 0) { // We're going to try to see if we can use the contents of the // N property. if (isset($this->N)) { $value = explode(';', (string) $this->N); if (isset($value[1]) && $value[1]) { $this->FN = $value[1] . ' ' . $value[0]; } else { $this->FN = $value[0]; } // Otherwise, the ORG property may work } elseif (isset($this->ORG)) { $this->FN = (string) $this->ORG; } elseif (isset($this->EMAIL)) { $this->FN = (string) $this->EMAIL; } } } $n = $this->select('N'); if (count($n) !== 1) { $warnings[] = array('level' => 1, 'message' => 'The N property must appear in the VCARD component exactly 1 time', 'node' => $this); // TODO: Make a better effort parsing FN. if ($options & self::REPAIR && count($n) === 0) { // Take 2 first name parts of 'FN' and reverse. $slice = array_reverse(array_slice(explode(' ', (string) $this->FN), 0, 2)); if (count($slice) < 2) { // If not enought, add one more... $slice[] = ""; } $this->N = implode(';', $slice) . ';;;'; } } if (!isset($this->UID)) { $warnings[] = array('level' => 1, 'message' => 'Every vCard must have a UID', 'node' => $this); if ($options & self::REPAIR) { $this->UID = Utils\Properties::generateUID(); } } if ($options & self::REPAIR || $options & self::UPGRADE) { $now = new \DateTime(); $this->REV = $now->format(\DateTime::W3C); } return array_merge(parent::validate($options), $warnings); }
/** * Validates the node for correctness. * * The following options are supported: * - VCard::REPAIR - If something is broken, and automatic repair may * be attempted. * - VCard::UPGRADE - If needed the vCard will be upgraded to version 3.0. * * An array is returned with warnings. * * Every item in the array has the following properties: * * level - (number between 1 and 3 with severity information) * * message - (human readable message) * * node - (reference to the offending node) * * @param int $options * @return array */ public function validate($options = 0) { $warnings = array(); if ($options & self::UPGRADE) { $this->VERSION = self::DEFAULT_VERSION; foreach ($this->children as $idx => &$property) { $this->decodeProperty($property); $this->fixPropertyParameters($property); /* What exactly was I thinking here? switch((string)$property->name) { case 'LOGO': case 'SOUND': case 'PHOTO': if(isset($property['TYPE']) && strpos((string)$property['TYPE'], '/') === false) { $property['TYPE'] = 'image/' . strtolower($property['TYPE']); } }*/ } } $version = $this->select('VERSION'); if (count($version) !== 1) { $warnings[] = array('level' => 1, 'message' => 'The VERSION property must appear in the VCARD component exactly 1 time', 'node' => $this); if ($options & self::REPAIR) { $this->VERSION = self::DEFAULT_VERSION; if (!$options & self::UPGRADE) { $options |= self::UPGRADE; } } } else { $version = (string) $this->VERSION; if ($version !== '2.1' && $version !== '3.0' && $version !== '4.0') { $warnings[] = array('level' => 1, 'message' => 'Only vcard version 4.0 (RFC6350), version 3.0 (RFC2426) or version 2.1 (icm-vcard-2.1) are supported.', 'node' => $this); if ($options & self::REPAIR) { $this->VERSION = self::DEFAULT_VERSION; if (!$options & self::UPGRADE) { $options |= self::UPGRADE; } } } } $fn = $this->select('FN'); if (count($fn) !== 1 || trim((string) $this->FN) === '') { $warnings[] = array('level' => 1, 'message' => 'The FN property must appear in the VCARD component exactly 1 time', 'node' => $this); if ($options & self::REPAIR) { // We're going to try to see if we can use the contents of the // N property. if (isset($this->N) && substr((string) $this->N, 2) !== ';;' && (string) $this->N !== '') { $value = explode(';', (string) $this->N); if (isset($value[1]) && $value[1]) { $this->FN = $value[1] . ' ' . $value[0]; } else { $this->FN = $value[0]; } // Otherwise, the ORG property may work } elseif (isset($this->ORG)) { $this->FN = (string) $this->ORG; } elseif (isset($this->EMAIL)) { $this->FN = (string) $this->EMAIL; } } } if (isset($this->BDAY)) { if ($options & self::REPAIR) { // If the BDAY has a format of e.g. 19960401 $bday = (string) $this->BDAY; if (strlen($bday) >= 8 && is_int(substr($bday, 0, 4)) && is_int(substr($bday, 4, 2)) && is_int(substr($bday, 6, 2))) { $this->BDAY = substr($bday, 0, 4) . '-' . substr($bday, 4, 2) . '-' . substr($bday, 6, 2); $this->BDAY->VALUE = 'DATE'; } else { if (empty($bday)) { // We don't want "New \DateTime($bday)" evaluate to current date because of empty value. // So we'll leave this item empty. \OCP\Util::writeLog('contacts', __METHOD__ . ' Removing invalid/empty BDAY.', \OCP\Util::DEBUG); unset($this->BDAY); } else { if ($bday[5] !== '-' || $bday[7] !== '-') { try { // Skype exports as e.g. Jan 14, 1996 $date = new \DateTime($bday); $this->BDAY = $date->format('Y-m-d'); $this->BDAY->VALUE = 'DATE'; } catch (\Exception $e) { \OCP\Util::writeLog('contacts', __METHOD__ . ' Removing invalid BDAY: ' . $bday, \OCP\Util::DEBUG); unset($this->BDAY); } } } } } } $n = $this->select('N'); if (count($n) !== 1) { $warnings[] = array('level' => 1, 'message' => 'The N property must appear in the VCARD component exactly 1 time', 'node' => $this); // TODO: Make a better effort parsing FN. if ($options & self::REPAIR && count($n) === 0) { // Take 2 first name parts of 'FN' and reverse. $slice = array_reverse(array_slice(explode(' ', (string) $this->FN), 0, 2)); if (count($slice) < 2) { // If not enought, add one more... $slice[] = ""; } $this->N = $slice; } } if (!isset($this->UID) || trim((string) $this->UID) === '') { $warnings[] = array('level' => 1, 'message' => 'Every vCard must have a UID', 'node' => $this); if ($options & self::REPAIR) { $this->UID = Utils\Properties::generateUID(); } } if ($options & self::REPAIR || $options & self::UPGRADE) { $now = new \DateTime(); $this->REV = $now->format(\DateTime::W3C); } return array_merge(parent::validate($options), $warnings); }
/** * @brief Checks if a contact with the same URI already exist in the address book. * @param string $addressBookId Address book ID. * @param string $uri * @returns string Unique URI */ protected function uniqueURI($addressBookId, $uri) { $stmt = $this->getPreparedQuery('counturi'); $result = $stmt->execute(array($addressBookId, $uri)); $result = $result->fetchRow(); if (is_array($result) && count($result) > 0 && $result['count'] > 0) { while (true) { $uri = Properties::generateUID() . '.vcf'; $result = $stmt->execute(array($addressBookId, $uri)); if (is_array($result) && count($result) > 0 && $result['count'] > 0) { continue; } else { return $uri; } } } return $uri; }
/** * @brief Checks if a contact with the same URI already exist in the address book. * @param string $addressBookId Address book ID. * @param string $uri * @returns string Unique URI */ protected function uniqueURI($addressBookId, $uri) { $stmt = \OCP\DB::prepare('SELECT * FROM `' . $this->cardsTableName . '` WHERE `addressbookid` = ? AND `uri` = ?'); $result = $stmt->execute(array($addressBookId, $uri)); if ($result->numRows() > 0) { while (true) { $uri = Properties::generateUID() . '.vcf'; $result = $stmt->execute(array($addressBookId, $uri)); if ($result->numRows() > 0) { continue; } else { return $uri; } } } else { return $uri; } }