Skip to content
Snippets Groups Projects
Commit 7c0799ea authored by Jared Hancock's avatar Jared Hancock
Browse files

variables: Add variable validation to email templates

parent 1898a6d5
No related branches found
No related tags found
No related merge requests found
......@@ -13,9 +13,10 @@
vim: expandtab sw=4 ts=4 sts=4:
**********************************************************************/
if(!defined('INCLUDE_DIR')) die('!');
require_once INCLUDE_DIR.'class.ajax.php';
class ContentAjaxAPI extends AjaxController {
function log($id) {
......@@ -208,51 +209,10 @@ class ContentAjaxAPI extends AjaxController {
if (!$_GET['root'])
Http::response(400, '`root` is required parameter');
switch ($_GET['root']) {
case 'cannedresponse':
$roots = array('ticket');
break;
default:
if ($info = Page::getContext($_GET['root'])) {
$roots = $info;
break;
}
// Get the context for an email template
$tpl_info = EmailTemplateGroup::getTemplateDescription($_GET['root']);
if (!$tpl_info)
Http::response(422, 'No such context');
$roots = $tpl_info['context'];
}
$items = VariableReplacer::getContextForRoot($_GET['root']);
$contextTypes = array(
'activity' => __('Type of recent activity'),
'assignee' => array('class' => 'Staff', 'desc' => __('Assigned agent/team')),
'assigner' => array('class' => 'Staff', 'desc' => __('Agent performing the assignment')),
'comments' => __('Assign/transfer comments'),
'link' => __('Access link'),
'message' => array('class' => 'MessageThreadEntry', 'desc' => 'Message from the EndUser'),
'note' => array('class' => 'NoteThreadEntry', 'desc' => __('Internal note')),
'poster' => array('class' => 'User', 'desc' => 'EndUser or Agent originating the message'),
// XXX: This could be EndUser -or- Staff object
'recipient' => array('class' => 'TicketUser', 'desc' => 'Message recipient'),
'response' => array('class' => 'ResponseThreadEntry', 'desc' => __('Outgoing response')),
'signature' => 'Selected staff or department signature',
'staff' => array('class' => 'Staff', 'desc' => 'Agent originating the activity'),
'ticket' => array('class' => 'Ticket', 'desc' => 'The ticket'),
'user' => array('class' => 'User', 'desc' => __('Message recipient')),
);
$context = array();
foreach ($roots as $C=>$desc) {
// $desc may be either the root or the description array
if (is_array($desc))
$context[$C] = $desc;
else
$context[$desc] = $contextTypes[$desc];
}
$global = osTicket::getVarScope();
$items = VariableReplacer::compileScope($context + $global);
if (!$items)
Http::response(422, 'No such context');
header('Content-Type: application/json');
return $this->encode($items);
......
......@@ -508,6 +508,22 @@ class EmailTemplate {
return $this->getGroup()->getTemplateDescription($this->ht['code_name']);
}
function getInvalidVariableUsage() {
$context = VariableReplacer::getContextForRoot($this->ht['code_name']);
$invalid = array();
foreach (array($this->getSubject(), $this->getBody()) as $B) {
$variables = array();
if (!preg_match_all('`%\{([^}]*)\}`', $B, $variables, PREG_SET_ORDER))
continue;
foreach ($variables as $V) {
if (!isset($context[$V[1]])) {
$invalid[] = $V[0];
}
}
}
return $invalid;
}
function update($vars, &$errors) {
if(!$this->save($this->getId(),$vars,$errors))
......
......@@ -210,6 +210,55 @@ class VariableReplacer {
}
return $items;
}
static function getContextForRoot($root) {
switch ($root) {
case 'cannedresponse':
$roots = array('ticket');
break;
default:
if ($info = Page::getContext($root)) {
$roots = $info;
break;
}
// Get the context for an email template
if ($tpl_info = EmailTemplateGroup::getTemplateDescription($root))
$roots = $tpl_info['context'];
}
if (!$roots)
return false;
$contextTypes = array(
'activity' => __('Type of recent activity'),
'assignee' => array('class' => 'Staff', 'desc' => __('Assigned agent/team')),
'assigner' => array('class' => 'Staff', 'desc' => __('Agent performing the assignment')),
'comments' => __('Assign/transfer comments'),
'link' => __('Access link'),
'message' => array('class' => 'MessageThreadEntry', 'desc' => 'Message from the EndUser'),
'note' => array('class' => 'NoteThreadEntry', 'desc' => __('Internal note')),
'poster' => array('class' => 'User', 'desc' => 'EndUser or Agent originating the message'),
// XXX: This could be EndUser -or- Staff object
'recipient' => array('class' => 'TicketUser', 'desc' => 'Message recipient'),
'response' => array('class' => 'ResponseThreadEntry', 'desc' => __('Outgoing response')),
'signature' => 'Selected staff or department signature',
'staff' => array('class' => 'Staff', 'desc' => 'Agent originating the activity'),
'ticket' => array('class' => 'Ticket', 'desc' => 'The ticket'),
'user' => array('class' => 'User', 'desc' => __('Message recipient')),
);
$context = array();
foreach ($roots as $C=>$desc) {
// $desc may be either the root or the description array
if (is_array($desc))
$context[$C] = $desc;
else
$context[$desc] = $contextTypes[$desc];
}
$global = osTicket::getVarScope();
return self::compileScope($context + $global);
}
}
class PlaceholderList
......
......@@ -99,6 +99,19 @@ $tpl=$msgtemplates[$selected];
<?php } ?>
</div>
<?php
$invalid = array();
if ($template instanceof EmailTemplate) {
if ($invalid = $template->getInvalidVariableUsage()) {
$invalid = array_unique($invalid); ?>
<div class="warning-banner"><?php echo
__('Some variables may not be a valid for this context. Please check for spelling errors and correct usage for this template.') ?>
<br/>
<code><?php echo implode(', ', $invalid); ?></code>
</div>
<?php }
} ?>
<div style="padding-bottom:3px;" class="faded"><strong><?php echo __('Email Subject and Body'); ?>:</strong></div>
<div id="toolbar"></div>
<div id="save" style="padding-top:5px;">
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment