/** * reads vcal blob and tries to repair some parsing problems that Sabre has * * @param string $blob * @param integer $failcount * @param integer $spacecount * @param integer $lastBrokenLineNumber * @param array $lastLines * @throws Sabre\VObject\ParseException * @return Sabre\VObject\Component\VCalendar * * @see 0006110: handle iMIP messages from outlook * * @todo maybe we can remove this when #7438 is resolved */ public static function readVCalBlob($blob, $failcount = 0, $spacecount = 0, $lastBrokenLineNumber = 0, $lastLines = array()) { // convert to utf-8 $blob = Tinebase_Helper::mbConvertTo($blob); if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) { Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' ' . $blob); } try { $vcalendar = \Sabre\VObject\Reader::read($blob); } catch (Sabre\VObject\ParseException $svpe) { // NOTE: we try to repair\Sabre\VObject\Reader as it fails to detect followup lines that do not begin with a space or tab if ($failcount < 10 && preg_match('/Invalid VObject, line ([0-9]+) did not follow the icalendar\\/vcard format/', $svpe->getMessage(), $matches)) { if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' ' . $svpe->getMessage() . ' lastBrokenLineNumber: ' . $lastBrokenLineNumber); } $brokenLineNumber = $matches[1] - 1 + $spacecount; if ($lastBrokenLineNumber === $brokenLineNumber) { if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Try again: concat this line to previous line.'); } $lines = $lastLines; $brokenLineNumber--; // increase spacecount because one line got removed $spacecount++; } else { $lines = preg_split('/[\\r\\n]*\\n/', $blob); if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Concat next line to this one.'); } $lastLines = $lines; // for retry } $lines[$brokenLineNumber] .= $lines[$brokenLineNumber + 1]; unset($lines[$brokenLineNumber + 1]); if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) { Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' failcount: ' . $failcount . ' brokenLineNumber: ' . $brokenLineNumber . ' spacecount: ' . $spacecount); } $vcalendar = self::readVCalBlob(implode("\n", $lines), $failcount + 1, $spacecount, $brokenLineNumber, $lastLines); } else { throw $svpe; } } return $vcalendar; }
/** * (mime) encode some headers ('subject', 'from', 'to', ...) * * @param string $_header * @return string * * @todo support multiple to, ... headers */ protected function _fixHeaderEncoding($_header) { $result = $_header; $encoding = extension_loaded('mbstring') ? mb_detect_encoding($result) : 'unknown'; if ($encoding !== 'ASCII' && preg_match('/[^\\x20-\\x7E]*/', $result)) { if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Non-ASCII character (encoding:' . $encoding . ') detected, mime encode some headers.'); } foreach (array('subject', 'from', 'to', 'cc', 'bcc') as $field) { if (preg_match('/' . $field . ': (.*?[\\n][\\s]*?)/i', $result, $matches)) { if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) { Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' ' . print_r($matches, TRUE)); } $headerValue = str_replace("\n", '', $matches[1]); $headerValue = Tinebase_Helper::mbConvertTo($headerValue); $headerString = iconv_mime_encode(ucfirst($field), $headerValue); $result = str_replace($matches[0], $headerString . "\n", $result); } } if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) { Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' ' . $result); } } return $result; }
/** * filter input string for database as some databases (looking at you, MySQL) can't cope with some chars * * @param string $string * @return string * * @see 0008644: error when sending mail with note (wrong charset) * @see http://stackoverflow.com/questions/1401317/remove-non-utf8-characters-from-string/8215387#8215387 * @see http://stackoverflow.com/questions/8491431/remove-4-byte-characters-from-a-utf-8-string */ public static function filterInputForDatabase($string) { if (self::getDb() instanceof Zend_Db_Adapter_Pdo_Mysql) { $string = Tinebase_Helper::mbConvertTo($string); // remove 4 byte utf8 $result = preg_replace('/[\\xF0-\\xF7].../s', '?', $string); } else { $result = $string; } return $result; }
/** * create new temp file * * @param string $_path * @param string $_name * @param string $_type * @param double $_size * @param integer $_error * @return Tinebase_Model_TempFile */ public function createTempFile($_path, $_name = 'tempfile.tmp', $_type = 'unknown', $_size = 0, $_error = 0) { // sanitize filename (convert to utf8) $filename = Tinebase_Helper::mbConvertTo($_name); $id = Tinebase_Model_TempFile::generateUID(); $tempFile = new Tinebase_Model_TempFile(array('id' => $id, 'session_id' => Tinebase_Core::getSessionId(false), 'time' => Tinebase_DateTime::now()->get(Tinebase_Record_Abstract::ISO8601LONG), 'path' => $_path, 'name' => $filename, 'type' => !empty($_type) ? $_type : 'unknown', 'error' => !empty($_error) ? $_error : 0, 'size' => !empty($_size) ? (double) $_size : (double) filesize($_path))); if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) { Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . " tempfile data: " . print_r($tempFile->toArray(), TRUE)); } $this->create($tempFile); return $tempFile; }