Thomas Bruederli
2013-09-19 84ffd59c0c3ff78bca5fbcd2c8893b741f36c9ba
Allow sysadmins to define static responses which are immutable for the user
9 files modified
63 ■■■■ changed files
config/main.inc.php.dist 6 ●●●●● patch | view | raw | blame | history
program/include/rcmail.php 15 ●●●●● patch | view | raw | blame | history
program/js/app.js 2 ●●● patch | view | raw | blame | history
program/steps/settings/edit_response.inc 19 ●●●● patch | view | raw | blame | history
program/steps/settings/responses.inc 8 ●●●●● patch | view | raw | blame | history
skins/classic/settings.css 5 ●●●●● patch | view | raw | blame | history
skins/classic/templates/responseedit.html 2 ●●● patch | view | raw | blame | history
skins/larry/settings.css 4 ●●●● patch | view | raw | blame | history
skins/larry/templates/responseedit.html 2 ●●● patch | view | raw | blame | history
config/main.inc.php.dist
@@ -406,6 +406,12 @@
// Note: useful when SMTP server stores sent mail in user mailbox
$rcmail_config['no_save_sent_messages'] = false;
// A static list of canned responses which are immutable for the user
$rcmail_config['compose_responses_static'] = array(
//  array('name' => 'Canned Response 1', 'text' => 'Static Response One'),
//  array('name' => 'Canned Response 2', 'text' => 'Static Response Two'),
);
// ----------------------------------
// PLUGINS
// ----------------------------------
program/include/rcmail.php
@@ -346,11 +346,24 @@
   * These are stored in local config and user preferences.
   *
   * @param boolean True to sort the list alphabetically
   * @param boolean True if only this user's responses shall be listed
   * @return array List of the current user's stored responses
   */
  public function get_compose_responses($sorted = false)
  public function get_compose_responses($sorted = false, $user_only = false)
  {
    $responses = array();
    if (!$user_only) {
      foreach ($this->config->get('compose_responses_static', array()) as $response) {
        if (empty($response['key']))
          $response['key'] = substr(md5($response['name']), 0, 16);
        $response['static'] = true;
        $response['class'] = 'readonly';
        $k = $sorted ? '0000-' . strtolower($response['name']) : $response['key'];
        $responses[$k] = $response;
      }
    }
    foreach ($this->config->get('compose_responses', array()) as $response) {
      if (empty($response['key']))
        $response['key'] = substr(md5($response['name']), 0, 16);
program/js/app.js
@@ -440,7 +440,7 @@
          this.responses_list = new rcube_list_widget(this.gui_objects.responseslist, {multiselect:false, draggable:false, keyboard:false});
          this.responses_list.addEventListener('select', function(list){
            var win, id = list.get_single_selection();
            p.enable_command('delete', !!id);
            p.enable_command('delete', !!id && $.inArray(id, p.env.readonly_responses) < 0);
            if (id && (win = p.get_frame_window(p.env.contentframe))) {
              p.set_busy(true);
              p.location_href({ _action:'edit-response', _key:id, _framed:1 }, win);
program/steps/settings/edit_response.inc
@@ -24,8 +24,6 @@
// edit-response
if (($key = get_input_value('_key', RCUBE_INPUT_GPC))) {
    foreach ($responses as $i => $response) {
        if (empty($response['key']))
            $response['key'] = substr(md5($response['name']), 0, 16);
        if ($response['key'] == $key) {
            $RESPONSE_RECORD = $response;
            $RESPONSE_RECORD['index'] = $i;
@@ -35,12 +33,9 @@
}
// save response
if ($RCMAIL->action == 'save-response' && isset($_POST['_name'])) {
if ($RCMAIL->action == 'save-response' && isset($_POST['_name']) && !$RESPONSE_RECORD['static']) {
    $name = trim(get_input_value('_name', RCUBE_INPUT_POST));
    $text = trim(get_input_value('_text', RCUBE_INPUT_POST));
    if (!empty($_REQUEST['_framed']))
        $RCMAIL->output->framed = 1;
    if (!empty($name) && !empty($text)) {
        $dupes = 0;
@@ -62,9 +57,11 @@
            $responses[] = $response;
        }
        if ($RCMAIL->user->save_prefs(array('compose_responses' => $responses))) {
        $responses = array_filter($responses, function($item){ return empty($item['static']); });
        if ($RCMAIL->user->save_prefs(array('compose_responses' => array_values($responses)))) {
            $RCMAIL->output->show_message('successfullysaved', 'confirmation');
            $RCMAIL->output->command('update_response_row', $response, $key);
            $RCMAIL->output->command('parent.update_response_row', $response, $key);
            $RCMAIL->overwrite_action('edit-response');
            $RESPONSE_RECORD = $response;
        }
    }
@@ -79,6 +76,7 @@
    global $RCMAIL, $OUTPUT, $RESPONSE_RECORD;
    // Set form tags and hidden fields
    $disabled = !empty($RESPONSE_RECORD['static']);
    $key = $RESPONSE_RECORD['key'];
    list($form_start, $form_end) = get_form_tags($attrib, 'save-response', $key, array('name' => '_key', 'value' => $key));
    unset($attrib['form'], $attrib['id']);
@@ -90,10 +88,10 @@
    $label = rcube_label('responsename');
    $table->add('title', html::label('ffname', Q(rcube_label('responsename'))));
    $table->add(null, rcube_output::get_edit_field('name', $RESPONSE_RECORD['name'], array('id' => 'ffname', 'size' => $attrib['size']), 'text'));
    $table->add(null, rcube_output::get_edit_field('name', $RESPONSE_RECORD['name'], array('id' => 'ffname', 'size' => $attrib['size'], 'disabled' => $disabled), 'text'));
    $table->add('title', html::label('fftext', Q(rcube_label('responsetext'))));
    $table->add(null, rcube_output::get_edit_field('text', $RESPONSE_RECORD['text'], array('id' => 'fftext', 'size' => $attrib['textareacols'], 'rows' => $attrib['textarearows']), 'textarea'));
    $table->add(null, rcube_output::get_edit_field('text', $RESPONSE_RECORD['text'], array('id' => 'fftext', 'size' => $attrib['textareacols'], 'rows' => $attrib['textarearows'], 'disabled' => $disabled), 'textarea'));
    $out .= $table->show($attrib);
    $out .= $form_end;
@@ -101,6 +99,7 @@
    return $out;
}
$OUTPUT->set_env('readonly', !empty($RESPONSE_RECORD['static']));
$OUTPUT->add_handler('responseform', 'rcube_response_form');
$OUTPUT->set_pagetitle(rcube_label(($RCMAIL->action=='add-response' ? 'savenewresponse' : 'editresponse')));
program/steps/settings/responses.inc
@@ -26,7 +26,7 @@
    if (!empty($name) && !empty($text)) {
        $dupes = 0;
        $responses = $RCMAIL->get_compose_responses();
        $responses = $RCMAIL->get_compose_responses(false, true);
        foreach ($responses as $resp) {
            if (strcasecmp($name, preg_replace('/\s\(\d+\)$/', '', $resp['name'])) == 0)
                $dupes++;
@@ -54,7 +54,7 @@
if ($RCMAIL->action == 'delete-response') {
    if ($key = get_input_value('_key', RCUBE_INPUT_GPC)) {
        $responses = $RCMAIL->get_compose_responses();
        $responses = $RCMAIL->get_compose_responses(false, true);
        foreach ($responses as $i => $response) {
            if (empty($response['key']))
                $response['key'] = substr(md5($response['name']), 0, 16);
@@ -67,7 +67,7 @@
    }
    if ($deleted) {
        $RCMAIL->output->command('display_message', rcube_label('successfullydeleted'), 'confirmation');
        $RCMAIL->output->command('display_message', rcube_label('deletedsuccessfully'), 'confirmation');
        $RCMAIL->output->command('remove_response', $key);
    }
@@ -99,6 +99,8 @@
    // set client env
    $OUTPUT->add_gui_object('responseslist', $attrib['id']);
    $OUTPUT->set_env('readonly_responses', array_values(array_map(function($rec){ return $rec['key']; },
      array_filter($plugin['list'], function($item){ return !empty($item['static']); }))));
    return $out;
}
skins/classic/settings.css
@@ -34,6 +34,11 @@
  height: 18px;
}
#identities-table tbody tr.readonly td
{
  font-style: italic;
}
#subscription-table tr.virtual td
{
  color: #666;
skins/classic/templates/responseedit.html
@@ -15,7 +15,7 @@
  <div id="formfooter">
    <div class="footerindent">
      <roundcube:button command="save" type="input" class="button mainaction" label="save" />
      <roundcube:button command="save" type="input" class="button mainaction" label="save" condition="!env:readonly" />
    </div>
  </div>
</div>
skins/larry/settings.css
@@ -194,6 +194,10 @@
    text-overflow: ellipsis;
}
#identities-table tbody tr.readonly td {
    font-style: italic;
}
#folder-details,
#identity-details {
    position: absolute;
skins/larry/templates/responseedit.html
@@ -13,7 +13,7 @@
</div>
<div class="footerleft formbuttons">
    <roundcube:button command="save" type="input" class="button mainaction" label="save" />
    <roundcube:button command="save" type="input" class="button mainaction" label="save" condition="!env:readonly" />
</div>
<roundcube:include file="/includes/footer.html" />