function getFile()
 {
     if (!$this->file && $this->getFileId()) {
         $this->file = AttachmentFile::lookup($this->getFileId());
     }
     return $this->file;
 }
Example #2
0
 function syncExistingAttachments()
 {
     $matches = array();
     if (!preg_match_all('/"cid:([\\w.-]{32})"/', $this->getBody(), $matches)) {
         return;
     }
     // Purge current attachments
     $this->attachments->deleteInlines();
     foreach ($matches[1] as $hash) {
         if ($file = AttachmentFile::getIdByHash($hash)) {
             $this->attachments->upload($file, true);
         }
     }
 }
 function run($runtime)
 {
     $errors = array();
     $i18n = new Internationalization('en_US');
     $tpls = $i18n->getTemplate('email_template_group.yaml')->getData();
     foreach ($tpls as $t) {
         // If the email template group specifies an id attribute, remove
         // it for upgrade because we cannot assume that the id slot is
         // available
         unset($t['id']);
         EmailTemplateGroup::create($t, $errors);
     }
     $files = $i18n->getTemplate('file.yaml')->getData();
     foreach ($files as $f) {
         $id = AttachmentFile::create($f, $errors);
         // Ensure the new files are never deleted (attached to Disk)
         $sql = 'INSERT INTO ' . ATTACHMENT_TABLE . ' SET object_id=0, `type`=\'D\', inline=1' . ', file_id=' . db_input($id);
         db_query($sql);
     }
 }
 /**
  * Processes the next item on the work queue. Emits a JSON messages to
  * indicate current progress.
  *
  * Returns:
  * TRUE/NULL if the migration was successful
  */
 function next()
 {
     # Fetch next item -- use the last item so the array indices don't
     # need to be recalculated for every shift() operation.
     $info = array_pop($this->queue);
     # Attach file to the ticket
     if (!($info['data'] = @file_get_contents($info['path']))) {
         # Continue with next file
         return $this->skip($info['attachId'], sprintf('%s: Cannot read file contents', $info['path']));
     }
     # Get the mime/type of each file
     # XXX: Use finfo_buffer for PHP 5.3+
     if (function_exists('mime_content_type')) {
         //XXX: function depreciated in newer versions of PHP!!!!!
         $info['type'] = mime_content_type($info['path']);
     } elseif (function_exists('finfo_file')) {
         // PHP 5.3.0+
         $finfo = finfo_open(FILEINFO_MIME_TYPE);
         $info['type'] = finfo_file($finfo, $info['path']);
     }
     # TODO: Add extension-based mime-type lookup
     if (!($fileId = AttachmentFile::save($info))) {
         return $this->skip($info['attachId'], sprintf('%s: Unable to migrate attachment', $info['path']));
     }
     # Update the ATTACHMENT_TABLE record to set file_id
     db_query('update ' . TICKET_ATTACHMENT_TABLE . ' set file_id=' . db_input($fileId) . ' where attach_id=' . db_input($info['attachId']));
     # Remove disk image of the file. If this fails, the migration for
     # this file would not be retried, because the file_id in the
     # TICKET_ATTACHMENT_TABLE has a nonzero value now
     if (!@unlink($info['path'])) {
         //XXX: what should we do on failure?
         $this->error(sprintf('%s: Unable to remove file from disk', $info['path']));
     }
     # TODO: Log an internal note to the ticket?
     return true;
 }
 /**
  * Processes the next item on the work queue. Emits a JSON messages to
  * indicate current progress.
  *
  * Returns:
  * TRUE/NULL if the migration was successful
  */
 function next()
 {
     # Fetch next item -- use the last item so the array indices don't
     # need to be recalculated for every shift() operation.
     $info = array_pop($this->queue);
     # Attach file to the ticket
     if (!($info['data'] = @file_get_contents($info['path']))) {
         # Continue with next file
         return $this->error(sprintf('%s: Cannot read file contents', $info['path']));
     }
     # Get the mime/type of each file
     # XXX: Use finfo_buffer for PHP 5.3+
     $info['type'] = mime_content_type($info['path']);
     if (!($fileId = AttachmentFile::save($info))) {
         return $this->error(sprintf('%s: Unable to migrate attachment', $info['path']));
     }
     # Update the ATTACHMENT_TABLE record to set file_id
     db_query('update ' . TICKET_ATTACHMENT_TABLE . ' set file_id=' . db_input($fileId) . ' where attach_id=' . db_input($info['attachId']));
     # Remove disk image of the file. If this fails, the migration for
     # this file would not be retried, because the file_id in the
     # TICKET_ATTACHMENT_TABLE has a nonzero value now
     if (!@unlink($info['path'])) {
         $this->error(sprintf('%s: Unable to remove file from disk', $info['path']));
     }
     # TODO: Log an internal note to the ticket?
     return true;
 }
Example #6
0
    file.php

    File download facilitator for clients

    Peter Rotich <*****@*****.**>
    Jared Hancock <*****@*****.**>
    Copyright (c)  2006-2014 osTicket
    http://www.osticket.com

    Released under the GNU General Public License WITHOUT ANY WARRANTY.
    See LICENSE.TXT for details.

    vim: expandtab sw=4 ts=4 sts=4:
**********************************************************************/
require 'client.inc.php';
require_once INCLUDE_DIR . 'class.file.php';
//Basic checks
if (!$_GET['key'] || !$_GET['signature'] || !$_GET['expires'] || !($file = AttachmentFile::lookup($_GET['key']))) {
    Http::response(404, __('Unknown or invalid file'));
}
// Validate session access hash - we want to make sure the link is FRESH!
// and the user has access to the parent ticket!!
if ($file->verifySignature($_GET['signature'], $_GET['expires'])) {
    if (($s = @$_GET['s']) && strpos($file->getType(), 'image/') === 0) {
        return $file->display($s);
    }
    // Download the file..
    $file->download(@$_GET['disposition'] ?: false, $_GET['expires']);
}
// else
Http::response(404, __('Unknown or invalid file'));
 function send($to, $subject, $message, $options = null)
 {
     global $ost;
     //Get the goodies
     require_once PEAR_DIR . 'Mail.php';
     // PEAR Mail package
     require_once PEAR_DIR . 'Mail/mime.php';
     // PEAR Mail_Mime packge
     //do some cleanup
     $to = preg_replace("/(\r\n|\r|\n)/s", '', trim($to));
     $subject = stripslashes(preg_replace("/(\r\n|\r|\n)/s", '', trim($subject)));
     $body = stripslashes(preg_replace("/(\r\n|\r)/s", "\n", trim($message)));
     /* Message ID - generated for each outgoing email */
     $messageId = sprintf('<%s%d-%s>', Misc::randCode(6), time(), $this->getEmail() ? $this->getEmail()->getEmail() : '@osTicketMailer');
     $headers = array('From' => $this->getFromAddress(), 'To' => $to, 'Subject' => $subject, 'Date' => date('D, d M Y H:i:s O'), 'Message-ID' => $messageId, 'X-Mailer' => 'osTicket Mailer', 'Content-Type' => 'text/html; charset="UTF-8"');
     $mime = new Mail_mime();
     $mime->setTXTBody($body);
     //XXX: Attachments
     if ($attachments = $this->getAttachments()) {
         foreach ($attachments as $attachment) {
             if ($attachment['file_id'] && ($file = AttachmentFile::lookup($attachment['file_id']))) {
                 $mime->addAttachment($file->getData(), $file->getType(), $file->getName(), false);
             } elseif ($attachment['file'] && file_exists($attachment['file']) && is_readable($attachment['file'])) {
                 $mime->addAttachment($attachment['file'], $attachment['type'], $attachment['name']);
             }
         }
     }
     //Desired encodings...
     $encodings = array('head_encoding' => 'quoted-printable', 'text_encoding' => 'quoted-printable', 'html_encoding' => 'base64', 'html_charset' => 'utf-8', 'text_charset' => 'utf-8', 'head_charset' => 'utf-8');
     //encode the body
     $body = $mime->get($encodings);
     //encode the headers.
     $headers = $mime->headers($headers);
     if ($smtp = $this->getSMTPInfo()) {
         //Send via SMTP
         $mail = mail::factory('smtp', array('host' => $smtp['host'], 'port' => $smtp['port'], 'auth' => $smtp['auth'], 'username' => $smtp['username'], 'password' => $smtp['password'], 'timeout' => 20, 'debug' => false));
         $result = $mail->send($to, $headers, $body);
         if (!PEAR::isError($result)) {
             return $messageId;
         }
         $alert = sprintf("Unable to email via SMTP:%s:%d [%s]\n\n%s\n", $smtp['host'], $smtp['port'], $smtp['username'], $result->getMessage());
         $this->logError($alert);
     }
     //No SMTP or it failed....use php's native mail function.
     $mail = mail::factory('mail');
     return PEAR::isError($mail->send($to, $headers, $body)) ? false : $messageId;
 }
Example #8
0
 function deleteAttachments()
 {
     $deleted = 0;
     // Clear reference table
     $res = db_query('DELETE FROM ' . TICKET_ATTACHMENT_TABLE . ' WHERE ticket_id=' . db_input($this->getId()));
     if ($res && db_affected_rows()) {
         $deleted = AttachmentFile::deleteOrphans();
     }
     return $deleted;
 }
     data-signature="<?php
         echo Format::htmlchars(Format::viewableImages($signature)); ?>"
     data-signature-field="signature" data-dept-field="deptId"
     placeholder="Intial response for the ticket"
     name="response" id="response" cols="21" rows="8"
     style="width:80%;"><?php echo $info['response']; ?></textarea>
 <table border="0" cellspacing="0" cellpadding="2" width="100%">
 <?php
 if($cfg->allowAttachments()) { ?>
     <tr><td width="100" valign="top">Attachments:</td>
         <td>
             <div class="canned_attachments">
             <?php
             if($info['cannedattachments']) {
                 foreach($info['cannedattachments'] as $k=>$id) {
                     if(!($file=AttachmentFile::lookup($id))) continue;
                     $hash=$file->getKey().md5($file->getId().session_id().$file->getKey());
                     echo sprintf('<label><input type="checkbox" name="cannedattachments[]"
                             id="f%d" value="%d" checked="checked"
                             <a href="file.php?h=%s">%s</a>&nbsp;&nbsp;</label>&nbsp;',
                             $file->getId(), $file->getId() , $hash, $file->getName());
                 }
             }
             ?>
             </div>
             <div class="uploads"></div>
             <div class="file_input">
                 <input type="file" class="multifile" name="attachments[]" size="30" value="" />
             </div>
         </td>
     </tr>
Example #10
0
<?php

/*********************************************************************
    image.php

    Simply downloads the file...on hash validation as follows;

    * Hash must be 64 chars long.
    * First 32 chars is the perm. file hash
    * Next 32 chars  is md5(file_id.session_id().file_hash)

    Peter Rotich <*****@*****.**>
    Copyright (c)  2006-2013 osTicket
    http://www.osticket.com

    Released under the GNU General Public License WITHOUT ANY WARRANTY.
    See LICENSE.TXT for details.

    vim: expandtab sw=4 ts=4 sts=4:
**********************************************************************/
require 'staff.inc.php';
require_once INCLUDE_DIR . 'class.file.php';
$h = trim($_GET['h']);
//basic checks
if (!$h || strlen($h) != 64 || !($file = AttachmentFile::lookup(substr($h, 0, 32))) || strcasecmp($h, $file->getDownloadHash())) {
    //next 32 is file id + session hash.
    die('Unknown or invalid file. #' . Format::htmlchars($_GET['h']));
}
$file->display();
 function deleteAttachments()
 {
     global $cfg;
     $deleted = 0;
     if ($attachments = $this->getAttachments()) {
         //Clear reference table - XXX: some attachments might be orphaned
         db_query('DELETE FROM ' . TICKET_ATTACHMENT_TABLE . ' WHERE ticket_id=' . db_input($this->getId()));
         //Delete file from DB IF NOT inuse.
         foreach ($attachments as $attachment) {
             if (($file = AttachmentFile::lookup($attachment['file_id'])) && !$file->isInuse() && $file->delete()) {
                 $deleted++;
             }
         }
     }
     return $deleted;
 }
Example #12
0
 function getValue()
 {
     $data = $this->field->getSource();
     $ids = array();
     // Handle manual uploads (IE<10)
     if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_FILES[$this->name])) {
         foreach (AttachmentFile::format($_FILES[$this->name]) as $file) {
             try {
                 $ids[] = $this->field->uploadFile($file);
             } catch (FileUploadError $ex) {
             }
         }
         return array_merge($ids, parent::getValue() ?: array());
     } elseif ($data && is_array($data) && !isset($data[$this->name])) {
         return array();
     }
     return parent::getValue();
 }
Example #13
0
 function viewableImages($html, $script = false)
 {
     return preg_replace_callback('/"cid:([\\w._-]{32})"/', function ($match) use($script) {
         $hash = $match[1];
         if (!($file = AttachmentFile::lookup($hash))) {
             return $match[0];
         }
         return sprintf('"%s" data-cid="%s"', $file->getDownloadUrl(false, 'inline', $script), $match[1]);
     }, $html);
 }
Example #14
0
 function send($to, $subject, $message, $options = null)
 {
     global $ost;
     //Get the goodies
     require_once PEAR_DIR . 'Mail.php';
     // PEAR Mail package
     require_once PEAR_DIR . 'Mail/mime.php';
     // PEAR Mail_Mime packge
     //do some cleanup
     $to = preg_replace("/(\r\n|\r|\n)/s", '', trim($to));
     $subject = preg_replace("/(\r\n|\r|\n)/s", '', trim($subject));
     //We're decoding html entities here becasuse we only support plain text for now - html support comming.
     $body = Format::htmldecode(preg_replace("/(\r\n|\r)/s", "\n", trim($message)));
     /* Message ID - generated for each outgoing email */
     $messageId = sprintf('<%s%d-%s>', Misc::randCode(6), time(), $this->getEmail() ? $this->getEmail()->getEmail() : '@osTicketMailer');
     $headers = array('From' => $this->getFromAddress(), 'To' => $to, 'Subject' => $subject, 'Date' => date('D, d M Y H:i:s O'), 'Message-ID' => $messageId, 'X-Mailer' => 'osTicket Mailer');
     //Set bulk/auto-response headers.
     if ($options && ($options['autoreply'] or $options['bulk'])) {
         $headers += array('X-Autoreply' => 'yes', 'X-Auto-Response-Suppress' => 'ALL, AutoReply', 'Auto-Submitted' => 'auto-replied');
         if ($options['bulk']) {
             $headers += array('Precedence' => 'bulk');
         } else {
             $headers += array('Precedence' => 'auto_reply');
         }
     }
     if ($options) {
         if (isset($options['inreplyto']) && $options['inreplyto']) {
             $headers += array('In-Reply-To' => $options['inreplyto']);
         }
         if (isset($options['references']) && $options['references']) {
             if (is_array($options['references'])) {
                 $headers += array('References' => implode(' ', $options['references']));
             } else {
                 $headers += array('References' => $options['references']);
             }
         }
     }
     $mime = new Mail_mime();
     $mime->setTXTBody($body);
     //XXX: Attachments
     if ($attachments = $this->getAttachments()) {
         foreach ($attachments as $attachment) {
             if ($attachment['file_id'] && ($file = AttachmentFile::lookup($attachment['file_id']))) {
                 $mime->addAttachment($file->getData(), $file->getType(), $file->getName(), false);
             } elseif ($attachment['file'] && file_exists($attachment['file']) && is_readable($attachment['file'])) {
                 $mime->addAttachment($attachment['file'], $attachment['type'], $attachment['name']);
             }
         }
     }
     //Desired encodings...
     $encodings = array('head_encoding' => 'quoted-printable', 'text_encoding' => 'base64', 'html_encoding' => 'base64', 'html_charset' => 'utf-8', 'text_charset' => 'utf-8', 'head_charset' => 'utf-8');
     //encode the body
     $body = $mime->get($encodings);
     //encode the headers.
     $headers = $mime->headers($headers, true);
     if ($smtp = $this->getSMTPInfo()) {
         //Send via SMTP
         $mail = mail::factory('smtp', array('host' => $smtp['host'], 'port' => $smtp['port'], 'auth' => $smtp['auth'], 'username' => $smtp['username'], 'password' => $smtp['password'], 'timeout' => 20, 'debug' => false));
         $result = $mail->send($to, $headers, $body);
         if (!PEAR::isError($result)) {
             return $messageId;
         }
         $alert = sprintf("Unable to email via SMTP:%s:%d [%s]\n\n%s\n", $smtp['host'], $smtp['port'], $smtp['username'], $result->getMessage());
         $this->logError($alert);
     }
     //No SMTP or it failed....use php's native mail function.
     $mail = mail::factory('mail');
     return PEAR::isError($mail->send($to, $headers, $body)) ? false : $messageId;
 }
Example #15
0
 function deleteAttachments()
 {
     $deleted = 0;
     $sql = 'DELETE FROM ' . FAQ_ATTACHMENT_TABLE . ' WHERE faq_id=' . db_input($this->getId());
     if (db_query($sql) && db_affected_rows()) {
         $deleted = AttachmentFile::deleteOrphans();
     }
     return $deleted;
 }
Example #16
0
 function save($info, $inline = true)
 {
     if (!($fileId = AttachmentFile::save($info))) {
         return false;
     }
     $sql = 'INSERT INTO ' . ATTACHMENT_TABLE . ' SET `type`=' . db_input($this->getType()) . ',object_id=' . db_input($this->getId()) . ',file_id=' . db_input($fileId) . ',inline=' . db_input($inline ? 1 : 0);
     if (!db_query($sql) || !db_affected_rows()) {
         return false;
     }
     return $fileId;
 }
Example #17
0
 public function savefile($uid, $original_file_path, $original_basename, $file_name = NULL, $file_ext = NULL, $description = NULL)
 {
     if (!file_exists($original_file_path)) {
         return FALSE;
     }
     is_null($file_ext) && ($file_ext = strtolower(pathinfo($original_basename, PATHINFO_EXTENSION)));
     is_null($file_name) && ($file_name = mb_basename($original_basename, '.' . $file_ext));
     //支持中文的basename
     $size = filesize($original_file_path);
     if (!in_array($file_ext, $this->_config['ext'])) {
         return static::UPLOAD_ERR_EXT;
     }
     if ($size > $this->_config['maxsize']) {
         return static::UPLOAD_ERR_MAXSIZE;
     }
     if (empty($size)) {
         return static::UPLOAD_ERR_EMPTY;
     }
     //传文件都耗费了那么多时间,还怕md5?
     $hash = md5_file($original_file_path);
     $file = $this->fileModel->get_byhash($hash, $size);
     if (empty($file)) {
         $new_basename = $this->_get_hash_basename();
         $new_hash_path = $this->get_hash_path($new_basename);
         if (!$this->_save_file($original_file_path, $new_basename)) {
             return static::UPLOAD_ERR_SAVE;
         }
         $file = AttachmentFile::create(['basename' => $new_basename, 'path' => $new_hash_path, 'hash' => $hash, 'size' => $size]);
     } else {
         //已经存在此文件
         @unlink($original_file_path);
     }
     $attachment = $this->create(['afid' => $file->getKey(), 'filename' => $file_name, 'ext' => $file_ext, 'original_basename' => $original_basename, 'description' => $description, 'uid' => $uid]);
     //当前Model更新
     //$this->setRawAttributes($attachment->getAttributes(), true);
     return $this->get($attachment->getKey());
 }
Example #18
0
         // page refresh or a nice bar popup immediately with
         // something like "This page is out-of-date", and allow the
         // user to voluntarily delete their draft
         //
         // Delete drafts for all users for this canned response
         Draft::deleteForNamespace('canned.' . $canned->getId());
     } elseif (!$errors['err']) {
         $errors['err'] = 'Error updating canned response. Try again!';
     }
     break;
 case 'create':
     if ($id = Canned::create($_POST, $errors)) {
         $msg = 'Canned response added successfully';
         $_REQUEST['a'] = null;
         //Upload attachments
         if ($_FILES['attachments'] && ($c = Canned::lookup($id)) && ($files = AttachmentFile::format($_FILES['attachments']))) {
             $c->attachments->upload($files);
         }
         // Attach inline attachments from the editor
         if (isset($_POST['draft_id']) && ($draft = Draft::lookup($_POST['draft_id']))) {
             $c->attachments->upload($draft->getAttachmentIds($_POST['response']), true);
         }
         // Delete this user's drafts for new canned-responses
         Draft::deleteForNamespace('canned', $thisstaff->getId());
     } elseif (!$errors['err']) {
         $errors['err'] = 'Unable to add canned response. Correct error(s) below and try again.';
     }
     break;
 case 'mass_process':
     if (!$_POST['ids'] || !is_array($_POST['ids']) || !count($_POST['ids'])) {
         $errors['err'] = 'You must select at least one canned response';
Example #19
0
 public function removeLicense()
 {
     //delete all documents and associated expressions and SFX providers
     $document = new Document();
     foreach ($this->getDocuments() as $document) {
         //delete all expressions and expression notes
         $expression = new Expression();
         foreach ($document->getExpressions() as $expression) {
             $expressionNote = new ExpressionNote();
             foreach ($expression->getExpressionNotes() as $expressionNote) {
                 $expressionNote->delete();
             }
             $expression->removeQualifiers();
             $expression->delete();
         }
         $sfxProvider = new SFXProvider();
         foreach ($document->getSFXProviders() as $sfxProvider) {
             $sfxProvider->delete();
         }
         $signature = new Signature();
         foreach ($document->getSignatures() as $signature) {
             $signature->delete();
         }
         $document->delete();
     }
     //delete all attachments
     $attachment = new Attachment();
     foreach ($this->getAttachments() as $attachment) {
         $attachmentFile = new AttachmentFile();
         foreach ($attachment->getAttachmentFiles() as $attachmentFile) {
             $attachmentFile->delete();
         }
         $attachment->delete();
     }
     $this->delete();
 }
Example #20
0
 function run($args, $options)
 {
     Bootstrap::connect();
     osTicket::start();
     switch ($args['action']) {
         case 'backends':
             // List configured backends
             foreach (FileStorageBackend::allRegistered() as $char => $bk) {
                 print "{$char} -- {$bk::$desc} ({$bk})\n";
             }
             break;
         case 'list':
             // List files matching criteria
             // ORM would be nice!
             $files = FileModel::objects();
             $this->_applyCriteria($options, $files);
             foreach ($files as $f) {
                 printf("% 5d %s % 8d %s % 16s %s\n", $f->id, $f->bk, $f->size, $f->created, $f->type, $f->name);
                 if ($f->attrs) {
                     printf("        %s\n", $f->attrs);
                 }
             }
             break;
         case 'dump':
             $files = FileModel::objects();
             $this->_applyCriteria($options, $files);
             if ($files->count() != 1) {
                 $this->fail('Criteria must select exactly 1 file');
             }
             if (($f = AttachmentFile::lookup($files[0]->id)) && ($bk = $f->open())) {
                 $bk->passthru();
             }
             break;
         case 'load':
             // Load file content from STDIN
             $files = FileModel::objects();
             $this->_applyCriteria($options, $files);
             if ($files->count() != 1) {
                 $this->fail('Criteria must select exactly 1 file');
             }
             $f = AttachmentFile::lookup($files[0]->id);
             try {
                 if ($bk = $f->open()) {
                     $bk->unlink();
                 }
             } catch (Exception $e) {
             }
             if ($options['to']) {
                 $bk = FileStorageBackend::lookup($options['to'], $f);
             } else {
                 // Use the system default
                 $bk = AttachmentFile::getBackendForFile($f);
             }
             $type = false;
             $signature = '';
             $finfo = new finfo(FILEINFO_MIME_TYPE);
             if ($options['file'] && $options['file'] != '-') {
                 if (!file_exists($options['file'])) {
                     $this->fail($options['file'] . ': Cannot open file');
                 }
                 if (!$bk->upload($options['file'])) {
                     $this->fail('Unable to upload file contents to backend');
                 }
                 $type = $finfo->file($options['file']);
                 list(, $signature) = AttachmentFile::_getKeyAndHash($options['file'], true);
             } else {
                 $stream = fopen('php://stdin', 'rb');
                 while ($block = fread($stream, $bk->getBlockSize())) {
                     if (!$bk->write($block)) {
                         $this->fail('Unable to send file contents to backend');
                     }
                     if (!$type) {
                         $type = $finfo->buffer($block);
                     }
                 }
                 if (!$bk->flush()) {
                     $this->fail('Unable to commit file contents to backend');
                 }
             }
             // TODO: Update file metadata
             $sql = 'UPDATE ' . FILE_TABLE . ' SET bk=' . db_input($bk->getBkChar()) . ', created=CURRENT_TIMESTAMP' . ', type=' . db_input($type) . ', signature=' . db_input($signature) . ' WHERE id=' . db_input($f->getId());
             if (!db_query($sql) || db_affected_rows() != 1) {
                 $this->fail('Unable to update file metadata');
             }
             $this->stdout->write("Successfully saved contents\n");
             break;
         case 'migrate':
             if (!$options['to']) {
                 $this->fail('Please specify a target backend for migration');
             }
             if (!FileStorageBackend::isRegistered($options['to'])) {
                 $this->fail('Target backend is not installed. See `backends` action');
             }
             $files = FileModel::objects();
             $this->_applyCriteria($options, $files);
             $count = 0;
             foreach ($files as $m) {
                 $f = AttachmentFile::lookup($m->id);
                 if ($f->getBackend() == $options['to']) {
                     continue;
                 }
                 if ($options['verbose']) {
                     $this->stdout->write('Migrating ' . $m->name . "\n");
                 }
                 try {
                     if (!$f->migrate($options['to'])) {
                         $this->stderr->write('Unable to migrate ' . $m->name . "\n");
                     } else {
                         $count++;
                     }
                 } catch (IOException $e) {
                     $this->stderr->write('IOError: ' . $e->getMessage());
                 }
             }
             $this->stdout->write("Migrated {$count} files\n");
             break;
             /**
              * export
              *
              * Export file contents to a stream file. The format of the stream
              * will be a continuous stream of file information in the following
              * format:
              *
              * AFIL<meta-length><data-length><meta><data>EOF\x1c
              *
              * Where
              *   A              is the version code of the export
              *   "FIL"          is the literal text 'FIL'
              *   meta-length    is 'V' packed header length (bytes)
              *   data-length    is 'V' packed data length (bytes)
              *   meta           is the %file record, php serialized
              *   data           is the raw content of the file
              *   "EOF"          is the literal text 'EOF'
              *   \x1c           is an ASCII 0x1c byte (file separator)
              *
              * Options:
              * --file       File to which to direct the stream output, default
              *              is stdout
              */
         /**
          * export
          *
          * Export file contents to a stream file. The format of the stream
          * will be a continuous stream of file information in the following
          * format:
          *
          * AFIL<meta-length><data-length><meta><data>EOF\x1c
          *
          * Where
          *   A              is the version code of the export
          *   "FIL"          is the literal text 'FIL'
          *   meta-length    is 'V' packed header length (bytes)
          *   data-length    is 'V' packed data length (bytes)
          *   meta           is the %file record, php serialized
          *   data           is the raw content of the file
          *   "EOF"          is the literal text 'EOF'
          *   \x1c           is an ASCII 0x1c byte (file separator)
          *
          * Options:
          * --file       File to which to direct the stream output, default
          *              is stdout
          */
         case 'export':
             $files = FileModel::objects();
             $this->_applyCriteria($options, $files);
             if (!$options['file'] || $options['file'] == '-') {
                 $options['file'] = 'php://stdout';
             }
             if (!($stream = fopen($options['file'], 'wb'))) {
                 $this->fail($options['file'] . ': Unable to open file for export stream');
             }
             foreach ($files as $m) {
                 $f = AttachmentFile::lookup($m->id);
                 if ($options['verbose']) {
                     $this->stderr->write($m->name . "\n");
                 }
                 // TODO: Log %attachment and %ticket_attachment entries
                 $info = array('file' => $f->getInfo());
                 $header = serialize($info);
                 fwrite($stream, 'AFIL' . pack('VV', strlen($header), $f->getSize()));
                 fwrite($stream, $header);
                 $FS = $f->open();
                 while ($block = $FS->read()) {
                     fwrite($stream, $block);
                 }
                 fwrite($stream, "EOF");
             }
             fclose($stream);
             break;
             /**
              * import
              *
              * Import a collection of file contents exported by the `export`.
              * See the export function above for details about the stream
              * format.
              *
              * Options:
              * --file       File from which to read the export stream, default
              *              is stdin
              * --to         Backend to receive the contents (@see `backends`)
              * --verbose    Show file names while importing
              */
         /**
          * import
          *
          * Import a collection of file contents exported by the `export`.
          * See the export function above for details about the stream
          * format.
          *
          * Options:
          * --file       File from which to read the export stream, default
          *              is stdin
          * --to         Backend to receive the contents (@see `backends`)
          * --verbose    Show file names while importing
          */
         case 'import':
             if (!$options['file'] || $options['file'] == '-') {
                 $options['file'] = 'php://stdin';
             }
             if (!($stream = fopen($options['file'], 'rb'))) {
                 $this->fail($options['file'] . ': Unable to open import stream');
             }
             while (true) {
                 // Read the file header
                 // struct file_data_header {
                 //   char[4] marker; // Four chars, 'AFIL'
                 //   int     lenMeta;
                 //   int     lenData;
                 // };
                 if (!($header = fread($stream, 12))) {
                     break;
                 }
                 // EOF
                 list(, $mark, $hlen, $dlen) = unpack('V3', $header);
                 // AFIL written as little-endian 4-byte int is 0x4c4946xx (LIFA),
                 // where 'A' is the version code of the export
                 $version = $mark & 0xff;
                 if ($mark >> 8 != 0x4c4946) {
                     $this->fail('Bad file record');
                 }
                 // Read the header
                 $header = fread($stream, $hlen);
                 if (strlen($header) != $hlen) {
                     $this->fail('Short read getting header info');
                 }
                 $header = unserialize($header);
                 if (!$header) {
                     $this->fail('Unable to decipher file header');
                 }
                 // Find or create the file record
                 $finfo = $header['file'];
                 // TODO: Consider the $version code
                 $f = AttachmentFile::lookup($finfo['id']);
                 if ($f) {
                     // Verify file information
                     if ($f->getSize() != $finfo['size'] || $f->getSignature() != $finfo['signature']) {
                         $this->fail(sprintf('%s: File data does not match existing file record', $finfo['name']));
                     }
                     // Drop existing file contents, if any
                     try {
                         if ($bk = $f->open()) {
                             $bk->unlink();
                         }
                     } catch (Exception $e) {
                     }
                 } else {
                     $fm = FileModel::create($finfo);
                     if (!$fm->save() || !($f = AttachmentFile::lookup($fm->id))) {
                         $this->fail(sprintf('%s: Unable to create new file record', $finfo['name']));
                     }
                 }
                 // Determine the backend to recieve the file contents
                 if ($options['to']) {
                     $bk = FileStorageBackend::lookup($options['to'], $f);
                 } else {
                     $bk = AttachmentFile::getBackendForFile($f);
                 }
                 if ($options['verbose']) {
                     $this->stdout->write('Importing ' . $f->getName() . "\n");
                 }
                 // Write file contents to the backend
                 $md5 = hash_init('md5');
                 $sha1 = hash_init('sha1');
                 $written = 0;
                 // Handle exceptions by dropping imported file contents and
                 // then returning the error to the error output stream.
                 try {
                     while ($dlen > 0) {
                         $read_size = min($dlen, $bk->getBlockSize());
                         $contents = '';
                         // reading from the stream will likely return an amount of
                         // data different from the backend requested block size. Loop
                         // until $read_size bytes are recieved.
                         while ($read_size > 0 && ($block = fread($stream, $read_size))) {
                             $contents .= $block;
                             $read_size -= strlen($block);
                         }
                         if ($read_size != 0) {
                             // short read
                             throw new Exception(sprintf('%s: Some contents are missing from the stream', $f->getName()));
                         }
                         // Calculate MD5 and SHA1 hashes of the file to verify
                         // contents after successfully written to backend
                         if (!$bk->write($contents)) {
                             throw new Exception('Unable to send file contents to backend');
                         }
                         hash_update($md5, $contents);
                         hash_update($sha1, $contents);
                         $dlen -= strlen($contents);
                         $written += strlen($contents);
                     }
                     // Some backends cannot handle flush() without a
                     // corresponding write() call.
                     if ($written && !$bk->flush()) {
                         throw new Exception('Unable to commit file contents to backend');
                     }
                     // Check the signature hash
                     if ($finfo['signature']) {
                         $md5 = base64_encode(hash_final($md5, true));
                         $sha1 = base64_encode(hash_final($sha1, true));
                         $sig = str_replace(array('=', '+', '/'), array('', '-', '_'), substr($sha1, 0, 16) . substr($md5, 0, 16));
                         if ($sig != $finfo['signature']) {
                             throw new Exception(sprintf('%s: Signature verification failed', $f->getName()));
                         }
                     }
                     // Update file to record current backend
                     $sql = 'UPDATE ' . FILE_TABLE . ' SET bk=' . db_input($bk->getBkChar()) . ' WHERE id=' . db_input($f->getId());
                     if (!db_query($sql) || db_affected_rows() != 1) {
                         return false;
                     }
                 } catch (Exception $ex) {
                     if ($bk) {
                         $bk->unlink();
                     }
                     $this->fail($ex->getMessage());
                 }
                 // Read file record footer
                 $footer = fread($stream, 4);
                 if (strlen($footer) != 4) {
                     $this->fail('Unable to read file EOF marker');
                 }
                 list(, $footer) = unpack('N', $footer);
                 // Footer should be EOF\x1c as an int
                 if ($footer != 0x454f461c) {
                     $this->fail('Incorrect file EOF marker');
                 }
             }
             break;
         case 'zip':
             // Create a temporary ZIP file
             $files = FileModel::objects();
             $this->_applyCriteria($options, $files);
             if (!$options['file']) {
                 $this->fail('Please specify zip file with `-f`');
             }
             $zip = new ZipArchive();
             if (true !== ($reason = $zip->open($options['file'], ZipArchive::CREATE))) {
                 $this->fail($reason . ': Unable to create zip file');
             }
             foreach ($files as $m) {
                 $f = AttachmentFile::lookup($m->id);
                 if ($options['verbose']) {
                     $this->stderr->write($m->name . "\n");
                 }
                 $name = Format::encode(sprintf('%d-%s', $f->getId(), $f->getName()), 'utf-8', 'cp437');
                 $zip->addFromString($name, $f->getData());
             }
             $zip->close();
             break;
         case 'expunge':
             $files = FileModel::objects();
             $this->_applyCriteria($options, $files);
             foreach ($files as $m) {
                 // Drop associated attachment links
                 $m->tickets->expunge();
                 $f = AttachmentFile::lookup($m->id);
                 // Drop file contents
                 if ($bk = $f->open()) {
                     $bk->unlink();
                 }
                 // Drop file record
                 $f->delete();
             }
     }
 }
Example #21
0
 function updatePagesSettings($vars, &$errors)
 {
     global $ost;
     $f = array();
     $f['landing_page_id'] = array('type' => 'int', 'required' => 1, 'error' => 'required');
     $f['offline_page_id'] = array('type' => 'int', 'required' => 1, 'error' => 'required');
     $f['thank-you_page_id'] = array('type' => 'int', 'required' => 1, 'error' => 'required');
     if ($_FILES['logo']) {
         $error = false;
         list($logo) = AttachmentFile::format($_FILES['logo']);
         if (!$logo) {
         } elseif ($logo['error']) {
             $errors['logo'] = $logo['error'];
         } elseif (!($id = AttachmentFile::uploadLogo($logo, $error))) {
             $errors['logo'] = sprintf(__('Unable to upload logo image: %s'), $error);
         }
     }
     $company = $ost->company;
     $company_form = $company->getForm();
     $company_form->setSource($_POST);
     if (!$company_form->isValid()) {
         $errors += $company_form->errors();
     }
     if (!Validator::process($f, $vars, $errors) || $errors) {
         return false;
     }
     $company_form->save();
     if (isset($vars['delete-logo'])) {
         foreach ($vars['delete-logo'] as $id) {
             if ($vars['selected-logo'] != $id && ($f = AttachmentFile::lookup($id))) {
                 $f->delete();
             }
         }
     }
     return $this->updateAll(array('landing_page_id' => $vars['landing_page_id'], 'offline_page_id' => $vars['offline_page_id'], 'thank-you_page_id' => $vars['thank-you_page_id'], 'client_logo_id' => is_numeric($vars['selected-logo']) && $vars['selected-logo'] ? $vars['selected-logo'] : false, 'staff_logo_id' => is_numeric($vars['selected-logo-scp']) && $vars['selected-logo-scp'] ? $vars['selected-logo-scp'] : false));
 }
Example #22
0
 function add($vars, &$errors)
 {
     if (!($id = self::create($vars, $errors))) {
         return false;
     }
     if ($faq = self::lookup($id)) {
         $faq->updateTopics($vars['topics']);
         if ($_FILES['attachments'] && ($files = AttachmentFile::format($_FILES['attachments']))) {
             $faq->uploadAttachments($files);
         }
         $faq->reload();
     }
     return $faq;
 }
 function add($vars, &$errors)
 {
     if (!($id = self::create($vars, $errors))) {
         return false;
     }
     if ($faq = self::lookup($id)) {
         $faq->updateTopics($vars['topics']);
         if ($_FILES['attachments'] && ($files = AttachmentFile::format($_FILES['attachments']))) {
             $faq->attachments->upload($files);
         }
         // Inline images (attached to the draft)
         if (isset($vars['draft_id']) && $vars['draft_id']) {
             if ($draft = Draft::lookup($vars['draft_id'])) {
                 $faq->attachments->upload($draft->getAttachmentIds(), true);
             }
         }
         $faq->reload();
     }
     return $faq;
 }
Example #24
0
                             $errors['err'] = 'You do not have permission to delete tickets';
                         }
                         break;
                     default:
                         $errors['err'] = 'Unknown or unsupported action - get technical help';
                 }
             }
             break;
         case 'open':
             $ticket = null;
             if (!$thisstaff || !$thisstaff->canCreateTickets()) {
                 $errors['err'] = 'You do not have permission to create tickets. Contact admin for such access';
             } else {
                 $vars = $_POST;
                 if ($_FILES['attachments']) {
                     $vars['files'] = AttachmentFile::format($_FILES['attachments']);
                 }
                 if ($ticket = Ticket::open($vars, $errors)) {
                     $msg = 'Ticket created successfully';
                     $_REQUEST['a'] = null;
                     if (!$ticket->checkStaffAccess($thisstaff) || $ticket->isClosed()) {
                         $ticket = null;
                     }
                 } elseif (!$errors['err']) {
                     $errors['err'] = 'Unable to create the ticket. Correct the error(s) and try again';
                 }
             }
             break;
     }
 }
 if (!$errors) {
Example #25
0
 function CleanOrphanedFiles()
 {
     require_once INCLUDE_DIR . 'class.file.php';
     AttachmentFile::deleteOrphans();
 }
Example #26
0
 function allLogos()
 {
     $sql = 'SELECT id FROM ' . FILE_TABLE . ' WHERE ft="L"
         ORDER BY created';
     $logos = array();
     $res = db_query($sql);
     while (list($id) = db_fetch_row($res)) {
         $logos[] = AttachmentFile::lookup($id);
     }
     return $logos;
 }
Example #27
0
 function send($to, $subject, $message, $attachments = null, $options = null)
 {
     global $cfg;
     //Get SMTP info IF enabled!
     $smtp = array();
     if ($this->isSMTPEnabled() && ($info = $this->getSMTPInfo())) {
         //is SMTP enabled for the current email?
         $smtp = $info;
     } elseif ($cfg && ($email = $cfg->getDefaultSMTPEmail()) && $email->isSMTPEnabled()) {
         //What about global SMTP setting?
         if ($email->allowSpoofing() && ($info = $email->getSMTPInfo())) {
             //If spoofing is allowed..then continue.
             $smtp = $info;
         } elseif ($email->getId() != $this->getId()) {
             //No spoofing allowed. Send it via the default SMTP email.
             return $email->send($to, $subject, $message, $attachments, $options);
         }
     }
     //Get the goodies
     require_once 'Mail.php';
     // PEAR Mail package
     require_once 'Mail/mime.php';
     // PEAR Mail_Mime packge
     //do some cleanup
     $eol = "\n";
     $to = preg_replace("/(\r\n|\r|\n)/s", '', trim($to));
     $subject = stripslashes(preg_replace("/(\r\n|\r|\n)/s", '', trim($subject)));
     $body = stripslashes(preg_replace("/(\r\n|\r)/s", "\n", trim($message)));
     $fromname = $this->getName();
     $from = sprintf('"%s"<%s>', $fromname ? $fromname : $this->getEmail(), $this->getEmail());
     $headers = array('From' => $from, 'To' => $to, 'Subject' => $subject, 'Date' => date('D,d M Y H:i:s O'), 'Message-ID' => '<' . Misc::randCode(6) . '' . time() . '-' . $this->getEmail() . '>', 'X-Mailer' => 'osTicket v1.7', 'Content-Type' => 'text/html; charset="UTF-8"');
     $mime = new Mail_mime();
     $mime->setTXTBody($body);
     //XXX: Attachments
     if ($attachments) {
         foreach ($attachments as $attachment) {
             if ($attachment['file_id'] && ($file = AttachmentFile::lookup($attachment['file_id']))) {
                 $mime->addAttachment($file->getData(), $file->getType(), $file->getName(), false);
             } elseif ($attachment['file'] && file_exists($attachment['file']) && is_readable($attachment['file'])) {
                 $mime->addAttachment($attachment['file'], $attachment['type'], $attachment['name']);
             }
         }
     }
     $options = array('head_encoding' => 'quoted-printable', 'text_encoding' => 'quoted-printable', 'html_encoding' => 'base64', 'html_charset' => 'utf-8', 'text_charset' => 'utf-8');
     //encode the body
     $body = $mime->get($options);
     //encode the headers.
     $headers = $mime->headers($headers);
     if ($smtp) {
         //Send via SMTP
         $mail = mail::factory('smtp', array('host' => $smtp['host'], 'port' => $smtp['port'], 'auth' => $smtp['auth'] ? true : false, 'username' => $smtp['username'], 'password' => $smtp['password'], 'timeout' => 20, 'debug' => false));
         $result = $mail->send($to, $headers, $body);
         if (!PEAR::isError($result)) {
             return true;
         }
         $alert = sprintf("Unable to email via %s:%d [%s]\n\n%s\n", $smtp['host'], $smtp['port'], $smtp['username'], $result->getMessage());
         Sys::log(LOG_ALERT, 'SMTP Error', $alert, false);
         //print_r($result);
     }
     //No SMTP or it failed....use php's native mail function.
     $mail = mail::factory('mail');
     return PEAR::isError($mail->send($to, $headers, $body)) ? false : true;
 }
     break;
 case 'deleteAttachment':
     $attachment = new Attachment(new NamedArguments(array('primaryKey' => $_GET['attachmentID'])));
     //first delete attachments
     foreach ($attachment->getAttachmentFiles() as $attachmentFile) {
         $attachmentFile->delete();
     }
     try {
         $attachment->delete();
         echo "Attachment successfully deleted";
     } catch (Exception $e) {
         echo $e->getMessage();
     }
     break;
 case 'deleteAttachmentFile':
     $attachmentFile = new AttachmentFile(new NamedArguments(array('primaryKey' => $_GET['attachmentFileID'])));
     try {
         $attachmentFile->delete();
         echo "Attachment file successfully deleted";
     } catch (Exception $e) {
         echo $e->getMessage();
     }
     break;
     //updates license status when a new one is selected in dropdown box
 //updates license status when a new one is selected in dropdown box
 case 'updateStatus':
     $licenseID = $_GET['licenseID'];
     $statusID = $_GET['statusID'];
     $statusDate = date('Y-m-d H:i:s');
     //update license
     $license = new License(new NamedArguments(array('primaryKey' => $_GET['licenseID'])));
Example #29
0
<?php

/*********************************************************************
    file.php
    
    Simply downloads the file...on hash validation as follows;
    
    * Hash must be 64 chars long.
    * First 32 chars is the perm. file hash
    * Next 32 chars  is md5(file_id.session_id().file_hash)

    Peter Rotich <*****@*****.**>
    Copyright (c)  2006-2013 osTicket
    http://www.osticket.com

    Released under the GNU General Public License WITHOUT ANY WARRANTY.
    See LICENSE.TXT for details.

    vim: expandtab sw=4 ts=4 sts=4:
**********************************************************************/
require 'staff.inc.php';
require_once INCLUDE_DIR . 'class.file.php';
$h = trim($_GET['h']);
//basic checks
if (!$h || strlen($h) != 64 || !($file = AttachmentFile::lookup(substr($h, 0, 32))) || strcasecmp(substr($h, -32), md5($file->getId() . session_id() . $file->getHash()))) {
    //next 32 is file id + session hash.
    die('Unknown or invalid file. #' . Format::htmlchars($_GET['h']));
}
$file->download();
Example #30
0
<?php
/*********************************************************************
    file.php

    Simply downloads the file...on hash validation as follows;

    * Hash must be 64 chars long.
    * First 32 chars is the perm. file hash
    * Next 32 chars  is md5(file_id.session_id().file_hash)

    Peter Rotich <*****@*****.**>
    Copyright (c)  2006-2013 osTicket
    http://www.osticket.com

    Released under the GNU General Public License WITHOUT ANY WARRANTY.
    See LICENSE.TXT for details.

    vim: expandtab sw=4 ts=4 sts=4:
**********************************************************************/
require('staff.inc.php');
require_once(INCLUDE_DIR.'class.file.php');
$h=trim($_GET['h']);
//basic checks
if(!$h  || strlen($h)!=64  //32*2
        || !($file=AttachmentFile::lookup(substr($h,0,32))) //first 32 is the file hash.
        || strcasecmp($file->getDownloadHash(), $h)) //next 32 is file id + session hash.
    Http::response(404, __('Unknown or invalid file'));

$file->download();
?>