private static function _savePhoto(&$response, &$model, &$params) { if (!empty($params['delete_photo'])) { $model->removePhoto(); $model->save(); } if (isset($_FILES['image']['tmp_name'][0]) && is_uploaded_file($_FILES['image']['tmp_name'][0])) { $destinationFile = new \GO\Base\Fs\File(\GO::config()->getTempFolder()->path() . '/' . $_FILES['image']['name'][0]); move_uploaded_file($_FILES['image']['tmp_name'][0], $destinationFile->path()); $model->setPhoto($destinationFile); $model->save(); $response['photo_url'] = $model->photoThumbURL; $response['original_photo_url'] = $model->photoURL; } elseif (!empty($params['download_photo_url'])) { $file = \GO\Base\Fs\File::tempFile(); $c = new \GO\Base\Util\HttpClient(); if (!$c->downloadFile($params['download_photo_url'], $file)) { throw new \Exception("Could not download photo from: '" . $params['download_photo_url'] . "'"); } $model->setPhoto($file); $model->save(); $response['photo_url'] = $model->photoThumbURL; $response['original_photo_url'] = $model->photoURL; } }
public static function save(\GO\Base\Fs\File $file, array $config) { $configData = "<?php\n/**\n" . " * Group-Office configuration file.\n" . " * Visit https://www.group-office.com/wiki/Configuration_file for available values\n" . " */\n\n"; $configReflection = new ReflectionClass(GO::config()); $defaults = $configReflection->getDefaultProperties(); foreach ($config as $key => $value) { if (!isset($defaults[$key]) || $defaults[$key] !== $value) { $configData .= '$config["' . $key . '"]=' . var_export($value, true) . ';' . "\n"; } } //make sure directory exists $file->parent()->create(); //clear opcache in PHP 5.5 if (function_exists('opcache_invalidate')) { opcache_invalidate($file->path(), true); } return file_put_contents($file->path(), $configData); }
protected function afterSubmit(&$response, &$model, &$params, $modifiedAttributes) { $stmt = \GO\Addressbook\Model\Addresslist::model()->find(); while ($addresslist = $stmt->fetch()) { $linkModel = $addresslist->hasManyMany('companies', $model->id); $mustHaveLinkModel = isset($params['addresslist_' . $addresslist->id]); if ($linkModel && !$mustHaveLinkModel) { $linkModel->delete(); } if (!$linkModel && $mustHaveLinkModel) { $addresslist->addManyMany('companies', $model->id); } } if (!empty($params['delete_photo'])) { $model->removePhoto(); $model->save(); } if (isset($_FILES['image']['tmp_name'][0]) && is_uploaded_file($_FILES['image']['tmp_name'][0])) { $destinationFile = new \GO\Base\Fs\File(\GO::config()->getTempFolder()->path() . '/' . $_FILES['image']['name'][0]); move_uploaded_file($_FILES['image']['tmp_name'][0], $destinationFile->path()); $model->setPhoto($destinationFile); $model->save(); $response['photo_url'] = $model->photoThumbURL; $response['original_photo_url'] = $model->photoURL; } elseif (!empty($params['download_photo_url'])) { $file = \GO\Base\Fs\File::tempFile(); $c = new \GO\Base\Util\HttpClient(); if (!$c->downloadFile($params['download_photo_url'], $file)) { throw new \Exception("Could not download photo from: '" . $params['download_photo_url'] . "'"); } $model->setPhoto($file); $model->save(); $response['photo_url'] = $model->photoThumbURL; $response['original_photo_url'] = $model->photoURL; } return parent::afterSubmit($response, $model, $params, $modifiedAttributes); }
protected function actionSaveAttachment($params) { $folder = \GO\Files\Model\Folder::model()->findByPk($params['folder_id']); if (!$folder) { trigger_error("GO\\Email\\Controller\\Message::actionSaveAttachment(" . $params['folder_id'] . ") folder not found", E_USER_WARNING); throw new \GO\Base\Exception\NotFound("Specified folder not found"); } if (!$folder->checkPermissionLevel(\GO\Base\Model\Acl::WRITE_PERMISSION)) { throw new \GO\Base\Exception\AccessDenied(); } $params['filename'] = \GO\Base\Fs\File::stripInvalidChars($params['filename']); $file = new \GO\Base\Fs\File(GO::config()->file_storage_path . $folder->path . '/' . $params['filename']); if (empty($params['tmp_file'])) { $account = Account::model()->findByPk($params['account_id']); $imap = $account->openImapConnection($params['mailbox']); $response['success'] = $imap->save_to_file($params['uid'], $file->path(), $params['number'], $params['encoding'], true); } else { $tmpfile = new \GO\Base\Fs\File(GO::config()->tmpdir . $params['tmp_file']); $file = $tmpfile->copy($file->parent(), $params['filename']); $response['success'] = $file != false; } if (!$folder->hasFile($file->name())) { $folder->addFile($file->name()); } if (!$response['success']) { $response['feedback'] = 'Could not save to ' . $file->stripFileStoragePath(); } return $response; }
/** * Download a file * * @param string $url * @param \GO\Base\Fs\File $outputFile * @param array $params * @return boolean */ public function downloadFile($url, \GO\Base\Fs\File $outputFile, $params = array()) { $this->_lastDownloadUrl = $url; $this->_initRequest($url, $params); $fp = fopen($outputFile->path(), 'w'); curl_setopt($this->_curl, CURLOPT_FILE, $fp); curl_setopt($this->_curl, CURLOPT_HEADERFUNCTION, array($this, 'readHeader')); $response = curl_exec($this->_curl); fclose($fp); if ($outputFile->size()) { return true; } else { return false; } }
/** * Used in actionCheckLanguage. Parse the file, putting its language fields * into $contentArr. * @param String $filePath The full path to the file. * @param Array &$contentArr The array to put the language fields in. * @return string Output string, possibly containing warnings for the user. */ private function _langFieldsToArray($filePath, &$contentArr) { $outputString = ''; $langFile = new \GO\Base\Fs\File($filePath); if (!file_exists($langFile->path())) { $outputString .= '<i><font color="red">File not found: "' . $langFile->path() . '"</font></i><br />'; } else { $this->_replaceBOM($filePath); $encodingName = $langFile->detectEncoding($langFile->getContents()); if ($encodingName == 'UTF-8' || $encodingName == 'ASCII' || $langFile->convertToUtf8()) { $lines = file($langFile->path()); if (count($lines)) { foreach ($lines as $line) { $first_equal = strpos($line, '='); if ($first_equal != 0) { $key = str_replace('"', '\'', trim(substr($line, 0, $first_equal))); $contentArr[$key] = trim(substr($line, $first_equal, strlen($line) - 1)); } } } else { $outputString .= '<i><font color="red">Could not compare ' . str_replace(\GO::config()->root_path, '', $langFile->path()) . ', because it has no translation contents!</font></i><br />'; } } else { $outputString .= '<i><font color="red">Could not compare with ' . str_replace(\GO::config()->root_path, '', $langFile->path()) . ', because it cannot be made UTF-8!</font></i><br />'; } //for displaying errors include $filePath; } return $outputString; }
protected function actionThumb($params) { GO::session()->closeWriting(); $dir = GO::config()->root_path . 'views/Extjs3/themes/Default/images/128x128/filetypes/'; $url = GO::config()->host . 'views/Extjs3/themes/Default/images/128x128/filetypes/'; $file = new \GO\Base\Fs\File(GO::config()->file_storage_path . $params['src']); if (is_dir(GO::config()->file_storage_path . $params['src'])) { $src = $dir . 'folder.png'; } else { switch (strtolower($file->extension())) { case 'svg': case 'ico': case 'jpg': case 'jpeg': case 'png': case 'gif': case 'xmind': $src = GO::config()->file_storage_path . $params['src']; break; case 'tar': case 'tgz': case 'gz': case 'bz2': case 'zip': $src = $dir . 'zip.png'; break; case 'odt': case 'docx': case 'doc': case 'htm': case 'html': $src = $dir . 'doc.png'; break; case 'odc': case 'ods': case 'xls': case 'xlsx': $src = $dir . 'spreadsheet.png'; break; case 'odp': case 'pps': case 'pptx': case 'ppt': $src = $dir . 'pps.png'; break; case 'eml': $src = $dir . 'message.png'; break; case 'log': $src = $dir . 'txt.png'; break; default: if (file_exists($dir . $file->extension() . '.png')) { $src = $dir . $file->extension() . '.png'; } else { $src = $dir . 'unknown.png'; } break; } } $file = new \GO\Base\Fs\File($src); if ($file->size() > \GO::config()->max_thumbnail_size * 1024 * 1024) { throw new \Exception("Image may not be larger than 5MB."); } $w = isset($params['w']) ? intval($params['w']) : 0; $h = isset($params['h']) ? intval($params['h']) : 0; $zc = !empty($params['zc']) && !empty($w) && !empty($h); $lw = isset($params['lw']) ? intval($params['lw']) : 0; $lh = isset($params['lh']) ? intval($params['lh']) : 0; $pw = isset($params['pw']) ? intval($params['pw']) : 0; $ph = isset($params['ph']) ? intval($params['ph']) : 0; if ($file->extension() == 'xmind') { // $filename = $file->nameWithoutExtension().'.jpeg'; // // if (!file_exists($GLOBALS['GO_CONFIG']->file_storage_path . 'thumbcache/' . $filename) || filectime($GLOBALS['GO_CONFIG']->file_storage_path . 'thumbcache/' . $filename) < filectime($GLOBALS['GO_CONFIG']->file_storage_path . $path)) { // $zipfile = zip_open($GLOBALS['GO_CONFIG']->file_storage_path . $path); // // while ($entry = zip_read($zipfile)) { // if (zip_entry_name($entry) == 'Thumbnails/thumbnail.jpg') { // require_once($GLOBALS['GO_CONFIG']->class_path . 'filesystem.class.inc'); // zip_entry_open($zipfile, $entry, 'r'); // file_put_contents($GLOBALS['GO_CONFIG']->file_storage_path . 'thumbcache/' . $filename, zip_entry_read($entry, zip_entry_filesize($entry))); // zip_entry_close($entry); // break; // } // } // zip_close($zipfile); // } // $path = 'thumbcache/' . $filename; } $cacheDir = new \GO\Base\Fs\Folder(GO::config()->orig_tmpdir . 'thumbcache'); $cacheDir->create(); $cacheFilename = str_replace(array('/', '\\'), '_', $file->parent()->path() . '_' . $w . '_' . $h . '_' . $lw . '_' . $ph . '_' . '_' . $pw . '_' . $lw); if ($zc) { $cacheFilename .= '_zc'; } //$cache_filename .= '_'.filesize($full_path); $cacheFilename .= $file->name(); $readfile = $cacheDir->path() . '/' . $cacheFilename; $thumbExists = file_exists($cacheDir->path() . '/' . $cacheFilename); $thumbMtime = $thumbExists ? filemtime($cacheDir->path() . '/' . $cacheFilename) : 0; GO::debug("Thumb mtime: " . $thumbMtime . " (" . $cacheFilename . ")"); if (!empty($params['nocache']) || !$thumbExists || $thumbMtime < $file->mtime() || $thumbMtime < $file->ctime()) { GO::debug("Resizing image"); $image = new \GO\Base\Util\Image($file->path()); if (!$image->load_success) { GO::debug("Failed to load image for thumbnailing"); //failed. Stream original image $readfile = $file->path(); } else { if ($zc) { $image->zoomcrop($w, $h); } else { if ($lw || $lh || $pw || $lw) { //treat landscape and portrait differently $landscape = $image->landscape(); if ($landscape) { $w = $lw; $h = $lh; } else { $w = $pw; $h = $ph; } } GO::debug($w . "x" . $h); if ($w && $h) { $image->resize($w, $h); } elseif ($w) { $image->resizeToWidth($w); } else { $image->resizeToHeight($h); } } $image->save($cacheDir->path() . '/' . $cacheFilename); } } header("Expires: " . date("D, j M Y G:i:s ", time() + 86400 * 365) . 'GMT'); //expires in 1 year header('Cache-Control: cache'); header('Pragma: cache'); header('Content-Type: ' . $file->mimeType()); header('Content-Disposition: inline; filename="' . $cacheFilename . '"'); header('Content-Transfer-Encoding: binary'); readfile($readfile); // case 'pdf': // $this->redirect($url . 'pdf.png'); // break; // // case 'tar': // case 'tgz': // case 'gz': // case 'bz2': // case 'zip': // $this->redirect( $url . 'zip.png'); // break; // case 'odt': // case 'docx': // case 'doc': // $this->redirect( $url . 'doc.png'); // break; // // case 'odc': // case 'ods': // case 'xls': // case 'xlsx': // $this->redirect( $url . 'spreadsheet.png'); // break; // // case 'odp': // case 'pps': // case 'pptx': // case 'ppt': // $this->redirect( $url . 'pps.png'); // break; // case 'eml': // $this->redirect( $url . 'message.png'); // break; // // case 'htm': // $this->redirect( $url . 'doc.png'); // break; // // case 'log': // $this->redirect( $url . 'txt.png'); // break; // // default: // if (file_exists($dir . $file->extension() . '.png')) { // $this->redirect( $url . $file->extension() . '.png'); // } else { // $this->redirect( $url . 'unknown.png'); // } // break; }
/** * handleEmailFormInput * * This method can be used in Models and Controllers. It puts the email body * and inline (image) attachments from the client in the message, which can * then be used for storage in the database or sending emails. * * @param Array $params Must contain elements: body (string) and * * inlineAttachments (string). */ public function handleEmailFormInput($params) { if (!empty($params['subject'])) { $this->setSubject($params['subject']); } if (!empty($params['to'])) { $to = new EmailRecipients($params['to']); foreach ($to->getAddresses() as $email => $personal) { $this->addTo($email, $personal); } } if (!empty($params['cc'])) { $cc = new EmailRecipients($params['cc']); foreach ($cc->getAddresses() as $email => $personal) { $this->addCc($email, $personal); } } if (!empty($params['bcc'])) { $bcc = new EmailRecipients($params['bcc']); foreach ($bcc->getAddresses() as $email => $personal) { $this->addBcc($email, $personal); } } if (isset($params['alias_id'])) { $alias = \GO\Email\Model\Alias::model()->findByPk($params['alias_id']); $this->setFrom($alias->email, $alias->name); if (!empty($params['notification'])) { $this->setReadReceiptTo(array($alias->email => $alias->name)); } } if (isset($params['priority'])) { $this->setPriority($params['priority']); } if (isset($params['in_reply_to'])) { $headers = $this->getHeaders(); $headers->addTextHeader('In-Reply-To', $params['in_reply_to']); $headers->addTextHeader('References', $params['in_reply_to']); } if ($params['content_type'] == 'html') { $params['htmlbody'] = $this->_embedPastedImages($params['htmlbody']); //inlineAttachments is an array(array('url'=>'',tmp_file=>'relative/path/'); if (!empty($params['inlineAttachments'])) { $inlineAttachments = json_decode($params['inlineAttachments']); /* inline attachments must of course exist as a file, and also be used in * the message body */ if (count($inlineAttachments)) { foreach ($inlineAttachments as $ia) { //$tmpFile = new \GO\Base\Fs\File(\GO::config()->tmpdir.$ia['tmp_file']); if (empty($ia->tmp_file)) { continue; // Continue to the next inline attachment for processing. //throw new Exception("No temp file for inline attachment ".$ia->name); } $path = empty($ia->from_file_storage) ? \GO::config()->tmpdir . $ia->tmp_file : \GO::config()->file_storage_path . $ia->tmp_file; $tmpFile = new \GO\Base\Fs\File($path); if ($tmpFile->exists()) { //Different browsers reformat URL's to absolute or relative. So a pattern match on the filename. //$filename = rawurlencode($tmpFile->name()); $result = preg_match('/="([^"]*' . preg_quote($ia->token) . '[^"]*)"/', $params['htmlbody'], $matches); if ($result) { $img = \Swift_EmbeddedFile::fromPath($tmpFile->path()); $img->setContentType($tmpFile->mimeType()); $contentId = $this->embed($img); //$tmpFile->delete(); $params['htmlbody'] = \GO\Base\Util\String::replaceOnce($matches[1], $contentId, $params['htmlbody']); } else { //this may happen when an inline image was attached but deleted in the editor afterwards. // //throw new \Exception("Error: inline attachment could not be found in text: ".$ia->token); } } else { throw new \Exception("Error: inline attachment missing on server: " . $tmpFile->stripTempPath() . ".<br /><br />The temporary files folder is cleared on each login. Did you relogin?"); } } } } $params['htmlbody'] = $this->_fixRelativeUrls($params['htmlbody']); $htmlTop = '<html> <head> <style type="text/css"> body,p,td,div,span{ ' . \GO::config()->html_editor_font . ' }; body p{ margin:0px; } </style> </head> <body>'; $htmlBottom = '</body></html>'; $this->setHtmlAlternateBody($htmlTop . $params['htmlbody'] . $htmlBottom); } else { $this->setBody($params['plainbody'], 'text/plain'); } if (!empty($params['attachments'])) { $attachments = json_decode($params['attachments']); foreach ($attachments as $att) { $path = empty($att->from_file_storage) ? \GO::config()->tmpdir . $att->tmp_file : \GO::config()->file_storage_path . $att->tmp_file; $tmpFile = new \GO\Base\Fs\File($path); if ($tmpFile->exists()) { $file = \Swift_Attachment::fromPath($tmpFile->path()); $file->setContentType($tmpFile->mimeType()); $file->setFilename($att->fileName); $this->attach($file); //$tmpFile->delete(); } else { throw new \Exception("Error: attachment missing on server: " . $tmpFile->stripTempPath() . ".<br /><br />The temporary files folder is cleared on each login. Did you relogin?"); } } } }
protected function actionImportVCard($params) { $summaryLog = new \GO\Base\Component\SummaryLog(); $readOnly = !empty($params['readOnly']); if (isset($_FILES['files']['tmp_name'][0])) { $params['file'] = $_FILES['files']['tmp_name'][0]; } if (!empty($params['importBaseParams'])) { $importBaseParams = json_decode($params['importBaseParams'], true); $params['addressbook_id'] = $importBaseParams['addressbook_id']; } $file = new \GO\Base\Fs\File($params['file']); $file->convertToUtf8(); $options = \Sabre\VObject\Reader::OPTION_FORGIVING + \Sabre\VObject\Reader::OPTION_IGNORE_INVALID_LINES; $vcards = new \Sabre\VObject\Splitter\VCard(fopen($file->path(), 'r+'), $options); unset($params['file']); $nr = 0; if ($readOnly) { $contactsAttr = array(); } while ($vObject = $vcards->getNext()) { $nr++; \GO\Base\VObject\Reader::convertVCard21ToVCard30($vObject); $contact = new \GO\Addressbook\Model\Contact(); try { if ($contact->importVObject($vObject, $params, !$readOnly)) { $summaryLog->addSuccessful(); } if ($readOnly) { $contactsAttr[] = $contact->getAttributes('formatted'); } } catch (\Exception $e) { $summaryLog->addError($nr, $e->getMessage()); } } $response = $summaryLog->getErrorsJson(); if ($readOnly) { $response['contacts'] = $contactsAttr; } $response['successCount'] = $summaryLog->getTotalSuccessful(); $response['totalCount'] = $summaryLog->getTotal(); $response['success'] = true; return $response; }
public function setPhoto(\GO\Base\Fs\File $file) { if ($this->isNew) { throw new \Exception("Cannot save a photo on a new contact that is not yet saved."); } $this->getPhotoFile()->delete(); $photoPath = new \GO\Base\Fs\Folder(\GO::config()->file_storage_path . 'addressbook/photos/' . $this->addressbook_id . '/'); $photoPath->create(); // if(strtolower($file->extension())!='jpg'){ $filename = $photoPath->path() . '/com_' . $this->id . '.jpg'; $img = new \GO\Base\Util\Image(); if (!$img->load($file->path())) { throw new \Exception(\GO::t('imageNotSupported', 'addressbook')); } $aspectRatio = $img->getHeight() > $img->getWidth() ? $img->getHeight() / $img->getWidth() : $img->getWidth() / $img->getHeight(); //resize it to small image so we don't get in trouble with sync clients if ($img->getHeight() > $img->getWidth()) { $img->fitBox(320 / $aspectRatio, 320); } else { $img->fitBox(320, 320 / $aspectRatio); } if (!$img->save($filename, IMAGETYPE_JPEG)) { throw new \Exception("Could not save photo!"); } $file = new \GO\Base\Fs\File($filename); // }else // { // $file->move($photoPath, $this->id.'.'.strtolower($file->extension())); // } $this->photo = $file->stripFileStoragePath(); }
protected function actionDecompress($params) { if (!\GO\Base\Util\Common::isWindows()) { putenv('LANG=en_US.UTF-8'); } $sources = json_decode($params['decompress_sources'], true); $workingFolder = \GO\Files\Model\Folder::model()->findByPk($params['working_folder_id']); $workingPath = \GO::config()->file_storage_path . $workingFolder->path; chdir($workingPath); while ($filePath = array_shift($sources)) { $file = new \GO\Base\Fs\File(\GO::config()->file_storage_path . $filePath); switch (strtolower($file->extension())) { case 'zip': $folder = \GO\Base\Fs\Folder::tempFolder(uniqid()); if (class_exists("\\ZipArchive")) { $zip = new \ZipArchive(); $zip->open($file->path()); $zip->extractTo($folder->path()); $this->_convertZipEncoding($folder); } else { chdir($folder->path()); $cmd = \GO::config()->cmd_unzip . ' -n ' . escapeshellarg($file->path()); exec($cmd, $output, $ret); if ($ret != 0) { throw new \Exception("Could not decompress\n" . implode("\n", $output)); } } $items = $folder->ls(); foreach ($items as $item) { $item->move(new \GO\Base\Fs\Folder($workingPath)); } $folder->delete(); break; case 'gz': case 'tgz': $cmd = \GO::config()->cmd_tar . ' zxf ' . escapeshellarg($file->path()); exec($cmd, $output, $ret); if ($ret != 0) { throw new \Exception("Could not decompress\n" . implode("\n", $output)); } break; case 'tar': $cmd = \GO::config()->cmd_tar . ' xf ' . escapeshellarg($file->path()); exec($cmd, $output, $ret); if ($ret != 0) { throw new \Exception("Could not decompress\n" . implode("\n", $output)); } break; } } $workingFolder->syncFilesystem(true); return array('success' => true); }
private function _decryptFile(\GO\Base\Fs\File $srcFile, \GO\Email\Model\Account $account) { $data = $srcFile->getContents(); if (strpos($data, "enveloped-data") || strpos($data, 'Encrypted Message')) { $cert = \GO\Smime\Model\Certificate::model()->findByPk($account->id); $password = \GO::session()->values['smime']['passwords'][$_REQUEST['account_id']]; openssl_pkcs12_read($cert->cert, $certs, $password); $decryptedFile = \GO\Base\Fs\File::tempFile(); $ret = openssl_pkcs7_decrypt($srcFile->path(), $decryptedFile->path(), $certs['cert'], array($certs['pkey'], $password)); if (!$decryptedFile->exists()) { throw new \Exception("Could not decrypt message: " . openssl_error_string()); } $decryptedFile->move($srcFile->parent(), $srcFile->name()); } }