Merged branch devel-addressbook from r443 back to trunk
parent
9e5d051e97
commit
f1154163b0
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
require_once('../program/lib/html2text.inc');
|
||||
|
||||
$htmlText = $HTTP_RAW_POST_DATA;
|
||||
$converter = new html2text($htmlText);
|
||||
|
||||
header('Content-Type: text/plain; charset=UTF-8');
|
||||
$plaintext = $converter->get_text();
|
||||
|
||||
if (function_exists('html_entity_decode'))
|
||||
print html_entity_decode($plaintext, ENT_COMPAT, 'UTF-8');
|
||||
else
|
||||
print $plaintext;
|
||||
|
||||
?>
|
@ -0,0 +1,631 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
+-----------------------------------------------------------------------+
|
||||
| program/include/rcmail_template.inc |
|
||||
| |
|
||||
| This file is part of the RoundCube Webmail client |
|
||||
| Copyright (C) 2007, RoundCube Dev. - Switzerland |
|
||||
| Licensed under the GNU GPL |
|
||||
| |
|
||||
| PURPOSE: |
|
||||
| Class to handle HTML page output using a skin template. |
|
||||
| Extends rcube_html_page class from rcube_shared.inc |
|
||||
| |
|
||||
+-----------------------------------------------------------------------+
|
||||
| Author: Thomas Bruederli <roundcube@gmail.com> |
|
||||
+-----------------------------------------------------------------------+
|
||||
|
||||
$Id: $
|
||||
|
||||
*/
|
||||
|
||||
require_once('include/rcube_shared.inc');
|
||||
|
||||
|
||||
class rcmail_template extends rcube_html_page
|
||||
{
|
||||
var $config;
|
||||
var $task = '';
|
||||
var $framed = false;
|
||||
var $ajax_call = false;
|
||||
var $pagetitle = '';
|
||||
var $env = array();
|
||||
var $js_env = array();
|
||||
var $js_commands = array();
|
||||
var $object_handlers = array();
|
||||
|
||||
|
||||
// PHP 5 constructor
|
||||
function __construct(&$config, $task)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->task = $task;
|
||||
$this->config = $config;
|
||||
$this->ajax_call = !empty($_GET['_remote']) || !empty($_POST['_remote']);
|
||||
|
||||
// add common javascripts
|
||||
if (!$this->ajax_call)
|
||||
{
|
||||
$javascript = "var ".JS_OBJECT_NAME." = new rcube_webmail();";
|
||||
|
||||
// don't wait for page onload. Call init at the bottom of the page (delayed)
|
||||
$javascript_foot = "if (window.call_init)\n call_init('".JS_OBJECT_NAME."');";
|
||||
|
||||
$this->add_script($javascript, 'head_top');
|
||||
$this->add_script($javascript_foot, 'foot');
|
||||
$this->scripts_path = 'program/js/';
|
||||
$this->include_script('common.js');
|
||||
$this->include_script('app.js');
|
||||
}
|
||||
}
|
||||
|
||||
// PHP 4 compatibility
|
||||
function rcmail_template(&$config, $task)
|
||||
{
|
||||
$this->__construct($config, $task);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set environment variable
|
||||
*/
|
||||
function set_env($name, $value, $addtojs=true)
|
||||
{
|
||||
$this->env[$name] = $value;
|
||||
if ($addtojs || isset($this->js_env[$name]))
|
||||
$this->js_env[$name] = $value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set page title variable
|
||||
*/
|
||||
function set_pagetitle($title)
|
||||
{
|
||||
$this->pagetitle = $title;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Register a template object handler
|
||||
*
|
||||
* @param string Object name
|
||||
* @param string Function name to call
|
||||
*/
|
||||
function add_handler($obj, $func)
|
||||
{
|
||||
$this->object_handlers[$obj] = $func;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a list of template object handlers
|
||||
*
|
||||
* @param array Hash array with object=>handler pairs
|
||||
*/
|
||||
function add_handlers($arr)
|
||||
{
|
||||
$this->object_handlers = array_merge($this->object_handlers, $arr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a GUI object to the client script
|
||||
*
|
||||
* @param string Object name
|
||||
* @param string Object ID
|
||||
*/
|
||||
function add_gui_object($obj, $id)
|
||||
{
|
||||
$this->add_script(JS_OBJECT_NAME.".gui_object('$obj', '$id');");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Call a client method
|
||||
*
|
||||
* @param string Method to call
|
||||
* @param ... Additional arguments
|
||||
*/
|
||||
function command()
|
||||
{
|
||||
$this->js_commands[] = func_get_args();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Invoke display_message command
|
||||
*/
|
||||
function show_message($message, $type='notice', $vars=NULL)
|
||||
{
|
||||
$this->command(
|
||||
'display_message',
|
||||
rcube_label(array('name' => $message, 'vars' => $vars)),
|
||||
$type);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Delete all stored env variables and commands
|
||||
*/
|
||||
function reset()
|
||||
{
|
||||
$this->env = array();
|
||||
$this->js_env = array();
|
||||
$this->js_commands = array();
|
||||
$this->object_handlers = array();
|
||||
parent::reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the request output to the client.
|
||||
* This will either parse a skin tempalte or send an AJAX response
|
||||
*
|
||||
* @param string Template name
|
||||
* @param boolean True if script should terminate (default)
|
||||
*/
|
||||
function send($templ=null, $exit=true)
|
||||
{
|
||||
if ($this->ajax_call)
|
||||
$this->remote_response('', !$exit);
|
||||
else if ($templ != 'iframe')
|
||||
$this->parse($templ, false);
|
||||
else
|
||||
{
|
||||
$this->framed = $templ == 'iframe' ? true : $this->framed;
|
||||
$this->write();
|
||||
}
|
||||
|
||||
if ($exit)
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Send an AJAX response with executable JS code
|
||||
*
|
||||
* @param string Additional JS code
|
||||
* @param boolean True if output buffer should be flushed
|
||||
*/
|
||||
function remote_response($add='', $flush=false)
|
||||
{
|
||||
static $s_header_sent = FALSE;
|
||||
|
||||
if (!$s_header_sent)
|
||||
{
|
||||
$s_header_sent = TRUE;
|
||||
send_nocacheing_headers();
|
||||
header('Content-Type: application/x-javascript; charset='.RCMAIL_CHARSET);
|
||||
print '/** ajax response ['.date('d/M/Y h:i:s O')."] **/\n";
|
||||
}
|
||||
|
||||
// unset default env vars
|
||||
unset($this->js_env['task'], $this->js_env['action'], $this->js_env['comm_path']);
|
||||
|
||||
// send response code
|
||||
print rcube_charset_convert($this->get_js_commands() . $add, RCMAIL_CHARSET, $this->get_charset());
|
||||
|
||||
if ($flush) // flush the output buffer
|
||||
flush();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
function write($template='')
|
||||
{
|
||||
// write all env variables to client
|
||||
$js = $this->framed ? "if(window.parent) {\n" : '';
|
||||
$js .= $this->get_js_commands() . ($this->framed ? ' }' : '');
|
||||
$this->add_script($js, 'head_top');
|
||||
|
||||
// call super method
|
||||
parent::write($template, $this->config['skin_path']);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse a specific skin template and deliver to stdout
|
||||
*
|
||||
* @param string Template name
|
||||
* @param boolean Exit script
|
||||
*/
|
||||
function parse($name='main', $exit=true)
|
||||
{
|
||||
$skin_path = $this->config['skin_path'];
|
||||
|
||||
// read template file
|
||||
$templ = '';
|
||||
$path = "$skin_path/templates/$name.html";
|
||||
|
||||
if($fp = @fopen($path, 'r'))
|
||||
{
|
||||
$templ = fread($fp, filesize($path));
|
||||
fclose($fp);
|
||||
}
|
||||
else
|
||||
{
|
||||
raise_error(array(
|
||||
'code' => 501,
|
||||
'type' => 'php',
|
||||
'line' => __LINE__,
|
||||
'file' => __FILE__,
|
||||
'message' => "Error loading template for '$name'"), TRUE, TRUE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// parse for specialtags
|
||||
$output = $this->parse_xml($this->parse_conditions($templ));
|
||||
|
||||
// add debug console
|
||||
if ($this->config['debug_level'] & 8)
|
||||
$this->add_footer('<div style="position:absolute;top:5px;left:5px;width:400px;padding:0.2em;background:white;opacity:0.8;z-index:9000">
|
||||
<a href="#toggle" onclick="con=document.getElementById(\'dbgconsole\');con.style.display=(con.style.display==\'none\'?\'block\':\'none\');return false">console</a>
|
||||
<form action="/" name="debugform"><textarea name="console" id="dbgconsole" rows="20" cols="40" wrap="off" style="display:none;width:400px;border:none;font-size:x-small"></textarea></form></div>');
|
||||
|
||||
$this->write(trim($this->parse_with_globals($output)), $skin_path);
|
||||
|
||||
if ($exit)
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return executable javascript code for all registered commands
|
||||
* @private
|
||||
*/
|
||||
function get_js_commands()
|
||||
{
|
||||
$out = '';
|
||||
if (!$this->framed)
|
||||
$out .= ($this->ajax_call ? 'this' : JS_OBJECT_NAME) . '.set_env('.json_serialize($this->js_env).");\n";
|
||||
|
||||
foreach ($this->js_commands as $i => $args)
|
||||
{
|
||||
$method = array_shift($args);
|
||||
foreach ($args as $i => $arg)
|
||||
$args[$i] = json_serialize($arg);
|
||||
|
||||
$parent = $this->framed || preg_match('/^parent\./', $method);
|
||||
$out .= sprintf(
|
||||
"%s.%s(%s);\n",
|
||||
$this->ajax_call ? 'this' : ($parent ? 'parent.' : '') . JS_OBJECT_NAME,
|
||||
preg_replace('/^parent\./', '', $method),
|
||||
join(',', $args));
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make URLs starting with a slash point to skin directory
|
||||
*/
|
||||
function abs_url($str)
|
||||
{
|
||||
return preg_replace('/^\//', $this->config['skin_path'].'/', $str);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***** Template parsing methods *****/
|
||||
|
||||
/**
|
||||
* Replace all strings ($varname) with the content
|
||||
* of the according global variable.
|
||||
*/
|
||||
function parse_with_globals($input)
|
||||
{
|
||||
$GLOBALS['__comm_path'] = $GLOBALS['COMM_PATH'];
|
||||
return preg_replace('/\$(__[a-z0-9_\-]+)/e', '$GLOBALS["\\1"]', $input);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse for conditional tags
|
||||
*/
|
||||
function parse_conditions($input)
|
||||
{
|
||||
if (($matches = preg_split('/<roundcube:(if|elseif|else|endif)\s+([^>]+)>/is', $input, 2, PREG_SPLIT_DELIM_CAPTURE)) && count($matches)==4)
|
||||
{
|
||||
if (preg_match('/^(else|endif)$/i', $matches[1]))
|
||||
return $matches[0] . $this->parse_conditions($matches[3]);
|
||||
else
|
||||
{
|
||||
$attrib = parse_attrib_string($matches[2]);
|
||||
if (isset($attrib['condition']))
|
||||
{
|
||||
$condmet = $this->check_condition($attrib['condition']);
|
||||
$submatches = preg_split('/<roundcube:(elseif|else|endif)\s+([^>]+)>/is', $matches[3], 2, PREG_SPLIT_DELIM_CAPTURE);
|
||||
|
||||
if ($condmet)
|
||||
$result = $submatches[0] . preg_replace('/.*<roundcube:endif\s+[^>]+>/is', '', $submatches[3]);
|
||||
else
|
||||
$result = "<roundcube:$submatches[1] $submatches[2]>" . $submatches[3];
|
||||
|
||||
return $matches[0] . $this->parse_conditions($result);
|
||||
}
|
||||
else
|
||||
{
|
||||
raise_error(array('code' => 500, 'type' => 'php', 'line' => __LINE__, 'file' => __FILE__,
|
||||
'message' => "Unable to parse conditional tag " . $matches[2]), TRUE, FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $input;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Determines if a given condition is met
|
||||
*
|
||||
* @return True if condition is valid, False is not
|
||||
*/
|
||||
function check_condition($condition)
|
||||
{
|
||||
$condition = preg_replace(
|
||||
array('/session:([a-z0-9_]+)/i', '/config:([a-z0-9_]+)/i', '/env:([a-z0-9_]+)/i', '/request:([a-z0-9_]+)/ie'),
|
||||
array("\$_SESSION['\\1']", "\$this->config['\\1']", "\$this->env['\\1']", "get_input_value('\\1', RCUBE_INPUT_GPC)"),
|
||||
$condition);
|
||||
|
||||
return @eval("return (".$condition.");");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Search for special tags in input and replace them
|
||||
* with the appropriate content
|
||||
*
|
||||
* @param string Input string to parse
|
||||
* @return Altered input string
|
||||
*/
|
||||
function parse_xml($input)
|
||||
{
|
||||
return preg_replace('/<roundcube:([-_a-z]+)\s+([^>]+)>/Uie', "\$this->xml_command('\\1', '\\2')", $input);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert a xml command tag into real content
|
||||
*
|
||||
* @param string Tag command: object,button,label, etc.
|
||||
* @param string Attribute string
|
||||
* @return Tag/Object content string
|
||||
*/
|
||||
function xml_command($command, $str_attrib, $add_attrib=array())
|
||||
{
|
||||
$command = strtolower($command);
|
||||
$attrib = parse_attrib_string($str_attrib) + $add_attrib;
|
||||
|
||||
// empty output if required condition is not met
|
||||
if (!empty($attrib['condition']) && !$this->check_condition($attrib['condition']))
|
||||
return '';
|
||||
|
||||
// execute command
|
||||
switch ($command)
|
||||
{
|
||||
// return a button
|
||||
case 'button':
|
||||
if ($attrib['command'])
|
||||
return $this->button($attrib);
|
||||
break;
|
||||
|
||||
// show a label
|
||||
case 'label':
|
||||
if ($attrib['name'] || $attrib['command'])
|
||||
return Q(rcube_label($attrib + array('vars' => array('product' => $this->config['product_name']))));
|
||||
break;
|
||||
|
||||
// include a file
|
||||
case 'include':
|
||||
$path = realpath($this->config['skin_path'].$attrib['file']);
|
||||
if ($fp = @fopen($path, 'r'))
|
||||
{
|
||||
$incl = fread($fp, filesize($path));
|
||||
fclose($fp);
|
||||
return $this->parse_xml($incl);
|
||||
}
|
||||
break;
|
||||
|
||||
// return code for a specific application object
|
||||
case 'object':
|
||||
$object = strtolower($attrib['name']);
|
||||
|
||||
// execute object handler function
|
||||
if ($this->object_handlers[$object] && function_exists($this->object_handlers[$object]))
|
||||
return call_user_func($this->object_handlers[$object], $attrib);
|
||||
|
||||
else if ($object=='productname')
|
||||
{
|
||||
$name = !empty($this->config['product_name']) ? $this->config['product_name'] : 'RoundCube Webmail';
|
||||
return Q($name);
|
||||
}
|
||||
else if ($object=='version')
|
||||
{
|
||||
return (string)RCMAIL_VERSION;
|
||||
}
|
||||
else if ($object=='pagetitle')
|
||||
{
|
||||
$task = $this->task;
|
||||
$title = !empty($this->config['product_name']) ? $this->config['product_name'].' :: ' : '';
|
||||
|
||||
if (!empty($this->pagetitle))
|
||||
$title .= $this->pagetitle;
|
||||
else if ($task == 'login')
|
||||
$title = rcube_label(array('name' => 'welcome', 'vars' => array('product' => $this->config['product_name'])));
|
||||
else
|
||||
$title .= ucfirst($task);
|
||||
|
||||
return Q($title);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create and register a button
|
||||
*
|
||||
* @param array Button attributes
|
||||
* @return HTML button
|
||||
*/
|
||||
function button($attrib)
|
||||
{
|
||||
global $CONFIG, $OUTPUT, $BROWSER, $MAIN_TASKS;
|
||||
static $sa_buttons = array();
|
||||
static $s_button_count = 100;
|
||||
|
||||
// these commands can be called directly via url
|
||||
$a_static_commands = array('compose', 'list');
|
||||
|
||||
$skin_path = $this->config['skin_path'];
|
||||
|
||||
if (!($attrib['command'] || $attrib['name']))
|
||||
return '';
|
||||
|
||||
// try to find out the button type
|
||||
if ($attrib['type'])
|
||||
$attrib['type'] = strtolower($attrib['type']);
|
||||
else
|
||||
$attrib['type'] = ($attrib['image'] || $attrib['imagepas'] || $attrib['imageact']) ? 'image' : 'link';
|
||||
|
||||
$command = $attrib['command'];
|
||||
|
||||
// take the button from the stack
|
||||
if($attrib['name'] && $sa_buttons[$attrib['name']])
|
||||
$attrib = $sa_buttons[$attrib['name']];
|
||||
|
||||
// add button to button stack
|
||||
else if($attrib['image'] || $attrib['imageact'] || $attrib['imagepas'] || $attrib['class'])
|
||||
{
|
||||
if (!$attrib['name'])
|
||||
$attrib['name'] = $command;
|
||||
|
||||
if (!$attrib['image'])
|
||||
$attrib['image'] = $attrib['imagepas'] ? $attrib['imagepas'] : $attrib['imageact'];
|
||||
|
||||
$sa_buttons[$attrib['name']] = $attrib;
|
||||
}
|
||||
|
||||
// get saved button for this command/name
|
||||
else if ($command && $sa_buttons[$command])
|
||||
$attrib = $sa_buttons[$command];
|
||||
|
||||
//else
|
||||
// return '';
|
||||
|
||||
|
||||
// set border to 0 because of the link arround the button
|
||||
if ($attrib['type']=='image' && !isset($attrib['border']))
|
||||
$attrib['border'] = 0;
|
||||
|
||||
if (!$attrib['id'])
|
||||
$attrib['id'] = sprintf('rcmbtn%d', $s_button_count++);
|
||||
|
||||
// get localized text for labels and titles
|
||||
if ($attrib['title'])
|
||||
$attrib['title'] = Q(rcube_label($attrib['title']));
|
||||
if ($attrib['label'])
|
||||
$attrib['label'] = Q(rcube_label($attrib['label']));
|
||||
|
||||
if ($attrib['alt'])
|
||||
$attrib['alt'] = Q(rcube_label($attrib['alt']));
|
||||
|
||||
// set title to alt attribute for IE browsers
|
||||
if ($BROWSER['ie'] && $attrib['title'] && !$attrib['alt'])
|
||||
{
|
||||
$attrib['alt'] = $attrib['title'];
|
||||
unset($attrib['title']);
|
||||
}
|
||||
|
||||
// add empty alt attribute for XHTML compatibility
|
||||
if (!isset($attrib['alt']))
|
||||
$attrib['alt'] = '';
|
||||
|
||||
|
||||
// register button in the system
|
||||
if ($attrib['command'])
|
||||
{
|
||||
$this->add_script(sprintf(
|
||||
"%s.register_button('%s', '%s', '%s', '%s', '%s', '%s');",
|
||||
JS_OBJECT_NAME,
|
||||
$command,
|
||||
$attrib['id'],
|
||||
$attrib['type'],
|
||||
$attrib['imageact'] ? $skin_path.$attrib['imageact'] : $attrib['classact'],
|
||||
$attrib['imagesel'] ? $skin_path.$attrib['imagesel'] : $attrib['classsel'],
|
||||
$attrib['imageover'] ? $skin_path.$attrib['imageover'] : '')
|
||||
);
|
||||
|
||||
// make valid href to specific buttons
|
||||
if (in_array($attrib['command'], $MAIN_TASKS))
|
||||
$attrib['href'] = Q(rcmail_self_url(null, null, $attrib['command']));
|
||||
else if (in_array($attrib['command'], $a_static_commands))
|
||||
$attrib['href'] = Q(rcmail_self_url($attrib['command']));
|
||||
}
|
||||
|
||||
// overwrite attributes
|
||||
if (!$attrib['href'])
|
||||
$attrib['href'] = '#';
|
||||
|
||||
if ($command)
|
||||
$attrib['onclick'] = sprintf("return %s.command('%s','%s',this)", JS_OBJECT_NAME, $command, $attrib['prop']);
|
||||
|
||||
if ($command && $attrib['imageover'])
|
||||
{
|
||||
$attrib['onmouseover'] = sprintf("return %s.button_over('%s','%s')", JS_OBJECT_NAME, $command, $attrib['id']);
|
||||
$attrib['onmouseout'] = sprintf("return %s.button_out('%s','%s')", JS_OBJECT_NAME, $command, $attrib['id']);
|
||||
}
|
||||
|
||||
if ($command && $attrib['imagesel'])
|
||||
{
|
||||
$attrib['onmousedown'] = sprintf("return %s.button_sel('%s','%s')", JS_OBJECT_NAME, $command, $attrib['id']);
|
||||
$attrib['onmouseup'] = sprintf("return %s.button_out('%s','%s')", JS_OBJECT_NAME, $command, $attrib['id']);
|
||||
}
|
||||
|
||||
$out = '';
|
||||
|
||||
// generate image tag
|
||||
if ($attrib['type']=='image')
|
||||
{
|
||||
$attrib_str = create_attrib_string($attrib, array('style', 'class', 'id', 'width', 'height', 'border', 'hspace', 'vspace', 'align', 'alt'));
|
||||
$img_tag = sprintf('<img src="%%s"%s />', $attrib_str);
|
||||
$btn_content = sprintf($img_tag, $skin_path.$attrib['image']);
|
||||
if ($attrib['label'])
|
||||
$btn_content .= ' '.$attrib['label'];
|
||||
|
||||
$link_attrib = array('href', 'onclick', 'onmouseover', 'onmouseout', 'onmousedown', 'onmouseup', 'title');
|
||||
}
|
||||
else if ($attrib['type']=='link')
|
||||
{
|
||||
$btn_content = $attrib['label'] ? $attrib['label'] : $attrib['command'];
|
||||
$link_attrib = array('href', 'onclick', 'title', 'id', 'class', 'style');
|
||||
}
|
||||
else if ($attrib['type']=='input')
|
||||
{
|
||||
$attrib['type'] = 'button';
|
||||
|
||||
if ($attrib['label'])
|
||||
$attrib['value'] = $attrib['label'];
|
||||
|
||||
$attrib_str = create_attrib_string($attrib, array('type', 'value', 'onclick', 'id', 'class', 'style'));
|
||||
$out = sprintf('<input%s disabled />', $attrib_str);
|
||||
}
|
||||
|
||||
// generate html code for button
|
||||
if ($btn_content)
|
||||
{
|
||||
$attrib_str = create_attrib_string($attrib, $link_attrib);
|
||||
$out = sprintf('<a%s>%s</a>', $attrib_str, $btn_content);
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
@ -0,0 +1,429 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
+-----------------------------------------------------------------------+
|
||||
| program/include/rcube_contacts.inc |
|
||||
| |
|
||||
| This file is part of the RoundCube Webmail client |
|
||||
| Copyright (C) 2006-2007, RoundCube Dev. - Switzerland |
|
||||
| Licensed under the GNU GPL |
|
||||
| |
|
||||
| PURPOSE: |
|
||||
| Interface to the local address book database |
|
||||
| |
|
||||
+-----------------------------------------------------------------------+
|
||||
| Author: Thomas Bruederli <roundcube@gmail.com> |
|
||||
+-----------------------------------------------------------------------+
|
||||
|
||||
$Id: rcube_contacts.inc 328 2006-08-30 17:41:21Z thomasb $
|
||||
|
||||
*/
|
||||
|
||||
class rcube_contacts
|
||||
{
|
||||
var $db = null;
|
||||
var $db_name = '';
|
||||
var $user_id = 0;
|
||||
var $filter = '1';
|
||||
var $result = null;
|
||||
var $search_fields;
|
||||
var $search_string;
|
||||
var $table_cols = array('name', 'email', 'firstname', 'surname');
|
||||
|
||||
/** public properties */
|
||||
var $primary_key = 'contact_id';
|
||||
var $readonly = false;
|
||||
var $list_page = 1;
|
||||
var $page_size = 10;
|
||||
var $ready = false;
|
||||
|
||||
|
||||
/**
|
||||
* Object constructor
|
||||
*
|
||||
* @param object Instance of the rcube_db class
|
||||
* @param integer User-ID
|
||||
*/
|
||||
function __construct($dbconn, $user)
|
||||
{
|
||||
$this->db = $dbconn;
|
||||
$this->db_name = get_table_name('contacts');
|
||||
$this->user_id = $user;
|
||||
$this->ready = $this->db && !$this->db->is_error();
|
||||
}
|
||||
|
||||
/**
|
||||
* PHP 4 object constructor
|
||||
*
|
||||
* @see rcube_contacts::__construct
|
||||
*/
|
||||
function rcube_contacts($dbconn, $user)
|
||||
{
|
||||
$this->__construct($dbconn, $user);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set internal list page
|
||||
*
|
||||
* @param number Page number to list
|
||||
* @access public
|
||||
*/
|
||||
function set_page($page)
|
||||
{
|
||||
$this->list_page = (int)$page;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set internal page size
|
||||
*
|
||||
* @param number Number of messages to display on one page
|
||||
* @access public
|
||||
*/
|
||||
function set_pagesize($size)
|
||||
{
|
||||
$this->page_size = (int)$size;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Save a search string for future listings
|
||||
*
|
||||
* @param string SQL params to use in listing method
|
||||
*/
|
||||
function set_search_set($filter)
|
||||
{
|
||||
$this->filter = $filter;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Getter for saved search properties
|
||||
*
|
||||
* @return mixed Search properties used by this class
|
||||
*/
|
||||
function get_search_set()
|
||||
{
|
||||
return $this->filter;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reset all saved results and search parameters
|
||||
*/
|
||||
function reset()
|
||||
{
|
||||
$this->result = null;
|
||||
$this->filter = '1';
|
||||
$this->search_fields = null;
|
||||
$this->search_string = null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* List the current set of contact records
|
||||
*
|
||||
* @param array List of cols to show
|
||||
* @return array Indexed list of contact records, each a hash array
|
||||
*/
|
||||
function list_records($cols=null, $subset=0)
|
||||
{
|
||||
// count contacts for this user
|
||||
$this->result = $this->count();
|
||||
$sql_result = NULL;
|
||||
|
||||
// get contacts from DB
|
||||
if ($this->result->count)
|
||||
{
|
||||
$start_row = $subset < 0 ? $this->result->first + $this->page_size + $subset : $this->result->first;
|
||||
$length = $subset != 0 ? abs($subset) : $this->page_size;
|
||||
|
||||
$sql_result = $this->db->limitquery(
|
||||
"SELECT * FROM ".$this->db_name."
|
||||
WHERE del<>1
|
||||
AND user_id=?
|
||||
AND (".$this->filter.")
|
||||
ORDER BY name",
|
||||
$start_row,
|
||||
$length,
|
||||
$this->user_id);
|
||||
}
|
||||
|
||||
while ($sql_result && ($sql_arr = $this->db->fetch_assoc($sql_result)))
|
||||
{
|
||||
$sql_arr['ID'] = $sql_arr[$this->primary_key];
|
||||
// make sure we have a name to display
|
||||
if (empty($sql_arr['name']))
|
||||
$sql_arr['name'] = $sql_arr['email'];
|
||||
$this->result->add($sql_arr);
|
||||
}
|
||||
|
||||
return $this->result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Search contacts
|
||||
*
|
||||
* @param array List of fields to search in
|
||||
* @param string Search value
|
||||
* @param boolean True if results are requested, False if count only
|
||||
* @return Indexed list of contact records and 'count' value
|
||||
*/
|
||||
function search($fields, $value, $select=true)
|
||||
{
|
||||
if (!is_array($fields))
|
||||
$fields = array($fields);
|
||||
|
||||
$add_where = array();
|
||||
foreach ($fields as $col)
|
||||
{
|
||||
if ($col == 'ID' || $col == $this->primary_key)
|
||||
{
|
||||
$ids = !is_array($value) ? split(',', $value) : $value;
|
||||
$add_where[] = $this->primary_key." IN (".join(',', $ids).")";
|
||||
}
|
||||
else
|
||||
$add_where[] = $this->db->quoteIdentifier($col)." LIKE ".$this->db->quote(strlen($value)>2 ? "%$value%" : "$value%");
|
||||
}
|
||||
|
||||
if (!empty($add_where))
|
||||
{
|
||||
$this->set_search_set(join(' OR ', $add_where));
|
||||
if ($select)
|
||||
$this->list_records();
|
||||
else
|
||||
$this->result = $this->count();
|
||||
}
|
||||
|
||||
return $this->result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Count number of available contacts in database
|
||||
*
|
||||
* @return Result array with values for 'count' and 'first'
|
||||
*/
|
||||
function count()
|
||||
{
|
||||
// count contacts for this user
|
||||
$sql_result = $this->db->query(
|
||||
"SELECT COUNT(contact_id) AS rows
|
||||
FROM ".$this->db_name."
|
||||
WHERE del<>1
|
||||
AND user_id=?
|
||||
AND (".$this->filter.")",
|
||||
$this->user_id);
|
||||
|
||||
$sql_arr = $this->db->fetch_assoc($sql_result);
|
||||
return new rcube_result_set($sql_arr['rows'], ($this->list_page-1) * $this->page_size);;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the last result set
|
||||
*
|
||||
* @return Result array or NULL if nothing selected yet
|
||||
*/
|
||||
function get_result($as_res=true)
|
||||
{
|
||||
return $this->result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a specific contact record
|
||||
*
|
||||
* @param mixed record identifier(s)
|
||||
* @return Result object with all record fields or False if not found
|
||||
*/
|
||||
function get_record($id, $assoc=false)
|
||||
{
|
||||
// return cached result
|
||||
if ($this->result && ($first = $this->result->first()) && $first[$this->primary_key] == $id)
|
||||
return $assoc ? $first : $this->result;
|
||||
|
||||
$this->db->query(
|
||||
"SELECT * FROM ".$this->db_name."
|
||||
WHERE contact_id=?
|
||||
AND user_id=?
|
||||
AND del<>1",
|
||||
$id,
|
||||
$this->user_id);
|
||||
|
||||
if ($sql_arr = $this->db->fetch_assoc())
|
||||
{
|
||||
$sql_arr['ID'] = $sql_arr[$this->primary_key];
|
||||
$this->result = new rcube_result_set(1);
|
||||
$this->result->add($sql_arr);
|
||||
}
|
||||
|
||||
return $assoc && $sql_arr ? $sql_arr : $this->result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a new contact record
|
||||
*
|
||||
* @param array Assoziative array with save data
|
||||
* @return The created record ID on success, False on error
|
||||
*/
|
||||
function insert($save_data, $check=false)
|
||||
{
|
||||
if (is_object($save_data) && is_a($save_data, rcube_result_set))
|
||||
return $this->insert_recset($save_data, $check);
|
||||
|
||||
$insert_id = $existing = false;
|
||||
|
||||
if ($check)
|
||||
$existing = $this->search('email', $save_data['email'], false);
|
||||
|
||||
$a_insert_cols = $a_insert_values = array();
|
||||
foreach ($this->table_cols as $col)
|
||||
if (isset($save_data[$col]))
|
||||
{
|
||||
$a_insert_cols[] = $this->db->quoteIdentifier($col);
|
||||
$a_insert_values[] = $this->db->quote($save_data[$col]);
|
||||
}
|
||||
|
||||
if (!$existing->count && !empty($a_insert_cols))
|
||||
{
|
||||
$this->db->query(
|
||||
"INSERT INTO ".$this->db_name."
|
||||
(user_id, changed, del, ".join(', ', $a_insert_cols).")
|
||||
VALUES (?, ".$this->db->now().", 0, ".join(', ', $a_insert_values).")",
|
||||
$this->user_id);
|
||||
|
||||
$insert_id = $this->db->insert_id(get_sequence_name('contacts'));
|
||||
}
|
||||
|
||||
return $insert_id;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Insert new contacts for each row in set
|
||||
*/
|
||||
function insert_recset($result, $check=false)
|
||||
{
|
||||
$ids = array();
|
||||
while ($row = $result->next())
|
||||
{
|
||||
if ($insert = $this->insert($row, $check))
|
||||
$ids[] = $insert;
|
||||
}
|
||||
return $ids;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update a specific contact record
|
||||
*
|
||||
* @param mixed Record identifier
|
||||
* @param array Assoziative array with save data
|
||||
* @return True on success, False on error
|
||||
*/
|
||||
function update($id, $save_cols)
|
||||
{
|
||||
$updated = false;
|
||||
$write_sql = array();
|
||||
foreach ($this->table_cols as $col)
|
||||
if (isset($save_cols[$col]))
|
||||
$write_sql[] = sprintf("%s=%s", $this->db->quoteIdentifier($col), $this->db->quote($save_cols[$col]));
|
||||
|
||||
if (!empty($write_sql))
|
||||
{
|
||||
$this->db->query(
|
||||
"UPDATE ".$this->db_name."
|
||||
SET changed=".$this->db->now().", ".join(', ', $write_sql)."
|
||||
WHERE contact_id=?
|
||||
AND user_id=?
|
||||
AND del<>1",
|
||||
$id,
|
||||
$this->user_id);
|
||||
|
||||
$updated = $this->db->affected_rows();
|
||||
}
|
||||
|
||||
return $updated;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Mark one or more contact records as deleted
|
||||
*
|
||||
* @param array Record identifiers
|
||||
*/
|
||||
function delete($ids)
|
||||
{
|
||||
if (is_array($ids))
|
||||
$ids = join(',', $ids);
|
||||
|
||||
$this->db->query(
|
||||
"UPDATE ".$this->db_name."
|
||||
SET del=1
|
||||
WHERE user_id=?
|
||||
AND contact_id IN (".$ids.")",
|
||||
$this->user_id);
|
||||
|
||||
return $this->db->affected_rows();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* RoundCube result set class.
|
||||
* Representing an address directory result set.
|
||||
*/
|
||||
class rcube_result_set
|
||||
{
|
||||
var $count = 0;
|
||||
var $first = 0;
|
||||
var $current = 0;
|
||||
var $records = array();
|
||||
|
||||
function __construct($c=0, $f=0)
|
||||
{
|
||||
$this->count = (int)$c;
|
||||
$this->first = (int)$f;
|
||||
}
|
||||
|
||||
function rcube_result_set($c=0, $f=0)
|
||||
{
|
||||
$this->__construct($c, $f);
|
||||
}
|
||||
|
||||
function add($rec)
|
||||
{
|
||||
$this->records[] = $rec;
|
||||
}
|
||||
|
||||
function iterate()
|
||||
{
|
||||
return $this->records[$this->current++];
|
||||
}
|
||||
|
||||
function first()
|
||||
{
|
||||
$this->current = 0;
|
||||
return $this->records[$this->current++];
|
||||
}
|
||||
|
||||
// alias
|
||||
function next()
|
||||
{
|
||||
return $this->iterate();
|
||||
}
|
||||
|
||||
function seek($i)
|
||||
{
|
||||
$this->current = $i;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
?>
|
@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
+-----------------------------------------------------------------------+
|
||||
| program/steps/addressbook/copy.inc |
|
||||
| |
|
||||
| This file is part of the RoundCube Webmail client |
|
||||
| Copyright (C) 2007, RoundCube Dev. - Switzerland |
|
||||
| Licensed under the GNU GPL |
|
||||
| |
|
||||
| PURPOSE: |
|
||||
| Copy a contact record from one direcotry to another |
|
||||
| |
|
||||
+-----------------------------------------------------------------------+
|
||||
| Author: Thomas Bruederli <roundcube@gmail.com> |
|
||||
+-----------------------------------------------------------------------+
|
||||
|
||||
$Id: copy.inc 471 2007-02-09 21:25:50Z thomasb $
|
||||
|
||||
*/
|
||||
|
||||
$cid = get_input_value('_cid', RCUBE_INPUT_POST);
|
||||
$target = get_input_value('_to', RCUBE_INPUT_POST);
|
||||
if ($cid && preg_match('/^[a-z0-9\-_=]+(,[a-z0-9\-_=]+)*$/i', $cid) && strlen($target) && $target != $source)
|
||||
{
|
||||
if ($target != '0')
|
||||
$TARGET = new rcube_ldap($CONFIG['ldap_public'][$target]);
|
||||
else
|
||||
$TARGET = new rcube_contacts($DB, $_SESSION['user_id']);
|
||||
|
||||
$success = false;
|
||||
if ($TARGET && $TARGET->ready && !$TARGET->readonly)
|
||||
$success = $TARGET->insert($CONTACTS->search($CONTACTS->primary_key, $cid), true);
|
||||
|
||||
if (empty($success))
|
||||
$OUTPUT->show_message('copyerror', 'error');
|
||||
else
|
||||
$OUTPUT->show_message('copysuccess', 'notice', array('nr' => count($success)));
|
||||
}
|
||||
|
||||
// send response
|
||||
$OUTPUT->send();
|
||||
|
||||
?>
|
@ -1,277 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
+-----------------------------------------------------------------------+
|
||||
| program/steps/addressbook/ldapsearch.inc |
|
||||
| |
|
||||
| This file is part of the RoundCube Webmail client |
|
||||
| Copyright (C) 2005, RoundCube Dev. - Switzerland |
|
||||
| Licensed under the GNU GPL |
|
||||
| |
|
||||
| PURPOSE: |
|
||||
| Show an ldap search form in the addressbook |
|
||||
| |
|
||||
+-----------------------------------------------------------------------+
|
||||
| Author: Justin Randell <justin.randell@gmail.com> |
|
||||
+-----------------------------------------------------------------------+
|
||||
|
||||
$Id$
|
||||
|
||||
*/
|
||||
require_once 'include/rcube_ldap.inc';
|
||||
|
||||
/**
|
||||
* draw the ldap public search form
|
||||
*/
|
||||
function rcmail_ldap_public_search_form($attrib)
|
||||
{
|
||||
global $CONFIG, $JS_OBJECT_NAME, $OUTPUT;
|
||||
if (!isset($CONFIG['ldap_public']))
|
||||
{
|
||||
// no ldap servers to search
|
||||
show_message('noldapserver', 'warning');
|
||||
rcmail_overwrite_action('add');
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// store some information in the session
|
||||
$_SESSION['ldap_public']['server_count'] = $server_count = count($CONFIG['ldap_public']);
|
||||
$_SESSION['ldap_public']['server_names'] = $server_names = array_keys($CONFIG['ldap_public']);
|
||||
}
|
||||
|
||||
list($form_start, $form_end) = get_form_tags($attrib);
|
||||
$out = "$form_start<table id=\"ldap_public_search_table\">\n\n";
|
||||
|
||||
// search name field
|
||||
$search_name = new textfield(array('name' => '_ldap_public_search_name',
|
||||
'id' => 'rcmfd_ldap_public_search_name'));
|
||||
$out .= "<tr><td class=\"title\"><label for=\"rcmfd_ldap_public_search_name\">" .
|
||||
rep_specialchars_output(rcube_label('ldappublicsearchname')) .
|
||||
"</label></td><td>" . $search_name->show() . "</td></tr>\n";
|
||||
|
||||
|
||||
// there's more than one server to search for, show a dropdown menu
|
||||
if ($server_count > 1)
|
||||
{
|
||||
$select_server = new select(array('name' => '_ldap_public_servers',
|
||||
'id' => 'rcfmd_ldap_public_servers'));
|
||||
|
||||
$select_server->add($server_names, $server_names);
|
||||
|
||||
$out .= '<tr><td class="title"><label for="rcfmd_ldap_public_servers">' .
|
||||
rep_specialchars_output(rcube_label('ldappublicserverselect')) .
|
||||
"</label></td><td>" . $select_server->show() . "</td></tr>\n";
|
||||
}
|
||||
|
||||
// foreach configured ldap server, set up the search fields
|
||||
for ($i = 0; $i < $server_count; $i++)
|
||||
{
|
||||
$server = $CONFIG['ldap_public'][$server_names[$i]];
|
||||
|
||||
// only display one search fields select - js takes care of the rest
|
||||
if (!$i)
|
||||
{
|
||||
$field_name = '_ldap_public_search_field';
|
||||
$field_id = 'rcfmd_ldap_public_search_field';
|
||||
|
||||
$search_fields = new select(array('name' => $field_name,
|
||||
'id' => $field_id));
|
||||
|
||||
$search_fields->add(array_keys($server['search_fields']), array_values($server['search_fields']));
|
||||
$out .= '<tr><td class="title"><label for="' . $field_id . '">' .
|
||||
rep_specialchars_output(rcube_label('ldappublicsearchfield')) .
|
||||
"</label></td><td>" . $search_fields->show() . "</td></tr>\n";
|
||||
|
||||
$attributes = array('name' => '_ldap_public_search_type',
|
||||
'id' => 'rcmfd_ldap_public_search_type');
|
||||
|
||||
// if there's only one server, and it doesn't accept fuzzy searches,
|
||||
// then check and disable the check box - thanks pieter
|
||||
if ($server_count == 1 && !$server['fuzzy_search'])
|
||||
{
|
||||
$attributes['CHECKED'] = 'CHECKED';
|
||||
$attributes['disabled'] = 'disabled';
|
||||
}
|
||||
|
||||
$search_type = new checkbox($attributes);
|
||||
|
||||
$out .= '<tr id="ldap_fuzzy_search"><td class="title"><label for="rcmfd_ldap_public_search_type">' .
|
||||
rep_specialchars_output(rcube_label('ldappublicsearchtype')) .
|
||||
"</label></td><td>" . $search_type->show() . "</td></tr>\n";
|
||||
}
|
||||
|
||||
if ($server_count > 1)
|
||||
{
|
||||
// store the search fields in a js array for each server
|
||||
$js = '';
|
||||
foreach ($server['search_fields'] as $search_name => $search_value)
|
||||
$js .= "['$search_name', '$search_value'], ";
|
||||
|
||||
// store whether this server accepts fuzzy search as last item in array
|
||||
$js .= $server['fuzzy_search'] ? "'fuzzy'" : "'exact'";
|
||||
$OUTPUT->add_script("rcmail.set_env('{$server_names[$i]}_search_fields', new Array($js));");
|
||||
}
|
||||
}
|
||||
|
||||
// add contact button label text
|
||||
$OUTPUT->add_script("rcmail.set_env('addcontact', '" . rcube_label('addcontact') . "');");
|
||||
|
||||
$out .= "\n</table>$form_end";
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* get search values and return ldap contacts
|
||||
*/
|
||||
function rcmail_ldap_public_list()
|
||||
{
|
||||
// just return if we are not being called from a search form
|
||||
if (!isset($_POST['_action']))
|
||||
return null;
|
||||
|
||||
global $CONFIG, $OUTPUT, $JS_OBJECT_NAME;
|
||||
|
||||
// show no search name warning and exit
|
||||
if (empty($_POST['_ldap_public_search_name']) || trim($_POST['_ldap_public_search_name']) == '')
|
||||
{
|
||||
show_message('nosearchname', 'warning');
|
||||
return false;
|
||||
}
|
||||
|
||||
// set up ldap server(s) array or bail
|
||||
if ($_SESSION['ldap_public']['server_count'] > 1)
|
||||
// show no ldap server warning and exit
|
||||
if (empty($_POST['_ldap_public_servers']))
|
||||
{
|
||||
show_message('noldappublicserver', 'warning');
|
||||
return false;
|
||||
}
|
||||
else
|
||||
$server_name = $_POST['_ldap_public_servers'];
|
||||
else if ($_SESSION['ldap_public']['server_count'] == 1)
|
||||
$server_name = $_SESSION['ldap_public']['server_names'][0];
|
||||
else
|
||||
return false;
|
||||
|
||||
// get search parameters
|
||||
$search_value = $_POST['_ldap_public_search_name'];
|
||||
$search_field = $_POST['_ldap_public_search_field'];
|
||||
|
||||
// only use the post var for search type if the ldap server allows 'like'
|
||||
$exact = true;
|
||||
if ($CONFIG['ldap_public'][$server_name]['fuzzy_search'])
|
||||
$exact = isset($_POST['_ldap_public_search_type']) ? true : false;
|
||||
|
||||
// perform an ldap search
|
||||
$contacts = rcmail_ldap_contact_search($search_value,
|
||||
$search_field,
|
||||
$CONFIG['ldap_public'][$server_name],
|
||||
$exact);
|
||||
|
||||
// if no results, show a warning and return
|
||||
if (!$contacts)
|
||||
{
|
||||
show_message('nocontactsreturned', 'warning');
|
||||
return false;
|
||||
}
|
||||
|
||||
// add id to message list table if not specified
|
||||
if (!strlen($attrib['id']))
|
||||
$attrib['id'] = 'ldapAddressList';
|
||||
|
||||
// define table class
|
||||
$attrib['class'] = 'records-table';
|
||||
$attrib['cellspacing'] = 0;
|
||||
|
||||
// define list of cols to be displayed
|
||||
$a_show_cols = array('name', 'email');
|
||||
|
||||
// create XHTML table
|
||||
$out = rcube_table_output($attrib, $contacts, $a_show_cols, 'row_id');
|
||||
|
||||
// set client env
|
||||
$javascript = "$JS_OBJECT_NAME.gui_object('ldapcontactslist', '{$attrib['id']}');\n";
|
||||
$OUTPUT->add_script($javascript);
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* perform search for contacts from given public ldap server
|
||||
*/
|
||||
function rcmail_ldap_contact_search($search_value, $search_field, $server, $exact=true)
|
||||
{
|
||||
global $CONFIG;
|
||||
|
||||
$attributes = array($server['name_field'], $server['mail_field']);
|
||||
|
||||
$LDAP = new rcube_ldap();
|
||||
if ($LDAP->connect($server['hosts'], $server['port'], $server['protocol']))
|
||||
{
|
||||
$filter = "$search_field=" . ($exact ? $search_value : "*$search_value*");
|
||||
$result = $LDAP->search($server['base_dn'],
|
||||
$filter,
|
||||
$attributes,
|
||||
$server['scope'],
|
||||
$sort=null);
|
||||
|
||||
// add any results to contact array
|
||||
if ($result['count'])
|
||||
{
|
||||
for ($n = 0; $n < $result['count']; $n++)
|
||||
{
|
||||
$contacts[$n]['name'] = $result[$n][$server['name_field']][0];
|
||||
$contacts[$n]['email'] = $result[$n][$server['mail_field']][0];
|
||||
$contacts[$n]['row_id'] = $n + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
return false;
|
||||
|
||||
// cleanup
|
||||
$LDAP->close();
|
||||
|
||||
if (!$result['count'])
|
||||
return false;
|
||||
|
||||
// weed out duplicate emails
|
||||
for ($n = 0; $n < $result['count']; $n++)
|
||||
for ($i = 0; $i < $result['count']; $i++)
|
||||
if ($contacts[$i]['email'] == $contacts[$n]['email'] && $i != $n)
|
||||
unset($contacts[$n]);
|
||||
|
||||
return $contacts;
|
||||
}
|
||||
|
||||
function get_form_tags($attrib)
|
||||
{
|
||||
global $OUTPUT, $JS_OBJECT_NAME, $EDIT_FORM, $SESS_HIDDEN_FIELD;
|
||||
|
||||
$form_start = '';
|
||||
if (!strlen($EDIT_FORM))
|
||||
{
|
||||
$hiddenfields = new hiddenfield(array('name' => '_task', 'value' => $GLOBALS['_task']));
|
||||
$hiddenfields->add(array('name' => '_action', 'value' => 'ldappublicsearch'));
|
||||
|
||||
if ($_framed)
|
||||
$hiddenfields->add(array('name' => '_framed', 'value' => 1));
|
||||
|
||||
$form_start .= !strlen($attrib['form']) ? '<form name="form" action="./" method="post">' : '';
|
||||
$form_start .= "\n$SESS_HIDDEN_FIELD\n";
|
||||
$form_start .= $hiddenfields->show();
|
||||
}
|
||||
|
||||
$form_end = (strlen($EDIT_FORM) && !strlen($attrib['form'])) ? '</form>' : '';
|
||||
$form_name = strlen($attrib['form']) ? $attrib['form'] : 'form';
|
||||
|
||||
$OUTPUT->add_script("$JS_OBJECT_NAME.gui_object('ldappublicsearchform', '$form_name');");
|
||||
|
||||
$EDIT_FORM = $form_name;
|
||||
|
||||
return array($form_start, $form_end);
|
||||
}
|
||||
|
||||
parse_template('ldappublicsearch');
|
||||
?>
|
@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
+-----------------------------------------------------------------------+
|
||||
| program/steps/addressbook/mailto.inc |
|
||||
| |
|
||||
| This file is part of the RoundCube Webmail client |
|
||||
| Copyright (C) 2007, RoundCube Dev. - Switzerland |
|
||||
| Licensed under the GNU GPL |
|
||||
| |
|
||||
| PURPOSE: |
|
||||
| Compose a recipient list with all selected contacts |
|
||||
| |
|
||||
+-----------------------------------------------------------------------+
|
||||
| Author: Thomas Bruederli <roundcube@gmail.com> |
|
||||
+-----------------------------------------------------------------------+
|
||||
|
||||
$Id: copy.inc 471 2007-02-09 21:25:50Z thomasb $
|
||||
|
||||
*/
|
||||
|
||||
$cid = get_input_value('_cid', RCUBE_INPUT_GET);
|
||||
$recipients = null;
|
||||
$mailto = array();
|
||||
|
||||
if ($cid && preg_match('/^[a-z0-9\-_=]+(,[a-z0-9\-_=]+)*$/i', $cid) && $CONTACTS->ready)
|
||||
{
|
||||
$recipients = $CONTACTS->search($CONTACTS->primary_key, $cid);
|
||||
|
||||
while (is_object($recipients) && ($rec = $recipients->iterate()))
|
||||
$mailto[] = format_email_recipient($rec['email'], $rec['name']);
|
||||
}
|
||||
|
||||
if (!empty($mailto))
|
||||
{
|
||||
$mailto_str = join(', ', $mailto);
|
||||
$mailto_id = substr(md5($mailto_str), 0, 16);
|
||||
$_SESSION['mailto'][$mailto_id] = $mailto_str;
|
||||
$OUTPUT->command('redirect', rcmail_self_url('compose', array('_mailto' => $mailto_id), 'mail'));
|
||||
}
|
||||
else
|
||||
$OUTPUT->show_message('nocontactsfound', 'warning');
|
||||
|
||||
|
||||
// send response
|
||||
$OUTPUT->send();
|
||||
|
||||
?>
|
@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
+-----------------------------------------------------------------------+
|
||||
| program/steps/addressbook/search.inc |
|
||||
| |
|
||||
| This file is part of the RoundCube Webmail client |
|
||||
| Copyright (C) 2005-2007, RoundCube Dev. - Switzerland |
|
||||
| Licensed under the GNU GPL |
|
||||
| |
|
||||
| PURPOSE: |
|
||||
| Search step for address book contacts |
|
||||
| |
|
||||
+-----------------------------------------------------------------------+
|
||||
| Author: Thomas Bruederli <roundcube@gmail.com> |
|
||||
+-----------------------------------------------------------------------+
|
||||
|
||||
$Id: search.inc 456 2007-01-10 12:34:33Z thomasb $
|
||||
|
||||
*/
|
||||
|
||||
$CONTACTS->set_page(1);
|
||||
$_SESSION['page'] = 1;
|
||||
|
||||
$search = trim(get_input_value('_q', RCUBE_INPUT_GET));
|
||||
$search_request = md5('addr'.$search);
|
||||
|
||||
// get contacts for this user
|
||||
$result = $CONTACTS->search(array('name','email'), $search);
|
||||
|
||||
if ($result->count > 0)
|
||||
{
|
||||
// save search settings in session
|
||||
$_SESSION['search'][$search_request] = $CONTACTS->get_search_set();
|
||||
|
||||
// create javascript list
|
||||
rcmail_js_contacts_list($result);
|
||||
}
|
||||
else
|
||||
{
|
||||
$OUTPUT->show_message('nocontactsfound', 'warning');
|
||||
$search_request = -1;
|
||||
}
|
||||
|
||||
// update message count display
|
||||
$OUTPUT->set_env('search_request', $search_request);
|
||||
$OUTPUT->set_env('pagecount', ceil($result->count / $CONTACTS->page_size));
|
||||
$OUTPUT->command('set_rowcount', rcmail_get_rowcount_text());
|
||||
|
||||
// send response
|
||||
$OUTPUT->send();
|
||||
|
||||
?>
|
@ -1,54 +0,0 @@
|
||||
/***** RoundCube|Mail address book task styles *****/
|
||||
|
||||
|
||||
body.iframe,
|
||||
{
|
||||
background-color: #F9F9F9;
|
||||
}
|
||||
|
||||
#ldapsearch-title
|
||||
{
|
||||
height: 12px !important;
|
||||
/* height: 20px; */
|
||||
padding: 4px 20px 3px 20px;
|
||||
border-bottom: 1px solid #999999;
|
||||
color: #333333;
|
||||
font-size: 11px;
|
||||
font-weight: bold;
|
||||
background-color: #EBEBEB;
|
||||
background-image: url(images/listheader_aqua.gif);
|
||||
}
|
||||
|
||||
#ldapsearch-details
|
||||
{
|
||||
padding: 15px 20px 10px 20px;
|
||||
}
|
||||
|
||||
#ldapsearch-details table td.title
|
||||
{
|
||||
color: #666666;
|
||||
font-weight: bold;
|
||||
text-align: right;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
#ldapAddressList
|
||||
{
|
||||
width: 100%;
|
||||
table-layout: fixed;
|
||||
/* css hack for IE */
|
||||
width: expression(document.getElementById('addresslist').clientWidth);
|
||||
}
|
||||
|
||||
#ldapAddressList table
|
||||
{
|
||||
border-top: 1px solid #999999;
|
||||
}
|
||||
|
||||
#ldap-search-results div
|
||||
{
|
||||
width: 100%;
|
||||
color: red;
|
||||
background-color: green;
|
||||
}
|
||||
|
@ -1,31 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title><roundcube:object name="pagetitle" /></title>
|
||||
<link rel="stylesheet" type="text/css" href="/common.css" />
|
||||
<link rel="stylesheet" type="text/css" href="/ldapsearchform.css" />
|
||||
</head>
|
||||
<body class="iframe">
|
||||
|
||||
<div id="ldapsearch-title"><roundcube:label name="ldappublicsearchform" /></div>
|
||||
|
||||
<div id="ldapsearch-details">
|
||||
<roundcube:object name="ldappublicsearch" size="40" />
|
||||
<p>
|
||||
<roundcube:button command="ldappublicsearch" type="input" class="button" label="ldappublicsearch" />
|
||||
<input type="button" value="<roundcube:label name="cancel" />" class="button" onclick="history.back()" />
|
||||
<br /></p>
|
||||
</div>
|
||||
|
||||
|
||||
<div id="ldapsearch-results">
|
||||
<roundcube:object name="ldappublicaddresslist"
|
||||
id="ldappublicaddresslist"
|
||||
cellspacing="0"
|
||||
summary="LDAP email address list" />
|
||||
</div>
|
||||
|
||||
<roundcube:include file="/includes/ldapscripts.html" />
|
||||
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue