Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

thread: Allow edits to the attachments of thread entry #120

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions thread-action-attachments/plugin.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

return array(
'id' => 'thread-entry:attachments', # notrans
'version' => '0.1',
'name' => /* trans */ 'Attachment management plugin for thread entries',
'author' => 'Jared Hancock',
'description' => /* trans */ 'Allows administrators to add, remove, and rename attachments to thread entries',
'url' => 'http://www.osticket.com/plugins/thread-entry/attachments',
'plugin' => 'tea_attachments.php:TEA_AttachmentsPlugin'
);

?>
163 changes: 163 additions & 0 deletions thread-action-attachments/tea_attachments.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
<?php

class TEA_ManageAttachments
extends ThreadEntryAction {
static $id = 'manage_attachments';
static $name = /* trans */ 'Attachments ...';
static $icon = 'paperclip';

function isVisible() {
// Only thread entries with attachments should have this option
return count($this->entry->attachments);
}

function isEnabled() {
global $thisstaff;

// Only an administrator with access to the thread, or the owner of the
// thread item can perform this action
$T = $this->entry->getThread()->getObject();
return $T->checkStaffPerm($thisstaff)
&& ($thisstaff->isAdmin()
|| $thisstaff->staff_id == $this->entry->staff_id
);
}

function getJsStub() {
return sprintf(<<<JS
var url = '%s';
$.dialog(url, [201], function(xhr, resp) {
var json = JSON.parse(resp);
if (!json || !json.thread_id)
return;
$('#thread-entry-'+json.thread_id)
.html(json.entry)
.find('.thread-body')
.delay(500)
.effect('highlight');
});
JS
, $this->getAjaxUrl());
}

function trigger() {
switch ($_SERVER['REQUEST_METHOD']) {
case 'GET':
return $this->trigger__get();
case 'POST':
return $this->trigger__post();
}
}

protected function getNewAttachmentsForm() {
if (!isset($this->__form)) {
$this->__form = new SimpleForm(array(
'new_uploads' => new FileUploadField(array(
'id' => 'attach',
'name'=>'attach:thread-entry',
)),
), $_POST);
}
return $this->__form;
}

protected function trigger__get($errors=array()) {
global $cfg, $thisstaff;

$poster = $this->entry->getStaff();
$action = str_replace('ajax.php/','#', $this->getAjaxUrl());
$new_attachments = $this->getNewAttachmentsForm();

include 'templates/thread-entry-attachments.tmpl.php';
}

protected function trigger__post() {
global $thisstaff;

// Sanity check first
$errors = array('attachment' => array());
$attachments = array();
foreach ($_POST['attachment-id'] as $i=>$id) {
if (isset($_POST['attachment-keep'][$id])) {
if (!($name = trim($_POST['attachment-name'][$id]))) {
$errors['attachment'][$id]
= __('File name is required');
}
else {
$attachments[$id] = trim(Format::striptags(
$_POST['attachment-name'][$id]
));
}
}
}

// Add new attachments
$new_attachments = $this->getNewAttachmentsForm();
$clean = $new_attachments->getField('new_uploads')->getClean();
if ($clean) {
// XXX: Arrgh. ThreadEntry::normalizeFileInfo is protected...
$files = array();
foreach ($clean as $name=>$id) {
$file = AttachmentFile::lookup($id);
$files[] = array(
'id' => $id,
'key' => $file->key,
// ThreadEntry::createAttachment checks if name differs
'name' => $name,
'file' => $file,
'inline' => false,
);
}

if ($new = $this->entry->createAttachments($files)) {
// Keep these new ones
foreach ($new as $attach)
$attachments[$attach->id] = $attach->getFilename();
}
else {
$errors['attachment'][0] = true;
Messages::error(__('Unable to save new attachments'));
}
}

if ($errors['attachment']) {
return $this->trigger__get($errors);
}

foreach ($this->entry->attachments as $attach) {
$id = $attach->id;
if (!isset($attachments[$id])) {
$attach->delete();
}
elseif ($attach->getFilename() != $attachments[$id]) {
// If the file was renamed to be the same as the original file
// name, just remove the edited name
if ($attach->file->getName() == $attachments[$id]) {
$attach->name = null;
}
else {
$attach->name = $attachments[$id];
}
$attach->save();
}
}

// Re-render the thread entry with the new attachment info
$entry = $this->entry;
ob_start();
include STAFFINC_DIR . 'templates/thread-entry.tmpl.php';
$content = ob_get_clean();

Http::response('201', JsonDataEncoder::encode(array(
'thread_id' => $this->entry->id,
'entry' => $content,
)));
}
}

class TEA_AttachmentsPlugin
extends Plugin {
function bootstrap() {
ThreadEntry::registerAction(/* trans */ 'Manage', 'TEA_ManageAttachments');
}
}
25 changes: 25 additions & 0 deletions thread-action-attachments/templates/attachment.tmpl.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<div style="margin:0.5em">
<input type="hidden" name="attachment-id[]"
value="<?php echo $attach->id; ?>" class="-attachment-keep" />
<label class="checkbox">
<input class="checkbox" type="checkbox" checked="checked"
onchange="javascript:
var T=$(this).closest('div');
T.add(T.find('.-attachment-name'))
.toggleClass('strike', !$(this).prop('checked'))"
name="attachment-keep[<?php echo $attach->id; ?>]"
class="-attachment-keep" />
<input type="text" size="30" maxlength="255"
class="-attachment-name"
value="<?php echo Format::htmlchars($attach->getFilename()); ?>"
name="attachment-name[<?php echo $attach->id; ?>]" />
<?php echo Format::file_size($attach->file->size); ?>
<a class="pull-right" href="<?php echo Format::htmlchars($attach->file->getDownloadUrl()); ?>"
><?php echo __('Download'); ?></a>

</label>
<?php foreach (@$errors['attachment'][$attach->id] as $err) { ?>
<div class="error"><?php echo Format::htmlchars($err); ?></div>
<?php } ?>
</div>
<div class="clear"></div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<h3 class="drag-handle"><?php echo __("Thread Entry Attachments"); ?></h3>
<b><a class="close" href="#"><i class="icon-remove-circle"></i></a></b>
<div class="clear"></div>
<hr />

<div style="margin:1em"><?php echo __(
"Uncheck attachments to remove them. Change the filename to rename the file for its attachment to this thread entry."); ?>
</div>

<?php
foreach (Messages::getMessages() as $M) { ?>
<div class="<?php echo strtolower($M->getLevel()); ?>-banner"><?php
echo (string) $M; ?></div>
<?php } ?>

<form method="post" action="<?php echo $action; ?>">
<div style="margin:1em 2em">
<?php foreach ($this->entry->getAttachments() as $attach) {
include 'attachment.tmpl.php';
}
?>
</div>

<div style="margin:1em 1em 0">
<?php
echo $new_attachments->asTable();
?>
</div>

<hr />
<p class="full-width">
<span class="buttons pull-left">
<input type="reset" value="<?php echo __('Reset'); ?>" />
<input type="button" name="cancel" class="close"
value="<?php echo __('Cancel'); ?>">
</span>
<span class="buttons pull-right">
<input type="submit" class="red button" value="<?php
echo $verb ?: __('Update'); ?>">
</span>
</p>
</form>
<div class="clear"></div>