using new api for mail app

This commit is contained in:
Ralf Becker 2016-05-03 19:17:44 +00:00
parent 7cc923bf41
commit 72404a1e29
14 changed files with 797 additions and 837 deletions

View File

@ -0,0 +1,165 @@
<?php
/**
* EGroupware API: contains classes and key constants for generating shortcuts
*
* @link http://www.egroupware.org
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package api
* @subpackage etemplate
* @author Andreas Stöckel
* @copyright (c) 2011 Stylite
* @version $Id$
*/
namespace EGroupware\Api\Etemplate;
class KeyManager
{
const BACKSPACE = 8;
const TAB = 9;
const ENTER = 13;
const ESCAPE = 27;
const DELETE = 46;
const SPACE = 32;
const PAGE_UP = 33;
const PAGE_DOWN = 34;
const ARROW_LEFT = 37;
const ARROW_UP = 38;
const ARROW_RIGHT = 39;
const ARROW_DOWN = 40;
const _0 = 48;
const _1 = 49;
const _2 = 50;
const _3 = 51;
const _4 = 52;
const _5 = 53;
const _6 = 54;
const _7 = 55;
const _8 = 56;
const _9 = 57;
const A = 65;
const B = 66;
const C = 67;
const D = 68;
const E = 69;
const F = 70;
const G = 71;
const H = 72;
const I = 73;
const J = 74;
const K = 75;
const L = 76;
const M = 77;
const N = 78;
const O = 79;
const P = 80;
const Q = 81;
const R = 82;
const S = 83;
const T = 84;
const U = 85;
const V = 86;
const W = 87;
const X = 88;
const Y = 89;
const Z = 90;
const F1 = 112;
const F2 = 113;
const F3 = 114;
const F4 = 115;
const F5 = 116;
const F6 = 117;
const F7 = 118;
const F8 = 119;
const F9 = 120;
const F10 = 121;
const F11 = 122;
const F12 = 123;
/**
* Converts the given key codes into translated key names.
*/
public static function key_name($keyCode)
{
// Keys which can be directly translated into ASCII chars
if (($keyCode >= self::_0 && $keyCode <= self::_9) ||
($keyCode >= self::A && $keyCode <= self::Z))
{
return chr($keyCode);
}
// Function keys
if ($keyCode >= self::F1 && $keyCode <= self::F12)
{
return "F".($keyCode - EGW_KEY_F1 + 1);
}
// Special keys
switch ($keyCode) {
case self::BACKSPACE:
return lang("Back");
case self::TAB:
return lang("Tab");
case self::DELETE:
return lang("Del");
case self::SPACE:
return lang("Space");
case self::PAGE_UP:
return lang("Pg up");
case self::PAGE_DOWN:
return lang("Pg down");
}
return "";
}
/**
* Generates the caption of the given shortcut and returns it
*/
public static function shortcut_caption($keyCode, $shift = false, $ctrl = false, $alt = false)
{
$elems = array();
if ($shift)
{
$elems[] = lang("Shift");
}
if ($ctrl)
{
$elems[] = lang("Ctrl");
}
if ($alt)
{
$elems[] = lang("Alt");
}
$elems[] = self::key_name($keyCode);
return implode(" + ", $elems);
}
/**
* Generates a shortcut structure which can be JSON encoded and send to the
* egw action system. This function and class could later be used to provide
* user defined shortcuts.
*/
public static function shortcut($keyCode, $shift = false, $ctrl = false, $alt = false)
{
return array(
"keyCode" => $keyCode,
"shift" => (boolean)$shift,
"ctrl" => (boolean)$ctrl,
"alt" => (boolean)$alt,
"caption" => self::shortcut_caption($keyCode, $shift, $ctrl, $alt)
);
}
}

View File

@ -44,7 +44,7 @@ $replace = array(
"#\\\$GLOBALS\['egw'\]->preferences->change#" => '$GLOBALS[\'egw\']->preferences->add',
);
// enclose class-names and static methods with some syntax check
$class_start = '#(?<!function)([\[\s,;().!])';
$class_start = '#(?<!function)([\[\s,;().!=])';
$class_end = '(::|\\(|\\)|;|\?|:|\\s|,|$)#';
foreach(array(
'accounts' => 'Api\\Accounts',
@ -158,6 +158,7 @@ foreach(array(
'etemplate_request' => 'Api\\Etemplate\\Request',
'nextmatch_widget::category_action' => 'Api\\Etemplate\\Widget\\Nextmatch::category_action',
'nextmatch_widget::DEFAULT_MAX_MENU_LENGTH' => 'Api\\Etemplate\\Widget\\Nextmatch::DEFAULT_MAX_MENU_LENGTH',
'egw_keymanager' => 'Api\\Etemplate\\KeyManager',
// so_sql and friends
'so_sql' => 'Api\\Storage\\Base',
'so_sql_cf' => 'Api\\Storage',
@ -167,6 +168,7 @@ foreach(array(
// addressbook backend
'addressbook_bo' => 'Api\\Contacts',
'addressbook_so' => 'Api\\Contacts\\Storage',
'addressbook_merge' => 'Api\\Contacts\\Merge',
) as $from => $to)
{
$replace[$class_start.$from.$class_end] = '$1'.$to.'$2';

View File

@ -11,6 +11,8 @@
*/
use EGroupware\Api;
use EGroupware\Api\Framework;
use EGroupware\Api\Etemplate;
use EGroupware\Api\Mail;
class mail_acl
@ -61,13 +63,13 @@ class mail_acl
*/
function edit(array $content=null ,$msg='')
{
$tmpl = new Api\Etemplate('mail.acl');
$tmpl = new Etemplate('mail.acl');
if (!is_array($content))
{
$acc_id = $_GET['acc_id']?$_GET['acc_id']:$GLOBALS['egw_info']['user']['preferences']['mail']['ActiveProfileID'];
if (isset($_GET['account_id']) && !isset($GLOBALS['egw_info']['user']['apps']['admin']))
{
egw_framework::window_close(lang('Permission denied'));
Framework::window_close(lang('Permission denied'));
}
$account_id = $_GET['account_id'];
}
@ -175,12 +177,12 @@ class mail_acl
$msg .= "\n".lang("Error: Could not save ACL").' '.lang("reason!");
}
//Send message
egw_framework::message($msg);
Framework::message($msg);
if ($button == "apply") break;
//Fall through
case 'cancel':
egw_framework::window_close();
Framework::window_close();
exit;
case 'delete':
@ -193,7 +195,7 @@ class mail_acl
{
error_log(__METHOD__.__LINE__. "()" . "The remove_acl suppose to return an array back, something is wrong there");
}
egw_framework::message($msg);
Framework::message($msg);
}
}
$readonlys = $sel_options = array();
@ -239,13 +241,13 @@ class mail_acl
/**
* Autocomplete for folder taglist
*
* @throws egw_exception_no_permission_admin
* @throws Api\Exception\NoPermission\Admin
*/
public static function ajax_folders()
{
if (!empty($_GET['account_id']) && !$GLOBALS['egw_info']['user']['apps']['admin'])
{
throw new egw_exception_no_permission_admin;
throw new Api\Exception\NoPermission\Admin;
}
$account = Mail\Account::read($_GET['acc_id'], $_GET['account_id']);
$imap = $account->imapServer(!empty($_GET['account_id']) ? (int)$_GET['account_id'] : false);
@ -263,7 +265,7 @@ class mail_acl
}
}
// switch regular JSON response handling off
egw_json_request::isJSONRequest(false);
Api\Json\Request::isJSONRequest(false);
header('Content-Type: application/json; charset=utf-8');
echo json_encode($folders);

View File

@ -11,6 +11,11 @@
*/
use EGroupware\Api;
use EGroupware\Api\Link;
use EGroupware\Api\Framework;
use EGroupware\Api\Egw;
use EGroupware\Api\Acl;
use EGroupware\Api\Etemplate;
use EGroupware\Api\Vfs;
use EGroupware\Api\Mail;
@ -65,7 +70,7 @@ class mail_compose
function __construct()
{
$this->displayCharset = translation::charset();
$this->displayCharset = Api\Translation::charset();
$profileID = (int)$GLOBALS['egw_info']['user']['preferences']['mail']['ActiveProfileID'];
$this->mail_bo = Mail::getInstance(true,$profileID);
@ -232,7 +237,7 @@ class mail_compose
{
$actions['prty']['children'][$content['priority']]['default'] = true;
}
if (html::$ua_mobile)
if (Api\Header\UserAgent::mobile())
{
foreach (array_keys($actions) as $key)
{
@ -256,7 +261,7 @@ class mail_compose
*/
function compose(array $_content=null,$msg=null, $_focusElement='to',$suppressSigOnTop=false, $isReply=false)
{
if ($msg) egw_framework::message($msg);
if ($msg) Framework::message($msg);
if (!empty($GLOBALS['egw_info']['user']['preferences']['mail']['LastSignatureIDUsed']))
{
@ -350,16 +355,16 @@ class mail_compose
{
$upload['file'] = $upload['tmp_name'] = Mail::checkFileBasics($upload,$this->composeID,false);
}
catch (egw_exception_wrong_userinput $e)
catch (Api\Exception\WrongUserinput $e)
{
egw_framework::message($e->getMessage(), 'error');
Framework::message($e->getMessage(), 'error');
unset($_content['uploadForCompose'][$i]);
continue;
}
if (is_dir($upload['file']) && (!$_content['filemode'] || $_content['filemode'] == Vfs\Sharing::ATTACH))
{
$_content['filemode'] = Vfs\Sharing::READONLY;
egw_framework::message(lang('Directories have to be shared.'), 'info');
Framework::message(lang('Directories have to be shared.'), 'info');
}
}
}
@ -449,7 +454,7 @@ class mail_compose
$GLOBALS['egw']->preferences->save_repository(true);
}
}
catch (egw_exception_wrong_userinput $e)
catch (Api\Exception\WrongUserinput $e)
{
$sendOK = false;
$message = $e->getMessage();
@ -494,7 +499,7 @@ class mail_compose
$rhA = mail_ui::splitRowID($_content['processedmail_id']);
$idsForRefresh[] = mail_ui::generateRowID($rhA['profileID'], $rhA['folder'], $rhA['msgUID'], $_prependApp=false);
}
$response = egw_json_response::get();
$response = Api\Json\Response::get();
if ($activeProfile != $composeProfile)
{
// we need a message only, when account ids (composeProfile vs. activeProfile) differ
@ -518,12 +523,12 @@ class mail_compose
$response->call('opener.egw_message',lang('Message send successfully.'));
}
//egw_framework::refresh_opener(lang('Message send successfully.'),'mail');
egw_framework::window_close();
Framework::window_close();
}
if ($sendOK == false)
{
$response = egw_json_response::get();
egw_framework::message(lang('Message send failed: %1',$message),'error');// maybe error is more appropriate
$response = Api\Json\Response::get();
Framework::message(lang('Message send failed: %1',$message),'error');// maybe error is more appropriate
$response->call('app.mail.clearIntevals');
}
}
@ -552,7 +557,7 @@ class mail_compose
$suppressSigOnTop = true;
if (stripos($content['mail_htmltext'],'<pre>')!==false)
{
$contentArr = translation::splithtmlByPRE($content['mail_htmltext']);
$contentArr = Api\Mail\Html::splithtmlByPRE($content['mail_htmltext']);
if (is_array($contentArr))
{
foreach ($contentArr as $k =>&$elem)
@ -563,7 +568,7 @@ class mail_compose
}
}
$content['mail_htmltext'] = $this->_getCleanHTML($content['mail_htmltext']);
$content['mail_htmltext'] = translation::convertHTMLToText($content['mail_htmltext'],$charset=false,false,true);
$content['mail_htmltext'] = Api\Mail\Html::convertHTMLToText($content['mail_htmltext'],$charset=false,false,true);
$content['body'] = $content['mail_htmltext'];
unset($content['mail_htmltext']);
@ -665,7 +670,7 @@ class mail_compose
{
$content['body'] = str_replace("\n",'\n',$content['body']); // dont know why, but \n screws up preg_replace
$styles = Mail::getStyles(array(array('body'=>$content['body'])));
if (stripos($content['body'],'style')!==false) translation::replaceTagsCompletley($content['body'],'style',$endtag='',true); // clean out empty or pagewide style definitions / left over tags
if (stripos($content['body'],'style')!==false) Api\Mail\Html::replaceTagsCompletley($content['body'],'style',$endtag='',true); // clean out empty or pagewide style definitions / left over tags
}
$content['body'] = str_replace(array("\r","\t","<br />\n",": "),array("","","<br />",":"),($_currentMode == 'html'?html::purify($content['body'],Mail::$htmLawed_config,array(),true):$content['body']));
Mail::$htmLawed_config = $_htmlConfig;
@ -747,7 +752,7 @@ class mail_compose
$mt = $_REQUEST['method'];
$id = $_REQUEST['id'];
// passed method MUST be registered
$method = egw_link::get_registry($app,$mt);
$method = Link::get_registry($app,$mt);
//error_log(__METHOD__.__LINE__.array2string($method));
if ($method)
{
@ -905,13 +910,13 @@ class mail_compose
// special handling for attaching vCard of iCal --> use their link-title as name
if (substr($path,-7) != '/.entry' ||
!(list($app,$id) = array_slice(explode('/',$path),-3)) ||
!($name = egw_link::title($app, $id)))
!($name = Link::title($app, $id)))
{
$name = Vfs::decodePath(Vfs::basename($path));
}
else
{
$name .= '.'.mime_magic::mime2ext($type);
$name .= '.'.Api\MimeMagic::mime2ext($type);
}
// use type specified by caller, if Vfs reports only default, or contains specified type (eg. "text/vcard; charset=utf-8")
if (!empty($types[$k]) && ($type == 'application/octet-stream' || stripos($types[$k], $type) === 0))
@ -928,14 +933,14 @@ class mail_compose
if ($formData['type'] == Vfs::DIR_MIME_TYPE && $content['filemode'] == Vfs\Sharing::ATTACH)
{
$content['filemode'] = Vfs\Sharing::READONLY;
egw_framework::message(lang('Directories have to be shared.'), 'info');
Framework::message(lang('Directories have to be shared.'), 'info');
}
}
elseif(is_readable($path))
{
$formData = array(
'name' => isset($names[$k]) ? $names[$k] : basename($path),
'type' => isset($types[$k]) ? $types[$k] : (function_exists('mime_content_type') ? mime_content_type($path) : mime_magic::filename2mime($path)),
'type' => isset($types[$k]) ? $types[$k] : (function_exists('mime_content_type') ? mime_content_type($path) : Api\MimeMagic::filename2mime($path)),
'file' => $path,
'size' => filesize($path),
);
@ -991,8 +996,8 @@ class mail_compose
$content['to'] = $email;
}
}
if (strpos($content['to'],'%40')!== false) $content['to'] = html::purify(str_replace('%40','@',$content['to']));
$rarr = array(html::purify($rest));
if (strpos($content['to'],'%40')!== false) $content['to'] = Api\Html::purify(str_replace('%40','@',$content['to']));
$rarr = array(Api\Html::purify($rest));
if (isset($rest)&&!empty($rest) && strpos($rest,'&')!== false) $rarr = explode('&',$rest);
//error_log(__METHOD__.__LINE__.$content['to'].'->'.array2string($rarr));
$karr = array();
@ -1011,7 +1016,7 @@ class mail_compose
{
if ($karr[$name]) $content[$name] = $karr[$name];
}
if (!empty($_REQUEST['subject'])) $content['subject'] = html::purify(trim(html_entity_decode($_REQUEST['subject'])));
if (!empty($_REQUEST['subject'])) $content['subject'] = Api\Html::purify(trim(html_entity_decode($_REQUEST['subject'])));
}
}
//error_log(__METHOD__.__LINE__.array2string($content));
@ -1054,7 +1059,7 @@ class mail_compose
}
}
if ($content['mimeType'] == 'html' && html::htmlarea_availible()===false)
if ($content['mimeType'] == 'html' && Api\Html::htmlarea_availible()===false)
{
$_content['mimeType'] = $content['mimeType'] = 'plain';
$content['body'] = $this->convertHTMLToText($content['body']);
@ -1152,7 +1157,7 @@ class mail_compose
// prepare body
// in a way, this tests if we are having real utf-8 (the displayCharset) by now; we should if charsets reported (or detected) are correct
$content['body'] = translation::convert_jsonsafe($content['body'],'utf-8');
$content['body'] = Api\Translation::convert_jsonsafe($content['body'],'utf-8');
//error_log(__METHOD__.__LINE__.array2string($content));
// get identities of all accounts as "$acc_id:$ident_id" => $identity
@ -1254,7 +1259,7 @@ class mail_compose
$sel_options['filemode'] = Vfs\Sharing::$modes;
if (!isset($content['priority']) || empty($content['priority'])) $content['priority']=3;
//$GLOBALS['egw_info']['flags']['currentapp'] = 'mail';//should not be needed
$etpl = new Api\Etemplate('mail.compose');
$etpl = new Etemplate('mail.compose');
$etpl->setElementAttribute('composeToolbar', 'actions', $this->getToolbarActions($_content));
if ($content['mimeType']=='html')
@ -1404,7 +1409,7 @@ class mail_compose
* Use ajax_merge to merge & send multiple
*/
// Merge selected ID (in mailtocontactbyid or $mail_id) into given document
$merge_class = preg_match('/^([a-z_-]+_merge)$/', $_REQUEST['merge']) ? $_REQUEST['merge'] : 'addressbook_merge';
$merge_class = preg_match('/^([a-z_-]+_merge)$/', $_REQUEST['merge']) ? $_REQUEST['merge'] : 'EGroupware\\Api\\Contacts\\Merge';
$document_merge = new $merge_class();
$this->mail_bo->openConnection();
$merge_ids = $_REQUEST['preset']['mailtocontactbyid'] ? $_REQUEST['preset']['mailtocontactbyid'] : $mail_id;
@ -1439,11 +1444,11 @@ class mail_compose
{
$success = implode(', ',$results['success']);
$fail = implode(', ', $results['failed']);
if($success) egw_framework::message($success, 'success');
egw_framework::window_close($fail);
if($success) Framework::message($success, 'success');
Framework::window_close($fail);
}
}
catch (egw_exception_wrong_userinput $e)
catch (Api\Exception\WrongUserinput $e)
{
// if this returns with an exeption, something failed big time
$content['msg'] = $e->getMessage();
@ -1463,7 +1468,7 @@ class mail_compose
static function replaceEmailAdresses(&$text)
{
// replace emailaddresses eclosed in <> (eg.: <me@you.de>) with the emailaddress only (e.g: me@you.de)
translation::replaceEmailAdresses($text);
Api\Mail\Html::replaceEmailAdresses($text);
return 1;
}
@ -1472,7 +1477,7 @@ class mail_compose
$stripalltags = true;
// third param is stripalltags, we may not need that, if the source is already in ascii
if (!$sourceishtml) $stripalltags=false;
return translation::convertHTMLToText($_html,$this->displayCharset,$stripcrl,$stripalltags);
return Api\Mail\Html::convertHTMLToText($_html,$this->displayCharset,$stripcrl,$stripalltags);
}
function generateRFC822Address($_addressObject)
@ -1644,7 +1649,7 @@ class mail_compose
$bodyParts[$i]['body'] = "<pre>".$bodyParts[$i]['body']."</pre>";
}
if ($bodyParts[$i]['charSet']===false) $bodyParts[$i]['charSet'] = Mail::detect_encoding($bodyParts[$i]['body']);
$bodyParts[$i]['body'] = translation::convert_jsonsafe($bodyParts[$i]['body'], $bodyParts[$i]['charSet']);
$bodyParts[$i]['body'] = Api\Translation::convert_jsonsafe($bodyParts[$i]['body'], $bodyParts[$i]['charSet']);
#error_log( "GetDraftData (HTML) CharSet:".mb_detect_encoding($bodyParts[$i]['body'] . 'a' , strtoupper($bodyParts[$i]['charSet']).','.strtoupper($this->displayCharset).',UTF-8, ISO-8859-1'));
$this->sessionData['body'] .= ($i>0?"<br>":""). $bodyParts[$i]['body'] ;
}
@ -1658,7 +1663,7 @@ class mail_compose
$this->sessionData['body'] .= "<hr>";
}
if ($bodyParts[$i]['charSet']===false) $bodyParts[$i]['charSet'] = Mail::detect_encoding($bodyParts[$i]['body']);
$bodyParts[$i]['body'] = translation::convert_jsonsafe($bodyParts[$i]['body'], $bodyParts[$i]['charSet']);
$bodyParts[$i]['body'] = Api\Translation::convert_jsonsafe($bodyParts[$i]['body'], $bodyParts[$i]['charSet']);
#error_log( "GetDraftData (Plain) CharSet".mb_detect_encoding($bodyParts[$i]['body'] . 'a' , strtoupper($bodyParts[$i]['charSet']).','.strtoupper($this->displayCharset).',UTF-8, ISO-8859-1'));
$this->sessionData['body'] .= ($i>0?"\r\n":""). $bodyParts[$i]['body'] ;
}
@ -1779,11 +1784,11 @@ class mail_compose
{
$tmpFileName = Mail::checkFileBasics($_formData,$this->composeID,false);
}
catch (egw_exception_wrong_userinput $e)
catch (Api\Exception\WrongUserinput $e)
{
$attachfailed = true;
$alert_msg = $e->getMessage();
egw_framework::message($e->getMessage(), 'error');
Framework::message($e->getMessage(), 'error');
}
//error_log(__METHOD__.__LINE__.array2string($tmpFileName));
//error_log(__METHOD__.__LINE__.array2string($_formData));
@ -1832,7 +1837,7 @@ class mail_compose
function getAttachment()
{
// read attachment data from etemplate request, use tmpname only to identify it
if (($request = etemplate_request::read($_GET['etemplate_exec_id'])))
if (($request = Etemplate\Request::read($_GET['etemplate_exec_id'])))
{
foreach($request->preserv['attachments'] as $attachment)
{
@ -1871,7 +1876,7 @@ class mail_compose
$buff = explode('.',$attachment['tmp_name']);
$suffix = '';
if (is_array($buff)) $suffix = array_pop($buff); // take the last extension to check with ext2mime
if (!empty($suffix)) $sfxMimeType = mime_magic::ext2mime($suffix);
if (!empty($suffix)) $sfxMimeType = Api\MimeMagic::ext2mime($suffix);
$attachment['type'] = $sfxMimeType;
if (strtoupper($sfxMimeType) == 'TEXT/VCARD' || strtoupper($sfxMimeType) == 'TEXT/X-VCARD') $attachment['type'] = strtoupper($sfxMimeType);
}
@ -1926,10 +1931,10 @@ class mail_compose
}
}
//error_log(__METHOD__.__LINE__.'->'.array2string($attachment));
html::safe_content_header($attachment['attachment'], $attachment['name'], $attachment['type'], $size=0, true, $_GET['mode'] == "save");
Api\Header\Content::safe($attachment['attachment'], $attachment['name'], $attachment['type'], $size=0, true, $_GET['mode'] == "save");
echo $attachment['attachment'];
common::egw_exit();
exit();
}
/**
@ -2111,7 +2116,7 @@ class mail_compose
$_htmlConfig = Mail::$htmLawed_config;
Mail::$htmLawed_config['comment'] = 2;
Mail::$htmLawed_config['transform_anchor'] = false;
$this->sessionData['body'] .= "<br>".self::_getCleanHTML(translation::convert_jsonsafe($bodyParts[$i]['body'], $bodyParts[$i]['charSet']));
$this->sessionData['body'] .= "<br>".self::_getCleanHTML(Api\Translation::convert_jsonsafe($bodyParts[$i]['body'], $bodyParts[$i]['charSet']));
Mail::$htmLawed_config = $_htmlConfig;
#error_log( "GetReplyData (HTML) CharSet:".mb_detect_encoding($bodyParts[$i]['body'] . 'a' , strtoupper($bodyParts[$i]['charSet']).','.strtoupper($this->displayCharset).',UTF-8, ISO-8859-1'));
}
@ -2134,7 +2139,7 @@ class mail_compose
}
// add line breaks to $bodyParts
$newBody2 = translation::convert_jsonsafe($bodyParts[$i]['body'],$bodyParts[$i]['charSet']);
$newBody2 = Api\Translation::convert_jsonsafe($bodyParts[$i]['body'],$bodyParts[$i]['charSet']);
#error_log( "GetReplyData (Plain) CharSet:".mb_detect_encoding($bodyParts[$i]['body'] . 'a' , strtoupper($bodyParts[$i]['charSet']).','.strtoupper($this->displayCharset).',UTF-8, ISO-8859-1'));
$newBody = mail_ui::resolve_inline_images($newBody2, $_folder, $_uid, $_partID, 'plain');
$this->sessionData['body'] .= "\r\n";
@ -2211,12 +2216,12 @@ class mail_compose
/**
* Create a message from given data and identity
*
* @param egw_mailer $_mailObject
* @param Api\Mailer $_mailObject
* @param array $_formData
* @param array $_identity
* @param boolean $_autosaving =false true: autosaving, false: save-as-draft or send
*/
function createMessage(egw_mailer $_mailObject, array $_formData, array $_identity, $_autosaving=false)
function createMessage(Api\Mailer $_mailObject, array $_formData, array $_identity, $_autosaving=false)
{
if (substr($_formData['body'], 0, 27) == '-----BEGIN PGP MESSAGE-----')
{
@ -2496,7 +2501,7 @@ class mail_compose
if ($html)
{
$links[] = html::a_href($name, $link).' '.
$links[] = Api\Html::a_href($name, $link).' '.
(is_dir($path) ? lang('Directory') : Vfs::hsize($attachment['size']));
}
else
@ -2525,7 +2530,7 @@ class mail_compose
public function ajax_saveAsDraft ($content, $action='button[saveAsDraft]')
{
//error_log(__METHOD__.__LINE__.array2string($content)."(, action=$action)");
$response = egw_json_response::get();
$response = Api\Json\Response::get();
$success = true;
// check if default account is changed then we need to change profile
@ -2573,7 +2578,7 @@ class mail_compose
{
$this->mail_bo->deleteMessages($duid,$dmailbox,'remove_immediately');
}
catch (egw_exception $e)
catch (Api\Exception $e)
{
$msg = str_replace('"',"'",$e->getMessage());
$success = false;
@ -2591,10 +2596,10 @@ class mail_compose
}
else
{
throw new egw_exception_wrong_userinput(lang("Error: Could not save Message as Draft"));
throw new Api\Exception\WrongUserinput(lang("Error: Could not save Message as Draft"));
}
}
catch (egw_exception_wrong_userinput $e)
catch (Api\Exception\WrongUserinput $e)
{
$msg = str_replace('"',"'",$e->getMessage());
error_log(__METHOD__.__LINE__.$msg);
@ -2658,7 +2663,7 @@ class mail_compose
{
//error_log(__METHOD__."(..., $savingDestination, action=$action)");
$mail_bo = $this->mail_bo;
$mail = new egw_mailer($this->mail_bo->profileID);
$mail = new Api\Mailer($this->mail_bo->profileID);
// preserve the bcc and if possible the save to folder information
$this->sessionData['folder'] = $_formData['folder'];
@ -2716,7 +2721,7 @@ class mail_compose
{
$messageUid = $mail_bo->appendMessage($savingDestination, $mail->getRaw(), null, $flags);
}
catch (egw_exception_wrong_userinput $e)
catch (Api\Exception\WrongUserinput $e)
{
error_log(__METHOD__.__LINE__.lang("Save of message %1 failed. Could not save message to folder %2 due to: %3",__METHOD__,$savingDestination,$e->getMessage()));
return false;
@ -2733,7 +2738,7 @@ class mail_compose
function send($_formData)
{
$mail_bo = $this->mail_bo;
$mail = new egw_mailer($mail_bo->profileID);
$mail = new Api\Mailer($mail_bo->profileID);
$messageIsDraft = false;
$this->sessionData['mailaccount'] = $_formData['mailaccount'];
@ -3001,7 +3006,7 @@ class mail_compose
//error_log(__METHOD__.__LINE__.array2string($folderName));
$mail_bo->appendMessage($folderName, $mail->getRaw(), null, $flags);
}
catch (egw_exception_wrong_userinput $e)
catch (Api\Exception\WrongUserinput $e)
{
error_log(__METHOD__.__LINE__.'->'.lang("Import of message %1 failed. Could not save message to folder %2 due to: %3",$this->sessionData['subject'],$folderName,$e->getMessage()));
}
@ -3035,7 +3040,7 @@ class mail_compose
//error_log(__METHOD__.__LINE__.array2string($folderName));
$this->mail_bo->appendMessage($folderName, $mail->getRaw(), null, $flags);
}
catch (egw_exception_wrong_userinput $e)
catch (Api\Exception\WrongUserinput $e)
{
error_log(__METHOD__.__LINE__.'->'.lang("Import of message %1 failed. Could not save message to folder %2 due to: %3",$this->sessionData['subject'],$folderName,$e->getMessage()));
}
@ -3076,7 +3081,7 @@ class mail_compose
$mail_bo->deleteMessages($lastDrafted['uid'],$lastDrafted['folder'],'remove_immediately');
}
}
catch (egw_exception $e)
catch (Api\Exception $e)
{
//error_log(__METHOD__.__LINE__." ". str_replace('"',"'",$e->getMessage()));
unset($e);
@ -3103,7 +3108,7 @@ class mail_compose
$mail_bo->deleteMessages(array($this->sessionData['uid']),$this->sessionData['messageFolder']);
}
}
catch (egw_exception $e)
catch (Api\Exception $e)
{
//error_log(__METHOD__.__LINE__." ". str_replace('"',"'",$e->getMessage()));
unset($e);
@ -3118,7 +3123,7 @@ class mail_compose
//error_log(__METHOD__.__LINE__.':'.array2string($this->sessionData['forwardedUID']).' F:'.$this->sessionData['sourceFolder']);
$mail_bo->flagMessages("forwarded", $this->sessionData['forwardedUID'],$this->sessionData['sourceFolder']);
}
catch (egw_exception $e)
catch (Api\Exception $e)
{
//error_log(__METHOD__.__LINE__." ". str_replace('"',"'",$e->getMessage()));
unset($e);
@ -3152,7 +3157,7 @@ class mail_compose
{
$app_name = substr($app_key,3);
// Get registered hook data of the app called for integration
$hook = $GLOBALS['egw']->hooks->single(array('location'=> 'mail_import'),$app_name);
$hook = Api\Hooks::single(array('location'=> 'mail_import'),$app_name);
// store mail / eml in temp. file to not have to download it from mail-server again
$eml = tempnam($GLOBALS['egw_info']['server']['temp_dir'],'mail_integrate');
@ -3163,9 +3168,9 @@ class mail_compose
// Open the app called for integration in a popup
// and store the mail raw data as egw_data, in order to
// be stored from registered app method later
egw_framework::popup(egw::link('/index.php', array(
Framework::popup(Egw::link('/index.php', array(
'menuaction' => $hook['menuaction'],
'egw_data' => egw_link::set_data(null,'mail_integration::integrate',array(
'egw_data' => Link::set_data(null,'mail_integration::integrate',array(
$mailaddresses,
$this->sessionData['subject'],
$this->convertHTMLToText($this->sessionData['body']),
@ -3281,7 +3286,7 @@ class mail_compose
{
$useCacheIfPossible = true;
}
$searchString = translation::convert($_searchString, Mail::$displayCharset,'UTF7-IMAP');
$searchString = Api\Translation::convert($_searchString, Mail::$displayCharset,'UTF7-IMAP');
foreach ($folderObjects as $k =>$fA)
{
//error_log(__METHOD__.__LINE__.$_searchString.'/'.$searchString.' in '.$k.'->'.$fA->displayName);
@ -3317,12 +3322,12 @@ class mail_compose
return $rL;
}
// switch regular JSON response handling off
egw_json_request::isJSONRequest(false);
Api\Json\Request::isJSONRequest(false);
header('Content-Type: application/json; charset=utf-8');
//error_log(__METHOD__.__LINE__);
echo json_encode($results);
common::egw_exit();
exit();
}
public static function ajax_searchAddress($_searchStringLength=2) {
@ -3432,7 +3437,7 @@ class mail_compose
if($include_lists)
{
$lists = array_filter(
$contacts_obj->get_lists(EGW_ACL_READ),
$contacts_obj->get_lists(Acl::READ),
function($element) use($_searchString) {
return (stripos($element, $_searchString) !== false);
}
@ -3452,12 +3457,12 @@ class mail_compose
}
}
// switch regular JSON response handling off
egw_json_request::isJSONRequest(false);
Api\Json\Request::isJSONRequest(false);
//error_log(__METHOD__.__LINE__.array2string($jsArray));
header('Content-Type: application/json; charset=utf-8');
echo json_encode($results);
common::egw_exit();
exit();
}
/**
@ -3468,14 +3473,14 @@ class mail_compose
*/
public function ajax_merge($contact_id)
{
$response = egw_json_response::get();
if(class_exists($_REQUEST['merge']) && is_subclass_of($_REQUEST['merge'],'bo_merge'))
$response = Api\Json\Response::get();
if(class_exists($_REQUEST['merge']) && is_subclass_of($_REQUEST['merge'], 'EGroupware\\Api\\Storage\\Merge'))
{
$document_merge = new $_REQUEST['merge']();
}
else
{
$document_merge = new addressbook_merge();
$document_merge = new Api\Contacts\Merge();
}
$this->mail_bo->openConnection();

View File

@ -11,6 +11,7 @@
*/
use EGroupware\Api;
use EGroupware\Api\Egw;
use EGroupware\Api\Mail;
/**
@ -31,7 +32,7 @@ class mail_hooks
if (Mail\Account::is_multiple($account) && $account['acc_imap_admin_username'] ||
$account['acc_imap_type'] == 'managementserver_imap')
{
translation::add_app('mail');
Api\Translation::add_app('mail');
if (true /* ToDo check ACL available */ || $account['acc_imap_type'] == 'managementserver_imap')
{
@ -40,7 +41,7 @@ class mail_hooks
'caption' => 'Folder ACL',
'icon' => 'lock',
'popup' => '750x420',
'url' => egw::link('/index.php', array(
'url' => Egw::link('/index.php', array(
'menuaction' => 'mail.mail_acl.edit',
'acc_id' => $data['acc_id'],
'account_id' => $data['account_id'],
@ -55,7 +56,7 @@ class mail_hooks
'caption' => 'Vacation notice',
'icon' => 'mail/navbar',
'popup' => '750x420',
'url' => egw::link('/index.php', array(
'url' => Egw::link('/index.php', array(
'menuaction' => 'mail.mail_sieve.editVacation',
'acc_id' => $data['acc_id'],
'account_id' => $data['account_id'],
@ -70,11 +71,13 @@ class mail_hooks
/**
* Hook called by link-class to include mail in the appregistry of the linkage
*
* @param array/string $location location and other parameters (not used)
* @param array|string $location location and other parameters (not used)
* @return array with method-names
*/
static function search_link($location)
{
unset($location); // not used, but required by function signature
return array(
'view' => array(
'menuaction' => 'mail.mail_ui.displayMessage',
@ -122,60 +125,23 @@ class mail_hooks
$profileID = 0;
if (isset($GLOBALS['egw_info']['user']['preferences']['mail']['ActiveProfileID']))
$profileID = (int)$GLOBALS['egw_info']['user']['preferences']['mail']['ActiveProfileID'];
$mailConfig = config::read('mail');
}
$connectionTimeout = array(
'0' => lang('use default timeout (20 seconds)'),
'10' => '10', // timeout used in SIEVE
'20' => '20',
'30' => '30',
'40' => '40',
'50' => '50',
'60' => '60',
'70' => '70',
'80' => '80',
'90' => '90',
);
$no_yes = array(
'0' => lang('no'),
'1' => lang('yes')
);
$no_yes_copy = array_merge($no_yes,array('2'=>lang('yes, offer copy option')));
$prefAllowManageFolders = $no_yes;
$forwardOptions = array(
'asmail' => lang('forward as attachment'),
'inline' => lang('forward inline'),
);
$sortOrder = array(
'0' => lang('date(newest first)'),
'1' => lang('date(oldest first)'),
'3' => lang('from(A->Z)'),
'2' => lang('from(Z->A)'),
'5' => lang('subject(A->Z)'),
'4' => lang('subject(Z->A)'),
'7' => lang('size(0->...)'),
'6' => lang('size(...->0)')
);
$trustServersUnseenOptions = array_merge(
$no_yes,
array('2' => lang('yes') . ' - ' . lang('but check shared folders'))
);
$selectOptions = array_merge(
$no_yes,
array('2' => lang('yes') . ' - ' . lang('small view'))
);
$newWindowOptions = array(
'1' => lang('only one window'),
'2' => lang('allways a new window'),
);
$deleteOptions = array(
'move_to_trash' => lang('move to trash'),
'mark_as_deleted' => lang('mark as deleted'),
@ -208,46 +174,10 @@ class mail_hooks
'only_if_no_text' => lang('display only when no plain text is available'),
'always_display' => lang('always show html emails'),
);
$toggle = false;
if ($GLOBALS['egw_info']['user']['preferences']['common']['select_mode'] == 'EGW_SELECTMODE_TOGGLE') $toggle=true;
$rowOrderStyle = array(
'mail' => lang('mail'),
'outlook' => 'Outlook',
'mail_wCB' => lang('mail').' '.($toggle?lang('(select mails by clicking on the line, like a checkbox)'):lang('(with checkbox enforced)')),
'outlook_wCB' => 'Outlook'.' '.($toggle?lang('(select mails by clicking on the line, like a checkbox)'):lang('(with checkbox enforced)')),
);
// otherwise we get warnings during setup
if (!is_array($folderList)) $folderList = array();
$trashOptions = array_merge(
array(
'none' => lang("Don't use Trash")
),
$folderList
);
$sentOptions = array_merge(
array(
'none' => lang("Don't use Sent")
),
$folderList
);
$draftOptions = array_merge(
array(
'none' => lang("Don't use draft folder")
),
$folderList
);
$templateOptions = array_merge(
array(
'none' => lang("Don't use template folder")
),
$folderList
);
// modify folderlist, add a none entry, to be able to force the regarding settings, if no folders apply
$folderList['none'] = lang('no folders');
@ -434,6 +364,8 @@ class mail_hooks
*/
static function admin($hook_data)
{
unset($hook_data); // not used, but required by function signature
unset($GLOBALS['egw_info']['user']['preferences']['common']['auto_hide_sidebox']);
// Only Modify the $file and $title variables.....
$title = $appname = 'mail';
@ -442,7 +374,7 @@ class mail_hooks
$profileID = (int)$GLOBALS['egw_info']['user']['preferences']['mail']['ActiveProfileID'];
$file = Array(
'Site Configuration' => egw::link('/index.php',array('menuaction'=>'admin.uiconfig.index','appname'=>'mail')),
'Site Configuration' => Egw::link('/index.php',array('menuaction'=>'admin.uiconfig.index','appname'=>'mail')),
);
display_section($appname,$title,$file);
}
@ -454,6 +386,8 @@ class mail_hooks
*/
static function sidebox_menu($hook_data)
{
unset($hook_data); // not used, but required by function signature
//error_log(__METHOD__);
// always show the side bar
unset($GLOBALS['egw_info']['user']['preferences']['common']['auto_hide_sidebox']);
@ -513,7 +447,7 @@ class mail_hooks
);
$file += array(
'import message' => "javascript:egw_openWindowCentered2('".egw::link('/index.php', $linkData,false)."','importMessageDialog',600,100,'no','$appname');",
'import message' => "javascript:egw_openWindowCentered2('".Egw::link('/index.php', $linkData,false)."','importMessageDialog',600,100,'no','$appname');",
);
@ -522,21 +456,21 @@ class mail_hooks
{
$file += array(
'create new account' => "javascript:egw_openWindowCentered2('" .
egw::link('/index.php', array('menuaction' => 'mail.mail_wizard.add'), '').
Egw::link('/index.php', array('menuaction' => 'mail.mail_wizard.add'), '').
"','_blank',640,480,'yes')",
);
}
// display them all
display_sidebox($appname,$menu_title,$file);
if ($GLOBALS['egw_info']['user']['apps']['admin'] && !html::$ua_mobile)
if ($GLOBALS['egw_info']['user']['apps']['admin'] && !Api\Header\UserAgent::mobile())
{
$file = Array(
'Site Configuration' => egw::link('/index.php','menuaction=admin.uiconfig.index&appname=' . $appname),
'Site Configuration' => Egw::link('/index.php','menuaction=admin.uiconfig.index&appname=' . $appname),
);
display_sidebox($appname,lang('Admin'),$file);
}
hooks::pgp_encryption_menu('mail');
Api\Hooks::pgp_encryption_menu('mail');
}
@ -555,7 +489,7 @@ class mail_hooks
//error_log(__METHOD__.__LINE__." Job should not run too often; we limit this to once every 3 Minutes :". ($currentTime-$lastRun). " Seconds to go!");
return true;
}
$accountsToSearchObj = Mail\Account::search($only_current_user=true, $just_name=true);
$accountsToSearchObj = Mail\Account::search(true, true);
foreach($accountsToSearchObj as $acc_id => $identity_name)
{
@ -614,8 +548,7 @@ class mail_hooks
$notified_mail_uidsCache[$activeProfile][$notify_folder] = array();
}
$folder_status[$notify_folder] = $bomail->getFolderStatus($notify_folder);
$cutoffdate = time();
$cutoffdate = $cutoffdate - (60*60*24*14); // last 14 days
$cutoffdate = time() - (60*60*24*14); // last 14 days
$_filter = array('status'=>array('UNSEEN','UNDELETED'),'type'=>"SINCE",'string'=> date("d-M-Y", $cutoffdate));
//error_log(__METHOD__.__LINE__.' (user: '.$currentRecipient->account_lid.') Mailbox:'.$notify_folder.' filter:'.array2string($_filter));
// $_folderName, $_startMessage, $_numberOfMessages, $_sort, $_reverse, $_filter, $_thisUIDOnly=null, $_cacheResult=true
@ -695,7 +628,7 @@ class mail_hooks
{
return true; // allways give admins or emailadmins all rights, even if they are in a denied group
}
if (!isset($config)) $config = (array)config::read('mail');
if (!isset($config)) $config = (array)Api\Config::read('mail');
//error_log(__METHOD__.__LINE__.' '.$feature.':'.array2string($config['deny_'.$feature]));
if (!empty($config['deny_'.$feature]))
{

View File

@ -10,6 +10,9 @@
* @version $Id:$
*/
use EGroupware\Api;
use EGroupware\Api\Link;
/**
* Class cotains methods and functions
* to be used to integrate mail's message into other applications
@ -60,7 +63,7 @@ class mail_integration {
* @param string $_date
* @param string $_rawMail path to file with raw mail
* @param int $_icServerID mail profile id
* @throws egw_exception_assertion_failed
* @throws Api\Exception\AssertionFailed
*/
public static function integrate ($_to_emailAddress=false,$_subject=false,$_body=false,$_attachments=false,$_date=false,$_rawMail=null,$_icServerID=null)
{
@ -74,7 +77,7 @@ class mail_integration {
if (!$_date)
{
$time = time();
$_date = egw_time::server2user($time->now,'ts');
$_date = Api\DateTime::server2user($time->now,'ts');
}
// For dealing with multiple files of the same name
@ -91,10 +94,10 @@ class mail_integration {
if (!($GLOBALS['egw_info']['user']['preferences'][$sessionLocation]['saveAsOptions']==='text_only')&&is_array($_attachments))
{
// initialize mail open connection requirements
if (!isset($_icServerID)) $_icServerID =& egw_cache::getSession($sessionLocation,'activeProfileID');
if (!isset($_icServerID)) $_icServerID =& Api\Cache::getSession($sessionLocation,'activeProfileID');
$mo = mail_bo::getInstance(true,$_icServerID);
$mo->openConnection();
$messageUID = $messagePartId = $messageFolder = null;
$messagePartId = $messageFolder = null;
foreach ($_attachments as $attachment)
{
//error_log(__METHOD__.__LINE__.array2string($attachment));
@ -165,7 +168,7 @@ class mail_integration {
{
$mo->deleteMessages(array($messageUid),$messageFolder);
}
catch (egw_exception $e)
catch (Api\Exception $e)
{
//error_log(__METHOD__.__LINE__." ". str_replace('"',"'",$e->getMessage()));
unset($e);
@ -222,14 +225,14 @@ class mail_integration {
$hA = mail_ui::splitRowID($_GET['rowid']);
$sessionLocation = $hA['app']; // THIS is part of the row ID, we may use this for validation
// Check the mail app
if ($sessionLocation != 'mail') throw new egw_exception_assertion_failed(lang('Application mail expected but got: %1',$sessionLocation));
if ($sessionLocation != 'mail') throw new Api\Exception\AssertionFailed(lang('Application mail expected but got: %1',$sessionLocation));
$uid = $hA['msgUID'];
$mailbox = $hA['folder'];
$icServerID = $hA['profileID'];
if ($uid && $mailbox)
{
if (!isset($icServerID)) $icServerID =& egw_cache::getSession($sessionLocation,'activeProfileID');
if (!isset($icServerID)) $icServerID =& Api\Cache::getSession($sessionLocation,'activeProfileID');
$mo = mail_bo::getInstance(true,$icServerID);
$mo->openConnection();
$mo->reopen($mailbox);
@ -292,7 +295,7 @@ class mail_integration {
);
if ($uid && !$mailcontent['attachments'][$key]['add_raw'])
{
$data_attachments[$key]['egw_data'] = egw_link::set_data($mailcontent['attachments'][$key]['mimeType'],
$data_attachments[$key]['egw_data'] = Link::set_data($mailcontent['attachments'][$key]['mimeType'],
'EGroupware\\Api\\Mail::getAttachmentAccount',array($icServerID, $mailbox, $uid, $attachment['partID'], $is_winmail, true),true);
}
unset($mailcontent['attachments'][$key]['add_raw']);
@ -300,21 +303,18 @@ class mail_integration {
}
// Check if the hook is registered
if ($GLOBALS['egw']->hooks->hook_exists('mail_import',$app) == 0)
if (Api\Hooks::exists('mail_import',$app) == 0)
{
// Try to register hook
if(!$GLOBALS['egw']->hooks->register_single_app_hook($app,'mail_import'))
{
throw new egw_exception_assertion_failed('Hook import_mail registration faild for '.$app.' app! Please, contact your system admin in order to clear cache and register hooks.');
}
Api\Hooks::read(true);
}
// Get the registered hook method of requested app for integration
$hook = $GLOBALS['egw']->hooks->single(array('location' => 'mail_import'),$app);
$hook = Api\Hooks::single(array('location' => 'mail_import'),$app);
// Load translation for the app since the original URL
// is from mail integration and only loads mail translation
translation::add_app($app);
// Load Api\Translation for the app since the original URL
// is from mail integration and only loads mail Api\Translation
Api\Translation::add_app($app);
// Execute import mail with provided content
ExecMethod($hook['menuaction'],array (

View File

@ -11,6 +11,8 @@
*/
use EGroupware\Api;
use EGroupware\Api\Framework;
use EGroupware\Api\Etemplate;
use EGroupware\Api\Mail;
class mail_sieve
@ -91,8 +93,8 @@ class mail_sieve
{
Api\Cache::setSession(__CLASS__, 'acc_id', $this->account->acc_id);
}
//Instantiate an Api\Etemplate object
$tmpl = new Api\Etemplate('mail.sieve.index');
//Instantiate an eTemplate object
$tmpl = new Etemplate('mail.sieve.index');
if ($msg)
{
@ -131,8 +133,8 @@ class mail_sieve
*/
function editEmailNotification($content=null, $msg='')
{
//Instantiate an Api\Etemplate object, representing sieve.emailNotification
$eNotitmpl = new Api\Etemplate('mail.sieve.emailNotification');
//Instantiate an eTemplate object, representing sieve.emailNotification
$eNotitmpl = new Etemplate('mail.sieve.emailNotification');
if ($this->account->acc_sieve_enabled)
{
@ -186,14 +188,14 @@ class mail_sieve
$msg .= lang('email notification update failed! You need to set an email address!');
break;
}
egw_framework::refresh_opener($msg, 'mail');
Framework::refresh_opener($msg, 'mail');
if ($button === 'apply')
{
break;
}
case 'cancel':
egw_framework::window_close();
Framework::window_close();
exit;
}
$this->saveSessionData();
@ -226,8 +228,8 @@ class mail_sieve
*/
function edit ($content=null)
{
//Instantiate an Api\Etemplate object, representing sieve.edit template
$etmpl = new Api\Etemplate('mail.sieve.edit');
//Instantiate an eTemplate object, representing sieve.edit template
$etmpl = new Etemplate('mail.sieve.edit');
$etmpl->setElementAttribute('action_folder_text','autocomplete_params', array('noPrefixId'=> true));
if (!is_array($content))
{
@ -333,7 +335,7 @@ class mail_sieve
$msg .= "\n".lang("Error: Could not save rule").' '.lang("No action defined!");
$error++;
}
egw_framework::refresh_opener($msg, 'mail', 'sieve');
Framework::refresh_opener($msg, 'mail', 'sieve');
if ($button == "apply")
{
break;
@ -356,10 +358,10 @@ class mail_sieve
$this->rules = array_values($this->rules);
$this->updateScript();
}
egw_framework::refresh_opener($msg, 'mail', 'sieve');
Framework::refresh_opener($msg, 'mail', 'sieve');
case 'cancel':
egw_framework::window_close();
Framework::window_close();
exit;
}
}
@ -397,7 +399,7 @@ class mail_sieve
{
if(!(empty($this->mailConfig['prefpreventnotificationformailviaemail']) || $this->mailConfig['prefpreventnotificationformailviaemail'] == 0))
{
throw new egw_exception_no_permission();
throw new Api\Exception\NoPermission();
}
try {
@ -421,7 +423,7 @@ class mail_sieve
{
if(!(empty($this->mailConfig['prefpreventabsentnotice']) || $this->mailConfig['prefpreventabsentnotice'] == 0))
{
throw new egw_exception_no_permission();
throw new Api\Exception\NoPermission();
}
try {
if ($this->is_admin_vac)
@ -438,11 +440,11 @@ class mail_sieve
}
catch(Exception $e)
{
egw_framework::window_close(lang($e->getMessage()));
Framework::window_close(lang($e->getMessage()));
}
if (is_null($accountID)) $accountID = $GLOBALS['egw_info']['user']['account_id'];
$accAllIdentities = $this->account->smtpServer()->getAccountEmailAddress(accounts::id2name($accountID));
$accAllIdentities = $this->account->smtpServer()->getAccountEmailAddress(Api\Accounts::id2name($accountID));
$allAliases = array($this->account->ident_email);
foreach ($accAllIdentities as &$arrVal)
{
@ -466,8 +468,8 @@ class mail_sieve
*/
function editVacation($content=null, $msg='')
{
//Instantiate an Api\Etemplate object, representing the sieve.vacation template
$vtmpl = new Api\Etemplate('mail.sieve.vacation');
//Instantiate an eTemplate object, representing the sieve.vacation template
$vtmpl = new Etemplate('mail.sieve.vacation');
$vacation = array();
if (isset($_GET['account_id'])) $account_id = $preserv['account_id'] = $_GET['account_id'];
@ -557,7 +559,7 @@ class mail_sieve
if (strlen(trim($content['text']))==0)
{
$content['msg'] = $msg = lang('error').': '.lang('No vacation notice text provided. Please enter a message.');
egw_framework::refresh_opener($msg, 'mail');
Framework::refresh_opener($msg, 'mail');
}
//Set default value for days new entry
if (empty($content['days']))
@ -639,7 +641,7 @@ class mail_sieve
//Reset vacationNotice cache which is used in mail_ui get_rows
if (isset($account_id) && $this->mail_admin)
{
$account_lid = accounts::id2name($account_id,'account_lid');
$account_lid = Api\Accounts::id2name($account_id,'account_lid');
$cachedVacations = array($icServer->acc_id => $newVacation) + (array)Api\Cache::getCache(Api\Cache::INSTANCE, 'email', 'vacationNotice'.$account_lid);
//error_log(__METHOD__.__LINE__.' Setting Cache for '.$account_lid.':'.array2string($cachedVacations));
Api\Cache::setCache(Api\Cache::INSTANCE,'email', 'vacationNotice'.$account_lid, $cachedVacations);
@ -658,9 +660,9 @@ class mail_sieve
$msg .= implode("\n",$this->errorStack);
}
// refresh vacationNotice on index
$response = egw_json_response::get();
$response = Api\Json\Response::get();
$response->call('app.mail.mail_callRefreshVacationNotice',$icServer->ImapServerId);
egw_framework::refresh_opener($msg, 'mail');
Framework::refresh_opener($msg, 'mail');
if ($button === 'apply' || $icServer->error !=="")
{
break;
@ -668,7 +670,7 @@ class mail_sieve
}
case 'cancel':
egw_framework::window_close();
Framework::window_close();
}
}
@ -739,10 +741,10 @@ class mail_sieve
{
if (!($_vacation['acc_id'] > 0))
{
throw new egw_exception_wrong_parameter('No acc_id given!');
throw new Api\Exception\WrongParameter('No acc_id given!');
}
// setting up an async job to enable/disable the vacation message
$async = new asyncservice();
$async = new Api\AsyncService();
if (empty($_vacation['account_id'])) $_vacation['account_id'] = $GLOBALS['egw_info']['user']['account_id'];
$async_id = !empty($_vacation['id']) ? $_vacation['id'] : 'mail-vacation-'.$_vacation['account_id'];
$async->delete($async_id);
@ -771,7 +773,7 @@ class mail_sieve
* Callback for the async job to enable/disable the vacation message
*
* @param array $_vacation
* @throws egw_exception_not_found if mail account is not found
* @throws Api\Exception\NotFound if mail account is not found
*/
static function async_vacation(array $_vacation)
{
@ -788,7 +790,7 @@ class mail_sieve
self::setAsyncJob($_vacation);
}
// if mail account no longer exists --> remove async job
catch (egw_exception_not_found $e)
catch (Api\Exception\NotFound $e)
{
$_vacation['status'] = 'off';
self::setAsyncJob($_vacation);
@ -899,7 +901,7 @@ class mail_sieve
$this->saveSessionData();
//Calling to referesh after move action
$response = egw_json_response::get();
$response = Api\Json\Response::get();
$response->call('app.mail.sieve_refresh');
}
@ -945,7 +947,7 @@ class mail_sieve
ob_start();
$result = $this->updateScript();
$response = egw_json_response::get();
$response = Api\Json\Response::get();
if($result)
{

View File

@ -5,11 +5,12 @@
* @link http://www.egroupware.org
* @package mail
* @author Hadi Nategh [hn@stylite.de]
* @copyright (c) 2015 by Stylite AG <info-AT-stylite.de>
* @copyright (c) 2015-16 by Stylite AG <info-AT-stylite.de>
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @version $Id:$
*/
use EGroupware\Api;
use EGroupware\Api\Mail;
use EGroupware\Api\Etemplate\Widget\Tree;
@ -375,7 +376,7 @@ class mail_tree
}
else
{
throw new egw_exception_assertion_failed(__METHOD__.':'.__LINE__.": id=$data[id]: Parent '$parent' '$component' not found!");
throw new Api\Exception\AssertionFailed(__METHOD__.':'.__LINE__.": id=$data[id]: Parent '$parent' '$component' not found!");
}
}
$parents[] = $component;

File diff suppressed because it is too large Load Diff

View File

@ -9,8 +9,11 @@
* @version $Id$
*/
use EGroupware\Api;
use EGroupware\Api\Framework;
/**
* Wizard to create mail accounts
* Wizard to create mail Api\Accounts
*
* Extends admin_mail to allow non-admins to use it.
*/
@ -29,11 +32,11 @@ class mail_wizard extends admin_mail
parent::__construct();
// need emailadmin's app.css file
egw_framework::includeCSS('admin','app');
Framework::includeCSS('admin','app');
// and translations
translation::add_app('admin');
Api\Translation::add_app('admin');
egw_framework::validate_file('/admin/js/app.js');
Framework::includeJS('/admin/js/app.js');
}
}

View File

@ -12,6 +12,7 @@
* @version $Id$
*/
use EGroupware\Api;
use EGroupware\Api\Mail;
/**
@ -97,7 +98,7 @@ class mail_zpush implements activesync_plugin_write, activesync_plugin_sendmail,
if (is_null(self::$profileID))
{
if ($this->debugLevel>1) error_log(__METHOD__.__LINE__.' self::ProfileID isNUll:'.array2string(self::$profileID));
self::$profileID =& egw_cache::getSession('mail','activeSyncProfileID');
self::$profileID =& Api\Cache::getSession('mail','activeSyncProfileID');
if ($this->debugLevel>1) error_log(__METHOD__.__LINE__.' ActiveProfileID (after reading Cache):'.array2string(self::$profileID));
}
if (isset($GLOBALS['egw_info']['user']['preferences']['activesync']['mail-ActiveSyncProfileID']))
@ -188,8 +189,8 @@ class mail_zpush implements activesync_plugin_write, activesync_plugin_sendmail,
if (isset($hook_data['prefs']['mail-ActiveSyncProfileID']) || $hook_data['type'] == 'user')
{
// eSync and eMail translations are not (yet) loaded
translation::add_app('activesync');
translation::add_app('mail');
Api\Translation::add_app('activesync');
Api\Translation::add_app('mail');
// inject preference to verify and call constructor
$GLOBALS['egw_info']['user']['preferences']['activesync']['mail-ActiveSyncProfileID'] =
@ -362,8 +363,8 @@ class mail_zpush implements activesync_plugin_write, activesync_plugin_sendmail,
ZLog::Write(LOGLEVEL_DEBUG,__METHOD__."(".__LINE__.")".' ProfileID:'.self::$profileID.' ActiveMailProfile:'.array2string($activeMailProfile));
// initialize the new egw_mailer object for sending
$mailObject = new egw_mailer(self::$profileID);
// initialize the new Api\Mailer object for sending
$mailObject = new Api\Mailer(self::$profileID);
$this->mail->parseRawMessageIntoMailObject($mailObject,$smartdata->mime);
// Horde SMTP Class uses utf-8 by default. as we set charset always to utf-8
$mailObject->Sender = $activeMailProfile['ident_email'];
@ -437,7 +438,7 @@ class mail_zpush implements activesync_plugin_write, activesync_plugin_sendmail,
else
{
$AltBody = $body;
$Body = trim(translation::convertHTMLToText($body));
$Body = trim(Api\Mail\Html::convertHTMLToText($body));
ZLog::Write(LOGLEVEL_DEBUG,__METHOD__."(".__LINE__.") fetched Body as :". $simpleBodyType.'=> Created Body');
}
}
@ -531,7 +532,7 @@ class mail_zpush implements activesync_plugin_write, activesync_plugin_sendmail,
$signature = $_signature['ident_signature'];
if ((isset($preferencesArray['disableRulerForSignatureSeparation']) &&
$preferencesArray['disableRulerForSignatureSeparation']) ||
empty($signature) || trim(translation::convertHTMLToText($signature)) =='')
empty($signature) || trim(Api\Mail\Html::convertHTMLToText($signature)) =='')
{
$disableRuler = true;
}
@ -541,7 +542,7 @@ class mail_zpush implements activesync_plugin_write, activesync_plugin_sendmail,
$sigText = Mail::merge($signature,array($GLOBALS['egw']->accounts->id2name($GLOBALS['egw_info']['user']['account_id'],'person_id')));
if ($this->debugLevel>0) ZLog::Write(LOGLEVEL_DEBUG,__METHOD__.__LINE__.' Signature to use:'.$sigText);
$sigTextHtml = $beforeHtml.$sigText;
$sigTextPlain = $beforePlain.translation::convertHTMLToText($sigText);
$sigTextPlain = $beforePlain.Api\Mail\Html::convertHTMLToText($sigText);
$isreply = $isforward = false;
// reply ---------------------------------------------------------------------------
if ($smartdata_task == 'reply' && isset($smartdata->source->itemid) &&
@ -578,7 +579,7 @@ class mail_zpush implements activesync_plugin_write, activesync_plugin_sendmail,
{
$isreply = true;
$AltBody = $AltBody."</br><pre>".nl2br($bodyBUFF).'</pre>'.$sigTextHtml;
if ($this->debugLevel>0) ZLog::Write(LOGLEVEL_DEBUG,__METHOD__.__LINE__." no html Body found use modified plaintext body for txt/html: ".$AltBody);
if ($this->debugLevel>0) ZLog::Write(LOGLEVEL_DEBUG,__METHOD__.__LINE__." no Api\Html Body found use modified plaintext body for txt/html: ".$AltBody);
}
}
@ -611,7 +612,6 @@ class mail_zpush implements activesync_plugin_write, activesync_plugin_sendmail,
// build a new mime message, forward entire old mail as file
if ($preferencesArray['message_forwarding'] == 'asmail')
{
$rawHeader='';
$rawHeader = $this->mail->getMessageRawHeader($smartdata->source->itemid, $_partID,$folder);
$rawBody = $this->mail->getMessageRawBody($smartdata->source->itemid, $_partID,$folder);
$mailObject->AddStringAttachment($rawHeader.$rawBody, $headers['SUBJECT'].'.eml', 'message/rfc822');
@ -664,7 +664,6 @@ class mail_zpush implements activesync_plugin_write, activesync_plugin_sendmail,
{
if ($this->debugLevel>0) ZLog::Write(LOGLEVEL_DEBUG,__METHOD__.__LINE__.' Key:'.$key.'->'.array2string($attachment));
$attachmentNames .= $attachment['name']."\n";
$attachmentData = '';
$attachmentData = $this->mail->getAttachment($uid, $attachment['partID'],0,false,false,$folder);
/*$x =*/ $mailObject->AddStringAttachment($attachmentData['attachment'], $mailObject->EncodeHeader($attachment['name']), $attachment['mimeType']);
ZLog::Write(LOGLEVEL_DEBUG,__METHOD__.__LINE__.' added part with number:'.$x);
@ -773,7 +772,7 @@ class mail_zpush implements activesync_plugin_write, activesync_plugin_sendmail,
$this->mail->appendMessage($folderName,$mailObject->getRaw(), null,
$flags);
}
catch (egw_exception_wrong_userinput $e)
catch (Api\Exception\WrongUserinput $e)
{
//$asf = false;
ZLog::Write(LOGLEVEL_DEBUG,__METHOD__.__LINE__.'->'.lang("Import of message %1 failed. Could not save message to folder %2 due to: %3",$mailObject->getHeader('Subject'),$folderName,$e->getMessage()));
@ -920,7 +919,7 @@ class mail_zpush implements activesync_plugin_write, activesync_plugin_sendmail,
$bodyStructplain = $this->mail->getMessageBody($id,'never_display', '', null, true,$_folderName); //'only_if_no_text');
if(isset($bodyStructplain[0])&&isset($bodyStructplain[0]['error'])&&$bodyStructplain[0]['error']==1)
{
$plainBody = translation::convertHTMLToText($body); // always display with preserved HTML
$plainBody = Api\Mail\Html::convertHTMLToText($body); // always display with preserved HTML
}
else
{
@ -939,8 +938,8 @@ class mail_zpush implements activesync_plugin_write, activesync_plugin_sendmail,
//SYNC_BODYPREFERENCE_MIME
ZLog::Write(LOGLEVEL_DEBUG,__METHOD__.__LINE__." bodypreference 4 requested");
$output->asbody->type = SYNC_BODYPREFERENCE_MIME;//4;
// use egw_mailer::convert to convert charset of all text parts to utf-8, which is a z-push or AS requirement!
$Body = egw_mailer::convert($this->mail->getMessageRawBody($id, '', $_folderName));
// use Api\Mailer::convert to convert charset of all text parts to utf-8, which is a z-push or AS requirement!
$Body = Api\Mailer::convert($this->mail->getMessageRawBody($id, '', $_folderName));
if ($this->debugLevel>2) debugLog(__METHOD__.__LINE__." Setting Mailobjectcontent to output:".$Body);
$output->asbody->data = $Body;
}
@ -1342,7 +1341,7 @@ class mail_zpush implements activesync_plugin_write, activesync_plugin_sendmail,
debugLog (__METHOD__.' for Folder:'.$folderid.' SINCE:'.$cutdate.'/'.date("d-M-Y", $cutdate));
if (empty($cutdate))
{
$cutdate = egw_time::to('now','ts')-(3600*24*28*3);
$cutdate = Api\DateTime::to('now','ts')-(3600*24*28*3);
ZLog::Write(LOGLEVEL_DEBUG,__METHOD__.' Client set no truncationdate. Using 12 weeks.'.date("d-M-Y", $cutdate));
}
return $this->fetchMessages($folderid, $cutdate);
@ -1504,7 +1503,7 @@ class mail_zpush implements activesync_plugin_write, activesync_plugin_sendmail,
// other types may be possible - we support quicksearch first (freeText in subject and from (or TO in Sent Folder))
if (is_null(Mail::$supportsORinQuery) || !isset(Mail::$supportsORinQuery[self::$profileID]))
{
Mail::$supportsORinQuery = egw_cache::getCache(egw_cache::INSTANCE,'email','supportsORinQuery'.trim($GLOBALS['egw_info']['user']['account_id']),$callback=null,$callback_params=array(),$expiration=60*60*10);
Mail::$supportsORinQuery = Api\Cache::getCache(Api\Cache::INSTANCE,'email','supportsORinQuery'.trim($GLOBALS['egw_info']['user']['account_id']),$callback=null,$callback_params=array(),$expiration=60*60*10);
if (!isset(Mail::$supportsORinQuery[self::$profileID])) Mail::$supportsORinQuery[self::$profileID]=true;
}
*/
@ -1539,8 +1538,8 @@ class mail_zpush implements activesync_plugin_write, activesync_plugin_sendmail,
$_filter['range'] = "BETWEEN";
list($sincedate,$crap) = explode('T',$searchquery['searchvaluegreater']);
list($beforedate,$crap) = explode('T',$searchquery['searchvalueless']);
$_filter['before'] = date("d-M-Y", egw_time::to($beforedate,'ts'));
$_filter['since'] = date("d-M-Y", egw_time::to($sincedate,'ts'));
$_filter['before'] = date("d-M-Y", Api\DateTime::to($beforedate,'ts'));
$_filter['since'] = date("d-M-Y", Api\DateTime::to($sincedate,'ts'));
}
//$_filter[] = array('type'=>"SINCE",'string'=> date("d-M-Y", $cutoffdate));
if ($this->debugLevel>1) debugLog (__METHOD__.' for Folder:'.$_folderName.' Filter:'.array2string($_filter));
@ -1773,7 +1772,7 @@ class mail_zpush implements activesync_plugin_write, activesync_plugin_sendmail,
{
$rv = $this->mail->deleteMessages($_messageUID, $folder);
}
catch (egw_exception $e)
catch (Api\Exception $e)
{
$error = $e->getMessage();
ZLog::Write(LOGLEVEL_DEBUG,__METHOD__.__LINE__." $_messageUID, $folder ->".$error);
@ -1885,7 +1884,7 @@ class mail_zpush implements activesync_plugin_write, activesync_plugin_sendmail,
* @param string $folder
* @param int $id =0
* @return string
* @throws egw_exception_wrong_parameter
* @throws Api\Exception\WrongParameter
*/
private function createID($account,$folder,$id=0)
{
@ -1909,7 +1908,7 @@ class mail_zpush implements activesync_plugin_write, activesync_plugin_sendmail,
* @param int &$account mail account id
* @param string &$folder
* @param int &$id=null
* @throws egw_exception_wrong_parameter
* @throws Api\Exception\WrongParameter
*/
private function splitID($str,&$account,&$folder,&$id=null)
{
@ -2007,13 +2006,13 @@ class mail_zpush implements activesync_plugin_write, activesync_plugin_sendmail,
* On request this function also returns, but never creates (!), old z-push 1 directory.
*
* @param boolean $old =false true: return old / pre-15 hash-file
* @throws egw_exception_assertion_failed
* @throws Api\Exception\AssertionFailed
*/
private function hashFile($old=false)
{
if (!($dev_id=Request::GetDeviceID()))
{
throw new egw_exception_assertion_failed(__METHOD__."() no DeviceID set!");
throw new Api\Exception\AssertionFailed(__METHOD__."() no DeviceID set!");
}
if ($old)
{

View File

@ -6,11 +6,13 @@
* @package mail
* @subpackage setup
* @author Stylite AG [info@stylite.de]
* @copyright (c) 2014 by Stylite AG <info-AT-stylite.de>
* @copyright (c) 2014-16 by Stylite AG <info-AT-stylite.de>
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @version $Id$
*/
use EGroupware\Api;
// change felamimail run rights to new mail app
$GLOBALS['egw_setup']->db->update('egw_acl', array(
'acl_appname' => 'mail',
@ -27,10 +29,10 @@ if (!$GLOBALS['egw_setup']->db->affected_rows())
}
// change common/default_app pref to mail, if it was felamimail
preferences::change_preference('common', 'default_app', 'mail', 'felamimail');
Api\Preferences::change_preference('common', 'default_app', 'mail', 'felamimail');
// copy felamimail preferences to new mail app, if they still exist there
preferences::copy_preferences('felamimail', 'mail', array(
// copy felamimail Api\Preferences to new mail app, if they still exist there
Api\Preferences::copy_preferences('felamimail', 'mail', array(
'htmlOptions',
'allowExternalIMGs',
'message_forwarding',

View File

@ -6,14 +6,14 @@
* @package mail
* @subpackage setup
* @author Stylite AG [info@stylite.de]
* @copyright (c) 2013-14 by Stylite AG <info-AT-stylite.de>
* @copyright (c) 2013-16 by Stylite AG <info-AT-stylite.de>
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @version $Id$
*/
$setup_info['mail']['name'] = 'mail';
$setup_info['mail']['title'] = 'mail';
$setup_info['mail']['version'] = '14.1';
$setup_info['mail']['version'] = '16.1';
$setup_info['mail']['app_order'] = 2;
$setup_info['mail']['enable'] = 1;
$setup_info['mail']['index'] = 'mail.mail_ui.index&ajax=true';
@ -39,10 +39,6 @@ $setup_info['mail']['hooks']['check_notify'] = 'mail_hooks::notification_check_m
$setup_info['mail']['hooks']['emailadmin_edit'] = 'mail_hooks::emailadmin_edit';
/* Dependencies for this app to work */
$setup_info['mail']['depends'][] = array(
'appname' => 'phpgwapi',
'versions' => Array('14.1')
);
$setup_info['mail']['depends'][] = array(
'appname' => 'api',
'versions' => Array('16.1')

View File

@ -5,159 +5,12 @@
* @link http://www.egroupware.org
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package api
* @subpackage egw action grid
* @subpackage etemplate
* @author Andreas Stöckel
* @copyright (c) 2011 Stylite
* @version $Id$
*/
class egw_keymanager
{
const BACKSPACE = 8;
const TAB = 9;
const ENTER = 13;
const ESCAPE = 27;
const DELETE = 46;
const SPACE = 32;
const PAGE_UP = 33;
const PAGE_DOWN = 34;
const ARROW_LEFT = 37;
const ARROW_UP = 38;
const ARROW_RIGHT = 39;
const ARROW_DOWN = 40;
const _0 = 48;
const _1 = 49;
const _2 = 50;
const _3 = 51;
const _4 = 52;
const _5 = 53;
const _6 = 54;
const _7 = 55;
const _8 = 56;
const _9 = 57;
const A = 65;
const B = 66;
const C = 67;
const D = 68;
const E = 69;
const F = 70;
const G = 71;
const H = 72;
const I = 73;
const J = 74;
const K = 75;
const L = 76;
const M = 77;
const N = 78;
const O = 79;
const P = 80;
const Q = 81;
const R = 82;
const S = 83;
const T = 84;
const U = 85;
const V = 86;
const W = 87;
const X = 88;
const Y = 89;
const Z = 90;
const F1 = 112;
const F2 = 113;
const F3 = 114;
const F4 = 115;
const F5 = 116;
const F6 = 117;
const F7 = 118;
const F8 = 119;
const F9 = 120;
const F10 = 121;
const F11 = 122;
const F12 = 123;
/**
* Converts the given key codes into translated key names.
*/
public static function key_name($keyCode)
{
// Keys which can be directly translated into ASCII chars
if (($keyCode >= self::_0 && $keyCode <= self::_9) ||
($keyCode >= self::A && $keyCode <= self::Z))
{
return chr($keyCode);
}
// Function keys
if ($keyCode >= self::F1 && $keyCode <= self::F12)
{
return "F".($keyCode - EGW_KEY_F1 + 1);
}
// Special keys
switch ($keyCode) {
case self::BACKSPACE:
return lang("Back");
case self::TAB:
return lang("Tab");
case self::DELETE:
return lang("Del");
case self::SPACE:
return lang("Space");
case self::PAGE_UP:
return lang("Pg up");
case self::PAGE_DOWN:
return lang("Pg down");
}
return "";
}
/**
* Generates the caption of the given shortcut and returns it
*/
public static function shortcut_caption($keyCode, $shift = false, $ctrl = false, $alt = false)
{
$elems = array();
if ($shift)
{
$elems[] = lang("Shift");
}
if ($ctrl)
{
$elems[] = lang("Ctrl");
}
if ($alt)
{
$elems[] = lang("Alt");
}
$elems[] = self::key_name($keyCode);
return implode(" + ", $elems);
}
/**
* Generates a shortcut structure which can be JSON encoded and send to the
* egw action system. This function and class could later be used to provide
* user defined shortcuts.
*/
public static function shortcut($keyCode, $shift = false, $ctrl = false, $alt = false)
{
return array(
"keyCode" => $keyCode,
"shift" => (boolean)$shift,
"ctrl" => (boolean)$ctrl,
"alt" => (boolean)$alt,
"caption" => self::shortcut_caption($keyCode, $shift, $ctrl, $alt)
);
}
}
use EGroupware\Api\Etemplate\KeyManager;
class egw_keymanager extends KeyManager{}