/**
  * 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;
 }