Helpdesk da PluGzOne, baseado no osTicket
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

195 lines
6.3 KiB

<?php
/**
* Class: Draft
*
* Defines a simple draft-saving mechanism for osTicket which supports draft
* fetch and update via an ajax mechanism (include/ajax.draft.php).
*
* Fields:
* id - (int:auto:pk) Draft ID number
* body - (text) Body of the draft
* namespace - (string) Identifier of draft grouping — useful for multiple
* drafts on the same document by different users
* staff_id - (int:null) Staff owner of the draft
* extra - (text:json) Extra attributes of the draft
* created - (date) Date draft was initially created
* updated - (date:null) Date draft was last updated
*/
class Draft extends VerySimpleModel {
static $meta = array(
'table' => DRAFT_TABLE,
'pk' => array('id'),
'joins' => array(
'attachments' => array(
'constraint' => array(
"'D'" => 'Attachment.type',
'id' => 'Attachment.object_id',
),
'list' => true,
'null' => true,
'broker' => 'GenericAttachments',
),
),
);
function getId() { return $this->id; }
function getBody() { return $this->body; }
function getStaffId() { return $this->staff_id; }
function getNamespace() { return $this->namespace; }
static protected function getCurrentUserId() {
global $thisstaff, $thisclient;
$user = $thisstaff ?: $thisclient;
if ($user)
return $user->getId();
return 1 << 31;
}
static function getDraftAndDataAttrs($namespace, $id=0, $original='') {
$draft_body = null;
$attrs = array(sprintf('data-draft-namespace="%s"', Format::htmlchars($namespace)));
$criteria = array(
'namespace' => $namespace,
'staff_id' => self::getCurrentUserId(),
);
if ($id) {
$attrs[] = sprintf('data-draft-object-id="%s"', Format::htmlchars($id));
$criteria['namespace'] .= '.' . $id;
}
if ($draft = static::objects()->filter($criteria)->first()) {
$attrs[] = sprintf('data-draft-id="%s"', $draft->getId());
$draft_body = $draft->getBody();
}
$attrs[] = sprintf('data-draft-original="%s"',
Format::htmlchars(Format::viewableImages($original)));
return array(Format::htmlchars(Format::viewableImages($draft_body)),
implode(' ', $attrs));
}
function getAttachmentIds($body=false) {
$attachments = array();
if (!$body)
$body = $this->getBody();
$body = Format::localizeInlineImages($body);
$matches = array();
if (preg_match_all('/"cid:([\\w.-]{32})"/', $body, $matches)) {
$files = AttachmentFile::objects()
->filter(array('key__in' => $matches[1]));
foreach ($files as $F) {
$attachments[] = array(
'id' => $F->getId(),
'inline' => true
);
}
}
return $attachments;
}
/*
* Ensures that the inline attachments cited in the body of this draft
* are also listed in the draft_attachment table. After calling this,
* the ::getAttachments() function should correctly return all inline
* attachments. This function should be called after creating a draft
* with an existing body
*/
function syncExistingAttachments() {
$matches = array();
if (!preg_match_all('/"cid:([\\w.-]{32})"/', $this->getBody(), $matches))
return;
// Purge current attachments
$this->attachments->deleteInlines();
foreach (AttachmentFile::objects()
->filter(array('key__in' => $matches[1]))
as $F
) {
$this->attachments->upload($F->getId(), true);
}
}
function setBody($body) {
// Change file.php urls back to content-id's
$body = Format::sanitize($body, false,
// Preserve annotation information, if any
'img=data-annotations,data-orig-annotated-image-src');
$this->body = $body ?: ' ';
$this->updated = SqlFunction::NOW();
return $this->save();
}
function delete() {
$this->attachments->deleteAll();
return parent::delete();
}
function isValid() {
// Required fields
return $this->namespace && isset($this->staff_id);
}
function save($refetch=false) {
if (!$this->isValid())
return false;
return parent::save($refetch);
}
static function create($vars=false) {
$attachments = @$vars['attachments'];
unset($vars['attachments']);
$vars['created'] = SqlFunction::NOW();
$vars['staff_id'] = self::getCurrentUserId();
$draft = new static($vars);
// Cloned attachments ...
if (false && $attachments && is_array($attachments))
// XXX: This won't work until the draft is saved
$draft->attachments->upload($attachments, true);
return $draft;
}
static function lookupByNamespaceAndStaff($namespace, $staff_id) {
return static::lookup(array(
'namespace'=>$namespace,
'staff_id'=>$staff_id
));
}
/**
* Delete drafts saved for a particular namespace. If the staff_id is
* specified, only drafts owned by that staff are deleted. Usually, if
* closing a ticket, the staff_id should be left null so that all drafts
* are cleaned up.
*/
static function deleteForNamespace($namespace, $staff_id=false) {
$attachments = Attachment::objects()
->filter(array('draft__namespace__startswith' => $namespace));
if ($staff_id)
$attachments->filter(array('draft__staff_id' => $staff_id));
$attachments->delete();
$criteria = array('namespace__like'=>$namespace);
if ($staff_id)
$criteria['staff_id'] = $staff_id;
return static::objects()->filter($criteria)->delete();
}
static function cleanup() {
// Keep drafts for two weeks (14 days)
$sql = 'DELETE FROM '.DRAFT_TABLE
." WHERE (updated IS NULL AND datediff(now(), created) > 14)
OR datediff(now(), updated) > 14";
return db_query($sql);
}
}
?>