[horde] About framework

http://www.pas-world.com dev001 at pas-world.com
Tue Feb 12 19:08:16 UTC 2008


Hello,
I am trying to use IMP Code of compose.php as prototype of new class,
that do not need IMP propietary configuration parameters, (other
configuration).
At the moment I see that the code and configuration are very merge, this
seems a problem to me, I only can send plain text, -- no signed, no
encrypted--. I am not sure, that I can finish this work, I see the code
very interlaced. Program do not use message content as a block, and get
post data using a Util:: function.
... seems difficult...

The idea is made a independent, with independent conf and  prefs, class
that manages mail using, some of Horde code.
(,...,...,){
$mail = new Mail();
$mail->loadConfig(..);
$mail->Signed = True;
$mail->Encripted = false;
$mail->setSubject(..);
$mail->...
$mail->addHTML(,'inline','loadembeded' = true);
$mail->addtext();
$mail->addattach();
$mail->send();
}
If anyone know easy way...



At the moment:
Add path to:
php_value include_path ".:/usr/share/pear:/usr/share/horde/lib:/usr/share/horde/imp"      

---------------------------------> To send , independent part, should be
a function, "only to test and see the way", this is a very bad way, :):


		$f_to = 'customer at secure.mail.com';
		$f_cc = 'jv at localhost';
		$f_bcc = 'jv at localhost';

		//We need at least one recipient & RFC 2822 requires that no  8-bit
characters can be in the address fields.
		$recipientArray = COMPOSE::_recipientList(array($f_to, $f_cc,
$f_bcc));
		if (is_a($recipientArray, 'PEAR_Error')) {
			$notification->push($recipientArray, 'horde.error');
			$get_sig = false;
			break;
		}
		$recipients = implode(', ', $recipientArray);

		//Get identity information now as it is needed for some of the
encryption  code.
		/*$identity = &Identity::singleton(array('imp', 'imp'));
		$identity_form = Util::getFormData('identity');
		$from = $identity->getFromLine($identity_form,
Util::getFormData('from'));
		$barefrom = IMP::bareAddress($from);
		$identity->setDefault($identity_form);
		$replyto = $identity->getValue('replyto_addr');*/
		$from='plu at mail.com';

		//Set up the base message now.
		$imp_compose = &new IMP_Compose(array('cacheID' =>
$oldMessageCacheID));
		$charset = 'UTF-8';
		$body = COMPOSE::_baseMessage($imp_compose, $charset,TRUE);
		if (is_a($body, 'PEAR_Error')) {
			$notification->push($body, 'horde.error');
			break;
		}

		// Prepare the array of messages to send out.  May be more than one if
we are encrypting for multiple recipients are storing an encrypted
message locally.
		$messagesToSend = array();

		//Do encryption.

		//		$encrypt = Util::getFormData('encrypt_options');
		//		$usePGP = ($prefs->getValue('use_pgp') && !
empty($conf['utils']['gnupg']));
		//		$useSMIME = $prefs->getValue('use_smime');
		$encrypt = IMP_SMIME_SIGNENC;
		$usePGP = false;
		$useSMIME = true;

		$multiple_pgp_msg = false;

		if ($usePGP &&
		in_array($encrypt, array(IMP_PGP_ENCRYPT, IMP_PGP_SIGNENC))) {
			if (empty($imp_pgp)) {
				require_once IMP_BASE .'/lib/Crypt/PGP.php';
				$imp_pgp = &new IMP_PGP();
			}
			if (empty($imp_pgp->multipleRecipientEncryption)) {
				$multiple_pgp_msg = true;
			}
		}

		if ($multiple_pgp_msg ||
		($useSMIME &&
		in_array($encrypt, array(IMP_SMIME_ENCRYPT, IMP_SMIME_SIGNENC)))) {
			// Must encrypt & send the message one recipient at a time.
			foreach ($recipientArray as $val) {

				$res = COMPOSE::_createMimeMessage(array($val), $body);
				if (is_a($res, 'PEAR_Error')) {
					$get_sig = false;
					$notification->push($res, 'horde.error');
					break 2;
				}
				$messagesToSend[] = $res;
			}
				echo "encrypted<br />";
			// Must target the encryption for the sender before saving message in
sent-mail.
			$messageToSave = COMPOSE::_createMimeMessage(array($from), $body);
			if (is_a($messageToSave, 'PEAR_Error')) {
				$get_sig = false;
				$notification->push($messageToSave, 'horde.error');
				break;
			}
		} else {
			// No encryption - can send in clear-text all at once.
			echo "Sin encriptar";
			$res = COMPOSE::_createMimeMessage($recipientArray, $body);
			if (is_a($res, 'PEAR_Error')) {
				$get_sig = false;
				$notification->push($res, 'horde.error');
				break;
			}
			$messagesToSend[] = $messageToSave = $res;
		}

		// Initalize a header object for the outgoing message.

		$msg_headers = &new IMP_Headers();

		// Add a Received header for the hop from browser to server.
		$msg_headers->addReceivedHeader();
		$msg_headers->addMessageIdHeader();

		// Add the X-Priority header, if requested. This appears here since
this is the "general" location that other mail clients insert this
header.

		/*if ($prefs->getValue('set_priority') &&
		Util::getFormData('x_priority')) {
		$msg_headers->addHeader('X-Priority',
Util::getFormData('x_priority'));
		}*/

		$msg_headers->addHeader('Date', date('r'));

		// Add Return Receipt Headers.
		$conf['compose']['allow_receipts'] = true;
		if ($conf['compose']['allow_receipts']) {
			if (Util::getFormData('request_read_receipt')) {
				require_once 'Horde/MIME/MDN.php';
				$mdn = &new MIME_MDN();
				$mdn->addMDNRequestHeaders($msg_headers, $barefrom);
			}
		}

		//	$browser_charset = NLS::getCharset();
		$browser_charset = $charset;

		$msg_headers->addHeader('From', String::convertCharset($from,
$browser_charset, $charset));

		if (!empty($replyto) && ($replyto != $barefrom)) {
			$msg_headers->addHeader('Reply-to', String::convertCharset($replyto,
$browser_charset, $charset));
		}
		if (!empty($f_to)) {
			$msg_headers->addHeader('To', String::convertCharset($f_to,
$browser_charset, $charset));
		} elseif (empty($f_to) && empty($f_cc)) {
			$msg_headers->addHeader('To', 'undisclosed-recipients:;');
		}
		if (!empty($f_cc)) {
			$msg_headers->addHeader('Cc', String::convertCharset($f_cc,
$browser_charset, $charset));
		}
		$_POST['subject']='Subject of message TEST';
		$msg_headers->addHeader('Subject',
String::convertCharset(Util::getFormData('subject', ''),
$browser_charset, $charset));

		//Add necessary headers for replies.
		$reply_type = Util::getFormData('reply_type');

		$irt = Util::getFormData('in_reply_to');
		if ($reply_type == 'reply') {
			if ($ref = Util::getFormData('references')) {
				$msg_headers->addHeader('References', implode(' ', preg_split('|\s
+|', trim($ref))));
			}
			if ($irt) {
				$msg_headers->addHeader('In-Reply-To', $irt);
			}
		}

		// Send the messages out now.
		foreach ($messagesToSend as $val) {
			$headers = &Util::cloneObject($msg_headers);
			$headers->addMIMEHeaders($val['msg']);
			$res = $imp_compose->sendMessage($val['to'], $headers, $val['msg'],
$charset);
			if (is_a($res, 'PEAR_Error')) {
				// Unsuccessful send.
				//				Horde::logMessage($res->getMessage(), __FILE__, __LINE__,
PEAR_LOG_ERR);
				//$notification->push(sprintf(_("There was an error sending your
message: %s"), $res->getMessage()), 'horde.error');
				echo "--Email fail--";
				$get_sig = false;
				//				break 2;
			} else
			{
				echo "Email sent";
			}
		}

		// Delete the attachment data.
		$num_attachments = $imp_compose->numberOfAttachments();
		$imp_compose->deleteAllAttachments();
		exit(0);
---------------> New class for compose out of,  little "unordered", only
to test.
 <?php
$GLOBALS['imp']['maildomain']='secure.mail.com';
$_SESSION['imp']['maildomain'] = $GLOBALS['imp']['maildomain'];
$GLOBALS['mailer']='sendmail';
$GLOBALS['rtemode']='';
$GLOBALS['conf']['msg']['append_trailer']=false;
$GLOBALS['useSMIME']=false;
$GLOBALS['usePGP']=false;
global $conf;
$conf['mailer']['params'] = '';
$conf['mailer']['type'] = 'sendmail';
define('IMP_BASE', '/usr/share/horde/imp');
require_once 'config/header.php';
require_once 'conf.php';
require_once 'Horde/Identity.php';
require_once 'Horde/MIME.php';
require_once 'Horde/MIME/Part.php';
require_once 'lib/IMP.php';
require_once 'lib/Compose.php';
require_once 'lib/MIME/Headers.php';
require_once 'Horde/NLS.php';


/**
 * Determines the actionID.
 */
class COMPOSE
{
	function _getActionID()
	{
		if (!($aid = Util::getFormData('actionID'))) {
			foreach (array('send_message', 'save_draft', 'cancel_compose',
'add_attachment') as $val) {
				if (Util::getFormData('btn_' . $val)) {
					$aid = $val;
					break;
				}
			}
		}

		/* Alter the 'Send Message' action if the "Spell check before sending
		* message?" preference has been enabled. */
		if (($aid == 'send_message') &&
		(Util::getFormData('done_action') != 'send') &&
		!empty($GLOBALS['conf']['utils']['spellchecker']) &&
		$GLOBALS['prefs']->getValue('compose_spellcheck')) {
			return 'spell_check_send';
		} else {
			return $aid;
		}
	}

	/**
 * Return an url for mailbox.php depending on what kind of start/page
 * information we have.
 *
 * @param boolean $encode  Whether or not to encode entities in the URL.
 * @param string $url      The base URL.
 */
	function _mailboxReturnURL($encode, $url = null)
	{
		if (empty($url)) {
			$url = Horde::applicationUrl('mailbox.php');
		}

		foreach (array('start', 'page') as $key) {
			if (($param = Util::getFormData($key))) {
				$url = Util::addParameter($url, $key, $param, $encode);
			}
		}

		return $url;
	}

	/**
 * Returns a To:, Cc: or Bcc: list build from a selection based on
'expand
 * names'.
 */
	function _getAddressList($field, $expand = false)
	{
		$to = trim(Util::getFormData($field));
		if (!empty($to)) {
			$to = implode(', ', _cleanAddrList(array($to), false));
			return $expand ? $to : _formatAddr($to);
		}

		$to_list = Util::getFormData($field . '_list');
		$to = Util::getFormData($field . '_field');

		$tmp = array();
		if (is_array($to)) {
			foreach ($to as $key => $address) {
				$tmp[$key] = $address;
			}
		}
		if (is_array($to_list)) {
			foreach ($to_list as $key => $address) {
				if ($address != '') {
					$tmp[$key] = $address;
				}
			}
		}

		$to_new = trim(Util::getFormData($field . '_new'));
		if (!empty($to_new)) {
			$tmp[] = $to_new;
		}
		return implode(', ', $tmp);
	}

	/**
 * Expand addresses in a header.
 */
	function _expandAddresses($header)
	{
		$result = IMP::expandAddresses(_getAddressList($header, true), true);

		if (is_array($result)) {
			$GLOBALS['notification']->push(_("Please resolve ambiguous or invalid
addresses."), 'horde.warning');
		} elseif (is_a($result, 'PEAR_Error')) {
			$error = $result;
			$result = array();

			$list = $error->getUserInfo();
			if (is_array($list)) {
				foreach ($list as $entry) {
					if (is_object($entry)) {
						$result[] = $entry->getUserInfo();
					} else {
						$result[] = $entry;
					}
				}
			}
			$GLOBALS['notification']->push($error, 'horde.warning');
		}

		return $result;
	}

	/**
 * Checks for non-standard address formats, such as separating with
spaces
 * or semicolons, and return a "cleaned address string".
 */
	function _formatAddr($addr)
	{
		/* If there are angle brackets (<>), or a colon (group name
		delimiter), assume the user knew what they were doing. */
		if (!empty($addr) &&
		(strpos($addr, '>') === false) &&
		(strpos($addr, ':') === false)) {
			$addr = trim(strtr($addr, ';,', '  '));
			$addr = preg_replace('|\s+|', ', ', $addr);
		}

		return $addr;
	}

	/**
 * Generate a recipient list.
 */
	function _recipientList($addr)
	{
		$addrlist = COMPOSE::_cleanAddrList($addr, true);

		if (empty($addrlist)) {
			return PEAR::raiseError(_("You must enter at least one recipient."));
		}

		foreach (MIME::bareAddress(implode(', ', $addrlist),
$GLOBALS['imp']['maildomain'], true) as $val) {
			if (MIME::is8bit($val)) {
				return PEAR::raiseError(sprintf(_("Invalid character in e-mail
address: %s."), $val));
			}
		}

		return $addrlist;
	}

	/**
 * Returns the charset to use for outgoing messages based on (by
replying
 * to or forwarding) the given MIME message and the user's default
settings
 * and any previously selected charset.
 */
	function _getEncoding($mime_message = null)
	{
		if ($GLOBALS['charset']) {
			return $GLOBALS['charset'];
		}

		$encoding = NLS::getEmailCharset();

		if (isset($mime_message)) {
			$mime_message = &Util::cloneObject($mime_message);
			$mime_part = $mime_message->getBasePart();
			if ($mime_part->getPrimaryType() == MIME::type(TYPEMULTIPART)) {
				foreach ($mime_part->getParts() as $part) {
					if ($part->getPrimaryType() == MIME::type(TYPETEXT)) {
						$mime_part = $part;
						break;
					}
				}
			}
			if (NLS::getCharset() == 'UTF-8') {
				$charset_upper = String::upper($mime_part->getCharset());
				if (($charset_upper != 'US-ASCII') &&
				($charset_upper != String::upper($encoding))) {
					$encoding = 'UTF-8';
				}
			}
		}

		return $encoding;
	}

	/**
 * Setup the base message MIME_Part object.
 */
	function _baseMessage(&$imp_compose, $charset, $final_msg = true)
	{

		$message = String::convertCharset(/*Util::getFormData('message', '')*/
'Test message', NLS::getCharset(), $charset);
		echo 'Message is:'.$message.'<br />';

		if ($GLOBALS['rtemode']) {
			$message_html = $message;
			require_once 'Horde/Text/Filter.php';
			$message = Text_Filter::filter($message, 'html2text', array('wrap' =>
false));
		}

		/* Get trailer message (if any). */
		$trailer = null;
		if ($final_msg &&
		$GLOBALS['conf']['msg']['append_trailer'] &&
		@is_readable(IMP_BASE . '/config/trailer.txt')) {
			require_once 'Horde/Text/Filter.php';
			$trailer = Text_Filter::filter("\n" . file_get_contents(IMP_BASE .
'/config/trailer.txt'), 'environment');
			/* If there is a user defined function, call it with the current
			trailer as an argument. */
			if (!empty($GLOBALS['conf']['hooks']['trailer'])) {
				require_once HORDE_BASE . '/config/hooks.php';
				if (function_exists('_imp_hook_trailer')) {
					$trailer = call_user_func('_imp_hook_trailer', $trailer);
				}
			}
		}

		/* Set up the body part now. */
		$textBody = &new MIME_Part('text/plain');
		$textBody->setContents($textBody->replaceEOL($message));
		$textBody->setCharset($charset);
		if (!is_null($trailer)) {
			$textBody->appendContents($trailer);
		}

		/* Send in flowed format. */
		require_once 'Text/Flowed.php';
		$flowed = &new Text_Flowed($textBody->getContents(), $charset);
		if (method_exists($flowed, 'setDelSp')) {
			$flowed->setDelSp(true);
			$textBody->setContentTypeParameter('DelSp', 'Yes');
		}
		$textBody->setContents($flowed->toFlowed());
		$textBody->setContentTypeParameter('format', 'flowed');

		/* Determine whether or not to send a multipart/alternative
		* message with an HTML part. */
		if (!empty($message_html)) {
			$htmlBody = &new MIME_Part('text/html', String::wrap($message_html),
null, 'inline');
			if (!is_null($trailer)) {
				require_once 'Horde/Text/Filter.php';
				$htmlBody->appendContents(Text_Filter::filter($trailer, 'text2html',
array('parselevel' => TEXT_HTML_MICRO_LINKURL, 'class' => null,
'callback' => null)));
			}
			$basepart = &new MIME_Part('multipart/alternative');
			$textBody->setDescription(_("Plaintext Version of Message"));
			$basepart->addPart($textBody);
			$htmlBody->setDescription(_("HTML Version of Message"));
			$htmlBody->setCharset($charset);

			if ($final_msg) {
				/* Any image links will be downloaded and appended to the
				* message body. */
				$htmlBody = $imp_compose->convertToMultipartRelated($htmlBody);
			}
			$basepart->addPart($htmlBody);
		} else {
			$basepart = $textBody;
		}

		/* Add attachments now. */
		if ($imp_compose->numberOfAttachments()) {
			if ((Util::getFormData('link_attachments') &&
$GLOBALS['conf']['compose']['link_attachments']) ||
			!empty($GLOBALS['conf']['compose']['link_all_attachments'])) {
				$body =
$imp_compose->linkAttachments(Horde::applicationUrl('attachment.php',
true), $basepart, Auth::getAuth());
			} else {
				$body = &new MIME_Part('multipart/mixed');
				$body->addPart($basepart);
				$imp_compose->buildAllAttachments($body, $charset);
			}
		} else {
			$body = $basepart;
		}

		return $body;
	}

	/**
 * Create the base MIME_Message for sending.
 */
	function _createMimeMessage($to, $body)
	{
		require_once 'Horde/MIME/Message.php';
		$mime_message = &new MIME_Message($GLOBALS['imp']['maildomain']);

		/* Set up the base message now. */
		if ($GLOBALS['usePGP'] &&
		in_array($GLOBALS['encrypt'], array(IMP_PGP_ENCRYPT, IMP_PGP_SIGN,
IMP_PGP_SIGNENC))) {
			if (empty($GLOBALS['imp_pgp'])) {
				require_once IMP_BASE .'/lib/Crypt/PGP.php';
				$GLOBALS['imp_pgp'] = &new IMP_PGP();
			}
			$imp_pgp = &$GLOBALS['imp_pgp'];

			/* Get the user's passphrase, if we need it. */
			$passphrase = '';
			if (in_array($GLOBALS['encrypt'], array(IMP_PGP_SIGN,
IMP_PGP_SIGNENC))) {
				/* Check to see if we have the user's passphrase yet. */
				$passphrase = $imp_pgp->getPassphrase();
				if (empty($passphrase)) {
					$GLOBALS['pgp_passphrase_dialog'] = true;
					return PEAR::raiseError(_("PGP Error: Need passphrase for personal
private key."));
				}
			}

			/* Do the encryption/signing requested. */
			switch ($GLOBALS['encrypt']) {
				case IMP_PGP_SIGN:
					$body = $imp_pgp->IMPsignMIMEPart($body);
					break;

				case IMP_PGP_ENCRYPT:
					$body = $imp_pgp->IMPencryptMIMEPart($body, $to);
					break;

				case IMP_PGP_SIGNENC:
					$body = $imp_pgp->IMPsignAndEncryptMIMEPart($body, $to);
					break;
			}

			/* Check for errors. */
			if (is_a($body, 'PEAR_Error')) {
				return PEAR::raiseError(_("PGP Error: ") . $body->getMessage());
			}
		} elseif ($GLOBALS['useSMIME'] &&
		in_array($GLOBALS['encrypt'], array(IMP_SMIME_ENCRYPT, IMP_SMIME_SIGN,
IMP_SMIME_SIGNENC))) {
			if (empty($GLOBALS['imp_smime'])) {
				require_once IMP_BASE. '/lib/Crypt/SMIME.php';
				$GLOBALS['imp_smime'] = &new IMP_SMIME();
			}
			$imp_smime = &$GLOBALS['imp_smime'];

			/* Check to see if we have the user's passphrase yet. */
			if (in_array($GLOBALS['encrypt'], array(IMP_SMIME_SIGN,
IMP_SMIME_SIGNENC))) {
				$passphrase = $imp_smime->getPassphrase();
				if ($passphrase === false) {
					$GLOBALS['smime_passphrase_dialog'] = true;
					return PEAR::raiseError(_("S/MIME Error: Need passphrase for
personal private key."));
				}
			}

			/* Do the encryption/signing requested. */
			switch ($GLOBALS['encrypt']) {
				case IMP_SMIME_SIGN:
					$body = $imp_smime->IMPsignMIMEPart($body);
					break;

				case IMP_SMIME_ENCRYPT:
					$body = $imp_smime->IMPencryptMIMEPart($body, $to[0]);
					break;

				case IMP_SMIME_SIGNENC:
					$body = $imp_smime->IMPsignAndEncryptMIMEPart($body, $to[0]);
					break;
			}

			/* Check for errors. */
			if (is_a($body, 'PEAR_Error')) {
				return PEAR::raiseError(_("S/MIME Error: ") . $body->getMessage());
			}
		}

		/* Add data to MIME_Message object. */
		$mime_message->addPart($body);

		/* Append PGP signature if set in the preferences. */
		if ($GLOBALS['usePGP'] && Util::getFormData('pgp_attach_pubkey')) {
			if (!isset($GLOBALS['imp_pgp'])) {
				require_once IMP_BASE . '/lib/Crypt/PGP.php';
				$GLOBALS['imp_pgp'] = &new IMP_PGP();
			}
			$mime_message->addPart($GLOBALS['imp_pgp']->publicKeyMIMEPart());
		}

		return array('to' => implode(', ', $to), 'msg' => &$mime_message);
	}

	function _cleanAddrList($addrs, $multiple)
	{
		$addrlist = array();

		foreach ($addrs as $val) {
			$addr_array = MIME::rfc822Explode($val, ',');
			$addr_array = array_map('trim', $addr_array);
			foreach ($addr_array as $email) {
				if (!empty($email)) {
					$uniques = IMP::bareAddress($email, $multiple);
					if (!$multiple) {
						$uniques = array($uniques);
					}
					foreach ($uniques as $unique) {
						if ($unique && $unique !=
'UNEXPECTED_DATA_AFTER_ADDRESS at .SYNTAX-ERROR.') {
							$addrlist[$unique] = $multiple ? $unique : $email;
						} else {
							$addrlist[$email] = $email;
						}
					}
				}
			}
		}

		return array_values($addrlist);
	}
}
?>

----------------> And some other modifications for "support of", do not
load of config, prefs, and GLOBALS






El mar, 12-02-2008 a las 17:38 +0100, Jan Schneider escribió:
> Zitat von "http://www.pas-world.com"
> > Hello,
> > I searching class that have support for smime.
> > Manage Openssl with .cgi is very poor, only text/plain. Some classes
> > have a good multipart support but do not for smime. (any suggestion?)
> >
> > For this reason, I am searching new php class, or library that manage
> > MIME and SMIME.
> > At this moment, I test horde framework, but have some problems.
> > - requires php function, do not work in some cases (pear file and
> > lib/Horde files, not found). This is ease solved with full path.
> 
> You need to be more specific about which errors you receive, what is  
> not working etc. As a starter, you should set the include_path to  
> include the horde library directory. That is /usr/share/horde/lib on  
> your install.
> 
> Jan.
> 
> -- 
> Do you need professional PHP or Horde consulting?
> http://horde.org/consulting/
> 



More information about the horde mailing list