diff options
author | Markus Warg <mw@it-sls.de> | 2010-04-14 15:20:40 +0200 |
---|---|---|
committer | Markus Warg <mw@it-sls.de> | 2010-04-14 15:20:40 +0200 |
commit | ae053ad0371d46f529a26c2a18953189620b88e4 (patch) | |
tree | aad5ebb03e7138647f950be8960c3f7c84df0020 /manager | |
parent | d09a673644f87ee067f62f3de978cb046a02c7a8 (diff) | |
download | cacert-mgr-ae053ad0371d46f529a26c2a18953189620b88e4.tar.gz cacert-mgr-ae053ad0371d46f529a26c2a18953189620b88e4.tar.xz cacert-mgr-ae053ad0371d46f529a26c2a18953189620b88e4.zip |
imap class / mail controller
add imap class to access captured emails
add mail controller to framework (display content)
Diffstat (limited to 'manager')
-rw-r--r-- | manager/application/controllers/MailController.php | 24 | ||||
-rw-r--r-- | manager/application/views/scripts/mail/index.phtml | 7 | ||||
-rw-r--r-- | manager/library/actions/ActionLogin.php | 53 | ||||
-rw-r--r-- | manager/library/actions/ActionMail.php | 53 | ||||
-rw-r--r-- | manager/library/imap/exception.IMAPException.php | 34 | ||||
-rw-r--r-- | manager/library/imap/imapConnection.php | 559 | ||||
-rw-r--r-- | manager/library/imap/imapMail.php | 16 | ||||
-rw-r--r-- | manager/library/imap/imapMailContainer.php | 18 | ||||
-rw-r--r-- | manager/library/imap/imapParseAction.php | 96 | ||||
-rw-r--r-- | manager/library/plugins/plugin.loginlogout.php | 8 |
10 files changed, 867 insertions, 1 deletions
diff --git a/manager/application/controllers/MailController.php b/manager/application/controllers/MailController.php new file mode 100644 index 0000000..afe902b --- /dev/null +++ b/manager/application/controllers/MailController.php @@ -0,0 +1,24 @@ +<?php +/** + * @author markus + * $Id: IndexController.php 6 2009-11-18 14:52:50Z markus $ + */ + +require_once(LIBRARY_PATH . '/imap/imapConnection.php'); + +class MailController extends Zend_Controller_Action +{ + + public function init() + { + /* Initialize action controller here */ + } + + public function indexAction() + { + // action body + } + + +} + diff --git a/manager/application/views/scripts/mail/index.phtml b/manager/application/views/scripts/mail/index.phtml new file mode 100644 index 0000000..4cbadc3 --- /dev/null +++ b/manager/application/views/scripts/mail/index.phtml @@ -0,0 +1,7 @@ +<?php
+/**
+ * @author markus
+ * $Id: index.phtml 25 2009-12-02 15:43:21Z markus $
+ */
+?>
+<H1><?php print I18n::_('Mail'); ?></H1>
diff --git a/manager/library/actions/ActionLogin.php b/manager/library/actions/ActionLogin.php new file mode 100644 index 0000000..02bae86 --- /dev/null +++ b/manager/library/actions/ActionLogin.php @@ -0,0 +1,53 @@ +<?php
+
+require_once (FWACTIONS_PATH . '/FWAction.php');
+
+class Login extends FWAction {
+ /**
+ * get a list of required permissions that are needed to access this action
+ * @return array
+ */
+ public static function getRequiredPermissions() {
+ return array();
+ }
+
+ /**
+ * get a role that is required for accessing that action
+ * @return string
+ */
+ public static function getRequiredRole() {
+ return 'User';
+ }
+
+ /**
+ * sort order for top navigation
+ * @return integer
+ */
+ public static function getTopNavPrio() {
+ return 1000;
+ }
+
+ /**
+ * controller to invoke
+ * @return string
+ */
+ public static function getController() {
+ return 'login';
+ }
+
+ /**
+ * action to invoke
+ * @return string
+ */
+ public static function getAction() {
+ return 'index';
+ }
+
+ /**
+ * get text for menu, caller is responsible for translating
+ * @return string
+ */
+ public static function getMenuText() {
+ return 'Login';
+ }
+}
diff --git a/manager/library/actions/ActionMail.php b/manager/library/actions/ActionMail.php new file mode 100644 index 0000000..4ed23de --- /dev/null +++ b/manager/library/actions/ActionMail.php @@ -0,0 +1,53 @@ +<?php
+
+require_once (FWACTIONS_PATH . '/FWAction.php');
+
+class Mail extends FWAction {
+ /**
+ * get a list of required permissions that are needed to access this action
+ * @return array
+ */
+ public static function getRequiredPermissions() {
+ return array();
+ }
+
+ /**
+ * get a role that is required for accessing that action
+ * @return string
+ */
+ public static function getRequiredRole() {
+ return 'User';
+ }
+
+ /**
+ * sort order for top navigation
+ * @return integer
+ */
+ public static function getTopNavPrio() {
+ return 100;
+ }
+
+ /**
+ * controller to invoke
+ * @return string
+ */
+ public static function getController() {
+ return 'mail';
+ }
+
+ /**
+ * action to invoke
+ * @return string
+ */
+ public static function getAction() {
+ return 'index';
+ }
+
+ /**
+ * get text for menu, caller is responsible for translating
+ * @return string
+ */
+ public static function getMenuText() {
+ return 'Mail';
+ }
+}
diff --git a/manager/library/imap/exception.IMAPException.php b/manager/library/imap/exception.IMAPException.php new file mode 100644 index 0000000..4672f6a --- /dev/null +++ b/manager/library/imap/exception.IMAPException.php @@ -0,0 +1,34 @@ +<?php
+/**
+ * @author markus
+ * $Id: $
+ */
+
+/**
+ * required files
+ * @ignore
+ */
+require_once(LIBRARY_PATH . '/exception/exception.Base.php');
+
+/**
+ * Exceptions thrown in the IMAP classes
+ *
+ * @package SLS
+ * @subpackage CONFIG.EXCEPTION
+ * @author Markus Warg <mw@it-sls.de>
+ */
+class IMAPException extends BaseException {
+ /**
+ * make new object
+ *
+ * @access public
+ * @param string $message
+ * @param int $code
+ * @param string $extra
+ */
+ /*
+ public function __construct($message,$code = 0,$extra = '') {
+ parent::__construct($message,$code, $extra);
+ }
+ */
+}
diff --git a/manager/library/imap/imapConnection.php b/manager/library/imap/imapConnection.php new file mode 100644 index 0000000..f78dc3d --- /dev/null +++ b/manager/library/imap/imapConnection.php @@ -0,0 +1,559 @@ +<?php +/** + * @author markus + * $Id: $ + */ + +/** + * required files + * @ignore + */ +require_once('exception.IMAPException.php'); + +define('IMAP_RETRIES', 5); + +/** + * Wraps PHP built in imap commands within a class, features open, hold, close connection and + * issue imap commands. + * + * @author markus + */ +class imapConnection { + + /** + * Array mit den bereits vorhandenen Instanzen + * @var array + */ + private static $instances = array(); + + /** + * Instanzname, die unterschiedlichen Entitäten werden über den Namen + * auseinandergehalten. + * @var string + */ + private $instanceName = ''; + + /** + * Configsection + * @var Config + */ + private $config = null; + + /** + * IMAP Resource + * @var imap_stream + */ + private $imap = null; + + /** + * Servername, Port, Flags + * @var string + */ + private $server = ''; + + /** + * Name der zuletzt geöffneten Mailbox + * @var string + */ + private $mbox = ''; + + /** + * wird auf true gesetzt, wenn imapPing die Connection neu aufbaut + * @var boolean + */ + private $reopenedConnection = false; + + /** + * liefert eine Liste der verfügbaren Folder + * @param string $pattern + * @return array + */ + public function imapList($pattern = '*') { + if ($this->imap === null) { + throw new IMAPException(__METHOD__ . ' not connected'); + } + $this->imapPing(true); + + return imap_list($this->imap, $this->server, $pattern); + } + + + /** + * Checkt die Anzahl Messages in einer Mailbox + * return array + */ + public function imapCheck() { + if ($this->imap === null) { + throw new IMAPException(__METHOD__ . ' not connected'); + } + $this->imapPing(true); + + return imap_check($this->imap); + } + + + /** + * per imap_reopen die aktuelle Connection auf eine andere mbox umstellen + * @param string $mbox + * @return boolean + */ + public function imapSwitchMbox($mbox) { + if ($this->imap === null) { + throw new IMAPException(__METHOD__ . ' not connected'); + } + $this->imapPing(true); + + if (imap_reopen($this->imap, $this->server.$mbox) === false) { + throw new IMAPException(__METHOD__ . ' reopen failed'); + } + + $this->mbox = $mbox; + + return true; + } + + + /** + * setzt ein Flag bei allen in $sequence aufgeführten Messages + * @param string $sequence + * @param string $flag + * @param integer $options + * @return boolean + */ + public function imapSetflagFull($sequence, $flag, $options = 0) { + if ($this->imap === null) { + throw new IMAPException(__METHOD__ . ' not connected'); + } + $this->imapPing(true); + + return imap_setflag_full($this->imap, $sequence, $flag, $options); + } + + + /** + * liefert die Mailheader + * @return array + */ + public function imapHeaders() { + if ($this->imap === null) { + throw new IMAPException(__METHOD__ . ' not connected'); + } + $this->imapPing(true); + + return imap_headers($this->imap); + } + + /** + * liefert die Header zu genau einer Mail mit der gegebenen ID + * @param integer $number + * @return array + */ + public function imapHeader($number) { + if ($this->imap === null) { + throw new IMAPException(__METHOD__ . ' not connected'); + } + $this->imapPing(true); + + return imap_headerinfo($this->imap, $number); + } + + /** + * liefert die Header zu genau einer Mail mit der gegebenen UID + * @param integer $uid + * @return array + */ + public function imapFetchHeader($uid) { + if ($this->imap === null) { + throw new IMAPException(__METHOD__ . ' not connected'); + } + + $ret = imap_fetchheader($this->imap, $uid, FT_UID); + + return $ret; + } + + /** + * liefert die Header zu genau einer Mail mit der gegebenen UID + * @param integer $uid + * @return array + */ + public function imapFetchOverview($uid) { + if ($this->imap === null) { + throw new IMAPException(__METHOD__ . ' not connected'); + } + + $ret = imap_fetch_overview($this->imap, $uid, FT_UID); + + return $ret[0]; + } + + /** + * liefert den Body zu genau einer Mail mit der gegebenen ID + * @param integer $number + * @return string + */ + public function imapBody($number) { + if ($this->imap === null) { + throw new IMAPException(__METHOD__ . ' not connected'); + } + $this->imapPing(true); + + return imap_body($this->imap, $number); + } + + /** + * liefert den Body zu genau einer Mail mit der gegebenen UID + * @param integer $uid + * @return string + */ + public function imapBodyByUID($uid) { + if ($this->imap === null) { + throw new IMAPException(__METHOD__ . ' not connected'); + } + $this->imapPing(true); + + return imap_body($this->imap, $uid, FT_UID ); + } + + /** + * markiert die Nachricht mit der unique ID zum löschen + * @param integer $uid + * return boolean + */ + public function imapDelete($uid) { + if ($this->imap === null) { + throw new IMAPException(__METHOD__ . ' not connected'); + } + $this->imapPing(true); + + $ret = imap_delete($this->imap, $uid, FT_UID); + + if ($ret !== true) { + print "imap delete returned false for ".$uid."\n"; + } + + return $ret; + } + + /** + * löscht alle zum löschen markierten Nachrichten + * @return boolean + */ + public function imapExpunge() { + if ($this->imap === null) { + throw new IMAPException(__METHOD__ . ' not connected'); + } + $this->imapPing(true); + + return imap_expunge($this->imap); + } + + /** + * kopiert die Nachricht mit der gegebenen uid in die gegebene Mailbox *auf dem selben Server* + * @param integer $uid + * @param string $dest_mbox + * @return boolean + */ + public function imapMailCopy($uid, $dest_mbox) { + if ($this->imap === null) { + throw new IMAPException(__METHOD__ . ' not connected'); + } + $this->imapPing(true); + + return imap_mail_copy($this->imap, $uid, $dest_mbox, CP_UID); + } + + /** + * verschiebt die Nachricht mit der gegebenen uid in die gegebene Mailbox *auf dem selben Server* + * @param integer $uid + * @param string $dest_mbox + * @return boolean + */ + public function imapMailMove($uid, $dest_mbox) { + if ($this->imap === null) { + throw new IMAPException(__METHOD__ . ' not connected'); + } + $this->imapPing(true); + /* + * dont't add the server part, + * only the mailbox name works fine + * + * $dest_mbox = $this->server.$dest_mbox; + */ + return imap_mail_move( $this->imap, $uid, $dest_mbox, CP_UID); + } + + /** + * legt eine neue Mailbox *auf dem selben Server* an + * @param string $mbox + * @return boolean + */ + public function imapCreateMailbox($mbox) { + if ($this->imap === null) { + throw new IMAPException(__METHOD__ . ' not connected'); + } + $this->imapPing(true); + + return imap_createmailbox($this->imap, $this->server.$mbox); + } + + /** + * fragt ab, ob eine mbox unterhalb von mbox_root existiert und liefert true zurück, falls ja + * Funktion existiert nicht direkt als IMAP Kommando, aus einzelnen Kommando's zusammengebaut + * + * @param string $mbox_root + * @param string $mbox + * @return boolean + */ + public function imapMailboxExists($mbox_root, $mbox) { + if ($this->imap === null) { + throw new IMAPException(__METHOD__ . ' not connected'); + } + $this->imapPing(true); + + $folderlist = $this->imapList($mbox_root); + $foundFolder = false; + foreach ($folderlist as $folder) { + if (strpos($folder, $mbox) !== false) { + return true; + } + } + + return false; + } + + const AR_YYYY = 'Y'; + const AR_YYYYMM = 'Ym'; + const AR_YYYYMMDD = 'Ymd'; + + /** + * erzeugt eine Archivmailbox zur Mailbox $mbox, dabei wird das Archiv unterhalb von $mbox + * auf dem selben Server angelegt, der Name der Mailbox enthält je nach $mode noch einen Datumsstamp + * Wenn der Input ($mbox) bereits mehrere Ebenen enthält (NOC3.domain.incoming z.B.), dann + * wird automatisch nur der am weitesten rechts stehende Teil extrahiert und benutzt. + * NOC3.domain.incoming => NOC3.domain.incoming.incoming-200705 + * @param string $mbox + * @param string $mode + * @param integer $timestamp + * @param string $delimiter + * @return string + */ + public static function imapMakeArchiveName($mbox, $mode, $timestamp = null, $delimiter = '-') { + if ($timestamp === null) + $timestamp = time(); + + $ar = explode('.', $mbox); + + $sub_mbox = $ar[count($ar) - 1]; + + return $mbox.'.'.$sub_mbox.$delimiter.date($mode,$timestamp); + } + + public static function imapMakePrefixedArchiveName($mbox, $mode, $prefix = '', $timestamp = null, $delimiter = '-') { + if ($timestamp === null) + $timestamp = time(); + + $ar = explode('.', $mbox); + + $sub_mbox = $ar[count($ar) - 1]; + + return $mbox.'.'.$prefix.$delimiter.$sub_mbox.$delimiter.date($mode,$timestamp); + } + + /** + * liefert die unique ID der Nachricht mit der laufenden msg_number + * @param integer $msg_number + * @return integer + */ + public function imapUID($msg_number) { + if ($this->imap === null) { + throw new IMAPException(__METHOD__ . ' not connected'); + } + $this->imapPing(true); + + return imap_uid($this->imap, $msg_number); + } + + + /** + * liefert die laufende msg_number der Nachricht, die die unique ID uid hat + * @param integer $uid + * @return integer + */ + public function imapMsgNo($uid) { + if ($this->imap === null) { + throw new IMAPException(__METHOD__ . ' not connected'); + } + $this->imapPing(true); + + return imap_msgno($this->imap, $uid); + } + + + /** + * prüft, ob die Connection noch aktiv ist, Exception falls keine Connection definiert ist, + * oder die Connection geschlossen wurde + * wenn reconnect = true, dann wird bei einer geschlossenen Connection die Connection neu aufgebaut + * @param boolean $reconnect + * @return boolean + */ + public function imapPing($reconnect = false) { + if ($this->imap === null) { + throw new IMAPException(__METHOD__ . ' not connected'); + } + + $ret = imap_ping($this->imap); + + if ($ret === false) { + if ($reconnect === true) { + $this->imap = $this->imapOpen($this->server.$this->mbox, + $this->config->getValue('username'), + $this->config->getValue('password'), + OP_HALFOPEN); + + $ret = imap_ping($this->imap); + + if ($ret === false) { + throw new IMAPException(__METHOD__ . ' reconnect failed'); + } + + $this->reopenedConnection = true; + } + else { + throw new IMAPException(__METHOD__ . ' not connected'); + } + } + + return true; + } + + + public function __destruct() { + if ($this->imap !== null) { + imap_close($this->imap); + $this->imap = null; + } + } + + + /** + * true, wenn imapPing die Connection neu aufgemacht hat + * Variable wird auf false gesetzt wenn $flush true ist + * @param boolean $flush + * @return boolean + */ + public function connectionReopened($flush = true) { + $ret = $this->reopenedConnection; + if ($flush === true) { + $this->reopenedConnection = false; + } + return $ret; + } + + + /** + * interne IMAP Open Methode + * + * @param string $servername + * @param string $username + * @param string password + * @param integer $flags + * @return resource + */ + protected function imapOpen($server, $username, $password, $flags) { + return imap_open($server, $username, $password, $flags); + } + + + /** + * privater Konstruktor, wird exklusiv von getInstance aufgerufen + * + * @param $instanceName + * @param $config + */ + protected function __construct($instanceName,$config) { + $this->instanceName = $instanceName; + $this->config = $config; + + if (!$this->config->hasValue('mailhost')) { + throw new IMAPException(__METHOD__ . ' config attribute missing: "mailhost"'); + } + if (!$this->config->hasValue('username')) { + throw new IMAPException(__METHOD__ . ' config attribute missing: "username"'); + } + if (!$this->config->hasValue('password')) { + throw new IMAPException(__METHOD__ . ' config attribute missing: "password"'); + } + if (!$this->config->hasValue('port')) { + throw new IMAPException(__METHOD__ . ' config attribute missing: "port"'); + } + + $this->server = '{'.$this->config->getValue('mailhost').':'.$this->config->getValue('port').'/imap'; + if( $this->config->hasValue('use_tls') && + $this->config->getValue('use_tls') == true ) { + $this->server .= '/tls'; + } + $this->server .= '/novalidate-cert}'; + + $mbox = ''; + + $this->mbox = $mbox; + + $this->imap = null; + + $this->imap = $this->imapOpen($this->server.$mbox, + $this->config->getValue('username'), + $this->config->getValue('password'), + OP_HALFOPEN); + + if ($this->imap === false) { + $this->imap = null; + throw new IMAPException(__METHOD__ . ' not connected'); + } + + $this->reopenedConnection = false; + } + + + /** + * sucht nach einer bereits vorhandenen Instanz, wird keine gefunden, + * dann wird eine neue Instanz angelegt. + * Man kann die Config-Variable weglassen, wenn man sicher ist, dass + * bereits eine Instanz mit dem gewünschten instanceName existiert, + * existiert aber keiner, dann liefert getInstance eine Exception. + * + * @param $instance + * @param $config + * @return imapConnection + */ + public static function getInstance($instanceName,$config = null) { + if (!self::$instances) + self::$instances = array(); + + foreach (self::$instances as $instance) { + if ($instance->getInstanceName() == $instanceName) + return $instance; + } + + if (!$config instanceof Config) { + throw new IMAPException(__METHOD__ . ' no config'); + } + + $object = new imapConnection($instanceName, $config); + + self::$instances[] = $object; + + return $object; + } + + + /** + * Liefert den Namen der aktuellen Instanz + * @return string + */ + public function getInstanceName() { + return $this->instanceName; + } + + +} diff --git a/manager/library/imap/imapMail.php b/manager/library/imap/imapMail.php new file mode 100644 index 0000000..e211cb4 --- /dev/null +++ b/manager/library/imap/imapMail.php @@ -0,0 +1,16 @@ +<?php +/** + * @author markus + * $Id: $ + */ + +/** + * required files + * @ignore + */ + +/** + * eine Mail, die per imapConnection vom Server geholt wurde + * + * ToDo + */ diff --git a/manager/library/imap/imapMailContainer.php b/manager/library/imap/imapMailContainer.php new file mode 100644 index 0000000..e4bd280 --- /dev/null +++ b/manager/library/imap/imapMailContainer.php @@ -0,0 +1,18 @@ +<?php +/** + * @author markus + * $Id: $ + */ + +/** + * required files + * @ignore + */ +require_once(LIBRARY_PATH . '/imap/class.imapMail.php'); + +/** + * Container, um imapMail Objekte zu gruppieren + */ +class imapMailContainer { + +} diff --git a/manager/library/imap/imapParseAction.php b/manager/library/imap/imapParseAction.php new file mode 100644 index 0000000..d9e3fb0 --- /dev/null +++ b/manager/library/imap/imapParseAction.php @@ -0,0 +1,96 @@ +<?php +/** + * @author markus + * $Id: $ + */ + +/** + * required files + * @ignore + */ +require_once('exception.IMAPException.php'); + +/** + * Supportklasse für imapCleanMailbox + * Soll den in der Config pro Mailbox angegebenen Action-String auswerten + * und in eine automatisiert weiterverarbeitbare Form bringen. + */ +class imapParseAction { + /** + * Actions als Konstanten + * @var integer + */ + const IMAP_ACTION_DELETE = 1; + const IMAP_ACTION_ARCHIVE = 2; + + /** + * gesetzte Action + * @var integer + */ + private $action = 0; + + /** + * Modifikator keep gesetzt? + * @var boolean + */ + private $delete_keep = false; + + /** + * Wert des Modifikators keep + * @var integer + */ + private $delete_keep_num = 0; + + /** + * getAction + * @return integer + */ + public function getAction() { + return $this->action; + } + + /** + * getDeleteKeep + * @return boolean + */ + public function getDeleteKeep() { + return $this->delete_keep; + } + + /** + * getDeleteKeepNum + * @return integer + */ + public function getDeleteKeepNum() { + return $this->delete_keep_num; + } + + /** + * Konstruktor, parst eine Zeile mit Tokens und ermittelt, welche Aktionen + * auf einer Mailbox ausgeführt werden sollen + * @param string $action + */ + public function __construct($action) { + $args = explode(' ', $action); + + $numargs = count($args); + + for ($arg = 0; $arg < $numargs; $arg++) { + switch ($args[$arg]) { + case 'delete': + $this->action = self::IMAP_ACTION_DELETE; + break; + case 'keep': + $arg++; + $this->delete_keep = true; + $this->delete_keep_num = $args[$arg]; + break; + default: + /** + * @todo Exception werfen + */ + break; + } + } + } +} diff --git a/manager/library/plugins/plugin.loginlogout.php b/manager/library/plugins/plugin.loginlogout.php index 6de7a92..8bd13db 100644 --- a/manager/library/plugins/plugin.loginlogout.php +++ b/manager/library/plugins/plugin.loginlogout.php @@ -17,9 +17,15 @@ class LoginLogout extends Zend_Controller_Plugin_Abstract { $controller = 'logout';
$text = 'Logout';
}
+ $cur_ctrl = $request->getControllerName();
+ if ($cur_ctrl == 'login')
+ $aclass=' class="active"';
+ else
+ $aclass='';
+
$view = Zend_Registry::get('view');
$view->topNav('<a href="' .
$view->url(array('controller' => $controller), 'default', true) .
- '">' . I18n::_($text) . '</a>', Zend_View_Helper_Placeholder_Container_Abstract::SET, 1000);
+ '"' . $aclass . '>' . I18n::_($text) . '</a>', Zend_View_Helper_Placeholder_Container_Abstract::SET, 1000);
}
}
|