$have_mark = $scriptor && in_array(Ingo_Storage::ACTION_FLAGONLY, $scriptor->availableActions());
/* Get the blacklist object. */
-$blacklist = &$ingo_storage->retrieve(Ingo_Storage::ACTION_BLACKLIST);
-if (is_a($blacklist, 'PEAR_Error')) {
- $notification->push($blacklist);
+try {
+ $blacklist = $ingo_storage->retrieve(Ingo_Storage::ACTION_BLACKLIST);
+} catch (Ingo_Exception $e) {
+ $notification->push($e);
$blacklist = new Ingo_Storage_Blacklist();
}
$folder = $blacklist_folder = null;
/* Perform requested actions. */
-$actionID = Horde_Util::getFormData('actionID');
-switch ($actionID) {
+$vars = Horde_Variables::getDefaultVariables();
+switch ($vars->actionID) {
case 'create_folder':
- $blacklist_folder = Ingo::createFolder(Horde_Util::getFormData('new_folder_name'));
+ $blacklist_folder = Ingo::createFolder($vars->new_folder_name);
break;
case 'rule_update':
- switch (Horde_Util::getFormData('action')) {
+ switch ($vars->action) {
case 'delete':
$folder = '';
break;
break;
case 'folder':
- $folder = Horde_Util::getFormData('actionvalue');
+ $folder = $vars->actionvalue;
break;
}
if (($folder == Ingo::BLACKLIST_MARKER) && !$have_mark) {
$notification->push("Not supported by this script generator.", 'horde.error');
} else {
- $ret = $blacklist->setBlacklist(Horde_Util::getFormData('blacklist'));
+ $ret = $blacklist->setBlacklist($vars->blacklist);
if (is_a($ret, 'PEAR_Error')) {
$notification->push($ret, $ret->getCode());
} else {
'].checked=true');
/* Get the blacklist rule. */
-$filters = &$ingo_storage->retrieve(Ingo_Storage::ACTION_FILTERS);
+$filters = $ingo_storage->retrieve(Ingo_Storage::ACTION_FILTERS);
$bl_rule = $filters->findRule(Ingo_Storage::ACTION_BLACKLIST);
Ingo::prepareMenu();
* $Id$
*/
$ingo_fields = array(
- 'To' => array(
- 'label' => _("To"),
- 'type' => Ingo_Storage::TYPE_HEADER
- ),
- 'Subject' => array(
- 'label' => _("Subject"),
- 'type' => Ingo_Storage::TYPE_HEADER
- ),
- 'Sender' => array(
- 'label' => _("Sender"),
- 'type' => Ingo_Storage::TYPE_HEADER
- ),
- 'From' => array(
- 'label' => _("From"),
- 'type' => Ingo_Storage::TYPE_HEADER
- ),
- 'Cc' => array(
- 'label' => _("Cc"),
- 'type' => Ingo_Storage::TYPE_HEADER
- ),
- 'Bcc' => array(
- 'label' => _("Bcc"),
- 'type' => Ingo_Storage::TYPE_HEADER
- ),
- 'Resent-from' => array(
- 'label' => _("Resent-From"),
- 'type' => Ingo_Storage::TYPE_HEADER
- ),
- 'Resent-to' => array(
- 'label' => _("Resent-To"),
- 'type' => Ingo_Storage::TYPE_HEADER
- ),
- 'List-Id' => array(
- 'label' => _("List-ID"),
- 'type' => Ingo_Storage::TYPE_HEADER
- ),
- 'Received' => array(
- 'label' => _("Received"),
- 'type' => Ingo_Storage::TYPE_HEADER
- ),
- 'X-Spam-Level' => array(
- 'label' => _("X-Spam-Level"),
- 'type' => Ingo_Storage::TYPE_HEADER
- ),
- 'X-Spam-Score' => array(
- 'label' => _("X-Spam-Score"),
- 'type' => Ingo_Storage::TYPE_HEADER
- ),
- 'X-Spam-Status' => array(
- 'label' => _("X-Spam-Status"),
- 'type' => Ingo_Storage::TYPE_HEADER
- ),
- 'X-Priority' => array(
- 'label' => _("X-Priority"),
- 'type' => Ingo_Storage::TYPE_HEADER
- ),
- 'To,Cc,Bcc,Resent-to' => array(
- 'label' => _("Destination (To, Cc, Bcc, etc.)"),
- 'type' => Ingo_Storage::TYPE_HEADER
- ),
- 'From,Sender,Reply-to,Resent-from' => array(
- 'label' => _("Source (From, Reply-to, etc.)"),
- 'type' => Ingo_Storage::TYPE_HEADER
- ),
- 'To,Cc,Bcc,Resent-to,From,Sender,Reply-to,Resent-from' => array(
- 'label' => _("Participant (From, To, etc.)"),
- 'type' => Ingo_Storage::TYPE_HEADER
- ),
- 'Size' => array(
- 'label' => _("Size"),
- 'type' => Ingo_Storage::TYPE_SIZE,
- 'tests' => array('greater than', 'less than')
- ),
- 'Body' => array(
- 'label' => _("Body"),
- 'type' => Ingo_Storage::TYPE_BODY,
- 'tests' => array('contains', 'not contain', 'is', 'not is', 'begins with',
- 'not begins with', 'ends with', 'not ends with', 'regex',
- 'matches', 'not matches')
- )
+ 'To' => array(
+ 'label' => _("To"),
+ 'type' => Ingo_Storage::TYPE_HEADER
+ ),
+ 'Subject' => array(
+ 'label' => _("Subject"),
+ 'type' => Ingo_Storage::TYPE_HEADER
+ ),
+ 'Sender' => array(
+ 'label' => _("Sender"),
+ 'type' => Ingo_Storage::TYPE_HEADER
+ ),
+ 'From' => array(
+ 'label' => _("From"),
+ 'type' => Ingo_Storage::TYPE_HEADER
+ ),
+ 'Cc' => array(
+ 'label' => _("Cc"),
+ 'type' => Ingo_Storage::TYPE_HEADER
+ ),
+ 'Bcc' => array(
+ 'label' => _("Bcc"),
+ 'type' => Ingo_Storage::TYPE_HEADER
+ ),
+ 'Resent-from' => array(
+ 'label' => _("Resent-From"),
+ 'type' => Ingo_Storage::TYPE_HEADER
+ ),
+ 'Resent-to' => array(
+ 'label' => _("Resent-To"),
+ 'type' => Ingo_Storage::TYPE_HEADER
+ ),
+ 'List-Id' => array(
+ 'label' => _("List-ID"),
+ 'type' => Ingo_Storage::TYPE_HEADER
+ ),
+ 'Received' => array(
+ 'label' => _("Received"),
+ 'type' => Ingo_Storage::TYPE_HEADER
+ ),
+ 'X-Spam-Level' => array(
+ 'label' => _("X-Spam-Level"),
+ 'type' => Ingo_Storage::TYPE_HEADER
+ ),
+ 'X-Spam-Score' => array(
+ 'label' => _("X-Spam-Score"),
+ 'type' => Ingo_Storage::TYPE_HEADER
+ ),
+ 'X-Spam-Status' => array(
+ 'label' => _("X-Spam-Status"),
+ 'type' => Ingo_Storage::TYPE_HEADER
+ ),
+ 'X-Priority' => array(
+ 'label' => _("X-Priority"),
+ 'type' => Ingo_Storage::TYPE_HEADER
+ ),
+ 'To,Cc,Bcc,Resent-to' => array(
+ 'label' => _("Destination (To, Cc, Bcc, etc.)"),
+ 'type' => Ingo_Storage::TYPE_HEADER
+ ),
+ 'From,Sender,Reply-to,Resent-from' => array(
+ 'label' => _("Source (From, Reply-to, etc.)"),
+ 'type' => Ingo_Storage::TYPE_HEADER
+ ),
+ 'To,Cc,Bcc,Resent-to,From,Sender,Reply-to,Resent-from' => array(
+ 'label' => _("Participant (From, To, etc.)"),
+ 'type' => Ingo_Storage::TYPE_HEADER
+ ),
+ 'Size' => array(
+ 'label' => _("Size"),
+ 'type' => Ingo_Storage::TYPE_SIZE,
+ 'tests' => array('greater than', 'less than')
+ ),
+ 'Body' => array(
+ 'label' => _("Body"),
+ 'type' => Ingo_Storage::TYPE_BODY,
+ 'tests' => array(
+ 'contains', 'not contain', 'is', 'not is', 'begins with',
+ 'not begins with', 'ends with', 'not ends with', 'regex',
+ 'matches', 'not matches'
+ )
+ )
);
);
// Blacklist.
-// Lock this preference to disable blacklists.
$_prefs['blacklist'] = array(
'value' => 'a:2:{s:1:"a";a:0:{}s:1:"f";s:0:"";}',
+ // Lock this preference to disable blacklists.
'locked' => false,
'shared' => false,
'type' => 'implicit'
);
// Whitelist.
-// Lock this preference to disable whitelists.
$_prefs['whitelist'] = array(
'value' => 'a:0:{}',
+ // Lock this preference to disable whitelists.
'locked' => false,
'shared' => false,
'type' => 'implicit'
);
// Vacation notices.
-// Lock this preference to disable vacation notices.
$_prefs['vacation'] = array(
'value' => 'a:8:{s:9:"addresses";a:0:{}s:4:"days";i:7;s:8:"excludes";a:0:{}s:10:"ignorelist";b:1;s:6:"reason";s:0:"";s:7:"subject";s:0:"";s:5:"start";i:0;s:3:"end";i:0;}',
+ // Lock this preference to disable vacation notices.
'locked' => false,
'shared' => false,
'type' => 'implicit'
);
// Forwarding.
-// Lock this preference to disable forwarding.
$_prefs['forward'] = array(
'value' => 'a:2:{s:1:"a";a:0:{}s:1:"k";i:0;}',
+ // Lock this preference to disable forwarding.
'locked' => false,
'shared' => false,
'type' => 'implicit'
);
// Spam rule.
-// Lock this preference to disable the spam rule.
$_prefs['spam'] = array(
'value' => 'a:2:{s:6:"folder";N;s:5:"level";i:5;}',
+ // Lock this preference to disable the spam rule.
'locked' => false,
'shared' => false,
'type' => 'implicit'
Horde_Registry::appInit('ingo');
/* Get the list of filter rules. */
-$filters = &$ingo_storage->retrieve(Ingo_Storage::ACTION_FILTERS);
-if (is_a($filters, 'PEAR_Error')) {
- throw new Horde_Exception($filters);
-}
+$filters = $ingo_storage->retrieve(Ingo_Storage::ACTION_FILTERS);
/* Load the Ingo_Script:: driver. */
$ingo_script = Ingo::loadIngoScript();
$on_demand = $ingo_script->performAvailable();
/* Get web parameter data. */
-$actionID = Horde_Util::getFormData('actionID');
-$id = Horde_Util::getFormData('rulenumber');
+$vars = Horde_Variables::getDefaultVariables();
/* Get permissions. */
$edit_allowed = Ingo::hasSharePermission(Horde_Perms::EDIT);
$delete_allowed = Ingo::hasSharePermission(Horde_Perms::DELETE);
/* Perform requested actions. */
-switch ($actionID) {
+switch ($vars->actionID) {
case 'rule_down':
case 'rule_up':
case 'rule_copy':
header('Location: ' . Horde::applicationUrl('filters.php', true));
exit;
}
- switch ($actionID) {
+ switch ($vars->actionID) {
case 'rule_delete':
if (!$delete_allowed) {
$notification->push(_("You do not have permission to delete filter rules."), 'horde.error');
exit;
}
- $tmp = $filters->getFilter($id);
- if ($filters->deleteRule($id)) {
+ $tmp = $filters->getFilter($vars->rulenumber);
+ if ($filters->deleteRule($vars->rulenumber)) {
$notification->push(sprintf(_("Rule \"%s\" deleted."), $tmp['name']), 'horde.success');
}
break;
$notification->push($message, 'horde.error', array('content.raw'));
break 2;
} else {
- $tmp = $filters->getFilter($id);
- if ($filters->copyRule($id)) {
+ $tmp = $filters->getFilter($vars->rulenumber);
+ if ($filters->copyRule($vars->rulenumber)) {
$notification->push(sprintf(_("Rule \"%s\" copied."), $tmp['name']), 'horde.success');
}
}
break;
case 'rule_up':
- $steps = Horde_Util::getFormData('steps', 1);
- $filters->ruleUp($id, $steps);
+ $filters->ruleUp($vars->rulenumber, $vars->steps || 1);
break;
case 'rule_down':
- $steps = Horde_Util::getFormData('steps', 1);
- $filters->ruleDown($id, $steps);
+ $filters->ruleDown($vars->rulenumber, $vars->steps || 1);
break;
case 'rule_disable':
- $tmp = $filters->getFilter($id);
- $filters->ruleDisable($id);
+ $tmp = $filters->getFilter($vars->rulenumber);
+ $filters->ruleDisable($vars->rulenumber);
$notification->push(sprintf(_("Rule \"%s\" disabled."), $tmp['name']), 'horde.success');
break;
case 'rule_enable':
- $tmp = $filters->getFilter($id);
- $filters->ruleEnable($id);
+ $tmp = $filters->getFilter($vars->rulenumber);
+ $filters->ruleEnable($vars->rulenumber);
$notification->push(sprintf(_("Rule \"%s\" enabled."), $tmp['name']), 'horde.success');
break;
}
header('Location: ' . Horde::applicationUrl('filters.php', true));
exit;
}
- $prefs->setValue('show_filter_msg', Horde_Util::getFormData('show_filter_msg'));
- $prefs->setValue('filter_seen', Horde_Util::getFormData('filter_seen'));
+ $prefs->setValue('show_filter_msg', $vars->show_filter_msg);
+ $prefs->setValue('filter_seen', $vars->filter_seen);
$notification->push(_("Settings successfully updated."), 'horde.success');
break;
$entry = array();
$entry['number'] = ++$i;
- $url = Horde_Util::addParameter($filters_url, 'rulenumber', $rule_number);
+ $url = $filters_url->copy()->add('rulenumber', $rule_number);
$copyurl = $delurl = $editurl = $name = null;
switch ($filter['action']) {
break;
default:
- $editurl = Horde_Util::addParameter($rule_url, array('edit' => $rule_number, 'actionID' => 'rule_edit'));
- $delurl = Horde_Util::addParameter($url, 'actionID', 'rule_delete');
- $copyurl = Horde_Util::addParameter($url, 'actionID', 'rule_copy');
+ $editurl = $rule_url->copy()->add(array('edit' => $rule_number, 'actionID' => 'rule_edit'));
+ $delurl = $url->copy()->add('actionID', 'rule_delete');
+ $copyurl = $url->copy()->add('actionID', 'rule_copy');
$entry['filterimg'] = false;
$name = $filter['name'];
break;
}
/* Create up/down arrow links. */
- $entry['upurl'] = Horde_Util::addParameter($url, 'actionID', 'rule_up');
- $entry['downurl'] = Horde_Util::addParameter($url, 'actionID', 'rule_down');
- $entry['uplink'] = ($i > 1) ? Horde::link($entry['upurl'], _("Move Rule Up")) : false;
- $entry['downlink'] = ($i < $rule_count) ? Horde::link($entry['downurl'], _("Move Rule Down")) : false;
+ $entry['upurl'] = $url->copy()->add('actionID', 'rule_up');
+ $entry['downurl'] = $url->copy()->add('actionID', 'rule_down');
+ $entry['uplink'] = ($i > 1)
+ ? Horde::link($entry['upurl'], _("Move Rule Up"))
+ : false;
+ $entry['downlink'] = ($i < $rule_count)
+ ? Horde::link($entry['downurl'], _("Move Rule Down"))
+ : false;
if (empty($filter['disable'])) {
if ($edit_allowed) {
- $entry['disablelink'] = Horde::link(Horde_Util::addParameter($url, 'actionID', 'rule_disable'), sprintf(_("Disable %s"), $name));
+ $entry['disablelink'] = Horde::link($url->copy()->add('actionID', 'rule_disable'), sprintf(_("Disable %s"), $name));
$entry['disableimg'] = Horde::img('enable.png', sprintf(_("Disable %s"), $name));
} else {
$entry['disableimg'] = Horde::img('enable.png');
$entry['enableimg'] = false;
} else {
if ($edit_allowed) {
- $entry['enablelink'] = Horde::link(Horde_Util::addParameter($url, 'actionID', 'rule_enable'), sprintf(_("Enable %s"), $name));
+ $entry['enablelink'] = Horde::link($url->copy()->add('actionID', 'rule_enable'), sprintf(_("Enable %s"), $name));
$entry['enableimg'] = Horde::img('disable.png', sprintf(_("Enable %s"), $name));
} else {
$entry['enableimg'] = Horde::img('disable.png');
}
/* Get the forward object and rule. */
-$forward = &$ingo_storage->retrieve(Ingo_Storage::ACTION_FORWARD);
-$filters = &$ingo_storage->retrieve(Ingo_Storage::ACTION_FILTERS);
+$forward = $ingo_storage->retrieve(Ingo_Storage::ACTION_FORWARD);
+$filters = $ingo_storage->retrieve(Ingo_Storage::ACTION_FILTERS);
$fwd_id = $filters->findRuleId(Ingo_Storage::ACTION_FORWARD);
$fwd_rule = $filters->getRule($fwd_id);
/* Load libraries. */
-$vars = &Horde_Variables::getDefaultVariables();
-if ($vars->get('submitbutton') == _("Return to Rules List")) {
+$vars = Horde_Variables::getDefaultVariables();
+if ($vars->submitbutton == _("Return to Rules List")) {
header('Location: ' . Horde::applicationUrl('filters.php', true));
exit;
}
/* Build form. */
$form = new Horde_Form($vars);
-$v = &$form->addVariable(_("Keep a copy of messages in this account?"), 'keep_copy', 'boolean', false);
+$v = $form->addVariable(_("Keep a copy of messages in this account?"), 'keep_copy', 'boolean', false);
$v->setHelp('forward-keepcopy');
-$v = &$form->addVariable(_("Address(es) to forward to:"), 'addresses', 'longtext', false, false, null, array(5, 40));
+$v = $form->addVariable(_("Address(es) to forward to:"), 'addresses', 'longtext', false, false, null, array(5, 40));
$v->setHelp('forward-addresses');
$form->setButtons(_("Save"));
/* Perform requested actions. */
if ($form->validate($vars)) {
- $forward->setForwardAddresses($vars->get('addresses'));
- $forward->setForwardKeep($vars->get('keep_copy') == 'on');
+ $forward->setForwardAddresses($vars->addresses);
+ $forward->setForwardKeep($vars->keep_copy == 'on');
$success = true;
- if (is_a($result = $ingo_storage->store($forward), 'PEAR_Error')) {
- $notification->push($result);
- $success = false;
- } else {
+ try {
+ $ingo_storage->store($forward);
$notification->push(_("Changes saved."), 'horde.success');
- if ($vars->get('submitbutton') == _("Save and Enable")) {
+ if ($vars->submitbutton == _("Save and Enable")) {
$filters->ruleEnable($fwd_id);
- if (is_a($result = $ingo_storage->store($filters), 'PEAR_Error')) {
- $notification->push($result);
- $success = false;
- } else {
- $notification->push(_("Rule Enabled"), 'horde.success');
- $fwd_rule['disable'] = false;
- }
- } elseif ($vars->get('submitbutton') == _("Save and Disable")) {
+ $ingo_storage->store($filters);
+ $notification->push(_("Rule Enabled"), 'horde.success');
+ $fwd_rule['disable'] = false;
+ } elseif ($vars->submitbutton == _("Save and Disable")) {
$filters->ruleDisable($fwd_id);
- if (is_a($result = $ingo_storage->store($filters), 'PEAR_Error')) {
- $notification->push($result);
- $success = false;
- } else {
- $notification->push(_("Rule Disabled"), 'horde.success');
- $fwd_rule['disable'] = true;
- }
+ $ingo_storage->store($filters);
+ $notification->push(_("Rule Disabled"), 'horde.success');
+ $fwd_rule['disable'] = true;
}
+ } catch (Ingo_Exception $e) {
+ $notification->push($e);
+ $success = false;
}
+
if ($success && $prefs->getValue('auto_update')) {
Ingo::updateScript();
}
/* Set default values. */
if (!$form->isSubmitted()) {
- $vars->set('keep_copy', $forward->getForwardKeep());
- $vars->set('addresses', implode("\n", $forward->getForwardAddresses()));
+ $vars->keep_copy = $forward->getForwardKeep();
+ $vars->addresses = implode("\n", $forward->getForwardAddresses());
}
/* Set form title. */
}
if (!empty($addresses)) {
- $blacklist = &$GLOBALS['ingo_storage']->retrieve(Ingo_Storage::ACTION_BLACKLIST);
- $ret = $blacklist->setBlacklist(array_merge($blacklist->getBlacklist(), $addresses));
- if (is_a($ret, 'PEAR_Error')) {
- $GLOBALS['notification']->push($ret, $ret->getCode());
- } else {
+ try {
+ $blacklist = $GLOBALS['ingo_storage']->retrieve(Ingo_Storage::ACTION_BLACKLIST);
+ $blacklist->setBlacklist(array_merge($blacklist->getBlacklist(), $addresses));
$GLOBALS['ingo_storage']->store($blacklist);
Ingo::updateScript();
foreach ($addresses as $from) {
$GLOBALS['notification']->push(sprintf(_("The address \"%s\" has been added to your blacklist."), $from));
}
+ } catch (Ingo_Exception $e) {
+ $GLOBALS['notification']->push($e);
}
}
}
$_SESSION['ingo']['current_share'] = $signature;
}
- $whitelist = &$GLOBALS['ingo_storage']->retrieve(Ingo_Storage::ACTION_WHITELIST);
- $ret = $whitelist->setWhitelist(array_merge($whitelist->getWhitelist(), $addresses));
- if (is_a($ret, 'PEAR_Error')) {
- $GLOBALS['notification']->push($ret, $ret->getCode());
- } else {
+ try {
+ $whitelist = $GLOBALS['ingo_storage']->retrieve(Ingo_Storage::ACTION_WHITELIST);
+ $whitelist->setWhitelist(array_merge($whitelist->getWhitelist(), $addresses));
$GLOBALS['ingo_storage']->store($whitelist);
Ingo::updateScript();
foreach ($addresses as $from) {
$GLOBALS['notification']->push(sprintf(_("The address \"%s\" has been added to your whitelist."), $from));
}
+ } catch (Ingo_Exception $e) {
+ $GLOBALS['notification']->push($e);
}
}
*/
public function canApplyFilters()
{
- $ingo_script = Ingo::loadIngoScript();
- return $ingo_script
- ? $ingo_script->performAvailable()
- : false;
+ try {
+ return Ingo::loadIngoScript()->performAvailable();
+ } catch (Ingo_Exception $e) {
+ return false;
+ }
}
/**
if (!empty($GLOBALS['ingo_shares'])) {
$_SESSION['ingo']['current_share'] = $signature;
}
- $ingo_script = Ingo::loadIngoScript();
- if (!$ingo_script) {
+
+ try {
+ $ingo_script = Ingo::loadIngoScript();
+ } catch (Ingo_Exception $e) {
return false;
}
+
if (!isset($params['filter_seen'])) {
$params['filter_seen'] = $GLOBALS['prefs']->getValue('filter_seen');
}
+
if (!isset($params['show_filter_msg'])) {
$params['show_filter_msg'] = $GLOBALS['prefs']->getValue('show_filter_msg');
}
+
return $ingo_script->perform($params);
}
*/
public function setVacation($info)
{
- if (!empty($GLOBALS['ingo_shares'])) {
- $_SESSION['ingo']['current_share'] = $signature;
- }
-
if (empty($info)) {
return true;
}
+ if (!empty($GLOBALS['ingo_shares'])) {
+ $_SESSION['ingo']['current_share'] = $signature;
+ }
+
/* Get vacation filter. */
- $filters = &$GLOBALS['ingo_storage']->retrieve(Ingo_Storage::ACTION_FILTERS);
+ $filters = $GLOBALS['ingo_storage']->retrieve(Ingo_Storage::ACTION_FILTERS);
$vacation_rule_id = $filters->findRuleId(Ingo_Storage::ACTION_VACATION);
/* Set vacation object and rules. */
- $vacation = &$GLOBALS['ingo_storage']->retrieve(Ingo_Storage::ACTION_VACATION);
+ $vacation = $GLOBALS['ingo_storage']->retrieve(Ingo_Storage::ACTION_VACATION);
/* Make sure we have at least one address. */
if (empty($info['addresses'])) {
}
$filters->ruleEnable($vacation_rule_id);
- $result = $GLOBALS['ingo_storage']->store($filters);
- if (!is_a($result, 'PEAR_Error')) {
+
+ try {
+ $GLOBALS['ingo_storage']->store($filters);
+
if ($GLOBALS['prefs']->getValue('auto_update')) {
Ingo::updateScript();
}
/* Update the timestamp for the rules. */
$_SESSION['ingo']['change'] = time();
- }
- return $result;
+ return true;
+ } catch (Ingo_Exception $e) {}
+
+ return false;
}
/**
}
/* Get vacation filter. */
- $filters = &$GLOBALS['ingo_storage']->retrieve(Ingo_Storage::ACTION_FILTERS);
+ $filters = $GLOBALS['ingo_storage']->retrieve(Ingo_Storage::ACTION_FILTERS);
$vacation_rule_id = $filters->findRuleId(Ingo_Storage::ACTION_VACATION);
$filters->ruleDisable($vacation_rule_id);
- $result = $GLOBALS['ingo_storage']->store($filters);
- if (!is_a($result, 'PEAR_Error')) {
+
+ try {
+ $GLOBALS['ingo_storage']->store($filters);
+
if ($GLOBALS['prefs']->getValue('auto_update')) {
Ingo::updateScript();
}
/* Update the timestamp for the rules. */
$_SESSION['ingo']['change'] = time();
- }
- return $result;
+ return true;
+ } catch (Ingo_Exception $e) {}
+
+ return false;
}
}
// Load the Ingo_Storage driver.
$GLOBALS['ingo_storage'] = Ingo_Storage::factory();
- // Create the ingo session (if needed).
- if (!isset($_SESSION['ingo']) || !is_array($_SESSION['ingo'])) {
- Ingo_Session::createSession();
- }
+ // Create the ingo session.
+ Ingo::createSession();
// Create shares if necessary.
$driver = Ingo::getDriver();
*
* @param string $user Name of user to remove data for.
*
- * @return mixed true on success | PEAR_Error on failure
+ * @throws Horde_Auth_Exception.
*/
public function removeUserData($user)
{
- if (!Horde_Auth::isAdmin() && $user != Horde_Auth::getAuth()) {
- return PEAR::raiseError(_("You are not allowed to remove user data."));
+ if (!Horde_Auth::isAdmin() &&
+ ($user != Horde_Auth::getAuth())) {
+ throw new Horde_Auth_Exception(_("You are not allowed to remove user data."));
}
/* Remove all filters/rules owned by the user. */
- $result = $GLOBALS['ingo_storage']->removeUserData($user);
- if (is_a($result, 'PEAR_Error')) {
- Horde::logMessage($result, __FILE__, __LINE__, PEAR_LOG_ERR);
- return $result;
+ try {
+ $GLOBALS['ingo_storage']->removeUserData($user);
+ } catch (Ingo_Exception $e) {
+ Horde::logMessage($e, __FILE__, __LINE__, PEAR_LOG_ERR);
+ throw new Horde_Auth_Exception($e);
}
/* Now remove all shares owned by the user. */
if (!empty($GLOBALS['ingo_shares'])) {
/* Get the user's default share. */
$share = $GLOBALS['ingo_shares']->getShare($user);
- if (is_a($share, 'PEAR_Error')) {
+ if ($share instanceof PEAR_Error) {
Horde::logMessage($share, __FILE__, __LINE__, PEAR_LOG_ERR);
- return $share;
- } else {
- $result = $GLOBALS['ingo_shares']->removeShare($share);
- if (is_a($result, 'PEAR_Error')) {
- Horde::logMessage($result, __FILE__, __LINE__, PEAR_LOG_ERR);
- return $result;
- }
+ throw new Horde_Auth_Exception($share);
+ }
+
+ $result = $GLOBALS['ingo_shares']->removeShare($share);
+ if ($result instanceof PEAR_Error) {
+ Horde::logMessage($result, __FILE__, __LINE__, PEAR_LOG_ERR);
+ throw new Horde_Auth_Exception($share);
}
/* Get a list of all shares this user has perms to and remove the
* perms. */
$shares = $GLOBALS['ingo_shares']->listShares($user);
- if (is_a($shares, 'PEAR_Error')) {
+ if ($shares instanceof PEAR_Error) {
Horde::logMessage($shares, __FILE__, __LINE__, PEAR_LOG_ERR);
- }
- foreach ($shares as $share) {
- $share->removeUser($user);
+ } else {
+ foreach ($shares as $share) {
+ $share->removeUser($user);
+ }
}
/* Get a list of all shares this user owns and has perms to delete
* and remove them. */
$shares = $GLOBALS['ingo_shares']->listShares($user, Horde_Perms::DELETE, $user);
- if (is_a($shares, 'PEAR_Error')) {
+ if ($shares instanceof PEAR_Error) {
Horde::logMessage($shares, __FILE__, __LINE__, PEAR_LOG_ERR);
- return $shares;
+ throw new Horde_Auth_Exception($share);
}
+
foreach ($shares as $share) {
$GLOBALS['ingo_shares']->removeShare($share);
}
}
-
- return true;
}
}
protected $_support_shares = false;
/**
- * Attempts to return a concrete Ingo_Driver instance based on $driver.
+ * Attempts to return a concrete instance based on $driver.
*
- * @param string $driver The type of concrete Ingo_Driver subclass to
- * return.
- * @param array $params A hash containing any additional configuration or
- * connection parameters a subclass might need.
+ * @param string $driver The type of concrete subclass to return.
+ * @param array $params A hash containing any additional configuration
+ * or connection parameters a subclass might need.
*
- * @return mixed The newly created concrete Ingo_Driver instance, or
- * false on error.
+ * @return Ingo_Driver The newly created concrete instance.
+ * @throws Ingo_Exception
*/
static public function factory($driver, $params = array())
{
- $driver = basename($driver);
- $class = 'Ingo_Driver_' . ucfirst($driver);
+ $class = __CLASS__ . '_' . ucfirst(basename($driver));
- return class_exists($class)
- ? new $class($params)
- : false;
+ if (class_exists($class)) {
+ return new $class($params);
+ }
+
+ throw new Ingo_Exception('Could not load driver.');
}
/**
*
* @param string $script The filter script.
*
- * @return mixed True on success, false if script can't be activated.
- * Returns PEAR_Error on error.
+ * @return boolean True on success, false if script can't be activated.
+ * @throws Ingo_Exception
*/
public function setScriptActive($script)
{
*/
public function supportShares()
{
- return $this->_support_shares && !empty($_SESSION['ingo']['backend']['shares']);
+ return ($this->_support_shares &&
+ !empty($_SESSION['ingo']['backend']['shares']));
}
}
/**
* Constructor.
*
- * @throws Horde_Exception
+ * @throws Ingo_Exception
*/
public function __construct($params = array())
{
if (!Horde_Util::extensionExists('ldap')) {
- throw new Horde_Exception(_("LDAP support is required but the LDAP module is not available or not loaded."));
+ throw new Ingo_Exception(_("LDAP support is required but the LDAP module is not available or not loaded."));
}
$default_params = array(
/**
* Connect and bind to ldap server.
+ *
+ * @throws Ingo_Exception
*/
protected function _connect()
{
if (!($ldapcn = @ldap_connect($this->_params['hostspec'],
$this->_params['port']))) {
- return PEAR::raiseError(_("Connection failure"));
+ throw new Ingo_Exception(_("Connection failure"));
}
/* Set the LDAP protocol version. */
}
/* Start TLS if we're using it. */
- if (!empty($this->_params['tls'])) {
- if (!@ldap_start_tls($ldapcn)) {
- return PEAR::raiseError(sprintf(_("STARTTLS failed: (%s) %s"),
- ldap_errno($ldapcn),
- ldap_error($ldapcn)));
- }
+ if (!empty($this->_params['tls']) &&
+ !@ldap_start_tls($ldapcn)) {
+ throw new Ingo_Exception(sprintf(_("STARTTLS failed: (%s) %s"),
+ ldap_errno($ldapcn),
+ ldap_error($ldapcn)));
}
/* Bind to the server. */
if (isset($this->_params['bind_dn'])) {
$bind_dn = $this->_substUser($this->_params['bind_dn']);
- if (is_a($bind_dn, 'PEAR_Error')) {
- return $bind_dn;
- }
- if (isset($this->_params['bind_password'])) {
- $password = $this->_params['bind_password'];
- } else {
- $password = $this->_params['password'];
- }
+ $password = isset($this->_params['bind_password'])
+ ? $this->_params['bind_password']
+ : $this->_params['password'];
- if (!@ldap_bind($ldapcn, $bind_dn, $password)) {
- return PEAR::raiseError(sprintf(_("Bind failed: (%s) %s"),
- ldap_errno($ldapcn),
- ldap_error($ldapcn)));
- }
- } elseif (!(@ldap_bind($ldapcn))) {
- return PEAR::raiseError(sprintf(_("Bind failed: (%s) %s"),
- ldap_errno($ldapcn),
- ldap_error($ldapcn)));
+ $bind_success = @ldap_bind($ldapcn, $bind_dn, $password);
+ } else {
+ $bind_success = @ldap_bind($ldapcn);
}
- return $ldapcn;
+ if ($bind_success) {
+ return $ldapcn;
+ }
+
+
+ throw new Ingo_Exception(sprintf(_("Bind failed: (%s) %s"),
+ ldap_errno($ldapcn),
+ ldap_error($ldapcn)));
}
/**
* @param resource $ldapcn The connection to the LDAP server.
* @param string $userDN Set to the user object's real DN.
*
- * @return mixed Array of script sources, or PEAR_Error on failure.
+ * @return array Script sources list.
+ * @throws Ingo_Exception
*/
protected function _getScripts($ldapcn, &$userDN)
{
$sr = @ldap_search($ldapcn, $this->_params['script_base'], $filter,
$attrs);
if ($sr === false) {
- return PEAR::raiseError(sprintf(_("Error retrieving current script: (%d) %s"),
- ldap_errno($ldapcn),
- ldap_error($ldapcn)));
+ throw new Ingo_Exception(sprintf(_("Error retrieving current script: (%d) %s"),
+ ldap_errno($ldapcn),
+ ldap_error($ldapcn)));
}
+
if (@ldap_count_entries($ldapcn, $sr) != 1) {
- return PEAR::raiseError(sprintf(_("Expected 1 object, got %d."),
- ldap_count_entries($ldapcn, $sr)));
+ throw new Ingo_Exception(sprintf(_("Expected 1 object, got %d."),
+ ldap_count_entries($ldapcn, $sr)));
}
+
$ent = @ldap_first_entry($ldapcn, $sr);
if ($ent === false) {
- return PEAR::raiseError(sprintf(_("Error retrieving current script: (%d) %s"),
- ldap_errno($ldapcn),
- ldap_error($ldapcn)));
+ throw new Ingo_Exception(sprintf(_("Error retrieving current script: (%d) %s"),
+ ldap_errno($ldapcn),
+ ldap_error($ldapcn)));
}
/* Retrieve the user's DN. */
$v = @ldap_get_dn($ldapcn, $ent);
if ($v === false) {
@ldap_free_result($sr);
- return PEAR::raiseError(sprintf(_("Error retrieving current script: (%d) %s"),
- ldap_errno($ldapcn),
- ldap_error($ldapcn)));
+ throw new Ingo_Exception(sprintf(_("Error retrieving current script: (%d) %s"),
+ ldap_errno($ldapcn),
+ ldap_error($ldapcn)));
}
$userDN = $v;
$attrs = @ldap_get_attributes($ldapcn, $ent);
@ldap_free_result($sr);
if ($attrs === false) {
- return PEAR::raiseError(sprintf(_("Error retrieving current script: (%d) %s"),
- ldap_errno($ldapcn),
- ldap_error($ldapcn)));
+ throw new Ingo_Exception(sprintf(_("Error retrieving current script: (%d) %s"),
+ ldap_errno($ldapcn),
+ ldap_error($ldapcn)));
}
/* Attribute can be in any case, and can have a ";binary"
*
* @param string $script The sieve script.
*
- * @return mixed True on success, PEAR_Error on error.
+ * @throws Ingo_Exception
*/
protected function setScriptActive($script)
{
$ldapcn = $this->_connect();
- if (is_a($ldapcn, 'PEAR_Error')) {
- return $ldapcn;
- }
-
$values = $this->_getScripts($ldapcn, $userDN);
- if (is_a($values, 'PEAR_Error')) {
- return $values;
- }
$found = false;
foreach ($values as $i => $value) {
break;
}
}
+
if (!$found && !empty($script)) {
$values[] = $script;
}
$replace = array(Horde_String::lower($this->_params['script_attribute']) => $values);
- if (empty($values)) {
- $r = @ldap_mod_del($ldapcn, $userDN, $replace);
- } else {
- $r = @ldap_mod_replace($ldapcn, $userDN, $replace);
- }
+ $r = empty($values)
+ ? @ldap_mod_del($ldapcn, $userDN, $replace)
+ : @ldap_mod_replace($ldapcn, $userDN, $replace);
+
if (!$r) {
- return PEAR::raiseError(sprintf(_("Activating the script for \"%s\" failed: (%d) %s"),
- $userDN,
- ldap_errno($ldapcn),
- ldap_error($ldapcn)));
+ throw new Ingo_Exception(sprintf(_("Activating the script for \"%s\" failed: (%d) %s"),
+ $userDN,
+ ldap_errno($ldapcn),
+ ldap_error($ldapcn)));
}
@ldap_close($ldapcn);
+
return true;
}
* Returns the content of the currently active script.
*
* @return string The complete ruleset of the specified user.
+ *
+ * @throws Ingo_Exception
*/
public function getScript()
{
$ldapcn = $this->_connect();
- if (is_a($ldapcn, 'PEAR_Error')) {
- return $ldapcn;
- }
-
$values = $this->_getScripts($ldapcn, $userDN);
- if (is_a($values, 'PEAR_Error')) {
- return $values;
- }
$script = '';
foreach ($values as $value) {
/**
* Connect to the sieve server.
*
- * @return mixed True on success, PEAR_Error on false.
+ * @throws Ingo_Exception;
*/
protected function _connect()
{
if (!empty($this->_sieve)) {
- return true;
+ return;
}
$this->sivtestSocket($this->_params['username'],
$this->_params['usetls']);
$res = $this->_sieve->getError();
- if (is_a($res, 'PEAR_Error')) {
+ if ($res instanceof PEAR_Error) {
unset($this->_sieve);
- return $res;
- } else {
- return true;
+ throw new Ingo_Exception($res);
}
}
*
* @param string $script The sieve script.
*
- * @return mixed True on success.
- * Returns PEAR_Error on error.
+ * @throws Ingo_Exception
*/
public function setScriptActive($script)
{
- $res = $this->_connect();
- if (is_a($res, 'PEAR_Error')) {
- return $res;
- }
+ $this->_connect();
$res = $this->_sieve->haveSpace($this->_params['scriptname'], strlen($script));
- if (is_a($res, 'PEAR_ERROR')) {
- return $res;
+ if ($res instanceof PEAR_Error) {
+ throw new Ingo_Exception($res);
}
return $this->_sieve->installScript($this->_params['scriptname'], $script, true);
* Returns the content of the currently active script.
*
* @return string The complete ruleset of the specified user.
+ * @throws Ingo Exception
*/
public function getScript()
{
- $res = $this->_connect();
- if (is_a($res, 'PEAR_Error')) {
- return $res;
- }
+ $this->_connect();
return $this->_sieve->getScript($this->_sieve->getActive());
}
* @param string $hostspec The hostspec.
*
* @return TODO
+ * @throws Ingo_Exception
*/
public function sivtestSocket($username, $password, $hostspec)
{
}
$socket = new Net_Socket();
$error = $socket->connect($domain_socket, 0, true, 30);
- if (!is_a($error, 'PEAR_Error')) {
+ if (!($error instanceof PEAR_Error)) {
break;
}
}
if (!empty($error_return)) {
- return PEAR::raiseError(_($error_return));
+ throw new Ingo_Exception($error_return);
}
$status = $socket->getStatus();
- if (is_a($status, 'PEAR_Error') || $status['eof']) {
- return PEAR::raiseError(_('Failed to write to socket: (connection lost!)'));
+ if ($status instanceof PEAR_Error || $status['eof']) {
+ throw new Ingo_Exception(_("Failed to write to socket: (connection lost!)"));
}
$error = $socket->writeLine("CAPABILITY");
- if (is_a($error, 'PEAR_Error')) {
- return PEAR::raiseError(_('Failed to write to socket: ' . $error->getMessage()));
+ if ($error instanceof PEAR_Error) {
+ throw new Ingo_Exception(_("Failed to write to socket: " . $error->getMessage()));
}
$result = $socket->readLine();
- if (is_a($result, 'PEAR_Error')) {
- return PEAR::raiseError(_('Failed to read from socket: ' . $error->getMessage()));
+ if ($result instanceof PEAR_Error) {
+ throw new Ingo_Exception(_("Failed to read from socket: " . $error->getMessage()));
}
if (preg_match('|^bye \(referral "(sieve://)?([^"]+)|i',
/**
* Connects to the sieve server.
+ *
+ * @throws Ingo_Exception
*/
protected function _connect()
{
return;
}
- if (empty($this->_params['admin'])) {
- $auth = $this->_params['username'];
- } else {
- $auth = $this->_params['admin'];
- }
+ $auth = empty($this->_params['admin'])
+ ? $this->_params['username']
+ : $this->_params['admin'];
+
$this->_sieve = new Net_Sieve($auth,
$this->_params['password'],
$this->_params['hostspec'],
$this->_params['usetls']);
$res = $this->_sieve->getError();
- if (is_a($res, 'PEAR_Error')) {
+ if ($res instanceof PEAR_Error) {
unset($this->_sieve);
- return $res;
+ throw new Ingo_Exception($res);
}
if (!empty($this->_params['debug'])) {
*
* @param string $script The sieve script.
*
- * @return mixed True on success, PEAR_Error on error.
+ * @return mixed True on success.
+ * @throws Ingo_Exception
*/
public function setScriptActive($script)
{
$res = $this->_connect();
- if (is_a($res, 'PEAR_Error')) {
- return $res;
- }
if (!strlen($script)) {
return $this->_sieve->setActive('');
}
- $res = $this->_sieve->haveSpace($this->_params['scriptname'],
- strlen($script));
- if (is_a($res, 'PEAR_ERROR')) {
- return $res;
+ $res = $this->_sieve->haveSpace($this->_params['scriptname'], strlen($script));
+ if ($res instanceof PEAR_Error) {
+ throw new Ingo_Exception($res);
}
return $this->_sieve->installScript($this->_params['scriptname'],
* Returns the content of the currently active script.
*
* @return string The complete ruleset of the specified user.
+ * @throws Ingo_Exception
*/
public function getScript()
{
$res = $this->_connect();
- if (is_a($res, 'PEAR_Error')) {
- return $res;
- }
$active = $this->_sieve->getActive();
- if (empty($active)) {
- return '';
- }
- return $this->_sieve->getScript($active);
+
+ return empty($active)
+ ? ''
+ : $this->_sieve->getScript($active);
}
}
/**
* Sets a script running on the backend.
*
- * @param string $script The filter script
+ * @param string $script The filter script.
*
- * @return mixed True on success, or PEAR_Error on failure.
+ * @return mixed True on success.
+ * @throws Ingo_Exception
*/
public function setScriptActive($script)
{
- $result = $this->_connect();
- if (is_a($result, 'PEAR_Error')) {
- return $result;
- }
+ $this->_connect();
- if (empty($script)) {
- $result = $this->_vfs->deleteFile($this->_params['vfs_path'], $this->_params['filename']);
- } else {
- $result = $this->_vfs->writeData($this->_params['vfs_path'], $this->_params['filename'], $script, true);
- }
- if (is_a($result, 'PEAR_Error')) {
- return $result;
+ $result = empty($script)
+ ? $this->_vfs->deleteFile($this->_params['vfs_path'], $this->_params['filename'])
+ : $this->_vfs->writeData($this->_params['vfs_path'], $this->_params['filename'], $script, true);
+ if ($result instanceof PEAR_Error) {
+ throw new Ingo_Exception($result);
}
if (isset($this->_params['file_perms']) && !empty($script)) {
$result = $this->_vfs->changePermissions($this->_params['vfs_path'], $this->_params['filename'], $this->_params['file_perms']);
- if (is_a($result, 'PEAR_Error')) {
- return $result;
+ if ($result instanceof PEAR_Error) {
+ throw new Ingo_Exception($result);
}
}
// Get the backend; necessary if a .forward is needed for
// procmail.
$backend = Ingo::getBackend();
- if ($backend['script'] == 'procmail' && isset($backend['params']['forward_file']) && isset($backend['params']['forward_string'])) {
- if (empty($script)) {
- $result = $this->_vfs->deleteFile($this->_params['vfs_forward_path'], $backend['params']['forward_file']);
- } else {
- $result = $this->_vfs->writeData($this->_params['vfs_forward_path'], $backend['params']['forward_file'], $backend['params']['forward_string'], true);
- }
- if (is_a($result, 'PEAR_Error')) {
- return $result;
+ if (($backend['script'] == 'procmail') &&
+ isset($backend['params']['forward_file']) &&
+ isset($backend['params']['forward_string'])) {
+ $result = empty($script)
+ ? $this->_vfs->deleteFile($this->_params['vfs_forward_path'], $backend['params']['forward_file'])
+ : $this->_vfs->writeData($this->_params['vfs_forward_path'], $backend['params']['forward_file'], $backend['params']['forward_string'], true);
+ if ($result instanceof PEAR_Error) {
+ throw new Ingo_Exception($result);
}
if (isset($this->_params['file_perms']) && !empty($script)) {
$result = $this->_vfs->changePermissions($this->_params['vfs_forward_path'], $backend['params']['forward_file'], $this->_params['file_perms']);
- if (is_a($result, 'PEAR_Error')) {
- return $result;
+ if ($result instanceof PEAR_Error) {
+ throw new Ingo_Exception($result);
}
}
}
* Returns the content of the currently active script.
*
* @return string The complete ruleset of the specified user.
+ * @throws Ingo_Exception
*/
public function getScript()
{
- $result = $this->_connect();
- if (is_a($result, 'PEAR_Error')) {
- return $result;
- }
+ $this->_connect();
return $this->_vfs->read($this->_params['vfs_path'], $this->_params['filename']);
}
/**
* Connect to the VFS server.
*
- * @return boolean True on success, PEAR_Error on false.
+ * @throws Ingo_Exception
*/
protected function _connect()
{
return true;
}
- $this->_vfs = &VFS::singleton($this->_params['vfstype'], $this->_params);
- if (is_a($this->_vfs, 'PEAR_Error')) {
- $error = $this->_vfs;
- $this->_vfs = null;
- return $error;
- } else {
- return true;
+ $this->_vfs = VFS::singleton($this->_params['vfstype'], $this->_params);
+ if ($this->_vfs instanceof PEAR_Error) {
+ $error = new Ingo_Exception($this->_vfs);
+ unset($this->_vfs);
+ throw new Ingo_Exception($error);
}
}
--- /dev/null
+<?php
+/**
+ * Base exception class for Ingo.
+ *
+ * Copyright 2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file LICENSE for license information (ASL). If you
+ * did not receive this file, see http://www.horde.org/licenses/asl.php.
+ *
+ * @author Michael Slusarz <slusarz@horde.org>
+ * @package Ingo
+ */
+class Ingo_Exception extends Horde_Exception
+{
+}
*/
const USER_HEADER = '++USER_HEADER++';
- /* getMenu() cache. */
+ /**
+ * getMenu() cache.
+ *
+ * @var string
+ */
static private $_menuCache = null;
- /* hasSharePermission() cache. */
+ /**
+ * hasSharePermission() cache.
+ *
+ * @var integer
+ */
static private $_shareCache = null;
/**
+ * Create an ingo session.
+ *
+ * Creates the $ingo session variable with the following entries:
+ * 'backend' (array) - The backend configuration to use.
+ * 'change' (integer) - The timestamp of the last time the rules were
+ * altered.
+ * 'storage' (array) - Used by Ingo_Storage:: for caching data.
+ * 'script_categories' (array) - The list of available categories for the
+ * Ingo_Script driver in use.
+ * 'script_generate' (boolean) - Is the Ingo_Script::generate() call
+ * available?
+ *
+ * @throws Ingo_Exception
+ */
+ static public function createSession()
+ {
+ if (isset($_SESSION['ingo'])) {
+ return;
+ }
+
+ global $prefs;
+
+ $_SESSION['ingo'] = array(
+ 'backend' => Ingo::getBackend(),
+ 'change' => 0,
+ 'storage' => array()
+ );
+
+ $ingo_script = Ingo::loadIngoScript();
+ $_SESSION['ingo']['script_generate'] = $ingo_script->generateAvailable();
+
+ /* Disable categories as specified in preferences */
+ $disabled = array();
+ if ($prefs->isLocked('blacklist')) {
+ $disabled[] = Ingo_Storage::ACTION_BLACKLIST;
+ }
+ if ($prefs->isLocked('whitelist')) {
+ $disabled[] = Ingo_Storage::ACTION_WHITELIST;
+ }
+ if ($prefs->isLocked('vacation')) {
+ $disabled[] = Ingo_Storage::ACTION_VACATION;
+ }
+ if ($prefs->isLocked('forward')) {
+ $disabled[] = Ingo_Storage::ACTION_FORWARD;
+ }
+ if ($prefs->isLocked('spam')) {
+ $disabled[] = Ingo_Storage::ACTION_SPAM;
+ }
+
+ /* Set the list of categories this driver supports. */
+ $_SESSION['ingo']['script_categories'] = array_merge($ingo_script->availableActions(), array_diff($ingo_script->availableCategories(), $disabled));
+ }
+
+ /**
* Generates a folder widget.
* If an application is available that provides a folderlist method
* then a <select> input is created else a simple text field
*/
static public function activateScript($script, $deactivate = false)
{
- global $notification;
-
$driver = self::getDriver();
- $res = $driver->setScriptActive($script);
- if (is_a($res, 'PEAR_Error')) {
+
+ try {
+ $res = $driver->setScriptActive($script);
+ } catch (Ingo_Exception $e) {
$msg = ($deactivate)
? _("There was an error deactivating the script.")
: _("There was an error activating the script.");
- $notification->push($msg . ' ' . _("The driver said: ") . $res->getMessage(), 'horde.error');
+ $GLOBALS['notification']->push($msg . ' ' . _("The driver said: ") . $e->getMessage(), 'horde.error');
+ return false;
+ }
+
+ if ($res === false) {
return false;
- } elseif ($res === true) {
- $msg = ($deactivate)
- ? _("Script successfully deactivated.")
- : _("Script successfully activated.");
- $notification->push($msg, 'horde.success');
- return true;
}
- return false;
+ $msg = ($deactivate)
+ ? _("Script successfully deactivated.")
+ : _("Script successfully activated.");
+ $GLOBALS['notification']->push($msg, 'horde.success');
+
+ return true;
}
/**
*/
static public function getScript()
{
- $driver = self::getDriver();
- return $driver->getScript();
+ return self::getDriver()->getScript();
}
/**
*/
static public function updateScript()
{
- global $notification;
-
if ($_SESSION['ingo']['script_generate']) {
- $ingo_script = self::loadIngoScript();
- if (!$ingo_script) {
- $notification->push(_("Script not updated."), 'horde.error');
- } else {
+ try {
+ $ingo_script = self::loadIngoScript();
+
/* Generate and activate the script. */
$script = $ingo_script->generate();
self::activateScript($script);
+ } catch (Ingo_Exception $e) {
+ $GLOBALS['notification']->push(_("Script not updated."), 'horde.error');
}
}
}
* single value or an array of multiple values.
*
* @return array The backend entry.
- * @throws Horde_Exception
+ * @throws Ingo_Exception
*/
static public function getBackend()
{
/* Check for valid backend configuration. */
if (!isset($backend)) {
- throw new Horde_Exception(_("No backend configured for this host"));
+ throw new Ingo_Exception(_("No backend configured for this host"));
}
$backends[$backend]['id'] = $name;
$backend = $backends[$backend];
if (empty($backend['script'])) {
- throw new Horde_Exception(sprintf(_("No \"%s\" element found in backend configuration."), 'script'));
+ throw new Ingo_Exception(sprintf(_("No \"%s\" element found in backend configuration."), 'script'));
} elseif (empty($backend['driver'])) {
- throw new Horde_Exception(sprintf(_("No \"%s\" element found in backend configuration."), 'driver'));
+ throw new Ingo_Exception(sprintf(_("No \"%s\" element found in backend configuration."), 'driver'));
}
/* Make sure the 'params' entry exists. */
* Loads a Ingo_Script:: backend and checks for errors.
*
* @return Ingo_Script Script object on success.
- * @throws Horde_Exception
+ * @throws Ingo_Exception
*/
static public function loadIngoScript()
{
- $ingo_script = Ingo_Script::factory($_SESSION['ingo']['backend']['script'],
- isset($_SESSION['ingo']['backend']['scriptparams']) ? $_SESSION['ingo']['backend']['scriptparams'] : array());
- if (is_a($ingo_script, 'PEAR_Error')) {
- throw new Horde_Exception($ingo_script);
- }
-
- return $ingo_script;
+ return Ingo_Script::factory($_SESSION['ingo']['backend']['script'],
+ isset($_SESSION['ingo']['backend']['scriptparams']) ? $_SESSION['ingo']['backend']['scriptparams'] : array());
}
/**
* Returns an instance of the configured driver.
*
* @return Ingo_Driver The configured driver.
+ * @throws Ingo_Exception
*/
static public function getDriver()
{
$permission = Horde_Perms::SHOW)
{
$rulesets = $GLOBALS['ingo_shares']->listShares(Horde_Auth::getAuth(), $permission, $owneronly ? Horde_Auth::getAuth() : null);
- if (is_a($rulesets, 'PEAR_Error')) {
+ if ($rulesets instanceof PEAR_Error) {
Horde::logMessage($rulesets, __FILE__, __LINE__, PEAR_LOG_ERR);
return array();
}
protected $_scriptfile = false;
/**
- * Attempts to return a concrete Ingo_Script instance based on $script.
+ * Attempts to return a concrete instance based on $script.
*
- * @param string $script The type of Ingo_Script subclass to return.
- * @param array $params Hash containing additional paramters to be passed
- * to the subclass' constructor.
+ * @param string $script The type of subclass to return.
+ * @param array $params Hash containing additional paramters to be
+ * passed to the subclass' constructor.
*
- * @return Ingo_Script The newly created concrete Ingo_Script instance, or
- * false on error.
+ * @return Ingo_Script The newly created concrete instance.
+ * @throws Ingo_Exception
*/
static public function factory($script, $params = array())
{
$script = Horde_String::ucfirst(basename($script));
- $class = 'Ingo_Script_' . $script;
+ $class = __CLASS__ . '_' . $script;
if (!isset($params['spam_compare'])) {
$params['spam_compare'] = $GLOBALS['conf']['spam']['compare'];
}
}
- return class_exists($class)
- ? new $class($params)
- : PEAR::raiseError(sprintf(_("Unable to load the definition of %s."), $class));
+ if (class_exists($class)) {
+ return new $class($params);
+ }
+
+ throw new Ingo_Exception(sprintf(_("Unable to load the definition of %s."), $class));
}
/**
{
$this->_params = $params;
- if (!isset($GLOBALS['registry'])) {
- return;
- }
-
/* Determine if ingo should handle the blacklist. */
$key = array_search(Ingo_Storage::ACTION_BLACKLIST, $this->_categories);
if ($key !== false && ($GLOBALS['registry']->hasMethod('mail/blacklistFrom') != 'ingo')) {
/**
* Returns a script previously generated with generate().
*
- * @abstract
- *
* @return string The script.
*/
public function toCode()
* Generates the script to do the filtering specified in
* the rules.
*
- * @abstract
- *
* @return string The script.
*/
public function generate()
/**
* Perform the filtering specified in the rules.
*
- * @abstract
- *
* @param array $params The parameter array.
*
* @return boolean True if filtering performed, false if not.
* function to be called from within Ingo ensuring that all necessary
* parameters are set.
*
- * @abstract
- *
* @return boolean See perform().
*/
public function apply()
}
/* Grab the rules list. */
- $filters = &$GLOBALS['ingo_storage']->retrieve(Ingo_Storage::ACTION_FILTERS);
+ $filters = $GLOBALS['ingo_storage']->retrieve(Ingo_Storage::ACTION_FILTERS);
/* Parse through the rules, one-by-one. */
foreach ($filters->getFilterList() as $rule) {
* @author Matt Weyland <mathias@weyland.ch>
* @package Ingo
*/
+class Ingo_Script_Maildrop extends Ingo_Script
+{
-/**
- * Additional storage action since maildrop does not support the
- * "c-flag" as in procmail.
- */
-define('MAILDROP_STORAGE_ACTION_STOREANDFORWARD', 100);
-
-/**
- */
-class Ingo_Script_Maildrop extends Ingo_Script {
+ /* Additional storage action since maildrop does not support the
+ * "c-flag" as in procmail. */
+ const MAILDROP_STORAGE_ACTION_STOREANDFORWARD = 100;
/**
* The list of actions allowed (implemented) for this driver.
*
* @var array
*/
- var $_actions = array(
+ protected $_actions = array(
Ingo_Storage::ACTION_KEEP,
Ingo_Storage::ACTION_MOVE,
Ingo_Storage::ACTION_DISCARD,
*
* @var array
*/
- var $_categories = array(
+ protected $_categories = array(
Ingo_Storage::ACTION_BLACKLIST,
Ingo_Storage::ACTION_WHITELIST,
Ingo_Storage::ACTION_VACATION,
*
* @var array
*/
- var $_types = array(
+ protected $_types = array(
Ingo_Storage::TYPE_HEADER,
);
*
* @var array
*/
- var $_tests = array(
+ protected $_tests = array(
'contains', 'not contain',
'is', 'not is',
'begins with','not begins with',
*
* @var boolean
*/
- var $_casesensitive = true;
+ protected $_casesensitive = true;
/**
* Does the driver support the stop-script option?
*
* @var boolean
*/
- var $_supportStopScript = false;
+ protected $_supportStopScript = false;
/**
* Does the driver require a script file to be generated?
*
* @var boolean
*/
- var $_scriptfile = true;
+ protected $_scriptfile = true;
/**
* The recipes that make up the code.
*
* @var array
*/
- var $_recipes = array();
+ protected $_recipes = array();
/**
* Returns a script previously generated with generate().
*
* @return string The maildrop script.
*/
- function toCode()
+ public function toCode()
{
$code = '';
foreach ($this->_recipes as $item) {
*
* @return string The maildrop script.
*/
- function generate()
+ public function generate()
{
$filters = $GLOBALS['ingo_storage']->retrieve(Ingo_Storage::ACTION_FILTERS);
- $this->addItem(new Maildrop_Comment(_("maildrop script generated by Ingo") . ' (' . date('F j, Y, g:i a') . ')'));
+ $this->addItem(new Ingo_Script_Maildrop_Comment(_("maildrop script generated by Ingo") . ' (' . date('F j, Y, g:i a') . ')'));
/* Add variable information, if present. */
if (!empty($this->_params['variables']) &&
is_array($this->_params['variables'])) {
foreach ($this->_params['variables'] as $key => $val) {
- $this->addItem(new Maildrop_Variable(array('name' => $key, 'value' => $val)));
+ $this->addItem(new Ingo_Script_Maildrop_Variable(array('name' => $key, 'value' => $val)));
}
}
default:
if (in_array($filter['action'], $this->_actions)) {
/* Create filter if using AND. */
- $recipe = new Maildrop_Recipe($filter, $this->_params);
+ $recipe = new Ingo_Script_Maildrop_Recipe($filter, $this->_params);
foreach ($filter['conditions'] as $condition) {
$recipe->addCondition($condition);
}
- $this->addItem(new Maildrop_Comment($filter['name'], !empty($filter['disable']), true));
+ $this->addItem(new Ingo_Script_Maildrop_Comment($filter['name'], !empty($filter['disable']), true));
$this->addItem($recipe);
}
}
*
* @param boolean $disable Disable the blacklist?
*/
- function generateBlacklist($disable = false)
+ public function generateBlacklist($disable = false)
{
- $blacklist = &$GLOBALS['ingo_storage']->retrieve(Ingo_Storage::ACTION_BLACKLIST);
+ $blacklist = $GLOBALS['ingo_storage']->retrieve(Ingo_Storage::ACTION_BLACKLIST);
$bl_addr = $blacklist->getBlacklist();
$bl_folder = $blacklist->getBlacklistFolder();
- $bl_type = (empty($bl_folder)) ? Ingo_Storage::ACTION_DISCARD : Ingo_Storage::ACTION_MOVE;
+ $bl_type = empty($bl_folder)
+ ? Ingo_Storage::ACTION_DISCARD
+ : Ingo_Storage::ACTION_MOVE;
if (!empty($bl_addr)) {
- $this->addItem(new Maildrop_Comment(_("Blacklisted Addresses"), $disable, true));
+ $this->addItem(new Ingo_Script_Maildrop_Comment(_("Blacklisted Addresses"), $disable, true));
$params = array('action-value' => $bl_folder,
'action' => $bl_type,
'disable' => $disable);
foreach ($bl_addr as $address) {
if (!empty($address)) {
- $recipe = new Maildrop_Recipe($params, $this->_params);
+ $recipe = new Ingo_Script_Maildrop_Recipe($params, $this->_params);
$recipe->addCondition(array('field' => 'From', 'value' => $address));
$this->addItem($recipe);
}
*
* @param boolean $disable Disable the whitelist?
*/
- function generateWhitelist($disable = false)
+ public function generateWhitelist($disable = false)
{
- $whitelist = &$GLOBALS['ingo_storage']->retrieve(Ingo_Storage::ACTION_WHITELIST);
+ $whitelist = $GLOBALS['ingo_storage']->retrieve(Ingo_Storage::ACTION_WHITELIST);
$wl_addr = $whitelist->getWhitelist();
if (!empty($wl_addr)) {
- $this->addItem(new Maildrop_Comment(_("Whitelisted Addresses"), $disable, true));
+ $this->addItem(new Ingo_Script_Maildrop_Comment(_("Whitelisted Addresses"), $disable, true));
foreach ($wl_addr as $address) {
if (!empty($address)) {
- $recipe = new Maildrop_Recipe(array('action' => Ingo_Storage::ACTION_KEEP, 'disable' => $disable), $this->_params);
+ $recipe = new Ingo_Script_Maildrop_Recipe(array('action' => Ingo_Storage::ACTION_KEEP, 'disable' => $disable), $this->_params);
$recipe->addCondition(array('field' => 'From', 'value' => $address));
$this->addItem($recipe);
}
*
* @param boolean $disable Disable forwarding?
*/
- function generateForward($disable = false)
+ public function generateForward($disable = false)
{
- $forward = &$GLOBALS['ingo_storage']->retrieve(Ingo_Storage::ACTION_FORWARD);
+ $forward = $GLOBALS['ingo_storage']->retrieve(Ingo_Storage::ACTION_FORWARD);
$addresses = $forward->getForwardAddresses();
if (!empty($addresses)) {
- $this->addItem(new Maildrop_Comment(_("Forwards"), $disable, true));
+ $this->addItem(new Ingo_Script_Maildrop_Comment(_("Forwards"), $disable, true));
$params = array('action' => Ingo_Storage::ACTION_FORWARD,
'action-value' => $addresses,
'disable' => $disable);
if ($forward->getForwardKeep()) {
- $params['action'] = MAILDROP_STORAGE_ACTION_STOREANDFORWARD;
+ $params['action'] = self::MAILDROP_STORAGE_ACTION_STOREANDFORWARD;
}
- $recipe = new Maildrop_Recipe($params, $this->_params);
+ $recipe = new Ingo_Script_Maildrop_Recipe($params, $this->_params);
$recipe->addCondition(array('field' => 'From', 'value' => ''));
$this->addItem($recipe);
}
*
* @param boolean $disable Disable forwarding?
*/
- function generateVacation($disable = false)
+ public function generateVacation($disable = false)
{
- $vacation = &$GLOBALS['ingo_storage']->retrieve(Ingo_Storage::ACTION_VACATION);
+ $vacation = $GLOBALS['ingo_storage']->retrieve(Ingo_Storage::ACTION_VACATION);
$addresses = $vacation->getVacationAddresses();
$actionval = array('addresses' => $addresses,
'subject' => $vacation->getVacationSubject(),
'end' => $vacation->getVacationEnd());
if (!empty($addresses)) {
- $this->addItem(new Maildrop_Comment(_("Vacation"), $disable, true));
+ $this->addItem(new Ingo_Script_Maildrop_Comment(_("Vacation"), $disable, true));
$params = array('action' => Ingo_Storage::ACTION_VACATION,
'action-value' => $actionval,
'disable' => $disable);
- $recipe = new Maildrop_Recipe($params, $this->_params);
+ $recipe = new Ingo_Script_Maildrop_Recipe($params, $this->_params);
$this->addItem($recipe);
}
}
/**
- * Generates the maildrop script to handle spam as identified by SpamAssassin
+ * Generates the maildrop script to handle spam as identified by
+ * SpamAssassin.
*
* @param boolean $disable Disable the spam-filter?
*/
- function generateSpamfilter($disable = false)
+ public function generateSpamfilter($disable = false)
{
- $spam = &$GLOBALS['ingo_storage']->retrieve(Ingo_Storage::ACTION_SPAM);
+ $spam = $GLOBALS['ingo_storage']->retrieve(Ingo_Storage::ACTION_SPAM);
if ($spam == false) {
return;
}
$spam_folder = $spam->getSpamFolder();
$spam_action = (empty($spam_folder)) ? Ingo_Storage::ACTION_DISCARD : Ingo_Storage::ACTION_MOVE;
- $this->addItem(new Maildrop_Comment(_("Spam Filter"), $disable, true));
+ $this->addItem(new Ingo_Script_Maildrop_Comment(_("Spam Filter"), $disable, true));
$params = array('action-value' => $spam_folder,
'action' => $spam_action,
'disable' => $disable);
- $recipe = new Maildrop_Recipe($params, $this->_params);
+ $recipe = new Ingo_Script_Maildrop_Recipe($params, $this->_params);
if ($this->_params['spam_compare'] == 'numeric') {
$recipe->addCondition(array('match' => 'greater than or equal to',
'field' => $this->_params['spam_header'],
* @param object $item The item to add to the recipe list.
* The object should have a generate() function.
*/
- function addItem($item)
+ public function addItem($item)
{
$this->_recipes[] = $item;
}
}
-
-/**
- * The Maildrop_Comment:: class represents a maildrop comment. This is
- * a pretty simple class, but it makes the code in Ingo_Script_Maildrop::
- * cleaner as it provides a generate() function and can be added to the
- * recipe list the same way as a recipe can be.
- *
- * @author Matt Weyland <mathias@weyland.ch>
- * @package Ingo
- */
-class Maildrop_Comment {
-
- /**
- * The comment text.
- *
- * @var string
- */
- var $_comment = '';
-
- /**
- * Constructs a new maildrop comment.
- *
- * @param string $comment Comment to be generated.
- * @param boolean $disable Output 'DISABLED' comment?
- * @param boolean $header Output a 'header' comment?
- */
- function Maildrop_Comment($comment, $disable = false, $header = false)
- {
- if ($disable) {
- $comment = _("DISABLED: ") . $comment;
- }
-
- if ($header) {
- $this->_comment .= "##### $comment #####";
- } else {
- $this->_comment .= "# $comment";
- }
- }
-
- /**
- * Returns the comment stored by this object.
- *
- * @return string The comment stored by this object.
- */
- function generate()
- {
- return $this->_comment;
- }
-
-}
-
-/**
- * The Maildrop_Recipe:: class represents a maildrop recipe.
- *
- * @author Matt Weyland <mathias@weyland.ch>
- * @package Ingo
- */
-class Maildrop_Recipe {
-
- var $_action = array();
- var $_conditions = array();
- var $_disable = '';
- var $_flags = '';
- var $_params = array();
- var $_combine = '';
- var $_valid = true;
-
- var $_operators = array(
- 'less than' => '<',
- 'less than or equal to' => '<=',
- 'equal' => '==',
- 'not equal' => '!=',
- 'greater than' => '>',
- 'greater than or equal to' => '>=',
- );
-
- /**
- * Constructs a new maildrop recipe.
- *
- * @param array $params Array of parameters.
- * REQUIRED FIELDS:
- * 'action'
- * OPTIONAL FIELDS:
- * 'action-value' (only used if the
- * 'action' requires it)
- * @param array $scriptparams Array of parameters passed to
- * Ingo_Script_Maildrop::.
- */
- function Maildrop_Recipe($params = array(), $scriptparams = array())
- {
- $this->_disable = !empty($params['disable']);
- $this->_params = $scriptparams;
- $this->_action[] = 'exception {';
-
- switch ($params['action']) {
- case Ingo_Storage::ACTION_KEEP:
- $this->_action[] = ' to "${DEFAULT}"';
- break;
-
- case Ingo_Storage::ACTION_MOVE:
- $this->_action[] = ' to ' . $this->maildropPath($params['action-value']);
- break;
-
- case Ingo_Storage::ACTION_DISCARD:
- $this->_action[] = ' exit';
- break;
-
- case Ingo_Storage::ACTION_REDIRECT:
- $this->_action[] = ' to "! ' . $params['action-value'] . '"';
- break;
-
- case Ingo_Storage::ACTION_REDIRECTKEEP:
- $this->_action[] = ' cc "! ' . $params['action-value'] . '"';
- $this->_action[] = ' to "${DEFAULT}"';
- break;
-
- case Ingo_Storage::ACTION_REJECT:
- $this->_action[] = ' EXITCODE=77'; # EX_NOPERM (permanent failure)
- $this->_action[] = ' echo "5.7.1 ' . $params['action-value'] . '"';
- $this->_action[] = ' exit';
- break;
-
- case Ingo_Storage::ACTION_VACATION:
- $from = '';
- foreach ($params['action-value']['addresses'] as $address) {
- $from = $address;
- }
-
- /**
- * @TODO
- *
- * Exclusion and listfilter
- */
- $exclude = '';
- foreach ($params['action-value']['excludes'] as $address) {
- $exclude .= $address . ' ';
- }
-
- $start = strftime($params['action-value']['start']);
- if ($start === false) {
- $start = 0;
- }
- $end = strftime($params['action-value']['end']);
- if ($end === false) {
- $end = 0;
- }
- $days = strftime($params['action-value']['days']);
- if ($days === false) {
- // Set to same value as $_days in ingo/lib/Storage.php
- $days = 7;
- }
-
- // Writing vacation.msg file
- $reason = Horde_Mime::encode($params['action-value']['reason'], $scriptparams['charset']);
- $driver = Ingo::getDriver();
- $driver->_connect();
- $result = $driver->_vfs->writeData($driver->_params['vfs_path'], 'vacation.msg', $reason, true);
-
- // Rule : Do not send responses to bulk or list messages
- if ($params['action-value']['ignorelist'] == 1) {
- $params['combine'] = Ingo_Storage::COMBINE_ALL;
- $this->addCondition(array('match' => 'filter', 'field' => '', 'value' => '! /^Precedence: (bulk|list|junk)/'));
- $this->addCondition(array('match' => 'filter', 'field' => '', 'value' => '! /^Return-Path:.*<#@\[\]>/'));
- $this->addCondition(array('match' => 'filter', 'field' => '', 'value' => '! /^Return-Path:.*<>/'));
- $this->addCondition(array('match' => 'filter', 'field' => '', 'value' => '! /^From:.*MAILER-DAEMON/'));
- $this->addCondition(array('match' => 'filter', 'field' => '', 'value' => '! /^X-ClamAV-Notice-Flag: *YES/'));
- $this->addCondition(array('match' => 'filter', 'field' => '', 'value' => '! /^Content-Type:.*message\/delivery-status/'));
- $this->addCondition(array('match' => 'filter', 'field' => '', 'value' => '! /^Subject:.*Delivery Status Notification/'));
- $this->addCondition(array('match' => 'filter', 'field' => '', 'value' => '! /^Subject:.*Undelivered Mail Returned to Sender/'));
- $this->addCondition(array('match' => 'filter', 'field' => '', 'value' => '! /^Subject:.*Delivery failure/'));
- $this->addCondition(array('match' => 'filter', 'field' => '', 'value' => '! /^Subject:.*Message delay/'));
- $this->addCondition(array('match' => 'filter', 'field' => '', 'value' => '! /^Subject:.*Mail Delivery Subsystem/'));
- $this->addCondition(array('match' => 'filter', 'field' => '', 'value' => '! /^Subject:.*Mail System Error.*Returned Mail/'));
- $this->addCondition(array('match' => 'filter', 'field' => '', 'value' => '! /^X-Spam-Flag: YES/ '));
- } else {
- $this->addCondition(array('field' => 'From', 'value' => ''));
- }
-
- // Rule : Start/End of vacation
- if (($start != 0) && ($end !== 0)) {
- $this->_action[] = ' flock "vacationprocess.lock" {';
- $this->_action[] = ' current_time=time';
- $this->_action[] = ' if ( \ ';
- $this->_action[] = ' ($current_time >= ' . $start . ') && \ ';
- $this->_action[] = ' ($current_time <= ' . $end . ')) ';
- $this->_action[] = ' {';
- }
- $this->_action[] = " cc \"| mailbot -D " . $params['action-value']['days'] . " -c '" . $scriptparams['charset'] . "' -t \$HOME/vacation.msg -d \$HOME/vacation -A 'From: $from' -s '" . Horde_Mime::encode($params['action-value']['subject'], $scriptparams['charset']) . "' /usr/sbin/sendmail -t \"";
- if (($start != 0) && ($end !== 0)) {
- $this->_action[] = ' }';
- $this->_action[] = ' }';
- }
-
- break;
-
- case Ingo_Storage::ACTION_FORWARD:
- case MAILDROP_STORAGE_ACTION_STOREANDFORWARD:
- foreach ($params['action-value'] as $address) {
- if (!empty($address)) {
- $this->_action[] = ' cc "! ' . $address . '"';
- }
- }
-
- /* The 'to' must be the last action, because maildrop
- * stops processing after it. */
- if ($params['action'] == MAILDROP_STORAGE_ACTION_STOREANDFORWARD) {
- $this->_action[] = ' to "${DEFAULT}"';
- } else {
- $this->_action[] = ' exit';
- }
- break;
-
- default:
- $this->_valid = false;
- break;
- }
-
- $this->_action[] = '}';
-
- if (isset($params['combine']) &&
- ($params['combine'] == Ingo_Storage::COMBINE_ALL)) {
- $this->_combine = '&& ';
- } else {
- $this->_combine = '|| ';
- }
- }
-
- /**
- * Adds a flag to the recipe.
- *
- * @param string $flag String of flags to append to the current flags.
- */
- function addFlag($flag)
- {
- $this->_flags .= $flag;
- }
-
- /**
- * Adds a condition to the recipe.
- *
- * @param optonal array $condition Array of parameters. Required keys
- * are 'field' and 'value'. 'case' is
- * an optional keys.
- */
- function addCondition($condition = array())
- {
- $flag = (!empty($condition['case'])) ? 'D' : '';
- if (empty($this->_conditions)) {
- $this->addFlag($flag);
- }
-
- $string = '';
- $extra = '';
-
- $match = (isset($condition['match'])) ? $condition['match'] : null;
- // negate tests starting with 'not ', except 'not equals', which simply uses the != operator
- if ($match != 'not equal' && substr($match, 0, 4) == 'not ') {
- $string .= '! ';
- }
-
- // convert 'field' to PCRE pattern matching
- if (strpos($condition['field'], ',') == false) {
- $string .= '/^' . $condition['field'] . ':\\s*';
- } else {
- $string .= '/^(' . str_replace(',', '|', $condition['field']) . '):\\s*';
- }
-
- switch ($match) {
- case 'not regex':
- case 'regex':
- $string .= $condition['value'] . '/:h';
- break;
-
- case 'filter':
- $string = $condition['value'];
- break;
-
- case 'exists':
- case 'not exist':
- // Just run a match for the header name
- $string .= '/:h';
- break;
-
- case 'less than or equal to':
- case 'less than':
- case 'equal':
- case 'not equal':
- case 'greater than or equal to':
- case 'greater than':
- $string .= '(\d+(\.\d+)?)/:h';
- $extra = ' && $MATCH1 ' . $this->_operators[$match] . ' ' . (int)$condition['value'];
- break;
-
- case 'begins with':
- case 'not begins with':
- $string .= preg_quote($condition['value'], '/') . '/:h';
- break;
-
- case 'ends with':
- case 'not ends with':
- $string .= '.*' . preg_quote($condition['value'], '/') . '$/:h';
- break;
-
- case 'is':
- case 'not is':
- $string .= preg_quote($condition['value'], '/') . '$/:h';
- break;
-
- case 'matches':
- case 'not matches':
- $string .= str_replace(array('\\*', '\\?'), array('.*', '.'), preg_quote($condition['value'], '/') . '$') . '/:h';
- break;
-
- case 'contains':
- case 'not contain':
- default:
- $string .= '.*' . preg_quote($condition['value'], '/') . '/:h';
- break;
- }
-
- $this->_conditions[] = array('condition' => $string, 'flags' => $flag, 'extra' => $extra);
- }
-
- /**
- * Generates maildrop code to represent the recipe.
- *
- * @return string maildrop code to represent the recipe.
- */
- function generate()
- {
- $text = array();
-
- if (!$this->_valid) {
- return '';
- }
-
- if (count($this->_conditions) > 0) {
-
- $text[] = "if( \\";
-
- $nest = false;
- foreach ($this->_conditions as $condition) {
- $cond = $nest ? $this->_combine : ' ';
- $text[] = $cond . $condition['condition'] . $condition['flags'] . $condition['extra'] . " \\";
- $nest = true;
- }
-
- $text[] = ')';
- }
-
- foreach ($this->_action as $val) {
- $text[] = $val;
- }
-
- if ($this->_disable) {
- $code = '';
- foreach ($text as $val) {
- $comment = new Maildrop_Comment($val);
- $code .= $comment->generate() . "\n";
- }
- return $code . "\n";
- } else {
- return implode("\n", $text) . "\n";
- }
- }
-
- /**
- * Returns a maildrop-ready mailbox path, converting IMAP folder pathname
- * conventions as necessary.
- *
- * @param string $folder The IMAP folder name.
- *
- * @return string The maildrop mailbox path.
- */
- function maildropPath($folder)
- {
- /* NOTE: '$DEFAULT' here is a literal, not a PHP variable. */
- if (isset($this->_params) &&
- ($this->_params['path_style'] == 'maildir')) {
- if (empty($folder) || ($folder == 'INBOX')) {
- return '"${DEFAULT}"';
- }
- if ($this->_params['strip_inbox'] &&
- substr($folder, 0, 6) == 'INBOX.') {
- $folder = substr($folder, 6);
- }
- return '"${DEFAULT}/.' . $folder . '/"';
- } else {
- if (empty($folder) || ($folder == 'INBOX')) {
- return '${DEFAULT}';
- }
- return str_replace(' ', '\ ', $folder);
- }
- }
-
-}
-
-/**
- * The Maildrop_Variable:: class represents a Maildrop variable.
- *
- * @author Matt Weyland <mathias@weyland.ch>
- * @package Ingo
- */
-class Maildrop_Variable {
-
- var $_name;
- var $_value;
-
- /**
- * Constructs a new maildrop variable.
- *
- * @param array $params Array of parameters. Expected fields are 'name'
- * and 'value'.
- */
- function Maildrop_Variable($params = array())
- {
- $this->_name = $params['name'];
- $this->_value = $params['value'];
- }
-
- /**
- * Generates maildrop code to represent the variable.
- *
- * @return string maildrop code to represent the variable.
- */
- function generate()
- {
- return $this->_name . '=' . $this->_value . "\n";
- }
-
-}
--- /dev/null
+<?php
+/**
+ * The Ingo_Script_Maildrop_Comment:: class represents a maildrop comment.
+ * This is a pretty simple class, but it makes the code in
+ * Ingo_Script_Maildrop:: cleaner as it provides a generate() function and can
+ * be added to the recipe list the same way as a recipe can be.
+ *
+ * Copyright 2005-2007 Matt Weyland <mathias@weyland.ch>
+ *
+ * See the enclosed file LICENSE for license information (ASL). If you
+ * did not receive this file, see http://www.horde.org/licenses/asl.php.
+ *
+ * @author Matt Weyland <mathias@weyland.ch>
+ * @package Ingo
+ */
+class Ingo_Script_Maildrop_Comment
+{
+ /**
+ * The comment text.
+ *
+ * @var string
+ */
+ protected $_comment = '';
+
+ /**
+ * Constructs a new maildrop comment.
+ *
+ * @param string $comment Comment to be generated.
+ * @param boolean $disable Output 'DISABLED' comment?
+ * @param boolean $header Output a 'header' comment?
+ */
+ public function __construct($comment, $disable = false, $header = false)
+ {
+ if ($disable) {
+ $comment = _("DISABLED: ") . $comment;
+ }
+
+ $this->_comment = $header
+ ? '##### ' . $comment . ' #####'
+ : '# ' . $comment;
+ }
+
+ /**
+ * Returns the comment stored by this object.
+ *
+ * @return string The comment stored by this object.
+ */
+ public function generate()
+ {
+ return $this->_comment;
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * The Ingo_Script_Maildrop_Recipe:: class represents a maildrop recipe.
+ *
+ * Copyright 2005-2007 Matt Weyland <mathias@weyland.ch>
+ *
+ * See the enclosed file LICENSE for license information (ASL). If you
+ * did not receive this file, see http://www.horde.org/licenses/asl.php.
+ *
+ * @author Matt Weyland <mathias@weyland.ch>
+ * @package Ingo
+ */
+class Maildrop_Recipe
+{
+ /**
+ */
+ protected $_action = array();
+
+ /**
+ */
+ protected $_conditions = array();
+
+ /**
+ */
+ protected $_disable = '';
+
+ /**
+ */
+ protected $_flags = '';
+
+ /**
+ */
+ protected $_params = array();
+
+ /**
+ */
+ protected $_combine = '';
+
+ /**
+ */
+ protected $_valid = true;
+
+ /**
+ */
+ protected $_operators = array(
+ 'less than' => '<',
+ 'less than or equal to' => '<=',
+ 'equal' => '==',
+ 'not equal' => '!=',
+ 'greater than' => '>',
+ 'greater than or equal to' => '>=',
+ );
+
+ /**
+ * Constructs a new maildrop recipe.
+ *
+ * @param array $params Array of parameters.
+ * REQUIRED FIELDS:
+ * 'action'
+ * OPTIONAL FIELDS:
+ * 'action-value' (only used if the
+ * 'action' requires it)
+ * @param array $scriptparams Array of parameters passed to
+ * Ingo_Script_Maildrop::.
+ */
+ public function __construct($params = array(), $scriptparams = array())
+ {
+ $this->_disable = !empty($params['disable']);
+ $this->_params = $scriptparams;
+ $this->_action[] = 'exception {';
+
+ switch ($params['action']) {
+ case Ingo_Storage::ACTION_KEEP:
+ $this->_action[] = ' to "${DEFAULT}"';
+ break;
+
+ case Ingo_Storage::ACTION_MOVE:
+ $this->_action[] = ' to ' . $this->maildropPath($params['action-value']);
+ break;
+
+ case Ingo_Storage::ACTION_DISCARD:
+ $this->_action[] = ' exit';
+ break;
+
+ case Ingo_Storage::ACTION_REDIRECT:
+ $this->_action[] = ' to "! ' . $params['action-value'] . '"';
+ break;
+
+ case Ingo_Storage::ACTION_REDIRECTKEEP:
+ $this->_action[] = ' cc "! ' . $params['action-value'] . '"';
+ $this->_action[] = ' to "${DEFAULT}"';
+ break;
+
+ case Ingo_Storage::ACTION_REJECT:
+ $this->_action[] = ' EXITCODE=77'; # EX_NOPERM (permanent failure)
+ $this->_action[] = ' echo "5.7.1 ' . $params['action-value'] . '"';
+ $this->_action[] = ' exit';
+ break;
+
+ case Ingo_Storage::ACTION_VACATION:
+ $from = '';
+ foreach ($params['action-value']['addresses'] as $address) {
+ $from = $address;
+ }
+
+ /**
+ * @TODO
+ *
+ * Exclusion and listfilter
+ */
+ $exclude = '';
+ foreach ($params['action-value']['excludes'] as $address) {
+ $exclude .= $address . ' ';
+ }
+
+ $start = strftime($params['action-value']['start']);
+ if ($start === false) {
+ $start = 0;
+ }
+ $end = strftime($params['action-value']['end']);
+ if ($end === false) {
+ $end = 0;
+ }
+ $days = strftime($params['action-value']['days']);
+ if ($days === false) {
+ // Set to same value as $_days in ingo/lib/Storage.php
+ $days = 7;
+ }
+
+ // Writing vacation.msg file
+ $reason = Horde_Mime::encode($params['action-value']['reason'], $scriptparams['charset']);
+ $driver = Ingo::getDriver();
+ $driver->_connect();
+ $result = $driver->_vfs->writeData($driver->_params['vfs_path'], 'vacation.msg', $reason, true);
+
+ // Rule : Do not send responses to bulk or list messages
+ if ($params['action-value']['ignorelist'] == 1) {
+ $params['combine'] = Ingo_Storage::COMBINE_ALL;
+ $this->addCondition(array('match' => 'filter', 'field' => '', 'value' => '! /^Precedence: (bulk|list|junk)/'));
+ $this->addCondition(array('match' => 'filter', 'field' => '', 'value' => '! /^Return-Path:.*<#@\[\]>/'));
+ $this->addCondition(array('match' => 'filter', 'field' => '', 'value' => '! /^Return-Path:.*<>/'));
+ $this->addCondition(array('match' => 'filter', 'field' => '', 'value' => '! /^From:.*MAILER-DAEMON/'));
+ $this->addCondition(array('match' => 'filter', 'field' => '', 'value' => '! /^X-ClamAV-Notice-Flag: *YES/'));
+ $this->addCondition(array('match' => 'filter', 'field' => '', 'value' => '! /^Content-Type:.*message\/delivery-status/'));
+ $this->addCondition(array('match' => 'filter', 'field' => '', 'value' => '! /^Subject:.*Delivery Status Notification/'));
+ $this->addCondition(array('match' => 'filter', 'field' => '', 'value' => '! /^Subject:.*Undelivered Mail Returned to Sender/'));
+ $this->addCondition(array('match' => 'filter', 'field' => '', 'value' => '! /^Subject:.*Delivery failure/'));
+ $this->addCondition(array('match' => 'filter', 'field' => '', 'value' => '! /^Subject:.*Message delay/'));
+ $this->addCondition(array('match' => 'filter', 'field' => '', 'value' => '! /^Subject:.*Mail Delivery Subsystem/'));
+ $this->addCondition(array('match' => 'filter', 'field' => '', 'value' => '! /^Subject:.*Mail System Error.*Returned Mail/'));
+ $this->addCondition(array('match' => 'filter', 'field' => '', 'value' => '! /^X-Spam-Flag: YES/ '));
+ } else {
+ $this->addCondition(array('field' => 'From', 'value' => ''));
+ }
+
+ // Rule : Start/End of vacation
+ if (($start != 0) && ($end !== 0)) {
+ $this->_action[] = ' flock "vacationprocess.lock" {';
+ $this->_action[] = ' current_time=time';
+ $this->_action[] = ' if ( \ ';
+ $this->_action[] = ' ($current_time >= ' . $start . ') && \ ';
+ $this->_action[] = ' ($current_time <= ' . $end . ')) ';
+ $this->_action[] = ' {';
+ }
+ $this->_action[] = " cc \"| mailbot -D " . $params['action-value']['days'] . " -c '" . $scriptparams['charset'] . "' -t \$HOME/vacation.msg -d \$HOME/vacation -A 'From: $from' -s '" . Horde_Mime::encode($params['action-value']['subject'], $scriptparams['charset']) . "' /usr/sbin/sendmail -t \"";
+ if (($start != 0) && ($end !== 0)) {
+ $this->_action[] = ' }';
+ $this->_action[] = ' }';
+ }
+
+ break;
+
+ case Ingo_Storage::ACTION_FORWARD:
+ case Ingo_Script_Maildrop::MAILDROP_STORAGE_ACTION_STOREANDFORWARD:
+ foreach ($params['action-value'] as $address) {
+ if (!empty($address)) {
+ $this->_action[] = ' cc "! ' . $address . '"';
+ }
+ }
+
+ /* The 'to' must be the last action, because maildrop
+ * stops processing after it. */
+ if ($params['action'] == Ingo_Script_Maildrop::MAILDROP_STORAGE_ACTION_STOREANDFORWARD) {
+ $this->_action[] = ' to "${DEFAULT}"';
+ } else {
+ $this->_action[] = ' exit';
+ }
+ break;
+
+ default:
+ $this->_valid = false;
+ break;
+ }
+
+ $this->_action[] = '}';
+
+ if (isset($params['combine']) &&
+ ($params['combine'] == Ingo_Storage::COMBINE_ALL)) {
+ $this->_combine = '&& ';
+ } else {
+ $this->_combine = '|| ';
+ }
+ }
+
+ /**
+ * Adds a flag to the recipe.
+ *
+ * @param string $flag String of flags to append to the current flags.
+ */
+ public function addFlag($flag)
+ {
+ $this->_flags .= $flag;
+ }
+
+ /**
+ * Adds a condition to the recipe.
+ *
+ * @param optonal array $condition Array of parameters. Required keys
+ * are 'field' and 'value'. 'case' is
+ * an optional keys.
+ */
+ public function addCondition($condition = array())
+ {
+ $flag = (!empty($condition['case'])) ? 'D' : '';
+ if (empty($this->_conditions)) {
+ $this->addFlag($flag);
+ }
+
+ $string = '';
+ $extra = '';
+
+ $match = (isset($condition['match'])) ? $condition['match'] : null;
+ // negate tests starting with 'not ', except 'not equals', which simply uses the != operator
+ if ($match != 'not equal' && substr($match, 0, 4) == 'not ') {
+ $string .= '! ';
+ }
+
+ // convert 'field' to PCRE pattern matching
+ if (strpos($condition['field'], ',') == false) {
+ $string .= '/^' . $condition['field'] . ':\\s*';
+ } else {
+ $string .= '/^(' . str_replace(',', '|', $condition['field']) . '):\\s*';
+ }
+
+ switch ($match) {
+ case 'not regex':
+ case 'regex':
+ $string .= $condition['value'] . '/:h';
+ break;
+
+ case 'filter':
+ $string = $condition['value'];
+ break;
+
+ case 'exists':
+ case 'not exist':
+ // Just run a match for the header name
+ $string .= '/:h';
+ break;
+
+ case 'less than or equal to':
+ case 'less than':
+ case 'equal':
+ case 'not equal':
+ case 'greater than or equal to':
+ case 'greater than':
+ $string .= '(\d+(\.\d+)?)/:h';
+ $extra = ' && $MATCH1 ' . $this->_operators[$match] . ' ' . (int)$condition['value'];
+ break;
+
+ case 'begins with':
+ case 'not begins with':
+ $string .= preg_quote($condition['value'], '/') . '/:h';
+ break;
+
+ case 'ends with':
+ case 'not ends with':
+ $string .= '.*' . preg_quote($condition['value'], '/') . '$/:h';
+ break;
+
+ case 'is':
+ case 'not is':
+ $string .= preg_quote($condition['value'], '/') . '$/:h';
+ break;
+
+ case 'matches':
+ case 'not matches':
+ $string .= str_replace(array('\\*', '\\?'), array('.*', '.'), preg_quote($condition['value'], '/') . '$') . '/:h';
+ break;
+
+ case 'contains':
+ case 'not contain':
+ default:
+ $string .= '.*' . preg_quote($condition['value'], '/') . '/:h';
+ break;
+ }
+
+ $this->_conditions[] = array('condition' => $string, 'flags' => $flag, 'extra' => $extra);
+ }
+
+ /**
+ * Generates maildrop code to represent the recipe.
+ *
+ * @return string maildrop code to represent the recipe.
+ */
+ public function generate()
+ {
+ $text = array();
+
+ if (!$this->_valid) {
+ return '';
+ }
+
+ if (count($this->_conditions) > 0) {
+
+ $text[] = "if( \\";
+
+ $nest = false;
+ foreach ($this->_conditions as $condition) {
+ $cond = $nest ? $this->_combine : ' ';
+ $text[] = $cond . $condition['condition'] . $condition['flags'] . $condition['extra'] . " \\";
+ $nest = true;
+ }
+
+ $text[] = ')';
+ }
+
+ foreach ($this->_action as $val) {
+ $text[] = $val;
+ }
+
+ if ($this->_disable) {
+ $code = '';
+ foreach ($text as $val) {
+ $comment = new Ingo_Script_Maildrop_Comment($val);
+ $code .= $comment->generate() . "\n";
+ }
+ return $code . "\n";
+ } else {
+ return implode("\n", $text) . "\n";
+ }
+ }
+
+ /**
+ * Returns a maildrop-ready mailbox path, converting IMAP folder pathname
+ * conventions as necessary.
+ *
+ * @param string $folder The IMAP folder name.
+ *
+ * @return string The maildrop mailbox path.
+ */
+ public function maildropPath($folder)
+ {
+ /* NOTE: '$DEFAULT' here is a literal, not a PHP variable. */
+ if (isset($this->_params) &&
+ ($this->_params['path_style'] == 'maildir')) {
+ if (empty($folder) || ($folder == 'INBOX')) {
+ return '"${DEFAULT}"';
+ }
+ if ($this->_params['strip_inbox'] &&
+ substr($folder, 0, 6) == 'INBOX.') {
+ $folder = substr($folder, 6);
+ }
+ return '"${DEFAULT}/.' . $folder . '/"';
+ } else {
+ if (empty($folder) || ($folder == 'INBOX')) {
+ return '${DEFAULT}';
+ }
+ return str_replace(' ', '\ ', $folder);
+ }
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * The Ingo_Script_Maildrop_Variable:: class represents a Maildrop variable.
+ *
+ * Copyright 2005-2007 Matt Weyland <mathias@weyland.ch>
+ *
+ * See the enclosed file LICENSE for license information (ASL). If you
+ * did not receive this file, see http://www.horde.org/licenses/asl.php.
+ *
+ * @author Matt Weyland <mathias@weyland.ch>
+ * @package Ingo
+ */
+class Maildrop_Variable
+{
+ /**
+ */
+ protected $_name;
+
+ /**
+ */
+ protected $_value;
+
+ /**
+ * Constructs a new maildrop variable.
+ *
+ * @param array $params Array of parameters. Expected fields are 'name'
+ * and 'value'.
+ */
+ public function __construct($params = array())
+ {
+ $this->_name = $params['name'];
+ $this->_value = $params['value'];
+ }
+
+ /**
+ * Generates maildrop code to represent the variable.
+ *
+ * @return string maildrop code to represent the variable.
+ */
+ public function generate()
+ {
+ return $this->_name . '=' . $this->_value . "\n";
+ }
+
+}
* @author Ben Chavet <ben@horde.org>
* @package Ingo
*/
-class Ingo_Script_Procmail extends Ingo_Script {
-
+class Ingo_Script_Procmail extends Ingo_Script
+{
/**
* The list of actions allowed (implemented) for this driver.
*
* @var array
*/
- var $_actions = array(
+ protected $_actions = array(
Ingo_Storage::ACTION_KEEP,
Ingo_Storage::ACTION_MOVE,
Ingo_Storage::ACTION_DISCARD,
*
* @var array
*/
- var $_categories = array(
+ protected $_categories = array(
Ingo_Storage::ACTION_BLACKLIST,
Ingo_Storage::ACTION_WHITELIST,
Ingo_Storage::ACTION_VACATION,
*
* @var array
*/
- var $_types = array(
+ protected $_types = array(
Ingo_Storage::TYPE_HEADER,
Ingo_Storage::TYPE_BODY
);
*
* @var array
*/
- var $_special_types = array(
+ protected $_special_types = array(
'Destination',
);
*
* @var array
*/
- var $_tests = array(
+ protected $_tests = array(
'contains',
'not contain',
'begins with',
*
* @var boolean
*/
- var $_casesensitive = true;
+ protected $_casesensitive = true;
/**
* Does the driver support the stop-script option?
*
* @var boolean
*/
- var $_supportStopScript = true;
+ protected $_supportStopScript = true;
/**
* Does the driver require a script file to be generated?
*
* @var boolean
*/
- var $_scriptfile = true;
+ protected $_scriptfile = true;
/**
* The recipes that make up the code.
*
* @var array
*/
- var $_recipes = array();
+ protected $_recipes = array();
/**
* Returns a script previously generated with generate().
*
* @return string The procmail script.
*/
- function toCode()
+ public function toCode()
{
$code = '';
foreach ($this->_recipes as $item) {
*
* @return string The procmail script.
*/
- function generate()
+ public function generate()
{
$filters = $GLOBALS['ingo_storage']->retrieve(Ingo_Storage::ACTION_FILTERS);
- $this->addItem(new Procmail_Comment(_("procmail script generated by Ingo") . ' (' . date('F j, Y, g:i a') . ')'));
+ $this->addItem(new Ingo_Script_Procmail_Comment(_("procmail script generated by Ingo") . ' (' . date('F j, Y, g:i a') . ')'));
/* Add variable information, if present. */
if (!empty($this->_params['variables']) &&
is_array($this->_params['variables'])) {
foreach ($this->_params['variables'] as $key => $val) {
- $this->addItem(new Procmail_Variable(array('name' => $key, 'value' => $val)));
+ $this->addItem(new Ingo_Script_Procmail_Variable(array('name' => $key, 'value' => $val)));
}
}
if (in_array($filter['action'], $this->_actions)) {
/* Create filter if using AND. */
if ($filter['combine'] == Ingo_Storage::COMBINE_ALL) {
- $recipe = new Procmail_Recipe($filter, $this->_params);
+ $recipe = new Ingo_Script_Procmail_Recipe($filter, $this->_params);
if (!$filter['stop']) {
$recipe->addFlag('c');
}
foreach ($filter['conditions'] as $condition) {
$recipe->addCondition($condition);
}
- $this->addItem(new Procmail_Comment($filter['name'], !empty($filter['disable']), true));
+ $this->addItem(new Ingo_Script_Procmail_Comment($filter['name'], !empty($filter['disable']), true));
$this->addItem($recipe);
} else {
/* Create filter if using OR */
- $this->addItem(new Procmail_Comment($filter['name'], !empty($filter['disable']), true));
+ $this->addItem(new Ingo_Script_Procmail_Comment($filter['name'], !empty($filter['disable']), true));
$loop = 0;
foreach ($filter['conditions'] as $condition) {
- $recipe = new Procmail_Recipe($filter, $this->_params);
+ $recipe = new Ingo_Script_Procmail_Recipe($filter, $this->_params);
if ($loop++) {
$recipe->addFlag('E');
}
*
* @param boolean $disable Disable the blacklist?
*/
- function generateBlacklist($disable = false)
+ public function generateBlacklist($disable = false)
{
- $blacklist = &$GLOBALS['ingo_storage']->retrieve(Ingo_Storage::ACTION_BLACKLIST);
+ $blacklist = $GLOBALS['ingo_storage']->retrieve(Ingo_Storage::ACTION_BLACKLIST);
$bl_addr = $blacklist->getBlacklist();
$bl_folder = $blacklist->getBlacklistFolder();
- $bl_type = (empty($bl_folder)) ? Ingo_Storage::ACTION_DISCARD : Ingo_Storage::ACTION_MOVE;
+ $bl_type = empty($bl_folder)
+ ? Ingo_Storage::ACTION_DISCARD
+ : Ingo_Storage::ACTION_MOVE;
if (!empty($bl_addr)) {
- $this->addItem(new Procmail_Comment(_("Blacklisted Addresses"), $disable, true));
+ $this->addItem(new Ingo_Script_Procmail_Comment(_("Blacklisted Addresses"), $disable, true));
$params = array('action-value' => $bl_folder,
'action' => $bl_type,
'disable' => $disable);
foreach ($bl_addr as $address) {
if (!empty($address)) {
- $recipe = new Procmail_Recipe($params, $this->_params);
+ $recipe = new Ingo_Script_Procmail_Recipe($params, $this->_params);
$recipe->addCondition(array('field' => 'From', 'value' => $address, 'match' => 'address'));
$this->addItem($recipe);
}
*
* @param boolean $disable Disable the whitelist?
*/
- function generateWhitelist($disable = false)
+ public function generateWhitelist($disable = false)
{
- $whitelist = &$GLOBALS['ingo_storage']->retrieve(Ingo_Storage::ACTION_WHITELIST);
+ $whitelist = $GLOBALS['ingo_storage']->retrieve(Ingo_Storage::ACTION_WHITELIST);
$wl_addr = $whitelist->getWhitelist();
if (!empty($wl_addr)) {
- $this->addItem(new Procmail_Comment(_("Whitelisted Addresses"), $disable, true));
+ $this->addItem(new Ingo_Script_Procmail_Comment(_("Whitelisted Addresses"), $disable, true));
foreach ($wl_addr as $address) {
if (!empty($address)) {
- $recipe = new Procmail_Recipe(array('action' => Ingo_Storage::ACTION_KEEP, 'disable' => $disable), $this->_params);
+ $recipe = new Ingo_Script_Procmail_Recipe(array('action' => Ingo_Storage::ACTION_KEEP, 'disable' => $disable), $this->_params);
$recipe->addCondition(array('field' => 'From', 'value' => $address, 'match' => 'address'));
$this->addItem($recipe);
}
*
* @param boolean $disable Disable vacation?
*/
- function generateVacation($disable = false)
+ public function generateVacation($disable = false)
{
- $vacation = &$GLOBALS['ingo_storage']->retrieve(Ingo_Storage::ACTION_VACATION);
+ $vacation = $GLOBALS['ingo_storage']->retrieve(Ingo_Storage::ACTION_VACATION);
$addresses = $vacation->getVacationAddresses();
$actionval = array(
'addresses' => $addresses,
);
if (!empty($addresses)) {
- $this->addItem(new Procmail_Comment(_("Vacation"), $disable, true));
+ $this->addItem(new Ingo_Script_Procmail_Comment(_("Vacation"), $disable, true));
$params = array('action' => Ingo_Storage::ACTION_VACATION,
'action-value' => $actionval,
'disable' => $disable);
- $recipe = new Procmail_Recipe($params, $this->_params);
+ $recipe = new Ingo_Script_Procmail_Recipe($params, $this->_params);
$this->addItem($recipe);
}
}
*
* @param boolean $disable Disable forwarding?
*/
- function generateForward($disable = false)
+ public function generateForward($disable = false)
{
- $forward = &$GLOBALS['ingo_storage']->retrieve(Ingo_Storage::ACTION_FORWARD);
+ $forward = $GLOBALS['ingo_storage']->retrieve(Ingo_Storage::ACTION_FORWARD);
$addresses = $forward->getForwardAddresses();
if (!empty($addresses)) {
- $this->addItem(new Procmail_Comment(_("Forwards"), $disable, true));
+ $this->addItem(new Ingo_Script_Procmail_Comment(_("Forwards"), $disable, true));
$params = array('action' => Ingo_Storage::ACTION_FORWARD,
'action-value' => $addresses,
'disable' => $disable);
- $recipe = new Procmail_Recipe($params, $this->_params);
+ $recipe = new Ingo_Script_Procmail_Recipe($params, $this->_params);
if ($forward->getForwardKeep()) {
$recipe->addFlag('c');
}
* @param object $item The item to add to the recipe list.
* The object should have a generate() function.
*/
- function addItem($item)
+ public function addItem($item)
{
$this->_recipes[] = $item;
}
}
-
-/**
- * The Procmail_Comment:: class represents a Procmail comment. This is
- * a pretty simple class, but it makes the code in Ingo_Script_Procmail::
- * cleaner as it provides a generate() function and can be added to the
- * recipe list the same way as a recipe can be.
- *
- * @author Ben Chavet <ben@chavet.net>
- * @package Ingo
- */
-class Procmail_Comment {
-
- /**
- * The comment text.
- *
- * @var string
- */
- var $_comment = '';
-
- /**
- * Constructs a new procmail comment.
- *
- * @param string $comment Comment to be generated.
- * @param boolean $disable Output 'DISABLED' comment?
- * @param boolean $header Output a 'header' comment?
- */
- function Procmail_Comment($comment, $disable = false, $header = false)
- {
- if ($disable) {
- $comment = _("DISABLED: ") . $comment;
- }
-
- if ($header) {
- $this->_comment .= "##### $comment #####";
- } else {
- $this->_comment .= "# $comment";
- }
- }
-
- /**
- * Returns the comment stored by this object.
- *
- * @return string The comment stored by this object.
- */
- function generate()
- {
- return $this->_comment;
- }
-
-}
-
-/**
- * The Procmail_Recipe:: class represents a Procmail recipe.
- *
- * @author Ben Chavet <ben@chavet.net>
- * @package Ingo
- */
-class Procmail_Recipe {
-
- var $_action = array();
- var $_conditions = array();
- var $_disable = '';
- var $_flags = '';
- var $_params = array(
- 'date' => 'date',
- 'echo' => 'echo',
- 'ls' => 'ls'
- );
- var $_valid = true;
-
- /**
- * Constructs a new procmail recipe.
- *
- * @param array $params Array of parameters.
- * REQUIRED FIELDS:
- * 'action'
- * OPTIONAL FIELDS:
- * 'action-value' (only used if the
- * 'action' requires it)
- * @param array $scriptparams Array of parameters passed to
- * Ingo_Script_Procmail::.
- */
- function Procmail_Recipe($params = array(), $scriptparams = array())
- {
- $this->_disable = !empty($params['disable']);
- $this->_params = array_merge($this->_params, $scriptparams);
-
- switch ($params['action']) {
- case Ingo_Storage::ACTION_KEEP:
- // Note: you may have to set the DEFAULT variable in your
- // backend configuration.
- if (isset($this->_params['delivery_agent']) && isset($this->_params['delivery_mailbox_prefix'])) {
- $this->_action[] = '| ' . $this->_params['delivery_agent'] . ' ' . $this->_params['delivery_mailbox_prefix'] . '$DEFAULT';
- } elseif (isset($this->_params['delivery_agent'])) {
- $this->_action[] = '| ' . $this->_params['delivery_agent'] . ' $DEFAULT';
- } else {
- $this->_action[] = '$DEFAULT';
- }
- break;
-
- case Ingo_Storage::ACTION_MOVE:
- if (isset($this->_params['delivery_agent']) && isset($this->_params['delivery_mailbox_prefix'])) {
- $this->_action[] = '| ' . $this->_params['delivery_agent'] . ' ' . $this->_params['delivery_mailbox_prefix'] . $this->procmailPath($params['action-value']);
- } elseif (isset($this->_params['delivery_agent'])) {
- $this->_action[] = '| ' . $this->_params['delivery_agent'] . ' ' . $this->procmailPath($params['action-value']);
- } else {
- $this->_action[] = $this->procmailPath($params['action-value']);
- }
- break;
-
- case Ingo_Storage::ACTION_DISCARD:
- $this->_action[] = '/dev/null';
- break;
-
- case Ingo_Storage::ACTION_REDIRECT:
- $this->_action[] = '! ' . $params['action-value'];
- break;
-
- case Ingo_Storage::ACTION_REDIRECTKEEP:
- $this->_action[] = '{';
- $this->_action[] = ' :0 c';
- $this->_action[] = ' ! ' . $params['action-value'];
- $this->_action[] = '';
- $this->_action[] = ' :0' . (isset($this->_params['delivery_agent']) ? ' w' : '');
- if (isset($this->_params['delivery_agent']) && isset($this->_params['delivery_mailbox_prefix'])) {
- $this->_action[] = ' | ' . $this->_params['delivery_agent'] . ' ' . $this->_params['delivery_mailbox_prefix'] . '$DEFAULT';
- } elseif (isset($this->_params['delivery_agent'])) {
- $this->_action[] = ' | ' . $this->_params['delivery_agent'] . ' $DEFAULT';
- } else {
- $this->_action[] = ' $DEFAULT';
- }
- $this->_action[] = '}';
- break;
-
- case Ingo_Storage::ACTION_REJECT:
- $this->_action[] = '{';
- $this->_action[] = ' EXITCODE=' . $params['action-value'];
- $this->_action[] = ' HOST="no.address.here"';
- $this->_action[] = '}';
- break;
-
- case Ingo_Storage::ACTION_VACATION:
- $days = $params['action-value']['days'];
- $timed = !empty($params['action-value']['start']) &&
- !empty($params['action-value']['end']);
- $this->_action[] = '{';
- foreach ($params['action-value']['addresses'] as $address) {
- if (!empty($address)) {
- $this->_action[] = ' :0';
- $this->_action[] = ' * ^TO_' . $address;
- $this->_action[] = ' {';
- $this->_action[] = ' FILEDATE=`test -f ${VACATION_DIR:-.}/\'.vacation.' . $address . '\' && '
- . $this->_params['ls'] . ' -lcn --time-style=+%s ${VACATION_DIR:-.}/\'.vacation.' . $address . '\' | '
- . 'awk \'{ print $6 + (' . $days * 86400 . ') }\'`';
- $this->_action[] = ' DATE=`' . $this->_params['date'] . ' +%s`';
- $this->_action[] = ' DUMMY=`test -f ${VACATION_DIR:-.}/\'.vacation.' . $address . '\' && '
- . 'test $FILEDATE -le $DATE && '
- . 'rm ${VACATION_DIR:-.}/\'.vacation.' . $address . '\'`';
- if ($timed) {
- $this->_action[] = ' START=' . $params['action-value']['start'];
- $this->_action[] = ' END=' . $params['action-value']['end'];
- }
- $this->_action[] = '';
- $this->_action[] = ' :0 h';
- $this->_action[] = ' SUBJECT=| formail -xSubject:';
- $this->_action[] = '';
- $this->_action[] = ' :0 Whc: ${VACATION_DIR:-.}/vacation.lock';
- if ($timed) {
- $this->_action[] = ' * ? test $DATE -gt $START && test $END -gt $DATE';
- $this->_action[] = ' {';
- $this->_action[] = ' :0 Wh';
- }
- $this->_action[] = ' * ^TO_' . $address;
- $this->_action[] = ' * !^X-Loop: ' . $address;
- $this->_action[] = ' * !^X-Spam-Flag: YES';
- if (count($params['action-value']['excludes']) > 0) {
- foreach ($params['action-value']['excludes'] as $exclude) {
- if (!empty($exclude)) {
- $this->_action[] = ' * !^From.*' . $exclude;
- }
- }
- }
- if ($params['action-value']['ignorelist']) {
- $this->_action[] = ' * !^FROM_DAEMON';
- }
- $this->_action[] = ' | formail -rD 8192 ${VACATION_DIR:-.}/.vacation.' . $address;
- $this->_action[] = ' :0 eh';
- $this->_action[] = ' | (formail -rI"Precedence: junk" \\';
- $this->_action[] = ' -a"From: <' . $address . '>" \\';
- $this->_action[] = ' -A"X-Loop: ' . $address . '" \\';
- if (Horde_Mime::is8bit($params['action-value']['reason'])) {
- $this->_action[] = ' -i"Subject: ' . Horde_Mime::encode($params['action-value']['subject'] . ' (Re: $SUBJECT)', $scriptparams['charset']) . '" \\';
- $this->_action[] = ' -i"Content-Transfer-Encoding: quoted-printable" \\';
- $this->_action[] = ' -i"Content-Type: text/plain; charset=' . $scriptparams['charset'] . '" ; \\';
- $reason = Horde_Mime::quotedPrintableEncode($params['action-value']['reason'], "\n");
- } else {
- $this->_action[] = ' -i"Subject: ' . Horde_Mime::encode($params['action-value']['subject'] . ' (Re: $SUBJECT)', $scriptparams['charset']) . '" ; \\';
- $reason = $params['action-value']['reason'];
- }
- $reason = addcslashes($reason, "\\\n\r\t\"`");
- $this->_action[] = ' ' . $this->_params['echo'] . ' -e "' . $reason . '" \\';
- $this->_action[] = ' ) | $SENDMAIL -f' . $address . ' -oi -t';
- if ($timed) {
- $this->_action[] = ' }';
- }
- $this->_action[] = ' }';
- }
- }
- $this->_action[] = '}';
- break;
-
- case Ingo_Storage::ACTION_FORWARD:
- /* Make sure that we prevent mail loops using 3 methods.
- *
- * First, we call sendmail -f to set the envelope sender to be the
- * same as the original sender, so bounces will go to the original
- * sender rather than to us. This unfortunately triggers lots of
- * Authentication-Warning: messages in sendmail's logs.
- *
- * Second, add an X-Loop header, to handle the case where the
- * address we forward to forwards back to us.
- *
- * Third, don't forward mailer daemon messages (i.e., bounces).
- * Method 1 above should make this redundant, unless we're sending
- * mail from this account and have a bad forward-to account.
- *
- * Get the from address, saving a call to formail if possible.
- * The procmail code for doing this is borrowed from the
- * Procmail Library Project, http://pm-lib.sourceforge.net/.
- * The Ingo project has the permission to use Procmail Library code
- * under Apache licence v 1.x or any later version.
- * Permission obtained 2006-04-04 from Author Jari Aalto. */
- $this->_action[] = '{';
- $this->_action[] = ' :0 ';
- $this->_action[] = ' *$ ! ^From *\/[^ ]+';
- $this->_action[] = ' *$ ! ^Sender: *\/[^ ]+';
- $this->_action[] = ' *$ ! ^From: *\/[^ ]+';
- $this->_action[] = ' *$ ! ^Reply-to: *\/[^ ]+';
- $this->_action[] = ' {';
- $this->_action[] = ' OUTPUT = `formail -zxFrom:`';
- $this->_action[] = ' }';
- $this->_action[] = ' :0 E';
- $this->_action[] = ' {';
- $this->_action[] = ' OUTPUT = $MATCH';
- $this->_action[] = ' }';
- $this->_action[] = '';
-
- /* Forward to each address on our list. */
- foreach ($params['action-value'] as $address) {
- if (!empty($address)) {
- $this->_action[] = ' :0 c';
- $this->_action[] = ' * !^FROM_MAILER';
- $this->_action[] = ' * !^X-Loop: to-' . $address;
- $this->_action[] = ' | formail -A"X-Loop: to-' . $address . '" | $SENDMAIL -oi -f $OUTPUT ' . $address;
- }
- }
-
- /* In case of mail loop or bounce, store a copy locally. Note
- * that if we forward to more than one address, only a mail loop
- * on the last address will cause a local copy to be saved. TODO:
- * The next two lines are redundant (and create an extra copy of
- * the message) if "Keep a copy of messages in this account" is
- * checked. */
- $this->_action[] = ' :0 E' . (isset($this->_params['delivery_agent']) ? 'w' : '');
- if (isset($this->_params['delivery_agent'])) {
- $this->_action[] = isset($this->_params['delivery_mailbox_prefix']) ?
- ' | ' . $this->_params['delivery_agent'] . ' ' . $this->_params['delivery_mailbox_prefix'] . '$DEFAULT' :
- ' | ' . $this->_params['delivery_agent'] . ' $DEFAULT';
- } else {
- $this->_action[] = ' $DEFAULT';
- }
- $this->_action[] = ' :0 ';
- $this->_action[] = ' /dev/null';
- $this->_action[] = '}';
- break;
-
- default:
- $this->_valid = false;
- break;
- }
- }
-
- /**
- * Adds a flag to the recipe.
- *
- * @param string $flag String of flags to append to the current flags.
- */
- function addFlag($flag)
- {
- $this->_flags .= $flag;
- }
-
- /**
- * Adds a condition to the recipe.
- *
- * @param array $condition Array of parameters. Required keys are 'field'
- * and 'value'. 'case' is an optional key.
- */
- function addCondition($condition = array())
- {
- $flag = !empty($condition['case']) ? 'D' : '';
- $match = isset($condition['match']) ? $condition['match'] : null;
- $string = '';
- $prefix = '';
-
- switch ($condition['field']) {
- case 'Destination':
- $string = '^TO_';
- break;
-
- case 'Body':
- $flag .= 'B';
- break;
-
- default:
- // convert 'field' to PCRE pattern matching
- if (!strpos($condition['field'], ',')) {
- $string = '^' . $condition['field'] . ':';
- } else {
- $string .= '^(' . str_replace(',', '|', $condition['field']) . '):';
- }
- $prefix = ' ';
- }
-
- $reverseCondition = false;
- switch ($match) {
- case 'regex':
- $string .= $prefix . $condition['value'];
- break;
-
- case 'address':
- $string .= '(.*\<)?' . quotemeta($condition['value']);
- break;
-
- case 'not begins with':
- $reverseCondition = true;
- // fall through
- case 'begins with':
- $string .= $prefix . quotemeta($condition['value']);
- break;
-
- case 'not ends with':
- $reverseCondition = true;
- // fall through
- case 'ends with':
- $string .= '.*' . quotemeta($condition['value']) . '$';
- break;
-
- case 'not contain':
- $reverseCondition = true;
- // fall through
- case 'contains':
- default:
- $string .= '.*' . quotemeta($condition['value']);
- break;
- }
-
- $this->_conditions[] = array('condition' => ($reverseCondition ? '* !' : '* ') . $string,
- 'flags' => $flag);
- }
-
- /**
- * Generates procmail code to represent the recipe.
- *
- * @return string Procmail code to represent the recipe.
- */
- function generate()
- {
- $nest = 0;
- $prefix = '';
- $text = array();
-
- if (!$this->_valid) {
- return '';
- }
-
- // Set the global flags for the whole rule, each condition
- // will add its own (such as Body or Case Sensitive)
- $global = $this->_flags;
- if (isset($this->_conditions[0])) {
- $global .= $this->_conditions[0]['flags'];
- }
- $text[] = ':0 ' . $global . (isset($this->_params['delivery_agent']) ? 'w' : '');
- foreach ($this->_conditions as $condition) {
- if ($nest > 0) {
- $text[] = str_repeat(' ', $nest - 1) . '{';
- $text[] = str_repeat(' ', $nest) . ':0 ' . $condition['flags'];
- $text[] = str_repeat(' ', $nest) . $condition['condition'];
- } else {
- $text[] = $condition['condition'];
- }
- $nest++;
- }
-
- if (--$nest > 0) {
- $prefix = str_repeat(' ', $nest);
- }
- foreach ($this->_action as $val) {
- $text[] = $prefix . $val;
- }
-
- for ($i = $nest; $i > 0; $i--) {
- $text[] = str_repeat(' ', $i - 1) . '}';
- }
-
- if ($this->_disable) {
- $code = '';
- foreach ($text as $val) {
- $comment = new Procmail_Comment($val);
- $code .= $comment->generate() . "\n";
- }
- return $code . "\n";
- } else {
- return implode("\n", $text) . "\n";
- }
- }
-
- /**
- * Returns a procmail-ready mailbox path, converting IMAP folder
- * pathname conventions as necessary.
- *
- * @param string $folder The IMAP folder name.
- *
- * @return string The procmail mailbox path.
- */
- function procmailPath($folder)
- {
- /* NOTE: '$DEFAULT' here is a literal, not a PHP variable. */
- if (isset($this->_params) &&
- ($this->_params['path_style'] == 'maildir')) {
- if (empty($folder) || ($folder == 'INBOX')) {
- return '$DEFAULT';
- }
- if (substr($folder, 0, 6) == 'INBOX.') {
- $folder = substr($folder, 6);
- }
- return '"$DEFAULT/.' . escapeshellcmd($folder) . '/"';
- } else {
- if (empty($folder) || ($folder == 'INBOX')) {
- return '$DEFAULT';
- }
- return str_replace(' ', '\ ', escapeshellcmd($folder));
- }
- }
-
-}
-
-/**
- * The Procmail_Variable:: class represents a Procmail variable.
- *
- * @author Michael Slusarz <slusarz@horde.org>
- * @package Ingo
- */
-class Procmail_Variable {
-
- var $_name;
- var $_value;
-
- /**
- * Constructs a new procmail variable.
- *
- * @param array $params Array of parameters. Expected fields are 'name'
- * and 'value'.
- */
- function Procmail_Variable($params = array())
- {
- $this->_name = $params['name'];
- $this->_value = $params['value'];
- }
-
- /**
- * Generates procmail code to represent the variable.
- *
- * @return string Procmail code to represent the variable.
- */
- function generate()
- {
- return $this->_name . '=' . $this->_value . "\n";
- }
-
-}
--- /dev/null
+<?php
+/**
+ * The Ingo_Script_Procmail_Comment:: class represents a Procmail comment.
+ * This is a simple class, but it makes the code in Ingo_Script_Procmail::
+ * cleaner as it provides a generate() function and can be added to the
+ * recipe list the same way as a recipe can be.
+ *
+ * Copyright 2003-2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file LICENSE for license information (ASL). If you
+ * did not receive this file, see http://www.horde.org/licenses/asl.php.
+ *
+ * @author Ben Chavet <ben@horde.org>
+ * @package Ingo
+ */
+class Ingo_Script_Procmail_Comment
+{
+ /**
+ * The comment text.
+ *
+ * @var string
+ */
+ protected $_comment = '';
+
+ /**
+ * Constructs a new procmail comment.
+ *
+ * @param string $comment Comment to be generated.
+ * @param boolean $disable Output 'DISABLED' comment?
+ * @param boolean $header Output a 'header' comment?
+ */
+ public function __construct($comment, $disable = false, $header = false)
+ {
+ if ($disable) {
+ $comment = _("DISABLED: ") . $comment;
+ }
+
+ $this->_comment = $header
+ ? '##### ' . $comment . ' #####'
+ : '# ' . $comment;
+ }
+
+ /**
+ * Returns the comment stored by this object.
+ *
+ * @return string The comment stored by this object.
+ */
+ public function generate()
+ {
+ return $this->_comment;
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * The Ingo_Script_Procmail_Recipe:: class represents a Procmail recipe.
+ *
+ * Copyright 2003-2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file LICENSE for license information (ASL). If you
+ * did not receive this file, see http://www.horde.org/licenses/asl.php.
+ *
+ * @author Ben Chavet <ben@horde.org>
+ * @package Ingo
+ */
+class Ingo_Script_Procmail_Recipe
+{
+ /**
+ */
+ protected $_action = array();
+
+ /**
+ */
+ protected $_conditions = array();
+
+ /**
+ */
+ protected $_disable = '';
+
+ /**
+ */
+ protected $_flags = '';
+
+ /**
+ */
+ protected $_params = array(
+ 'date' => 'date',
+ 'echo' => 'echo',
+ 'ls' => 'ls'
+ );
+
+ /**
+ */
+ protected $_valid = true;
+
+ /**
+ * Constructs a new procmail recipe.
+ *
+ * @param array $params Array of parameters.
+ * REQUIRED FIELDS:
+ * 'action'
+ * OPTIONAL FIELDS:
+ * 'action-value' (only used if the
+ * 'action' requires it)
+ * @param array $scriptparams Array of parameters passed to
+ * Ingo_Script_Procmail::.
+ */
+ public function __construct($params = array(), $scriptparams = array())
+ {
+ $this->_disable = !empty($params['disable']);
+ $this->_params = array_merge($this->_params, $scriptparams);
+
+ switch ($params['action']) {
+ case Ingo_Storage::ACTION_KEEP:
+ // Note: you may have to set the DEFAULT variable in your
+ // backend configuration.
+ if (isset($this->_params['delivery_agent']) && isset($this->_params['delivery_mailbox_prefix'])) {
+ $this->_action[] = '| ' . $this->_params['delivery_agent'] . ' ' . $this->_params['delivery_mailbox_prefix'] . '$DEFAULT';
+ } elseif (isset($this->_params['delivery_agent'])) {
+ $this->_action[] = '| ' . $this->_params['delivery_agent'] . ' $DEFAULT';
+ } else {
+ $this->_action[] = '$DEFAULT';
+ }
+ break;
+
+ case Ingo_Storage::ACTION_MOVE:
+ if (isset($this->_params['delivery_agent']) && isset($this->_params['delivery_mailbox_prefix'])) {
+ $this->_action[] = '| ' . $this->_params['delivery_agent'] . ' ' . $this->_params['delivery_mailbox_prefix'] . $this->procmailPath($params['action-value']);
+ } elseif (isset($this->_params['delivery_agent'])) {
+ $this->_action[] = '| ' . $this->_params['delivery_agent'] . ' ' . $this->procmailPath($params['action-value']);
+ } else {
+ $this->_action[] = $this->procmailPath($params['action-value']);
+ }
+ break;
+
+ case Ingo_Storage::ACTION_DISCARD:
+ $this->_action[] = '/dev/null';
+ break;
+
+ case Ingo_Storage::ACTION_REDIRECT:
+ $this->_action[] = '! ' . $params['action-value'];
+ break;
+
+ case Ingo_Storage::ACTION_REDIRECTKEEP:
+ $this->_action[] = '{';
+ $this->_action[] = ' :0 c';
+ $this->_action[] = ' ! ' . $params['action-value'];
+ $this->_action[] = '';
+ $this->_action[] = ' :0' . (isset($this->_params['delivery_agent']) ? ' w' : '');
+ if (isset($this->_params['delivery_agent']) && isset($this->_params['delivery_mailbox_prefix'])) {
+ $this->_action[] = ' | ' . $this->_params['delivery_agent'] . ' ' . $this->_params['delivery_mailbox_prefix'] . '$DEFAULT';
+ } elseif (isset($this->_params['delivery_agent'])) {
+ $this->_action[] = ' | ' . $this->_params['delivery_agent'] . ' $DEFAULT';
+ } else {
+ $this->_action[] = ' $DEFAULT';
+ }
+ $this->_action[] = '}';
+ break;
+
+ case Ingo_Storage::ACTION_REJECT:
+ $this->_action[] = '{';
+ $this->_action[] = ' EXITCODE=' . $params['action-value'];
+ $this->_action[] = ' HOST="no.address.here"';
+ $this->_action[] = '}';
+ break;
+
+ case Ingo_Storage::ACTION_VACATION:
+ $days = $params['action-value']['days'];
+ $timed = !empty($params['action-value']['start']) &&
+ !empty($params['action-value']['end']);
+ $this->_action[] = '{';
+ foreach ($params['action-value']['addresses'] as $address) {
+ if (!empty($address)) {
+ $this->_action[] = ' :0';
+ $this->_action[] = ' * ^TO_' . $address;
+ $this->_action[] = ' {';
+ $this->_action[] = ' FILEDATE=`test -f ${VACATION_DIR:-.}/\'.vacation.' . $address . '\' && '
+ . $this->_params['ls'] . ' -lcn --time-style=+%s ${VACATION_DIR:-.}/\'.vacation.' . $address . '\' | '
+ . 'awk \'{ print $6 + (' . $days * 86400 . ') }\'`';
+ $this->_action[] = ' DATE=`' . $this->_params['date'] . ' +%s`';
+ $this->_action[] = ' DUMMY=`test -f ${VACATION_DIR:-.}/\'.vacation.' . $address . '\' && '
+ . 'test $FILEDATE -le $DATE && '
+ . 'rm ${VACATION_DIR:-.}/\'.vacation.' . $address . '\'`';
+ if ($timed) {
+ $this->_action[] = ' START=' . $params['action-value']['start'];
+ $this->_action[] = ' END=' . $params['action-value']['end'];
+ }
+ $this->_action[] = '';
+ $this->_action[] = ' :0 h';
+ $this->_action[] = ' SUBJECT=| formail -xSubject:';
+ $this->_action[] = '';
+ $this->_action[] = ' :0 Whc: ${VACATION_DIR:-.}/vacation.lock';
+ if ($timed) {
+ $this->_action[] = ' * ? test $DATE -gt $START && test $END -gt $DATE';
+ $this->_action[] = ' {';
+ $this->_action[] = ' :0 Wh';
+ }
+ $this->_action[] = ' * ^TO_' . $address;
+ $this->_action[] = ' * !^X-Loop: ' . $address;
+ $this->_action[] = ' * !^X-Spam-Flag: YES';
+ if (count($params['action-value']['excludes']) > 0) {
+ foreach ($params['action-value']['excludes'] as $exclude) {
+ if (!empty($exclude)) {
+ $this->_action[] = ' * !^From.*' . $exclude;
+ }
+ }
+ }
+ if ($params['action-value']['ignorelist']) {
+ $this->_action[] = ' * !^FROM_DAEMON';
+ }
+ $this->_action[] = ' | formail -rD 8192 ${VACATION_DIR:-.}/.vacation.' . $address;
+ $this->_action[] = ' :0 eh';
+ $this->_action[] = ' | (formail -rI"Precedence: junk" \\';
+ $this->_action[] = ' -a"From: <' . $address . '>" \\';
+ $this->_action[] = ' -A"X-Loop: ' . $address . '" \\';
+ if (Horde_Mime::is8bit($params['action-value']['reason'])) {
+ $this->_action[] = ' -i"Subject: ' . Horde_Mime::encode($params['action-value']['subject'] . ' (Re: $SUBJECT)', $scriptparams['charset']) . '" \\';
+ $this->_action[] = ' -i"Content-Transfer-Encoding: quoted-printable" \\';
+ $this->_action[] = ' -i"Content-Type: text/plain; charset=' . $scriptparams['charset'] . '" ; \\';
+ $reason = Horde_Mime::quotedPrintableEncode($params['action-value']['reason'], "\n");
+ } else {
+ $this->_action[] = ' -i"Subject: ' . Horde_Mime::encode($params['action-value']['subject'] . ' (Re: $SUBJECT)', $scriptparams['charset']) . '" ; \\';
+ $reason = $params['action-value']['reason'];
+ }
+ $reason = addcslashes($reason, "\\\n\r\t\"`");
+ $this->_action[] = ' ' . $this->_params['echo'] . ' -e "' . $reason . '" \\';
+ $this->_action[] = ' ) | $SENDMAIL -f' . $address . ' -oi -t';
+ if ($timed) {
+ $this->_action[] = ' }';
+ }
+ $this->_action[] = ' }';
+ }
+ }
+ $this->_action[] = '}';
+ break;
+
+ case Ingo_Storage::ACTION_FORWARD:
+ /* Make sure that we prevent mail loops using 3 methods.
+ *
+ * First, we call sendmail -f to set the envelope sender to be the
+ * same as the original sender, so bounces will go to the original
+ * sender rather than to us. This unfortunately triggers lots of
+ * Authentication-Warning: messages in sendmail's logs.
+ *
+ * Second, add an X-Loop header, to handle the case where the
+ * address we forward to forwards back to us.
+ *
+ * Third, don't forward mailer daemon messages (i.e., bounces).
+ * Method 1 above should make this redundant, unless we're sending
+ * mail from this account and have a bad forward-to account.
+ *
+ * Get the from address, saving a call to formail if possible.
+ * The procmail code for doing this is borrowed from the
+ * Procmail Library Project, http://pm-lib.sourceforge.net/.
+ * The Ingo project has the permission to use Procmail Library code
+ * under Apache licence v 1.x or any later version.
+ * Permission obtained 2006-04-04 from Author Jari Aalto. */
+ $this->_action[] = '{';
+ $this->_action[] = ' :0 ';
+ $this->_action[] = ' *$ ! ^From *\/[^ ]+';
+ $this->_action[] = ' *$ ! ^Sender: *\/[^ ]+';
+ $this->_action[] = ' *$ ! ^From: *\/[^ ]+';
+ $this->_action[] = ' *$ ! ^Reply-to: *\/[^ ]+';
+ $this->_action[] = ' {';
+ $this->_action[] = ' OUTPUT = `formail -zxFrom:`';
+ $this->_action[] = ' }';
+ $this->_action[] = ' :0 E';
+ $this->_action[] = ' {';
+ $this->_action[] = ' OUTPUT = $MATCH';
+ $this->_action[] = ' }';
+ $this->_action[] = '';
+
+ /* Forward to each address on our list. */
+ foreach ($params['action-value'] as $address) {
+ if (!empty($address)) {
+ $this->_action[] = ' :0 c';
+ $this->_action[] = ' * !^FROM_MAILER';
+ $this->_action[] = ' * !^X-Loop: to-' . $address;
+ $this->_action[] = ' | formail -A"X-Loop: to-' . $address . '" | $SENDMAIL -oi -f $OUTPUT ' . $address;
+ }
+ }
+
+ /* In case of mail loop or bounce, store a copy locally. Note
+ * that if we forward to more than one address, only a mail loop
+ * on the last address will cause a local copy to be saved. TODO:
+ * The next two lines are redundant (and create an extra copy of
+ * the message) if "Keep a copy of messages in this account" is
+ * checked. */
+ $this->_action[] = ' :0 E' . (isset($this->_params['delivery_agent']) ? 'w' : '');
+ if (isset($this->_params['delivery_agent'])) {
+ $this->_action[] = isset($this->_params['delivery_mailbox_prefix']) ?
+ ' | ' . $this->_params['delivery_agent'] . ' ' . $this->_params['delivery_mailbox_prefix'] . '$DEFAULT' :
+ ' | ' . $this->_params['delivery_agent'] . ' $DEFAULT';
+ } else {
+ $this->_action[] = ' $DEFAULT';
+ }
+ $this->_action[] = ' :0 ';
+ $this->_action[] = ' /dev/null';
+ $this->_action[] = '}';
+ break;
+
+ default:
+ $this->_valid = false;
+ break;
+ }
+ }
+
+ /**
+ * Adds a flag to the recipe.
+ *
+ * @param string $flag String of flags to append to the current flags.
+ */
+ public function addFlag($flag)
+ {
+ $this->_flags .= $flag;
+ }
+
+ /**
+ * Adds a condition to the recipe.
+ *
+ * @param array $condition Array of parameters. Required keys are 'field'
+ * and 'value'. 'case' is an optional key.
+ */
+ public function addCondition($condition = array())
+ {
+ $flag = !empty($condition['case']) ? 'D' : '';
+ $match = isset($condition['match']) ? $condition['match'] : null;
+ $string = '';
+ $prefix = '';
+
+ switch ($condition['field']) {
+ case 'Destination':
+ $string = '^TO_';
+ break;
+
+ case 'Body':
+ $flag .= 'B';
+ break;
+
+ default:
+ // convert 'field' to PCRE pattern matching
+ if (!strpos($condition['field'], ',')) {
+ $string = '^' . $condition['field'] . ':';
+ } else {
+ $string .= '^(' . str_replace(',', '|', $condition['field']) . '):';
+ }
+ $prefix = ' ';
+ }
+
+ $reverseCondition = false;
+ switch ($match) {
+ case 'regex':
+ $string .= $prefix . $condition['value'];
+ break;
+
+ case 'address':
+ $string .= '(.*\<)?' . quotemeta($condition['value']);
+ break;
+
+ case 'not begins with':
+ $reverseCondition = true;
+ // fall through
+ case 'begins with':
+ $string .= $prefix . quotemeta($condition['value']);
+ break;
+
+ case 'not ends with':
+ $reverseCondition = true;
+ // fall through
+ case 'ends with':
+ $string .= '.*' . quotemeta($condition['value']) . '$';
+ break;
+
+ case 'not contain':
+ $reverseCondition = true;
+ // fall through
+ case 'contains':
+ default:
+ $string .= '.*' . quotemeta($condition['value']);
+ break;
+ }
+
+ $this->_conditions[] = array('condition' => ($reverseCondition ? '* !' : '* ') . $string,
+ 'flags' => $flag);
+ }
+
+ /**
+ * Generates procmail code to represent the recipe.
+ *
+ * @return string Procmail code to represent the recipe.
+ */
+ public function generate()
+ {
+ $nest = 0;
+ $prefix = '';
+ $text = array();
+
+ if (!$this->_valid) {
+ return '';
+ }
+
+ // Set the global flags for the whole rule, each condition
+ // will add its own (such as Body or Case Sensitive)
+ $global = $this->_flags;
+ if (isset($this->_conditions[0])) {
+ $global .= $this->_conditions[0]['flags'];
+ }
+ $text[] = ':0 ' . $global . (isset($this->_params['delivery_agent']) ? 'w' : '');
+ foreach ($this->_conditions as $condition) {
+ if ($nest > 0) {
+ $text[] = str_repeat(' ', $nest - 1) . '{';
+ $text[] = str_repeat(' ', $nest) . ':0 ' . $condition['flags'];
+ $text[] = str_repeat(' ', $nest) . $condition['condition'];
+ } else {
+ $text[] = $condition['condition'];
+ }
+ $nest++;
+ }
+
+ if (--$nest > 0) {
+ $prefix = str_repeat(' ', $nest);
+ }
+ foreach ($this->_action as $val) {
+ $text[] = $prefix . $val;
+ }
+
+ for ($i = $nest; $i > 0; $i--) {
+ $text[] = str_repeat(' ', $i - 1) . '}';
+ }
+
+ if ($this->_disable) {
+ $code = '';
+ foreach ($text as $val) {
+ $comment = new Ingo_Script_Procmail_Comment($val);
+ $code .= $comment->generate() . "\n";
+ }
+ return $code . "\n";
+ } else {
+ return implode("\n", $text) . "\n";
+ }
+ }
+
+ /**
+ * Returns a procmail-ready mailbox path, converting IMAP folder
+ * pathname conventions as necessary.
+ *
+ * @param string $folder The IMAP folder name.
+ *
+ * @return string The procmail mailbox path.
+ */
+ public function procmailPath($folder)
+ {
+ /* NOTE: '$DEFAULT' here is a literal, not a PHP variable. */
+ if (isset($this->_params) &&
+ ($this->_params['path_style'] == 'maildir')) {
+ if (empty($folder) || ($folder == 'INBOX')) {
+ return '$DEFAULT';
+ }
+ if (substr($folder, 0, 6) == 'INBOX.') {
+ $folder = substr($folder, 6);
+ }
+ return '"$DEFAULT/.' . escapeshellcmd($folder) . '/"';
+ } else {
+ if (empty($folder) || ($folder == 'INBOX')) {
+ return '$DEFAULT';
+ }
+ return str_replace(' ', '\ ', escapeshellcmd($folder));
+ }
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * The Ingo_Script_Procmail_Variable:: class represents a Procmail variable.
+ *
+ * Copyright 2003-2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file LICENSE for license information (ASL). If you
+ * did not receive this file, see http://www.horde.org/licenses/asl.php.
+ *
+ * @author Michael Slusarz <slusarz@horde.org>
+ * @package Ingo
+ */
+class Ingo_Script_Procmail_Variable
+{
+ /**
+ */
+ protected $_name;
+
+ /**
+ */
+ protected $_value;
+
+ /**
+ * Constructs a new procmail variable.
+ *
+ * @param array $params Array of parameters. Expected fields are 'name'
+ * and 'value'.
+ */
+ public function __construct($params = array())
+ {
+ $this->_name = $params['name'];
+ $this->_value = $params['value'];
+ }
+
+ /**
+ * Generates procmail code to represent the variable.
+ *
+ * @return string Procmail code to represent the variable.
+ */
+ public function generate()
+ {
+ return $this->_name . '=' . $this->_value . "\n";
+ }
+
+}
* @author Mike Cochrane <mike@graftonhall.co.nz>
* @package Ingo
*/
-class Ingo_Script_Sieve extends Ingo_Script {
-
+class Ingo_Script_Sieve extends Ingo_Script
+{
/**
* The list of actions allowed (implemented) for this driver.
*
* @var array
*/
- var $_actions = array(
+ protected $_actions = array(
Ingo_Storage::ACTION_KEEP,
Ingo_Storage::ACTION_MOVE,
Ingo_Storage::ACTION_DISCARD,
*
* @var array
*/
- var $_categories = array(
+ protected $_categories = array(
Ingo_Storage::ACTION_BLACKLIST,
Ingo_Storage::ACTION_WHITELIST,
Ingo_Storage::ACTION_VACATION,
*
* @var array
*/
- var $_tests = array(
- 'contains', 'not contain', 'is', 'not is', 'begins with',
- 'not begins with', 'ends with', 'not ends with', 'exists', 'not exist',
- 'less than', 'less than or equal to', 'equal', 'not equal',
- 'greater than', 'greater than or equal to', 'regex', 'matches',
+ protected $_tests = array(
+ 'contains',
+ 'not contain',
+ 'is',
+ 'not is',
+ 'begins with',
+ 'not begins with',
+ 'ends with',
+ 'not ends with',
+ 'exists',
+ 'not exist',
+ 'less than',
+ 'less than or equal to',
+ 'equal',
+ 'not equal',
+ 'greater than',
+ 'greater than or equal to',
+ 'regex',
+ 'matches',
'not matches'
);
*
* @var array
*/
- var $_types = array(
+ protected $_types = array(
Ingo_Storage::TYPE_HEADER,
Ingo_Storage::TYPE_SIZE,
Ingo_Storage::TYPE_BODY
*
* @var boolean
*/
- var $_casesensitive = true;
+ protected $_casesensitive = true;
/**
* Does the driver support setting IMAP flags?
*
* @var boolean
*/
- var $_supportIMAPFlags = true;
+ protected $_supportIMAPFlags = true;
/**
* Does the driver support the stop-script option?
*
* @var boolean
*/
- var $_supportStopScript = true;
+ protected $_supportStopScript = true;
/**
* Does the driver require a script file to be generated?
*
* @var boolean
*/
- var $_scriptfile = true;
+ protected $_scriptfile = true;
/**
* The blocks that make up the code.
*
* @var array
*/
- var $_blocks = array();
+ protected $_blocks = array();
/**
* The blocks that have to appear at the end of the code.
*
* @var array
*/
- var $_endBlocks = array();
+ protected $_endBlocks = array();
/**
* Returns a script previously generated with generate().
*
* @return string The Sieve script.
*/
- function toCode()
+ public function toCode()
{
$code = "# Sieve Filter\n# "
. _("Generated by Ingo (http://www.horde.org/ingo/)") . ' ('
*
* @return string The string, UTF-8 encoded.
*/
- function encode($string)
+ public function encode($string)
{
return Horde_String::convertCharset($string, $this->_params['charset'], 'UTF-8');
}
*
* @return string The escaped string.
*/
- function escapeString($string, $regexmode = false)
+ static public function escapeString($string, $regexmode = false)
{
/* Remove any backslashes in front of commas. */
$string = str_replace('\,', ',', $string);
- if ($regexmode) {
- return str_replace('"', addslashes('"'), $string);
- } else {
- return str_replace(array('\\', '"'), array(addslashes('\\'), addslashes('"')), $string);
- }
+ return $regexmode
+ ? str_replace('"', addslashes('"'), $string)
+ : str_replace(array('\\', '"'), array(addslashes('\\'), addslashes('"')), $string);
}
/**
* @return boolean|string True if all rules are valid, an error message
* otherwise.
*/
- function check()
+ public function check()
{
foreach ($this->_blocks as $block) {
$res = $block->check();
*
* @return array A Sieve extension list.
*/
- function requires()
+ public function requires()
{
$requires = array();
foreach ($this->_blocks as $block) {
/**
* Adds all blocks necessary for the forward rule.
*/
- function _addForwardBlocks()
+ protected function _addForwardBlocks()
{
if (!$this->_validRule(Ingo_Storage::ACTION_FORWARD)) {
return;
}
- $forward = &$GLOBALS['ingo_storage']->retrieve(Ingo_Storage::ACTION_FORWARD);
+ $forward = $GLOBALS['ingo_storage']->retrieve(Ingo_Storage::ACTION_FORWARD);
$fwd_addr = $forward->getForwardAddresses();
if (empty($fwd_addr)) {
return;
foreach ($fwd_addr as $addr) {
$addr = trim($addr);
if (!empty($addr)) {
- $action[] = new Sieve_Action_Redirect(array('address' => $addr));
+ $action[] = new Ingo_Script_Sieve_Action_Redirect(array('address' => $addr));
}
}
if (count($action)) {
if($forward->getForwardKeep()) {
- $this->_endBlocks[] = new Sieve_Comment($this->encode(_("Forward Keep Action")));
- $if = new Sieve_If(new Sieve_Test_True());
- $if->setActions(array(new Sieve_Action_Keep(),
- new Sieve_Action_Stop()));
+ $this->_endBlocks[] = new Ingo_Script_Sieve_Comment($this->encode(_("Forward Keep Action")));
+ $if = new Ingo_Script_Sieve_If(new Ingo_Script_Sieve_Test_True());
+ $if->setActions(array(new Ingo_Script_Sieve_Action_Keep(),
+ new Ingo_Script_Sieve_Action_Stop()));
$this->_endBlocks[] = $if;
} else {
- $action[] = new Sieve_Action_Stop();
+ $action[] = new Ingo_Script_Sieve_Action_Stop();
}
}
- $this->_blocks[] = new Sieve_Comment($this->encode(_("Forwards")));
+ $this->_blocks[] = new Ingo_Script_Sieve_Comment($this->encode(_("Forwards")));
- $test = new Sieve_Test_True();
- $if = new Sieve_If($test);
+ $test = new Ingo_Script_Sieve_Test_True();
+ $if = new Ingo_Script_Sieve_If($test);
$if->setActions($action);
$this->_blocks[] = $if;
}
/**
* Adds all blocks necessary for the blacklist rule.
*/
- function _addBlacklistBlocks()
+ protected function _addBlacklistBlocks()
{
if (!$this->_validRule(Ingo_Storage::ACTION_BLACKLIST)) {
return;
}
- $blacklist = &$GLOBALS['ingo_storage']->retrieve(Ingo_Storage::ACTION_BLACKLIST);
+ $blacklist = $GLOBALS['ingo_storage']->retrieve(Ingo_Storage::ACTION_BLACKLIST);
$bl_addr = $blacklist->getBlacklist();
$folder = $blacklist->getBlacklistFolder();
if (empty($bl_addr)) {
$action = array();
if (empty($folder)) {
- $action[] = new Sieve_Action_Discard();
+ $action[] = new Ingo_Script_Sieve_Action_Discard();
} elseif ($folder == Ingo::BLACKLIST_MARKER) {
- $action[] = new Sieve_Action_Addflag(array('flags' => Ingo_Storage::FLAG_DELETED));
- $action[] = new Sieve_Action_Keep();
- $action[] = new Sieve_Action_Removeflag(array('flags' => Ingo_Storage::FLAG_DELETED));
+ $action[] = new Ingo_Script_Sieve_Action_Addflag(array('flags' => Ingo_Storage::FLAG_DELETED));
+ $action[] = new Ingo_Script_Sieve_Action_Keep();
+ $action[] = new Ingo_Script_Sieve_Action_Removeflag(array('flags' => Ingo_Storage::FLAG_DELETED));
} else {
- $action[] = new Sieve_Action_Fileinto(array_merge($this->_params, array('folder' => $folder)));
+ $action[] = new Ingo_Script_Sieve_Action_Fileinto(array_merge($this->_params, array('folder' => $folder)));
}
- $action[] = new Sieve_Action_Stop();
+ $action[] = new Ingo_Script_Sieve_Action_Stop();
- $this->_blocks[] = new Sieve_Comment($this->encode(_("Blacklisted Addresses")));
+ $this->_blocks[] = new Ingo_Script_Sieve_Comment($this->encode(_("Blacklisted Addresses")));
/* Split the test up to only do 5 addresses at a time. */
$temp = array();
}
}
if (count($temp) == 5) {
- $test = new Sieve_Test_Address(array('headers' => "From\nSender\nResent-From", 'addresses' => implode("\n", $temp)));
- $if = new Sieve_If($test);
+ $test = new Ingo_Script_Sieve_Test_Address(array('headers' => "From\nSender\nResent-From", 'addresses' => implode("\n", $temp)));
+ $if = new Ingo_Script_Sieve_If($test);
$if->setActions($action);
$this->_blocks[] = $if;
$temp = array();
}
if (count($wildcards) == 5) {
- $test = new Sieve_Test_Address(array('headers' => "From\nSender\nResent-From", 'match-type' => ':matches', 'addresses' => implode("\n", $wildcards)));
- $if = new Sieve_If($test);
+ $test = new Ingo_Script_Sieve_Test_Address(array('headers' => "From\nSender\nResent-From", 'match-type' => ':matches', 'addresses' => implode("\n", $wildcards)));
+ $if = new Ingo_Script_Sieve_If($test);
$if->setActions($action);
$this->_blocks[] = $if;
$wildcards = array();
}
if ($temp) {
- $test = new Sieve_Test_Address(array('headers' => "From\nSender\nResent-From", 'addresses' => implode("\n", $temp)));
- $if = new Sieve_If($test);
+ $test = new Ingo_Script_Sieve_Test_Address(array('headers' => "From\nSender\nResent-From", 'addresses' => implode("\n", $temp)));
+ $if = new Ingo_Script_Sieve_If($test);
$if->setActions($action);
$this->_blocks[] = $if;
}
if ($wildcards) {
- $test = new Sieve_Test_Address(array('headers' => "From\nSender\nResent-From", 'match-type' => ':matches', 'addresses' => implode("\n", $wildcards)));
- $if = new Sieve_If($test);
+ $test = new Ingo_Script_Sieve_Test_Address(array('headers' => "From\nSender\nResent-From", 'match-type' => ':matches', 'addresses' => implode("\n", $wildcards)));
+ $if = new Ingo_Script_Sieve_If($test);
$if->setActions($action);
$this->_blocks[] = $if;
}
/**
* Adds all blocks necessary for the whitelist rule.
*/
- function _addWhitelistBlocks()
+ protected function _addWhitelistBlocks()
{
if (!$this->_validRule(Ingo_Storage::ACTION_WHITELIST)) {
return;
return;
}
- $this->_blocks[] = new Sieve_Comment($this->encode(_("Whitelisted Addresses")));
+ $this->_blocks[] = new Ingo_Script_Sieve_Comment($this->encode(_("Whitelisted Addresses")));
- $action = array(new Sieve_Action_Keep(), new Sieve_Action_Stop());
- $test = new Sieve_Test_Address(array('headers' => "From\nSender\nResent-From", 'addresses' => implode("\n", $wl_addr)));
- $if = new Sieve_If($test);
+ $action = array(new Ingo_Script_Sieve_Action_Keep(), new Ingo_Script_Sieve_Action_Stop());
+ $test = new Ingo_Script_Sieve_Test_Address(array('headers' => "From\nSender\nResent-From", 'addresses' => implode("\n", $wl_addr)));
+ $if = new Ingo_Script_Sieve_If($test);
$if->setActions($action);
$this->_blocks[] = $if;
}
/**
* Adds all blocks necessary for the vacation rule.
*/
- function _addVacationBlocks()
+ protected function _addVacationBlocks()
{
if (!$this->_validRule(Ingo_Storage::ACTION_VACATION)) {
return;
);
$action = $tests = array();
- $action[] = new Sieve_Action_Vacation($vals);
+ $action[] = new Ingo_Script_Sieve_Action_Vacation($vals);
if ($vacation->getVacationIgnorelist()) {
$mime_headers = new Horde_Mime_Headers();
$headers = $mime_headers->listHeaders();
$headers['Mailing-List'] = null;
- $tmp = new Sieve_Test_Exists(array('headers' => implode("\n", array_keys($headers))));
- $tests[] = new Sieve_Test_Not($tmp);
+ $tmp = new Ingo_Script_Sieve_Test_Exists(array('headers' => implode("\n", array_keys($headers))));
+ $tests[] = new Ingo_Script_Sieve_Test_Not($tmp);
$vals = array('headers' => 'Precedence',
'match-type' => ':is',
'strings' => "list\nbulk\njunk",
'comparator' => 'i;ascii-casemap');
- $tmp = new Sieve_Test_Header($vals);
- $tests[] = new Sieve_Test_Not($tmp);
+ $tmp = new Ingo_Script_Sieve_Test_Header($vals);
+ $tests[] = new Ingo_Script_Sieve_Test_Not($tmp);
$vals = array('headers' => 'To',
'match-type' => ':matches',
'strings' => 'Multiple recipients of*',
'comparator' => 'i;ascii-casemap');
- $tmp = new Sieve_Test_Header($vals);
- $tests[] = new Sieve_Test_Not($tmp);
+ $tmp = new Ingo_Script_Sieve_Test_Header($vals);
+ $tests[] = new Ingo_Script_Sieve_Test_Not($tmp);
}
$addrs = array();
}
if ($addrs) {
- $tmp = new Sieve_Test_Address(array('headers' => "From\nSender\nResent-From", 'addresses' => implode("\n", $addrs)));
- $tests[] = new Sieve_Test_Not($tmp);
+ $tmp = new Ingo_Script_Sieve_Test_Address(array('headers' => "From\nSender\nResent-From", 'addresses' => implode("\n", $addrs)));
+ $tests[] = new Ingo_Script_Sieve_Test_Not($tmp);
}
- $this->_blocks[] = new Sieve_Comment($this->encode(_("Vacation")));
+ $this->_blocks[] = new Ingo_Script_Sieve_Comment($this->encode(_("Vacation")));
if ($tests) {
- $test = new Sieve_Test_Allof($tests);
- $if = new Sieve_If($test);
+ $test = new Ingo_Script_Sieve_Test_Allof($tests);
+ $if = new Ingo_Script_Sieve_If($test);
$if->setActions($action);
$this->_blocks[] = $if;
} else {
/**
* Adds all blocks necessary for the spam rule.
*/
- function _addSpamBlocks()
+ protected function _addSpamBlocks()
{
if (!$this->_validRule(Ingo_Storage::ACTION_SPAM)) {
return;
}
- $spam = &$GLOBALS['ingo_storage']->retrieve(Ingo_Storage::ACTION_SPAM);
+ $spam = $GLOBALS['ingo_storage']->retrieve(Ingo_Storage::ACTION_SPAM);
if ($spam === false) {
return;
}
- $this->_blocks[] = new Sieve_Comment($this->encode(_("Spam Filter")));
+ $this->_blocks[] = new Ingo_Script_Sieve_Comment($this->encode(_("Spam Filter")));
$actions = array();
- $actions[] = new Sieve_Action_Fileinto(array_merge($this->_params, array('folder' => $spam->getSpamFolder())));
+ $actions[] = new Ingo_Script_Sieve_Action_Fileinto(array_merge($this->_params, array('folder' => $spam->getSpamFolder())));
if ($this->_params['spam_compare'] == 'numeric') {
$vals = array(
'comparison' => 'ge',
'value' => $spam->getSpamLevel(),
);
- $test = new Sieve_Test_Relational($vals);
+ $test = new Ingo_Script_Sieve_Test_Relational($vals);
} elseif ($this->_params['spam_compare'] == 'string') {
$vals = array(
'headers' => $this->_params['spam_header'],
$spam->getSpamLevel()),
'comparator' => 'i;ascii-casemap',
);
- $test = new Sieve_Test_Header($vals);
+ $test = new Ingo_Script_Sieve_Test_Header($vals);
}
- $actions[] = new Sieve_Action_Stop();
+ $actions[] = new Ingo_Script_Sieve_Action_Stop();
- $if = new Sieve_If($test);
+ $if = new Ingo_Script_Sieve_If($test);
$if->setActions($actions);
$this->_blocks[] = $if;
}
*
* @return string The Sieve script.
*/
- function generate()
+ public function generate()
{
global $ingo_storage;
switch ($filter['action']) {
case Ingo_Storage::ACTION_KEEP:
if (!empty($filter['flags'])) {
- $action[] = new Sieve_Action_Addflag(array('flags' => $filter['flags']));
+ $action[] = new Ingo_Script_Sieve_Action_Addflag(array('flags' => $filter['flags']));
}
- $action[] = new Sieve_Action_Keep();
+ $action[] = new Ingo_Script_Sieve_Action_Keep();
if (!empty($filter['flags'])) {
- $action[] = new Sieve_Action_RemoveFlag(array('flags' => $filter['flags']));
+ $action[] = new Ingo_Script_Sieve_Action_RemoveFlag(array('flags' => $filter['flags']));
}
break;
case Ingo_Storage::ACTION_DISCARD:
- $action[] = new Sieve_Action_Discard();
+ $action[] = new Ingo_Script_Sieve_Action_Discard();
break;
case Ingo_Storage::ACTION_MOVE:
if (!empty($filter['flags'])) {
- $action[] = new Sieve_Action_Addflag(array('flags' => $filter['flags']));
+ $action[] = new Ingo_Script_Sieve_Action_Addflag(array('flags' => $filter['flags']));
}
- $action[] = new Sieve_Action_Fileinto(array_merge($this->_params, array('folder' => $filter['action-value'])));
+ $action[] = new Ingo_Script_Sieve_Action_Fileinto(array_merge($this->_params, array('folder' => $filter['action-value'])));
if (!empty($filter['flags'])) {
- $action[] = new Sieve_Action_RemoveFlag(array('flags' => $filter['flags']));
+ $action[] = new Ingo_Script_Sieve_Action_RemoveFlag(array('flags' => $filter['flags']));
}
break;
case Ingo_Storage::ACTION_REJECT:
- $action[] = new Sieve_Action_Reject(array('reason' => $filter['action-value']));
+ $action[] = new Ingo_Script_Sieve_Action_Reject(array('reason' => $filter['action-value']));
break;
case Ingo_Storage::ACTION_REDIRECT:
- $action[] = new Sieve_Action_Redirect(array('address' => $filter['action-value']));
+ $action[] = new Ingo_Script_Sieve_Action_Redirect(array('address' => $filter['action-value']));
break;
case Ingo_Storage::ACTION_REDIRECTKEEP:
if (!empty($filter['flags'])) {
- $action[] = new Sieve_Action_Addflag(array('flags' => $filter['flags']));
+ $action[] = new Ingo_Script_Sieve_Action_Addflag(array('flags' => $filter['flags']));
}
- $action[] = new Sieve_Action_Redirect(array('address' => $filter['action-value']));
- $action[] = new Sieve_Action_Keep();
+ $action[] = new Ingo_Script_Sieve_Action_Redirect(array('address' => $filter['action-value']));
+ $action[] = new Ingo_Script_Sieve_Action_Keep();
if (!empty($filter['flags'])) {
- $action[] = new Sieve_Action_RemoveFlag(array('flags' => $filter['flags']));
+ $action[] = new Ingo_Script_Sieve_Action_RemoveFlag(array('flags' => $filter['flags']));
}
break;
case Ingo_Storage::ACTION_MOVEKEEP:
if (!empty($filter['flags'])) {
- $action[] = new Sieve_Action_Addflag(array('flags' => $filter['flags']));
+ $action[] = new Ingo_Script_Sieve_Action_Addflag(array('flags' => $filter['flags']));
}
- $action[] = new Sieve_Action_Keep();
- $action[] = new Sieve_Action_Fileinto(array_merge($this->_params, array('folder' => $filter['action-value'])));
+ $action[] = new Ingo_Script_Sieve_Action_Keep();
+ $action[] = new Ingo_Script_Sieve_Action_Fileinto(array_merge($this->_params, array('folder' => $filter['action-value'])));
if (!empty($filter['flags'])) {
- $action[] = new Sieve_Action_RemoveFlag(array('flags' => $filter['flags']));
+ $action[] = new Ingo_Script_Sieve_Action_RemoveFlag(array('flags' => $filter['flags']));
}
break;
case Ingo_Storage::ACTION_FLAGONLY:
if (!empty($filter['flags'])) {
- $action[] = new Sieve_Action_Addflag(array('flags' => $filter['flags']));
+ $action[] = new Ingo_Script_Sieve_Action_Addflag(array('flags' => $filter['flags']));
}
break;
case Ingo_Storage::ACTION_NOTIFY:
- $action[] = new Sieve_Action_Notify(array('address' => $filter['action-value'], 'name' => $filter['name']));
+ $action[] = new Ingo_Script_Sieve_Action_Notify(array('address' => $filter['action-value'], 'name' => $filter['name']));
break;
case Ingo_Storage::ACTION_WHITELIST:
continue 2;
}
- $this->_blocks[] = new Sieve_Comment($this->encode($filter['name']));
+ $this->_blocks[] = new Ingo_Script_Sieve_Comment($this->encode($filter['name']));
if ($filter['stop']) {
- $action[] = new Sieve_Action_Stop();
+ $action[] = new Ingo_Script_Sieve_Action_Stop();
}
- $test = new Sieve_Test();
+ $test = new Ingo_Script_Sieve_Test();
if ($filter['combine'] == Ingo_Storage::COMBINE_ANY) {
- $test = new Sieve_Test_Anyof();
+ $test = new Ingo_Script_Sieve_Test_Anyof();
} else {
- $test = new Sieve_Test_Allof();
+ $test = new Ingo_Script_Sieve_Test_Allof();
}
foreach ($filter['conditions'] as $condition) {
$tmp = '';
switch ($condition['match']) {
case 'equal':
- $tmp = new Sieve_Test_Relational(array('comparison' => 'eq', 'headers' => $condition['field'], 'value' => $condition['value']));
+ $tmp = new Ingo_Script_Sieve_Test_Relational(array('comparison' => 'eq', 'headers' => $condition['field'], 'value' => $condition['value']));
$test->addTest($tmp);
break;
case 'not equal':
- $tmp = new Sieve_Test_Relational(array('comparison' => 'ne', 'headers' => $condition['field'], 'value' => $condition['value']));
+ $tmp = new Ingo_Script_Sieve_Test_Relational(array('comparison' => 'ne', 'headers' => $condition['field'], 'value' => $condition['value']));
$test->addTest($tmp);
break;
case 'less than':
if ($condition['field'] == 'Size') {
/* Message Size Test. */
- $tmp = new Sieve_Test_Size(array('comparison' => ':under', 'size' => $condition['value']));
+ $tmp = new Ingo_Script_Sieve_Test_Size(array('comparison' => ':under', 'size' => $condition['value']));
} else {
/* Relational Test. */
- $tmp = new Sieve_Test_Relational(array('comparison' => 'lt', 'headers' => $condition['field'], 'value' => $condition['value']));
+ $tmp = new Ingo_Script_Sieve_Test_Relational(array('comparison' => 'lt', 'headers' => $condition['field'], 'value' => $condition['value']));
}
$test->addTest($tmp);
break;
case 'less than or equal to':
- $tmp = new Sieve_Test_Relational(array('comparison' => 'le', 'headers' => $condition['field'], 'value' => $condition['value']));
+ $tmp = new Ingo_Script_Sieve_Test_Relational(array('comparison' => 'le', 'headers' => $condition['field'], 'value' => $condition['value']));
$test->addTest($tmp);
break;
case 'greater than':
if ($condition['field'] == 'Size') {
/* Message Size Test. */
- $tmp = new Sieve_Test_Size(array('comparison' => ':over', 'size' => $condition['value']));
+ $tmp = new Ingo_Script_Sieve_Test_Size(array('comparison' => ':over', 'size' => $condition['value']));
} else {
/* Relational Test. */
- $tmp = new Sieve_Test_Relational(array('comparison' => 'gt', 'headers' => $condition['field'], 'value' => $condition['value']));
+ $tmp = new Ingo_Script_Sieve_Test_Relational(array('comparison' => 'gt', 'headers' => $condition['field'], 'value' => $condition['value']));
}
$test->addTest($tmp);
break;
case 'greater than or equal to':
- $tmp = new Sieve_Test_Relational(array('comparison' => 'ge', 'headers' => $condition['field'], 'value' => $condition['value']));
+ $tmp = new Ingo_Script_Sieve_Test_Relational(array('comparison' => 'ge', 'headers' => $condition['field'], 'value' => $condition['value']));
$test->addTest($tmp);
break;
case 'exists':
- $tmp = new Sieve_Test_Exists(array('headers' => $condition['field']));
+ $tmp = new Ingo_Script_Sieve_Test_Exists(array('headers' => $condition['field']));
$test->addTest($tmp);
break;
case 'not exist':
- $tmp = new Sieve_Test_Exists(array('headers' => $condition['field']));
- $test->addTest(new Sieve_Test_Not($tmp));
+ $tmp = new Ingo_Script_Sieve_Test_Exists(array('headers' => $condition['field']));
+ $test->addTest(new Ingo_Script_Sieve_Test_Not($tmp));
break;
case 'contains':
case 'contains':
$vals['match-type'] = ':contains';
if ($use_address_test) {
- $tmp = new Sieve_Test_Address($vals);
+ $tmp = new Ingo_Script_Sieve_Test_Address($vals);
} elseif ($condition['field'] == 'Body') {
- $tmp = new Sieve_Test_Body($vals);
+ $tmp = new Ingo_Script_Sieve_Test_Body($vals);
} else {
- $tmp = new Sieve_Test_Header($vals);
+ $tmp = new Ingo_Script_Sieve_Test_Header($vals);
}
$test->addTest($tmp);
break;
case 'not contain':
$vals['match-type'] = ':contains';
if ($use_address_test) {
- $tmp = new Sieve_Test_Address($vals);
+ $tmp = new Ingo_Script_Sieve_Test_Address($vals);
} elseif ($condition['field'] == 'Body') {
- $tmp = new Sieve_Test_Body($vals);
+ $tmp = new Ingo_Script_Sieve_Test_Body($vals);
} else {
- $tmp = new Sieve_Test_Header($vals);
+ $tmp = new Ingo_Script_Sieve_Test_Header($vals);
}
- $test->addTest(new Sieve_Test_Not($tmp));
+ $test->addTest(new Ingo_Script_Sieve_Test_Not($tmp));
break;
case 'is':
$vals['match-type'] = ':is';
if ($use_address_test) {
- $tmp = new Sieve_Test_Address($vals);
+ $tmp = new Ingo_Script_Sieve_Test_Address($vals);
} elseif ($condition['field'] == 'Body') {
- $tmp = new Sieve_Test_Body($vals);
+ $tmp = new Ingo_Script_Sieve_Test_Body($vals);
} else {
- $tmp = new Sieve_Test_Header($vals);
+ $tmp = new Ingo_Script_Sieve_Test_Header($vals);
}
$test->addTest($tmp);
break;
case 'not is':
$vals['match-type'] = ':is';
if ($use_address_test) {
- $tmp = new Sieve_Test_Address($vals);
+ $tmp = new Ingo_Script_Sieve_Test_Address($vals);
} elseif ($condition['field'] == 'Body') {
- $tmp = new Sieve_Test_Body($vals);
+ $tmp = new Ingo_Script_Sieve_Test_Body($vals);
} else {
- $tmp = new Sieve_Test_Header($vals);
+ $tmp = new Ingo_Script_Sieve_Test_Header($vals);
}
- $test->addTest(new Sieve_Test_Not($tmp));
+ $test->addTest(new Ingo_Script_Sieve_Test_Not($tmp));
break;
case 'begins with':
} else {
$vals['addresses'] .= '*';
}
- $tmp = new Sieve_Test_Address($vals);
+ $tmp = new Ingo_Script_Sieve_Test_Address($vals);
} else {
$add_arr = preg_split('(\r\n|\n|\r)', $vals['strings']);
if (count($add_arr) > 1) {
$vals['strings'] .= '*';
}
if ($condition['field'] == 'Body') {
- $tmp = new Sieve_Test_Body($vals);
+ $tmp = new Ingo_Script_Sieve_Test_Body($vals);
} else {
- $tmp = new Sieve_Test_Header($vals);
+ $tmp = new Ingo_Script_Sieve_Test_Header($vals);
}
}
$test->addTest($tmp);
} else {
$vals['addresses'] .= '*';
}
- $tmp = new Sieve_Test_Address($vals);
+ $tmp = new Ingo_Script_Sieve_Test_Address($vals);
} else {
$add_arr = preg_split('(\r\n|\n|\r)', $vals['strings']);
if (count($add_arr) > 1) {
$vals['strings'] .= '*';
}
if ($condition['field'] == 'Body') {
- $tmp = new Sieve_Test_Body($vals);
+ $tmp = new Ingo_Script_Sieve_Test_Body($vals);
} else {
- $tmp = new Sieve_Test_Header($vals);
+ $tmp = new Ingo_Script_Sieve_Test_Header($vals);
}
}
- $test->addTest(new Sieve_Test_Not($tmp));
+ $test->addTest(new Ingo_Script_Sieve_Test_Not($tmp));
break;
case 'ends with':
} else {
$vals['addresses'] = '*' . $vals['addresses'];
}
- $tmp = new Sieve_Test_Address($vals);
+ $tmp = new Ingo_Script_Sieve_Test_Address($vals);
} else {
$add_arr = preg_split('(\r\n|\n|\r)', $vals['strings']);
if (count($add_arr) > 1) {
$vals['strings'] = '*' . $vals['strings'];
}
if ($condition['field'] == 'Body') {
- $tmp = new Sieve_Test_Body($vals);
+ $tmp = new Ingo_Script_Sieve_Test_Body($vals);
} else {
- $tmp = new Sieve_Test_Header($vals);
+ $tmp = new Ingo_Script_Sieve_Test_Header($vals);
}
}
$test->addTest($tmp);
} else {
$vals['addresses'] = '*' . $vals['addresses'];
}
- $tmp = new Sieve_Test_Address($vals);
+ $tmp = new Ingo_Script_Sieve_Test_Address($vals);
} else {
$add_arr = preg_split('(\r\n|\n|\r)', $vals['strings']);
if (count($add_arr) > 1) {
$vals['strings'] = '*' . $vals['strings'];
}
if ($condition['field'] == 'Body') {
- $tmp = new Sieve_Test_Body($vals);
+ $tmp = new Ingo_Script_Sieve_Test_Body($vals);
} else {
- $tmp = new Sieve_Test_Header($vals);
+ $tmp = new Ingo_Script_Sieve_Test_Header($vals);
}
}
- $test->addTest(new Sieve_Test_Not($tmp));
+ $test->addTest(new Ingo_Script_Sieve_Test_Not($tmp));
break;
case 'regex':
$vals['match-type'] = ':regex';
if ($use_address_test) {
- $tmp = new Sieve_Test_Address($vals);
+ $tmp = new Ingo_Script_Sieve_Test_Address($vals);
} elseif ($condition['field'] == 'Body') {
- $tmp = new Sieve_Test_Body($vals);
+ $tmp = new Ingo_Script_Sieve_Test_Body($vals);
} else {
- $tmp = new Sieve_Test_Header($vals);
+ $tmp = new Ingo_Script_Sieve_Test_Header($vals);
}
$test->addTest($tmp);
break;
case 'matches':
$vals['match-type'] = ':matches';
if ($use_address_test) {
- $tmp = new Sieve_Test_Address($vals);
+ $tmp = new Ingo_Script_Sieve_Test_Address($vals);
} elseif ($condition['field'] == 'Body') {
- $tmp = new Sieve_Test_Body($vals);
+ $tmp = new Ingo_Script_Sieve_Test_Body($vals);
} else {
- $tmp = new Sieve_Test_Header($vals);
+ $tmp = new Ingo_Script_Sieve_Test_Header($vals);
}
$test->addTest($tmp);
break;
case 'not matches':
$vals['match-type'] = ':matches';
if ($use_address_test) {
- $tmp = new Sieve_Test_Address($vals);
+ $tmp = new Ingo_Script_Sieve_Test_Address($vals);
} elseif ($condition['field'] == 'Body') {
- $tmp = new Sieve_Test_Body($vals);
+ $tmp = new Ingo_Script_Sieve_Test_Body($vals);
} else {
- $tmp = new Sieve_Test_Header($vals);
+ $tmp = new Ingo_Script_Sieve_Test_Header($vals);
}
- $test->addTest(new Sieve_Test_Not($tmp));
+ $test->addTest(new Ingo_Script_Sieve_Test_Not($tmp));
break;
}
}
}
- $if = new Sieve_If($test);
+ $if = new Ingo_Script_Sieve_If($test);
$if->setActions($action);
$this->_blocks[] = $if;
}
}
}
-
-/**
- * The Sieve_If class represents a Sieve If Statement
- *
- * @author Mike Cochrane <mike@graftonhall.co.nz>
- * @package Ingo
- */
-class Sieve_If {
-
- /**
- * The Sieve_Test object for the if test.
- *
- * @var Sieve_Test
- */
- var $_test;
-
- /**
- * A list of Sieve_Action objects that go into the if clause.
- *
- * @var array
- */
- var $_actions = array();
-
- /**
- * A list of Sieve_Elseif objects that create optional elsif clauses.
- *
- * @var array
- */
- var $_elsifs = array();
-
- /**
- * A Sieve_Else object that creates an optional else clause.
- *
- * @var Sieve_Else
- */
- var $_else;
-
- /**
- * Constructor.
- *
- * @param Sieve_Test $test A Sieve_Test object.
- */
- function Sieve_If($test = null)
- {
- if (is_null($test)) {
- $this->_test = new Sieve_Test_False();
- } else {
- $this->_test = $test;
- }
-
- $this->_actions[] = new Sieve_Action_Keep();
- $this->_else = new Sieve_Else();
- }
-
- function getTest()
- {
- return $this->_test;
- }
-
- function setTest($test)
- {
- $this->_test = $test;
- }
-
- function getActions()
- {
- return $this->_actions;
- }
-
- function setActions($actions)
- {
- $this->_actions = $actions;
- }
-
- function getElsifs()
- {
- return $this->_elsifs;
- }
-
- function setElsifs($elsifs)
- {
- $this->_elsifs = $elsifs;
- }
-
- function addElsif($elsif)
- {
- $this->_elsifs[] = $elsif;
- }
-
- function getElse()
- {
- return $this->_else;
- }
-
- function setElse($else)
- {
- $this->_else = $else;
- }
-
- /**
- * Returns a script snippet representing this rule and any sub-rules.
- *
- * @return string A Sieve script snippet.
- */
- function toCode()
- {
- $code = 'if ' . $this->_test->toCode() . " { \n";
- foreach ($this->_actions as $action) {
- $code .= ' ' . $action->toCode() . "\n";
- }
- $code .= "} ";
-
- foreach ($this->_elsifs as $elsif) {
- $code .= $elsif->toCode();
- }
-
- $code .= $this->_else->toCode();
-
- return $code . "\n";
- }
-
- /**
- * Checks if all sub-rules are valid.
- *
- * @return boolean|string True if all rules are valid, an error message
- * otherwise.
- */
- function check()
- {
- $res = $this->_test->check();
- if ($res !== true) {
- return $res;
- }
-
- foreach ($this->_elsifs as $elsif) {
- $res = $elsif->check();
- if ($res !== true) {
- return $res;
- }
- }
-
- $res = $this->_else->check();
- if ($res !== true) {
- return $res;
- }
-
- foreach ($this->_actions as $action) {
- $res = $action->check();
- if ($res !== true) {
- return $res;
- }
- }
-
- return true;
- }
-
- /**
- * Returns a list of sieve extensions required for this rule and any
- * sub-rules.
- *
- * @return array A Sieve extension list.
- */
- function requires()
- {
- $requires = array();
-
- foreach ($this->_actions as $action) {
- $requires = array_merge($requires, $action->requires());
- }
-
- foreach ($this->_elsifs as $elsif) {
- $requires = array_merge($requires, $elsif->requires());
- }
-
- $requires = array_merge($requires, $this->_test->requires(), $this->_else->requires());
-
- return $requires;
- }
-
-}
-
-/**
- * The Sieve_Else class represents a Sieve Else Statement
- *
- * @author Mike Cochrane <mike@graftonhall.co.nz>
- * @package Ingo
- */
-class Sieve_Else {
-
- /**
- * A list of Sieve_Action objects that go into the else clause.
- *
- * @var array
- */
- var $_actions = array();
-
- /**
- * Constructor.
- *
- * @param Sieve_Action|array $actions A Sieve_Action object or a list of
- * Sieve_Action objects.
- */
- function Sieve_Else($actions = null)
- {
- if (is_array($actions)) {
- $this->_actions = $actions;
- } elseif (!is_null($actions)) {
- $this->_actions[] = $actions;
- }
- }
-
- /**
- * Returns a script snippet representing this rule and any sub-rules.
- *
- * @return string A Sieve script snippet.
- */
- function toCode()
- {
- if (count($this->_actions) == 0) {
- return '';
- }
-
- $code = 'else' . " { \n";
- foreach ($this->_actions as $action) {
- $code .= ' ' . $action->toCode() . "\n";
- }
- $code .= "} ";
-
- return $code;
- }
-
- function setActions($actions)
- {
- $this->_actions = $actions;
- }
-
- function getActions()
- {
- return $this->_actions;
- }
-
- /**
- * Checks if all sub-rules are valid.
- *
- * @return boolean|string True if all rules are valid, an error message
- * otherwise.
- */
- function check()
- {
- foreach ($this->_actions as $action) {
- $res = $action->check();
- if ($res !== true) {
- return $res;
- }
- }
-
- return true;
- }
-
- /**
- * Returns a list of sieve extensions required for this rule and any
- * sub-rules.
- *
- * @return array A Sieve extension list.
- */
- function requires()
- {
- $requires = array();
-
- foreach ($this->_actions as $action) {
- $requires = array_merge($requires, $action->requires());
- }
-
- return $requires;
- }
-
-}
-
-/**
- * The Sieve_Elsif class represents a Sieve Elsif Statement
- *
- * @author Mike Cochrane <mike@graftonhall.co.nz>
- * @package Ingo
- */
-class Sieve_Elsif {
-
- /**
- * The Sieve_Test object for the if test.
- *
- * @var Sieve_Test
- */
- var $_test;
-
- /**
- * A list of Sieve_Action objects that go into the if clause.
- *
- * @var array
- */
- var $_actions = array();
-
- /**
- * Constructor.
- *
- * @param Sieve_Test $test A Sieve_Test object.
- */
- function Sieve_Elsif($test = null)
- {
- if (is_null($test)) {
- $this->_test = new Sieve_Test_False();
- } else {
- $this->_test = $test;
- }
- $this->_actions[] = new Sieve_Action_Keep();
- }
-
- function getTest()
- {
- return $this->_test;
- }
-
- function setTest($test)
- {
- $this->_test = $test;
- }
-
- function getActions()
- {
- return $this->_actions;
- }
-
- function setActions($actions)
- {
- $this->_actions = $actions;
- }
-
- /**
- * Returns a script snippet representing this rule and any sub-rules.
- *
- * @return string A Sieve script snippet.
- */
- function toCode()
- {
- $code = 'elsif ' . $this->_test->toCode() . " { \n";
- foreach ($this->_actions as $action) {
- $code .= ' ' . $action->toCode() . "\n";
- }
- $code .= "} ";
-
- return $code;
- }
-
- /**
- * Checks if all sub-rules are valid.
- *
- * @return boolean|string True if all rules are valid, an error message
- * otherwise.
- */
- function check()
- {
- $res = $this->_test->check();
- if ($res !== true) {
- return $res;
- }
-
- foreach ($this->_actions as $action) {
- $res = $action->check();
- if ($res !== true) {
- return $res;
- }
- }
-
- return true;
- }
-
- /**
- * Returns a list of sieve extensions required for this rule and any
- * sub-rules.
- *
- * @return array A Sieve extension list.
- */
- function requires()
- {
- $requires = array();
-
- foreach ($this->_actions as $action) {
- $requires = array_merge($requires, $action->requires());
- }
-
- $requires = array_merge($requires, $this->_test->requires());
-
- return $requires;
- }
-
-}
-
-/**
- * The Sieve_Test class represents a Sieve Test.
- *
- * A test is a piece of code that evaluates to true or false.
- *
- * @author Mike Cochrane <mike@graftonhall.co.nz>
- * @package Ingo
- */
-class Sieve_Test {
-
- /**
- * Any necessary test parameters.
- *
- * @var array
- */
- var $_vars = array();
-
- /**
- * Returns a script snippet representing this rule and any sub-rules.
- *
- * @return string A Sieve script snippet.
- */
- function toCode()
- {
- return 'toCode() Function Not Implemented in class ' . get_class($this);
- }
-
- /**
- * Checks if the rule parameters are valid.
- *
- * @return boolean|string True if this rule is valid, an error message
- * otherwise.
- */
- function check()
- {
- return 'check() Function Not Implemented in class ' . get_class($this);
- }
-
- /**
- * Returns a list of sieve extensions required for this rule and any
- * sub-rules.
- *
- * @return array A Sieve extension list.
- */
- function requires()
- {
- return array();
- }
-
-}
-
-/**
- * The Sieve_Test_True class represents a test that always evaluates to true.
- *
- * @author Mike Cochrane <mike@graftonhall.co.nz>
- * @package Ingo
- */
-class Sieve_Test_True extends Sieve_Test {
-
- /**
- * Returns a script snippet representing this rule and any sub-rules.
- *
- * @return string A Sieve script snippet.
- */
- function toCode()
- {
- return 'true';
- }
-
- /**
- * Checks if the rule parameters are valid.
- *
- * @return boolean|string True if this rule is valid, an error message
- * otherwise.
- */
- function check()
- {
- return true;
- }
-
-}
-
-/**
- * The Sieve_Test_False class represents a test that always evaluates to
- * false.
- *
- * @author Mike Cochrane <mike@graftonhall.co.nz>
- * @package Ingo
- */
-class Sieve_Test_False extends Sieve_Test {
-
- /**
- * Returns a script snippet representing this rule and any sub-rules.
- *
- * @return string A Sieve script snippet.
- */
- function toCode()
- {
- return 'false';
- }
-
- /**
- * Checks if the rule parameters are valid.
- *
- * @return boolean|string True if this rule is valid, an error message
- * otherwise.
- */
- function check()
- {
- return true;
- }
-
-}
-
-/**
- * The Sieve_Test_Allof class represents a Allof test structure.
- *
- * Equivalent to a logical AND of all the tests it contains.
- *
- * @author Mike Cochrane <mike@graftonhall.co.nz>
- * @package Ingo
- */
-class Sieve_Test_Allof extends Sieve_Test {
-
- var $_tests = array();
-
- /**
- * Constructor.
- *
- * @param Sieve_Test|array $test A Sieve_Test object or a list of
- * Sieve_Test objects.
- */
- function Sieve_Test_Allof($test = null)
- {
- if (is_array($test)) {
- $this->_tests = $test;
- } elseif (!is_null($test)) {
- $this->_tests[] = $test;
- }
- }
-
- /**
- * Returns a script snippet representing this rule and any sub-rules.
- *
- * @return string A Sieve script snippet.
- */
- function toCode()
- {
- $code = '';
- if (count($this->_tests) > 1) {
- $testlist = '';
- foreach ($this->_tests as $test) {
- $testlist .= (empty($testlist)) ? '' : ', ';
- $testlist .= trim($test->toCode());
- }
-
- $code = "allof ( $testlist )";
- } elseif (count($this->_tests) == 1) {
- $code = $this->_tests[0]->toCode();
- } else {
- return 'true';
- }
- return $code;
- }
-
- /**
- * Checks if all sub-rules are valid.
- *
- * @return boolean|string True if all rules are valid, an error message
- * otherwise.
- */
- function check()
- {
- foreach ($this->_tests as $test) {
- $res = $test->check();
- if ($res !== true) {
- return $res;
- }
- }
-
- return true;
- }
-
- function addTest($test)
- {
- $this->_tests[] = $test;
- }
-
- function getTests()
- {
- return $this->_tests;
- }
-
- /**
- * Returns a list of sieve extensions required for this rule and any
- * sub-rules.
- *
- * @return array A Sieve extension list.
- */
- function requires()
- {
- $requires = array();
-
- foreach ($this->_tests as $test) {
- $requires = array_merge($requires, $test->requires());
- }
-
- return $requires;
- }
-
-}
-
-/**
- * The Sieve_Test_Anyof class represents a Anyof test structure.
- *
- * Equivalent to a logical OR of all the tests it contains.
- *
- * @author Mike Cochrane <mike@graftonhall.co.nz>
- * @package Ingo
- */
-class Sieve_Test_Anyof extends Sieve_Test {
-
- var $_tests = array();
-
- /**
- * Constructor.
- *
- * @param Sieve_Test|array $test A Sieve_Test object or a list of
- * Sieve_Test objects.
- */
- function Sieve_Test_Anyof($test = null)
- {
- if (is_array($test)) {
- $this->_tests = $test;
- } elseif (!is_null($test)) {
- $this->_tests[] = $test;
- }
- }
-
- /**
- * Returns a script snippet representing this rule and any sub-rules.
- *
- * @return string A Sieve script snippet.
- */
- function toCode()
- {
- $testlist = '';
- if (count($this->_tests) > 1) {
- $testlist = '';
- foreach ($this->_tests as $test) {
- $testlist .= (empty($testlist)) ? '' : ', ';
- $testlist .= trim($test->toCode());
- }
-
- $code = "anyof ( $testlist )";
- } elseif (count($this->_tests) == 1) {
- $code = $this->_tests[0]->toCode();
- } else {
- return 'true';
- }
- return $code;
- }
-
- function addTest($test)
- {
- $this->_tests[] = $test;
- }
-
- function getTests()
- {
- return $this->_tests;
- }
-
- /**
- * Checks if all sub-rules are valid.
- *
- * @return boolean|string True if all rules are valid, an error message
- * otherwise.
- */
- function check()
- {
- foreach ($this->_tests as $test) {
- $res = $test->check();
- if ($res !== true) {
- return $res;
- }
- }
-
- return true;
- }
-
- /**
- * Returns a list of sieve extensions required for this rule and any
- * sub-rules.
- *
- * @return array A Sieve extension list.
- */
- function requires()
- {
- $requires = array();
-
- foreach ($this->_tests as $test) {
- $requires = array_merge($requires, $test->requires());
- }
-
- return $requires;
- }
-
-}
-
-/**
- * The Sieve_Test_Relational class represents a relational test.
- *
- * @author Todd Merritt <tmerritt@email.arizona.edu>
- * @package Ingo
- */
-class Sieve_Test_Relational extends Sieve_Test {
-
- /**
- * Constructor.
- *
- * @param array $vars Any required parameters.
- */
- function Sieve_Test_Relational($vars = array())
- {
- $this->_vars['comparison'] = (isset($vars['comparison'])) ? $vars['comparison'] : '';
- $this->_vars['headers'] = (isset($vars['headers'])) ? $vars['headers'] : '';
- $this->_vars['value'] = (isset($vars['value'])) ? $vars['value'] : 0;
- }
-
- /**
- * Returns a script snippet representing this rule and any sub-rules.
- *
- * @return string A Sieve script snippet.
- */
- function toCode()
- {
- $code = 'header :value "' .
- $this->_vars['comparison'] . '" ' .
- ':comparator "i;ascii-numeric" ';
-
- $headers = preg_split('(\r\n|\n|\r)', $this->_vars['headers']);
- $header_count = count($headers);
-
- if ($header_count > 1) {
- $code .= "[";
- $headerstr = '';
-
- foreach ($headers as $val) {
- $headerstr .= (empty($headerstr) ? '"' : ', "') .
- Ingo_Script_Sieve::escapeString($val) . '"';
- }
-
- $code .= $headerstr . '] ';
- $headerstr = '[' . $headerstr . ']';
- } elseif ($header_count == 1) {
- $code .= '"' . Ingo_Script_Sieve::escapeString($headers[0]) . '" ';
- $headerstr = Ingo_Script_Sieve::escapeString($headers[0]);
- }
-
- $code .= '["' . $this->_vars['value'] . '"]';
-
- // Add workarounds for negative numbers - works only if the comparison
- // value is positive. Sieve doesn't support comparisons of negative
- // numbers at all so this is the best we can do.
- switch ($this->_vars['comparison']) {
- case 'gt':
- case 'ge':
- case 'eq':
- // Greater than, greater or equal, equal: number must be
- // non-negative.
- return 'allof ( not header :comparator "i;ascii-casemap" :contains "'
- . $headerstr . '" "-", ' . $code . ' )';
- break;
- case 'lt':
- case 'le':
- case 'ne':
- // Less than, less or equal, nonequal: also match negative numbers
- return 'anyof ( header :comparator "i;ascii-casemap" :contains "'
- . $headerstr . '" "-", ' . $code . ' )';
- break;
- }
- }
-
- /**
- * Checks if the rule parameters are valid.
- *
- * @return boolean|string True if this rule is valid, an error message
- * otherwise.
- */
- function check()
- {
- $headers = preg_split('(\r\n|\n|\r)', $this->_vars['headers']);
- return $headers ? true : _("No headers specified");
- }
-
- /**
- * Returns a list of sieve extensions required for this rule and any
- * sub-rules.
- *
- * @return array A Sieve extension list.
- */
- function requires()
- {
- return array('relational', 'comparator-i;ascii-numeric');
- }
-
-}
-
-/**
- * The Sieve_Test_Size class represents a message size test.
- *
- * @author Mike Cochrane <mike@graftonhall.co.nz>
- * @package Ingo
- */
-class Sieve_Test_Size extends Sieve_Test {
-
- /**
- * Constructor.
- *
- * @param array $vars Any required parameters.
- */
- function Sieve_Test_Size($vars = array())
- {
- $this->_vars['comparison'] = (isset($vars['comparison'])) ? $vars['comparison'] : '';
- $this->_vars['size'] = (isset($vars['size'])) ? $vars['size'] : '';
- }
-
- /**
- * Returns a script snippet representing this rule and any sub-rules.
- *
- * @return string A Sieve script snippet.
- */
- function toCode()
- {
- return 'size ' . $this->_vars['comparison'] . ' ' . $this->_vars['size'];
- }
-
- /**
- * Checks if the rule parameters are valid.
- *
- * @return boolean|string True if this rule is valid, an error message
- * otherwise.
- */
- function check()
- {
- if (!(isset($this->_vars['comparison']) &&
- isset($this->_vars['size']))) {
- return false;
- }
-
- return true;
- }
-
-}
-
-/**
- * The Sieve_Test_Not class represents the inverse of a given test.
- *
- * @author Mike Cochrane <mike@graftonhall.co.nz>
- * @package Ingo
- */
-class Sieve_Test_Not extends Sieve_Test {
-
- var $_test = array();
-
- /**
- * Constructor.
- *
- * @param Sieve_Test $test A Sieve_Test object.
- */
- function Sieve_Test_Not($test)
- {
- $this->_test = $test;
- }
-
- /**
- * Checks if the sub-rule is valid.
- *
- * @return boolean|string True if this rule is valid, an error message
- * otherwise.
- */
- function check()
- {
- return $this->_test->check();
- }
-
- /**
- * Returns a script snippet representing this rule and any sub-rules.
- *
- * @return string A Sieve script snippet.
- */
- function toCode()
- {
- return 'not ' . $this->_test->toCode();
- }
-
- /**
- * Returns a list of sieve extensions required for this rule and any
- * sub-rules.
- *
- * @return array A Sieve extension list.
- */
- function requires()
- {
- return $this->_test->requires();
- }
-
-}
-
-/**
- * The Sieve_Test_Exists class represents a test for the existsance of one or
- * more headers in a message.
- *
- * @author Mike Cochrane <mike@graftonhall.co.nz>
- * @package Ingo
- */
-class Sieve_Test_Exists extends Sieve_Test {
-
- /**
- * Constructor.
- *
- * @param array $vars Any required parameters.
- */
- function Sieve_Test_Exists($vars = array())
- {
- $this->_vars['headers'] = (isset($vars['headers'])) ? $vars['headers'] : '';
- }
-
- /**
- * Checks if the rule parameters are valid.
- *
- * @return boolean|string True if this rule is valid, an error message
- * otherwise.
- */
- function check()
- {
- $headers = preg_split('(\r\n|\n|\r)', $this->_vars['headers']);
- if (!$headers) {
- return _("No headers specified");
- }
-
- return true;
- }
-
- /**
- * Returns a script snippet representing this rule and any sub-rules.
- *
- * @return string A Sieve script snippet.
- */
- function toCode()
- {
- $code = 'exists ';
- $headers = preg_split('(\r\n|\n|\r)', $this->_vars['headers']);
- if (count($headers) > 1) {
- $code .= "[";
- $headerstr = '';
- foreach ($headers as $header) {
- $headerstr .= (empty($headerstr) ? '"' : ', "') .
- Ingo_Script_Sieve::escapeString($header) . '"';
- }
- $code .= $headerstr . "] ";
- } elseif (count($headers) == 1) {
- $code .= '"' . Ingo_Script_Sieve::escapeString($headers[0]) . '" ';
- } else {
- return "**error** No Headers Specified";
- }
-
- return $code;
- }
-
-}
-
-/**
- * The Sieve_Test_Address class represents a test on parts or all of the
- * addresses in the given fields.
- *
- * @author Mike Cochrane <mike@graftonhall.co.nz>
- * @package Ingo
- */
-class Sieve_Test_Address extends Sieve_Test {
-
- /**
- * Constructor.
- *
- * @param array $vars Any required parameters.
- */
- function Sieve_Test_Address($vars)
- {
- $this->_vars['headers'] = (isset($vars['headers'])) ? $vars['headers'] : '';
- $this->_vars['comparator'] = (isset($vars['comparator'])) ? $vars['comparator'] : 'i;ascii-casemap';
- $this->_vars['match-type'] = (isset($vars['match-type'])) ? $vars['match-type'] : ':is';
- $this->_vars['address-part'] = (isset($vars['address-part'])) ? $vars['address-part'] : ':all';
- $this->_vars['addresses'] = (isset($vars['addresses'])) ? $vars['addresses'] : '';
- }
-
- /**
- * Checks if the rule parameters are valid.
- *
- * @return boolean|string True if this rule is valid, an error message
- * otherwise.
- */
- function check()
- {
- $headers = preg_split('(\r\n|\n|\r)', $this->_vars['headers']);
- if (!$headers) {
- return false;
- }
-
- $addresses = preg_split('(\r\n|\n|\r)', $this->_vars['addresses']);
- if (!$addresses) {
- return false;
- }
-
- return true;
- }
-
- /**
- * Returns a script snippet representing this rule and any sub-rules.
- *
- * @return string A Sieve script snippet.
- */
- function toCode()
- {
- $code = 'address ' .
- $this->_vars['address-part'] . ' ' .
- ':comparator "' . $this->_vars['comparator'] . '" ' .
- $this->_vars['match-type'] . ' ';
-
- $headers = preg_split('(\r\n|\n|\r|,)', $this->_vars['headers']);
- $headers = array_filter($headers);
- if (count($headers) > 1) {
- $code .= "[";
- $headerstr = '';
- foreach ($headers as $header) {
- $header = trim($header);
- if (!empty($header)) {
- $headerstr .= empty($headerstr) ? '"' : ', "';
- $headerstr .= Ingo_Script_Sieve::escapeString($header, $this->_vars['match-type'] == ':regex') . '"';
- }
- }
- $code .= $headerstr . "] ";
- } elseif (count($headers) == 1) {
- $code .= '"' . Ingo_Script_Sieve::escapeString($headers[0], $this->_vars['match-type'] == ':regex') . '" ';
- } else {
- return "No Headers Specified";
- }
-
- $addresses = preg_split('(\r\n|\n|\r)', $this->_vars['addresses']);
- $addresses = array_filter($addresses);
- if (count($addresses) > 1) {
- $code .= "[";
- $addressstr = '';
- foreach ($addresses as $addr) {
- $addr = trim($addr);
- if (!empty($addr)) {
- $addressstr .= empty($addressstr) ? '"' : ', "';
- $addressstr .= Ingo_Script_Sieve::escapeString($addr, $this->_vars['match-type'] == ':regex') . '"';
- }
- }
- $code .= $addressstr . "] ";
- } elseif (count($addresses) == 1) {
- $code .= '"' . Ingo_Script_Sieve::escapeString($addresses[0], $this->_vars['match-type'] == ':regex') . '" ';
- } else {
- return "No Addresses Specified";
- }
-
- return $code;
- }
-
- /**
- * Returns a list of sieve extensions required for this rule and any
- * sub-rules.
- *
- * @return array A Sieve extension list.
- */
- function requires()
- {
- if ($this->_vars['match-type'] == ':regex') {
- return array('regex');
- }
- return array();
- }
-
-}
-
-/**
- * The Sieve_Test_Header class represents a test on the contents of one or
- * more headers in a message.
- *
- * @author Mike Cochrane <mike@graftonhall.co.nz>
- * @package Ingo
- */
-class Sieve_Test_Header extends Sieve_Test {
-
- /**
- * Constructor.
- *
- * @param array $vars Any required parameters.
- */
- function Sieve_Test_Header($vars = array())
- {
- $this->_vars['headers'] = isset($vars['headers'])
- ? $vars['headers']
- : 'Subject';
- $this->_vars['comparator'] = isset($vars['comparator'])
- ? $vars['comparator']
- : 'i;ascii-casemap';
- $this->_vars['match-type'] = isset($vars['match-type'])
- ? $vars['match-type']
- : ':is';
- $this->_vars['strings'] = isset($vars['strings'])
- ? $vars['strings']
- : '';
- }
-
- /**
- * Checks if the rule parameters are valid.
- *
- * @return boolean|string True if this rule is valid, an error message
- * otherwise.
- */
- function check()
- {
- $headers = preg_split('((?<!\\\)\,|\r\n|\n|\r)', $this->_vars['headers']);
- if (!$headers) {
- return false;
- }
-
- $strings = preg_split('((?<!\\\)\,|\r\n|\n|\r)', $this->_vars['strings']);
- if (!$strings) {
- return false;
- }
-
- return true;
- }
-
- /**
- * Returns a script snippet representing this rule and any sub-rules.
- *
- * @return string A Sieve script snippet.
- */
- function toCode()
- {
- $code = 'header ' .
- ':comparator "' . $this->_vars['comparator'] . '" ' .
- $this->_vars['match-type'] . ' ';
-
- $headers = preg_split('(\r\n|\n|\r)', $this->_vars['headers']);
- $headers = array_filter($headers);
- if (count($headers) > 1) {
- $code .= "[";
- $headerstr = '';
- foreach ($headers as $header) {
- $headerstr .= empty($headerstr) ? '"' : ', "';
- $headerstr .= Ingo_Script_Sieve::escapeString($header, $this->_vars['match-type'] == ':regex') . '"';
- }
- $code .= $headerstr . "] ";
- } elseif (count($headers) == 1) {
- $code .= '"' . $headers[0] . '" ';
- } else {
- return _("No headers specified");
- }
-
- $strings = preg_split('(\r\n|\n|\r)', $this->_vars['strings']);
- $strings = array_filter($strings);
- if (count($strings) > 1) {
- $code .= "[";
- $stringlist = '';
- foreach ($strings as $str) {
- $stringlist .= empty($stringlist) ? '"' : ', "';
- $stringlist .= Ingo_Script_Sieve::escapeString($str, $this->_vars['match-type'] == ':regex') . '"';
- }
- $code .= $stringlist . "] ";
- } elseif (count($strings) == 1) {
- $code .= '"' . Ingo_Script_Sieve::escapeString(reset($strings), $this->_vars['match-type'] == ':regex') . '" ';
- } else {
- return _("No strings specified");
- }
-
- return $code;
- }
-
- /**
- * Returns a list of sieve extensions required for this rule and any
- * sub-rules.
- *
- * @return array A Sieve extension list.
- */
- function requires()
- {
- if ($this->_vars['match-type'] == ':regex') {
- return array('regex');
- }
- return array();
- }
-
-}
-
-/**
- * The Sieve_Test_Body class represents a test on the contents of the body in
- * a message.
- *
- * @author Michael Menge <michael.menge@zdv.uni-tuebingen.de>
- * @package Ingo
- */
-class Sieve_Test_Body extends Sieve_Test {
-
- /**
- * Constructor.
- *
- * @param array $vars Any required parameters.
- */
- function Sieve_Test_Body($vars = array())
- {
- $this->_vars['comparator'] = (isset($vars['comparator'])) ? $vars['comparator'] : 'i;ascii-casemap';
- $this->_vars['match-type'] = (isset($vars['match-type'])) ? $vars['match-type'] : ':is';
- $this->_vars['strings'] = (isset($vars['strings'])) ? $vars['strings'] : '';
- }
-
- /**
- * Checks if the rule parameters are valid.
- *
- * @return boolean|string True if this rule is valid, an error message
- * otherwise.
- */
- function check()
- {
- $strings = preg_split('((?<!\\\)\,|\r\n|\n|\r)', $this->_vars['strings']);
- if (!$strings) {
- return false;
- }
-
- return true;
- }
-
- /**
- * Returns a script snippet representing this rule and any sub-rules.
- *
- * @return string A Sieve script snippet.
- */
- function toCode()
- {
- $code = 'body ' .
- ':comparator "' . $this->_vars['comparator'] . '" ' .
- $this->_vars['match-type'] . ' ';
-
- $strings = preg_split('(\r\n|\n|\r)', $this->_vars['strings']);
- $strings = array_filter($strings);
- if (count($strings) > 1) {
- $code .= "[";
- $stringlist = '';
- foreach ($strings as $str) {
- $stringlist .= empty($stringlist) ? '"' : ', "';
- $stringlist .= Ingo_Script_Sieve::escapeString($str, $this->_vars['match-type'] == ':regex') . '"';
- }
- $code .= $stringlist . "] ";
- } elseif (count($strings) == 1) {
- $code .= '"' . Ingo_Script_Sieve::escapeString($strings[0], $this->_vars['match-type'] == ':regex') . '" ';
- } else {
- return _("No strings specified");
- }
-
- return $code;
- }
-
- /**
- * Returns a list of sieve extensions required for this rule and any
- * sub-rules.
- *
- * @return array A Sieve extension list.
- */
- function requires()
- {
- if ($this->_vars['match-type'] == ':regex') {
- return array('regex', 'body');
- }
-
- return array('body');
- }
-
-}
-
-/**
- * A Comment.
- *
- * @author Mike Cochrane <mike@graftonhall.co.nz>
- * @package Ingo
- * @todo This and Sieve_If should really extends a Sieve_Block eventually.
- */
-class Sieve_Comment {
-
- var $_comment;
-
- /**
- * Constructor.
- *
- * @param string $comment The comment text.
- */
- function Sieve_Comment($comment)
- {
- $this->_comment = $comment;
- }
-
- /**
- * Returns a script snippet representing this rule and any sub-rules.
- *
- * @return string A Sieve script snippet.
- */
- function toCode()
- {
- $code = '';
- $lines = preg_split('(\r\n|\n|\r)', $this->_comment);
- foreach ($lines as $line) {
- $line = trim($line);
- if (strlen($line)) {
- $code .= (empty($code) ? '' : "\n") . '# ' . $line;
- }
- }
- return $code;
- }
-
- /**
- * Checks if the rule parameters are valid.
- *
- * @return boolean|string True if this rule is valid, an error message
- * otherwise.
- */
- function check()
- {
- return true;
- }
-
- /**
- * Returns a list of sieve extensions required for this rule and any
- * sub-rules.
- *
- * @return array A Sieve extension list.
- */
- function requires()
- {
- return array();
- }
-
-}
-
-/**
- * The Sieve_Action class represents an action in a Sieve script.
- *
- * An action is anything that has a side effect eg: discard, redirect.
- *
- * @author Mike Cochrane <mike@graftonhall.co.nz>
- * @package Ingo
- */
-class Sieve_Action {
-
- /**
- * Any necessary action parameters.
- *
- * @var array
- */
- var $_vars = array();
-
- /**
- * Returns a script snippet representing this rule and any sub-rules.
- *
- * @return string A Sieve script snippet.
- */
- function toCode()
- {
- return 'toCode() Function Not Implemented in class ' . get_class($this) ;
- }
-
- function toString()
- {
- return $this->toCode();
- }
-
- /**
- * Checks if the rule parameters are valid.
- *
- * @return boolean|string True if this rule is valid, an error message
- * otherwise.
- */
- function check()
- {
- return 'check() Function Not Implemented in class ' . get_class($this) ;
- }
-
- /**
- * Returns a list of sieve extensions required for this rule and any
- * sub-rules.
- *
- * @return array A Sieve extension list.
- */
- function requires()
- {
- return array();
- }
-
-}
-
-/**
- * The Sieve_Action_Redirect class represents a redirect action.
- *
- * @author Mike Cochrane <mike@graftonhall.co.nz>
- * @package Ingo
- */
-class Sieve_Action_Redirect extends Sieve_Action {
-
- /**
- * Constructor.
- *
- * @param array $vars Any required parameters.
- */
- function Sieve_Action_Redirect($vars = array())
- {
- $this->_vars['address'] = (isset($vars['address'])) ? $vars['address'] : '';
- }
-
- function toCode($depth = 0)
- {
- return str_repeat(' ', $depth * 4) . 'redirect ' .
- '"' . Ingo_Script_Sieve::escapeString($this->_vars['address']) . '";';
- }
-
- /**
- * Checks if the rule parameters are valid.
- *
- * @return boolean|string True if this rule is valid, an error message
- * otherwise.
- */
- function check()
- {
- if (empty($this->_vars['address'])) {
- return _("Missing address to redirect message to");
- }
-
- return true;
- }
-
-}
-
-/**
- * The Sieve_Action_Reject class represents a reject action.
- *
- * @author Mike Cochrane <mike@graftonhall.co.nz>
- * @package Ingo
- */
-class Sieve_Action_Reject extends Sieve_Action {
-
- /**
- * Constructor.
- *
- * @param array $vars Any required parameters.
- */
- function Sieve_Action_Reject($vars = array())
- {
- $this->_vars['reason'] = (isset($vars['reason'])) ? $vars['reason'] : '';
- }
-
- /**
- * Returns a script snippet representing this rule and any sub-rules.
- *
- * @return string A Sieve script snippet.
- */
- function toCode()
- {
- return 'reject "' . Ingo_Script_Sieve::escapeString($this->_vars['reason']) . '";';
- }
-
- /**
- * Checks if the rule parameters are valid.
- *
- * @return boolean|string True if this rule is valid, an error message
- * otherwise.
- */
- function check()
- {
- if (empty($this->_vars['reason'])) {
- return _("Missing reason for reject");
- }
-
- return true;
- }
-
- /**
- * Returns a list of sieve extensions required for this rule and any
- * sub-rules.
- *
- * @return array A Sieve extension list.
- */
- function requires()
- {
- return array('reject');
- }
-
-}
-
-/**
- * The Sieve_Action_Keep class represents a keep action.
- *
- * @author Mike Cochrane <mike@graftonhall.co.nz>
- * @package Ingo
- */
-class Sieve_Action_Keep extends Sieve_Action {
-
- /**
- * Returns a script snippet representing this rule and any sub-rules.
- *
- * @return string A Sieve script snippet.
- */
- function toCode()
- {
- return 'keep;';
- }
-
- /**
- * Checks if the rule parameters are valid.
- *
- * @return boolean|string True if this rule is valid, an error message
- * otherwise.
- */
- function check()
- {
- return true;
- }
-
-}
-
-/**
- * The Sieve_Action_Discard class represents a discard action.
- *
- * @author Mike Cochrane <mike@graftonhall.co.nz>
- * @package Ingo
- */
-class Sieve_Action_Discard extends Sieve_Action {
-
- /**
- * Returns a script snippet representing this rule and any sub-rules.
- *
- * @return string A Sieve script snippet.
- */
- function toCode()
- {
- return 'discard;';
- }
-
- /**
- * Checks if the rule parameters are valid.
- *
- * @return boolean|string True if this rule is valid, an error message
- * otherwise.
- */
- function check()
- {
- return true;
- }
-
-}
-
-/**
- * The Sieve_Action_Stop class represents a stop action.
- *
- * @author Mike Cochrane <mike@graftonhall.co.nz>
- * @package Ingo
- */
-class Sieve_Action_Stop extends Sieve_Action {
-
- /**
- * Returns a script snippet representing this rule and any sub-rules.
- *
- * @return string A Sieve script snippet.
- */
- function toCode()
- {
- return 'stop;';
- }
-
- /**
- * Checks if the rule parameters are valid.
- *
- * @return boolean|string True if this rule is valid, an error message
- * otherwise.
- */
- function check()
- {
- return true;
- }
-
-}
-
-/**
- * The Sieve_Action_Fileinto class represents a fileinto action.
- *
- * @author Mike Cochrane <mike@graftonhall.co.nz>
- * @package Ingo
- */
-class Sieve_Action_Fileinto extends Sieve_Action {
-
- /**
- * Constructor.
- *
- * @param array $vars Any required parameters.
- */
- function Sieve_Action_Fileinto($vars = array())
- {
- $this->_vars['folder'] = (isset($vars['folder'])) ? $vars['folder'] : '';
- if (!empty($vars['utf8'])) {
- $this->_vars['folder'] = String::convertCharset($this->_vars['folder'], 'UTF7-IMAP', 'UTF-8');
- }
- }
-
- /**
- * Returns a script snippet representing this rule and any sub-rules.
- *
- * @return string A Sieve script snippet.
- */
- function toCode()
- {
- return 'fileinto "' . Ingo_Script_Sieve::escapeString($this->_vars['folder']) . '";';
- }
-
- /**
- * Checks if the rule parameters are valid.
- *
- * @return boolean|string True if this rule is valid, an error message
- * otherwise.
- */
- function check()
- {
- if (empty($this->_vars['folder'])) {
- return _("Inexistant mailbox specified for message delivery.");
- }
-
- return true;
- }
-
- /**
- * Returns a list of sieve extensions required for this rule and any
- * sub-rules.
- *
- * @return array A Sieve extension list.
- */
- function requires()
- {
- return array('fileinto');
- }
-
-}
-
-/**
- * The Sieve_Action_Vacation class represents a vacation action.
- *
- * @author Mike Cochrane <mike@graftonhall.co.nz>
- * @package Ingo
- */
-class Sieve_Action_Vacation extends Sieve_Action {
-
- /**
- * Constructor.
- *
- * @param array $vars Any required parameters.
- */
- function Sieve_Action_Vacation($vars = array())
- {
- $this->_vars['days'] = isset($vars['days']) ? intval($vars['days']) : '';
- $this->_vars['addresses'] = isset($vars['addresses']) ? $vars['addresses'] : '';
- $this->_vars['subject'] = isset($vars['subject']) ? $vars['subject'] : '';
- $this->_vars['reason'] = isset($vars['reason']) ? $vars['reason'] : '';
- $this->_vars['start'] = isset($vars['start']) ? $vars['start'] : '';
- $this->_vars['start_year'] = isset($vars['start_year']) ? $vars['start_year'] : '';
- $this->_vars['start_month'] = isset($vars['start_month']) ? $vars['start_month'] : '';
- $this->_vars['start_day'] = isset($vars['start_day']) ? $vars['start_day'] : '';
- $this->_vars['end'] = isset($vars['end']) ? $vars['end'] : '';
- $this->_vars['end_year'] = isset($vars['end_year']) ? $vars['end_year'] : '';
- $this->_vars['end_month'] = isset($vars['end_month']) ? $vars['end_month'] : '';
- $this->_vars['end_day'] = isset($vars['end_day']) ? $vars['end_day'] : '';
- }
-
- /**
- * Returns a script snippet representing this rule and any sub-rules.
- *
- * @return string A Sieve script snippet.
- */
- function toCode()
- {
- $start_year = $this->_vars['start_year'];
- $start_month = $this->_vars['start_month'];
- $start_day = $this->_vars['start_day'];
-
- $end_year = $this->_vars['end_year'];
- $end_month = $this->_vars['end_month'];
- $end_day = $this->_vars['end_day'];
-
- $code = '';
-
- if (empty($this->_vars['start']) || empty($this->_vars['end'])) {
- return $this->_vacationCode();
- } elseif ($end_year > $start_year + 1) {
- $code .= $this->_yearCheck($start_year + 1, $end_year - 1)
- . $this->_vacationCode()
- . "\n}\n"
- . $this->_yearCheck($start_year, $start_year);
- if ($start_month < 12) {
- $code .= $this->_monthCheck($start_month + 1, 12)
- . $this->_vacationCode()
- . "\n}\n";
- }
- $code .= $this->_monthCheck($start_month, $start_month)
- . $this->_dayCheck($start_day, 31)
- . $this->_vacationCode()
- . "\n}\n}\n}\n"
- . $this->_yearCheck($end_year, $end_year);
- if ($end_month > 1) {
- $code .= $this->_monthCheck(1, $end_month - 1)
- . $this->_vacationCode()
- . "\n}\n";
- }
- $code .= $this->_monthCheck($end_month, $end_month)
- . $this->_dayCheck(1, $end_day)
- . $this->_vacationCode()
- . "\n}\n}\n}\n";
- } elseif ($end_year == $start_year + 1) {
- $code .= $this->_yearCheck($start_year, $start_year);
- if ($start_month < 12) {
- $code .= $this->_monthCheck($start_month + 1, 12)
- . $this->_vacationCode()
- . "\n}\n";
- }
- $code .= $this->_monthCheck($start_month, $start_month)
- . $this->_dayCheck($start_day, 31)
- . $this->_vacationCode()
- . "\n}\n}\n}\n"
- . $this->_yearCheck($end_year, $end_year);
- if ($end_month > 1) {
- $code .= $this->_monthCheck(1, $end_month - 1)
- . $this->_vacationCode()
- . "\n}\n";
- }
- $code .= $this->_monthCheck($end_month, $end_month)
- . $this->_dayCheck(1, $end_day)
- . $this->_vacationCode()
- . "\n}\n}\n}\n";
- } elseif ($end_year == $start_year) {
- $code .= $this->_yearCheck($start_year, $start_year);
- if ($end_month > $start_month) {
- if ($end_month > $start_month + 1) {
- $code .= $this->_monthCheck($start_month + 1, $end_month - 1)
- . $this->_vacationCode()
- . "\n}\n";
- }
- $code .= $this->_monthCheck($start_month, $start_month)
- . $this->_dayCheck($start_day, 31)
- . $this->_vacationCode()
- . "\n}\n}\n"
- . $this->_monthCheck($end_month, $end_month)
- . $this->_dayCheck(1, $end_day)
- . $this->_vacationCode()
- . "\n}\n}\n";
- } elseif ($end_month == $start_month) {
- $code .= $this->_monthCheck($start_month, $start_month)
- . $this->_dayCheck($start_day, $end_day)
- . $this->_vacationCode()
- . "\n}\n}\n";
- }
- $code .= "}\n";
- }
-
- return $code;
- }
-
- /**
- * Checks if the rule parameters are valid.
- *
- * @return boolean|string True if this rule is valid, an error message
- * otherwise.
- */
- function check()
- {
- if (empty($this->_vars['reason'])) {
- return _("Missing reason in vacation.");
- }
-
- return true;
- }
-
- /**
- * Returns a list of sieve extensions required for this rule and any
- * sub-rules.
- *
- * @return array A Sieve extension list.
- */
- function requires()
- {
- return array('vacation', 'regex');
- }
-
- /**
- */
- function _vacationCode()
- {
- $code = 'vacation :days ' . $this->_vars['days'] . ' ';
- $addresses = $this->_vars['addresses'];
- $stringlist = '';
- if (count($addresses) > 1) {
- foreach ($addresses as $address) {
- $address = trim($address);
- if (!empty($address)) {
- $stringlist .= empty($stringlist) ? '"' : ', "';
- $stringlist .= Ingo_Script_Sieve::escapeString($address) . '"';
- }
- }
- $stringlist = "[" . $stringlist . "] ";
- } elseif (count($addresses) == 1) {
- $stringlist = '"' . Ingo_Script_Sieve::escapeString($addresses[0]) . '" ';
- }
-
- if (!empty($stringlist)) {
- $code .= ':addresses ' . $stringlist;
- }
-
- if (!empty($this->_vars['subject'])) {
- $code .= ':subject "' . Horde_Mime::encode(Ingo_Script_Sieve::escapeString($this->_vars['subject']), 'UTF-8') . '" ';
- }
- return $code
- . '"' . Ingo_Script_Sieve::escapeString($this->_vars['reason'])
- . '";';
- }
-
- /**
- */
- function _yearCheck($begin, $end)
- {
- $code = 'if header :regex "Received" "^.*(' . $begin;
- for ($i = $begin + 1; $i <= $end; $i++) {
- $code .= '|' . $i;
- }
- return $code
- . ') (\\\\(.*\\\\) )?..:..:.. (\\\\(.*\\\\) )?((\\\\+|\\\\-)[[:digit:]]{4}|.{1,5})( \\\\(.*\\\\))?$" {'
- . "\n ";
- }
-
- /**
- */
- function _monthCheck($begin, $end)
- {
- $months = array('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
- 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec');
- $code = 'if header :regex "Received" "^.*(' . $months[$begin - 1];
- for ($i = $begin + 1; $i <= $end; $i++) {
- $code .= '|' . $months[$i - 1];
- }
- return $code
- . ') (\\\\(.*\\\\) )?.... (\\\\(.*\\\\) )?..:..:.. (\\\\(.*\\\\) )?((\\\\+|\\\\-)[[:digit:]]{4}|.{1,5})( \\\\(.*\\\\))?$" {'
- . "\n ";
- }
-
- /**
- */
- function _dayCheck($begin, $end)
- {
- $code = 'if header :regex "Received" "^.*(' . str_repeat('[0 ]', 2 - strlen($begin)) . $begin;
- for ($i = $begin + 1; $i <= $end; $i++) {
- $code .= '|' . str_repeat('[0 ]', 2 - strlen($i)) . $i;
- }
- return $code
- . ') (\\\\(.*\\\\) )?... (\\\\(.*\\\\) )?.... (\\\\(.*\\\\) )?..:..:.. (\\\\(.*\\\\) )?((\\\\+|\\\\-)[[:digit:]]{4}|.{1,5})( \\\\(.*\\\\))?$" {'
- . "\n ";
- }
-
-}
-
-/**
- * The Sieve_Action_Flag class is the base class for flag actions.
- *
- * @author Michael Slusarz <slusarz@horde.org>
- * @package Ingo
- */
-class Sieve_Action_Flag extends Sieve_Action {
-
- /**
- * Constructor.
- *
- * @params array $vars Any required parameters.
- */
- function Sieve_Action_Flag($vars = array())
- {
- if (isset($vars['flags'])) {
- if ($vars['flags'] & Ingo_Storage::FLAG_ANSWERED) {
- $this->_vars['flags'][] = '\Answered';
- }
- if ($vars['flags'] & Ingo_Storage::FLAG_DELETED) {
- $this->_vars['flags'][] = '\Deleted';
- }
- if ($vars['flags'] & Ingo_Storage::FLAG_FLAGGED) {
- $this->_vars['flags'][] = '\Flagged';
- }
- if ($vars['flags'] & Ingo_Storage::FLAG_SEEN) {
- $this->_vars['flags'][] = '\Seen';
- }
- } else {
- $this->_vars['flags'] = '';
- }
- }
-
- /**
- * Returns a script snippet representing this rule and any sub-rules.
- *
- * @param string $mode The sieve flag command to use. Either 'removeflag'
- * or 'addflag'.
- *
- * @return string A Sieve script snippet.
- */
- function _toCode($mode)
- {
- $code = '';
-
- if (is_array($this->_vars['flags']) && !empty($this->_vars['flags'])) {
- $code .= $mode . ' ';
- if (count($this->_vars['flags']) > 1) {
- $stringlist = '';
- foreach ($this->_vars['flags'] as $flag) {
- $flag = trim($flag);
- if (!empty($flag)) {
- $stringlist .= empty($stringlist) ? '"' : ', "';
- $stringlist .= Ingo_Script_Sieve::escapeString($flag) . '"';
- }
- }
- $stringlist = '[' . $stringlist . ']';
- $code .= $stringlist . ';';
- } else {
- $code .= '"' . Ingo_Script_Sieve::escapeString($this->_vars['flags'][0]) . '";';
- }
- }
- return $code;
- }
-
- /**
- * Checks if the rule parameters are valid.
- *
- * @return boolean|string True if this rule is valid, an error message
- * otherwise.
- */
- function check()
- {
- return true;
- }
-
- /**
- * Returns a list of sieve extensions required for this rule and any
- * sub-rules.
- *
- * @return array A Sieve extension list.
- */
- function requires()
- {
- return array('imapflags');
- }
-
-}
-
-/**
- * The Sieve_Action_Addflag class represents an add flag action.
- *
- * @author Mike Cochrane <mike@graftonhall.co.nz>
- * @package Ingo
- */
-class Sieve_Action_Addflag extends Sieve_Action_Flag {
-
- /**
- * Returns a script snippet representing this rule and any sub-rules.
- *
- * @return string A Sieve script snippet.
- */
- function toCode()
- {
- return $this->_toCode('addflag');
- }
-
-}
-
-/**
- * The Sieve_Action_Removeflag class represents a remove flag action.
- *
- * @author Mike Cochrane <mike@graftonhall.co.nz>
- * @package Ingo
- */
-class Sieve_Action_Removeflag extends Sieve_Action_Flag {
-
- /**
- * Returns a script snippet representing this rule and any sub-rules.
- *
- * @return string A Sieve script snippet.
- */
- function toCode()
- {
- return $this->_toCode('removeflag');
- }
-
-}
-
-/**
- * The Sieve_Action_Notify class represents a notify action.
- *
- * @author Paul Wolstenholme <wolstena@sfu.ca>
- * @package Ingo
- */
-class Sieve_Action_Notify extends Sieve_Action {
-
- /**
- * Constructor.
- *
- * @param array $vars Any required parameters.
- */
- function Sieve_Action_Notify($vars = array())
- {
- $this->_vars['address'] = isset($vars['address']) ? $vars['address'] : '';
- $this->_vars['name'] = isset($vars['name']) ? $vars['name'] : '';
- }
-
- /**
- * Returns a script snippet representing this rule and any sub-rules.
- *
- * @return string A Sieve script snippet.
- */
- function toCode()
- {
- return 'notify :method "mailto" :options "' .
- Ingo_Script_Sieve::escapeString($this->_vars['address']) .
- '" :message "' .
- _("You have received a new message") . "\n" .
- _("From:") . " \$from\$ \n" .
- _("Subject:") . " \$subject\$ \n" .
- _("Rule:") . ' ' . $this->_vars['name'] . '";';
- }
-
- /**
- * Checks if the rule parameters are valid.
- *
- * @return boolean|string True if this rule is valid, an error message
- * otherwise.
- */
- function check()
- {
- if (empty($this->_vars['address'])) {
- return _("Missing address to notify");
- }
-
- return true;
- }
-
- /**
- * Returns a list of sieve extensions required for this rule and any
- * sub-rules.
- *
- * @return array A Sieve extension list.
- */
- function requires()
- {
- return array('notify');
- }
-
-}
--- /dev/null
+<?php
+/**
+ * The Ingo_Script_Sieve_Action class represents an action in a Sieve script.
+ *
+ * An action is anything that has a side effect eg: discard, redirect.
+ *
+ * See the enclosed file LICENSE for license information (ASL). If you
+ * did not receive this file, see http://www.horde.org/licenses/asl.php.
+ *
+ * @author Mike Cochrane <mike@graftonhall.co.nz>
+ * @package Ingo
+ */
+class Ingo_Script_Sieve_Action
+{
+ /**
+ * Any necessary action parameters.
+ *
+ * @var array
+ */
+ protected $_vars = array();
+
+ /**
+ * Returns a script snippet representing this rule and any sub-rules.
+ *
+ * @return string A Sieve script snippet.
+ */
+ public function toCode()
+ {
+ return 'toCode() Function Not Implemented in class ' . get_class($this) ;
+ }
+
+ public function toString()
+ {
+ return $this->toCode();
+ }
+
+ /**
+ * Checks if the rule parameters are valid.
+ *
+ * @return boolean|string True if this rule is valid, an error message
+ * otherwise.
+ */
+ public function check()
+ {
+ return 'check() Function Not Implemented in class ' . get_class($this) ;
+ }
+
+ /**
+ * Returns a list of sieve extensions required for this rule and any
+ * sub-rules.
+ *
+ * @return array A Sieve extension list.
+ */
+ public function requires()
+ {
+ return array();
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * The Ingo_Script_Sieve_Action_Addflag class represents an add flag action.
+ *
+ * See the enclosed file LICENSE for license information (ASL). If you
+ * did not receive this file, see http://www.horde.org/licenses/asl.php.
+ *
+ * @author Mike Cochrane <mike@graftonhall.co.nz>
+ * @package Ingo
+ */
+class Ingo_Script_Sieve_Action_Addflag extends Ingo_Script_Sieve_Action_Flag
+{
+ /**
+ * Returns a script snippet representing this rule and any sub-rules.
+ *
+ * @return string A Sieve script snippet.
+ */
+ public function toCode()
+ {
+ return $this->_toCode('addflag');
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * The Ingo_Script_Sieve_Action_Discard class represents a discard action.
+ *
+ * See the enclosed file LICENSE for license information (ASL). If you
+ * did not receive this file, see http://www.horde.org/licenses/asl.php.
+ *
+ * @author Mike Cochrane <mike@graftonhall.co.nz>
+ * @package Ingo
+ */
+class Ingo_Script_Sieve_Action_Discard extends Ingo_Script_Sieve_Action
+{
+ /**
+ * Returns a script snippet representing this rule and any sub-rules.
+ *
+ * @return string A Sieve script snippet.
+ */
+ public function toCode()
+ {
+ return 'discard;';
+ }
+
+ /**
+ * Checks if the rule parameters are valid.
+ *
+ * @return boolean|string True if this rule is valid, an error message
+ * otherwise.
+ */
+ public function check()
+ {
+ return true;
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * The Ingo_Script_Sieve_Action_Fileinto class represents a fileinto action.
+ *
+ * See the enclosed file LICENSE for license information (ASL). If you
+ * did not receive this file, see http://www.horde.org/licenses/asl.php.
+ *
+ * @author Mike Cochrane <mike@graftonhall.co.nz>
+ * @package Ingo
+ */
+class Ingo_Script_Sieve_Action_Fileinto extends Ingo_Script_Sieve_Action
+{
+ /**
+ * Constructor.
+ *
+ * @param array $vars Any required parameters.
+ */
+ public function __construct($vars = array())
+ {
+ $this->_vars['folder'] = isset($vars['folder'])
+ ? $vars['folder']
+ : '';
+
+ if (!empty($vars['utf8'])) {
+ $this->_vars['folder'] = Horde_String::convertCharset($this->_vars['folder'], 'UTF7-IMAP', 'UTF-8');
+ }
+ }
+
+ /**
+ * Returns a script snippet representing this rule and any sub-rules.
+ *
+ * @return string A Sieve script snippet.
+ */
+ public function toCode()
+ {
+ return 'fileinto "' . Ingo_Script_Sieve::escapeString($this->_vars['folder']) . '";';
+ }
+
+ /**
+ * Checks if the rule parameters are valid.
+ *
+ * @return boolean|string True if this rule is valid, an error message
+ * otherwise.
+ */
+ public function check()
+ {
+ return empty($this->_vars['folder'])
+ ? _("Inexistant mailbox specified for message delivery.")
+ : true;
+ }
+
+ /**
+ * Returns a list of sieve extensions required for this rule and any
+ * sub-rules.
+ *
+ * @return array A Sieve extension list.
+ */
+ public function requires()
+ {
+ return array('fileinto');
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * The Ingo_Script_Sieve_Action_Flag class is the base class for flag actions.
+ *
+ * See the enclosed file LICENSE for license information (ASL). If you
+ * did not receive this file, see http://www.horde.org/licenses/asl.php.
+ *
+ * @author Michael Slusarz <slusarz@horde.org>
+ * @package Ingo
+ */
+class Ingo_Script_Sieve_Action_Flag extends Ingo_Script_Sieve_Action
+{
+ /**
+ * Constructor.
+ *
+ * @params array $vars Any required parameters.
+ */
+ public function __construct($vars = array())
+ {
+ if (isset($vars['flags'])) {
+ if ($vars['flags'] & Ingo_Storage::FLAG_ANSWERED) {
+ $this->_vars['flags'][] = '\Answered';
+ }
+ if ($vars['flags'] & Ingo_Storage::FLAG_DELETED) {
+ $this->_vars['flags'][] = '\Deleted';
+ }
+ if ($vars['flags'] & Ingo_Storage::FLAG_FLAGGED) {
+ $this->_vars['flags'][] = '\Flagged';
+ }
+ if ($vars['flags'] & Ingo_Storage::FLAG_SEEN) {
+ $this->_vars['flags'][] = '\Seen';
+ }
+ } else {
+ $this->_vars['flags'] = '';
+ }
+ }
+
+ /**
+ * Returns a script snippet representing this rule and any sub-rules.
+ *
+ * @param string $mode The sieve flag command to use. Either 'removeflag'
+ * or 'addflag'.
+ *
+ * @return string A Sieve script snippet.
+ */
+ public function _toCode($mode)
+ {
+ $code = '';
+
+ if (is_array($this->_vars['flags']) && !empty($this->_vars['flags'])) {
+ $code .= $mode . ' ';
+ if (count($this->_vars['flags']) > 1) {
+ $stringlist = '';
+ foreach ($this->_vars['flags'] as $flag) {
+ $flag = trim($flag);
+ if (!empty($flag)) {
+ $stringlist .= empty($stringlist) ? '"' : ', "';
+ $stringlist .= Ingo_Script_Sieve::escapeString($flag) . '"';
+ }
+ }
+ $stringlist = '[' . $stringlist . ']';
+ $code .= $stringlist . ';';
+ } else {
+ $code .= '"' . Ingo_Script_Sieve::escapeString($this->_vars['flags'][0]) . '";';
+ }
+ }
+ return $code;
+ }
+
+ /**
+ * Checks if the rule parameters are valid.
+ *
+ * @return boolean|string True if this rule is valid, an error message
+ * otherwise.
+ */
+ public function check()
+ {
+ return true;
+ }
+
+ /**
+ * Returns a list of sieve extensions required for this rule and any
+ * sub-rules.
+ *
+ * @return array A Sieve extension list.
+ */
+ public function requires()
+ {
+ return array('imapflags');
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * The Ingo_Script_Sieve_Action_Keep class represents a keep action.
+ *
+ * See the enclosed file LICENSE for license information (ASL). If you
+ * did not receive this file, see http://www.horde.org/licenses/asl.php.
+ *
+ * @author Mike Cochrane <mike@graftonhall.co.nz>
+ * @package Ingo
+ */
+class Ingo_Script_Sieve_Action_Keep extends Ingo_Script_Sieve_Action
+{
+ /**
+ * Returns a script snippet representing this rule and any sub-rules.
+ *
+ * @return string A Sieve script snippet.
+ */
+ public function toCode()
+ {
+ return 'keep;';
+ }
+
+ /**
+ * Checks if the rule parameters are valid.
+ *
+ * @return boolean|string True if this rule is valid, an error message
+ * otherwise.
+ */
+ public function check()
+ {
+ return true;
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * The Ingo_Script_Sieve_Action_Notify class represents a notify action.
+ *
+ * See the enclosed file LICENSE for license information (ASL). If you
+ * did not receive this file, see http://www.horde.org/licenses/asl.php.
+ *
+ * @author Paul Wolstenholme <wolstena@sfu.ca>
+ * @package Ingo
+ */
+class Ingo_Script_Sieve_Action_Notify extends Ingo_Script_Sieve_Action
+{
+ /**
+ * Constructor.
+ *
+ * @param array $vars Any required parameters.
+ */
+ public function __construct($vars = array())
+ {
+ $this->_vars['address'] = isset($vars['address'])
+ ? $vars['address']
+ : '';
+ $this->_vars['name'] = isset($vars['name'])
+ ? $vars['name']
+ : '';
+ }
+
+ /**
+ * Returns a script snippet representing this rule and any sub-rules.
+ *
+ * @return string A Sieve script snippet.
+ */
+ public function toCode()
+ {
+ return 'notify :method "mailto" :options "' .
+ Ingo_Script_Sieve::escapeString($this->_vars['address']) .
+ '" :message "' .
+ _("You have received a new message") . "\n" .
+ _("From:") . " \$from\$ \n" .
+ _("Subject:") . " \$subject\$ \n" .
+ _("Rule:") . ' ' . $this->_vars['name'] . '";';
+ }
+
+ /**
+ * Checks if the rule parameters are valid.
+ *
+ * @return boolean|string True if this rule is valid, an error message
+ * otherwise.
+ */
+ public function check()
+ {
+ return empty($this->_vars['address'])
+ ? _("Missing address to notify")
+ : true;
+ }
+
+ /**
+ * Returns a list of sieve extensions required for this rule and any
+ * sub-rules.
+ *
+ * @return array A Sieve extension list.
+ */
+ public function requires()
+ {
+ return array('notify');
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * The Ingo_Script_Sieve_Action_Redirect class represents a redirect action.
+ *
+ * See the enclosed file LICENSE for license information (ASL). If you
+ * did not receive this file, see http://www.horde.org/licenses/asl.php.
+ *
+ * @author Mike Cochrane <mike@graftonhall.co.nz>
+ * @package Ingo
+ */
+class Ingo_Script_Sieve_Action_Redirect extends Ingo_Script_Sieve_Action
+{
+ /**
+ * Constructor.
+ *
+ * @param array $vars Any required parameters.
+ */
+ public function __construct($vars = array())
+ {
+ $this->_vars['address'] = isset($vars['address'])
+ ? $vars['address']
+ : '';
+ }
+
+ /**
+ */
+ public function toCode($depth = 0)
+ {
+ return str_repeat(' ', $depth * 4) . 'redirect ' .
+ '"' . Ingo_Script_Sieve::escapeString($this->_vars['address']) . '";';
+ }
+
+ /**
+ * Checks if the rule parameters are valid.
+ *
+ * @return boolean|string True if this rule is valid, an error message
+ * otherwise.
+ */
+ public function check()
+ {
+ return empty($this->_vars['address'])
+ ? _("Missing address to redirect message to")
+ : true;
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * The Ingo_Script_Sieve_Action_Reject class represents a reject action.
+ *
+ * See the enclosed file LICENSE for license information (ASL). If you
+ * did not receive this file, see http://www.horde.org/licenses/asl.php.
+ *
+ * @author Mike Cochrane <mike@graftonhall.co.nz>
+ * @package Ingo
+ */
+class Ingo_Script_Sieve_Action_Reject extends Ingo_Script_Sieve_Action
+{
+ /**
+ * Constructor.
+ *
+ * @param array $vars Any required parameters.
+ */
+ public function __construct($vars = array())
+ {
+ $this->_vars['reason'] = isset($vars['reason'])
+ ? $vars['reason']
+ : '';
+ }
+
+ /**
+ * Returns a script snippet representing this rule and any sub-rules.
+ *
+ * @return string A Sieve script snippet.
+ */
+ public function toCode()
+ {
+ return 'reject "' . Ingo_Script_Sieve::escapeString($this->_vars['reason']) . '";';
+ }
+
+ /**
+ * Checks if the rule parameters are valid.
+ *
+ * @return boolean|string True if this rule is valid, an error message
+ * otherwise.
+ */
+ public function check()
+ {
+ return empty($this->_vars['reason'])
+ ? _("Missing reason for reject")
+ : true;
+ }
+
+ /**
+ * Returns a list of sieve extensions required for this rule and any
+ * sub-rules.
+ *
+ * @return array A Sieve extension list.
+ */
+ public function requires()
+ {
+ return array('reject');
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * The Ingo_Script_Sieve_Action_Removeflag class represents a remove flag
+ * action.
+ *
+ * See the enclosed file LICENSE for license information (ASL). If you
+ * did not receive this file, see http://www.horde.org/licenses/asl.php.
+ *
+ * @author Mike Cochrane <mike@graftonhall.co.nz>
+ * @package Ingo
+ */
+class Ingo_Script_Sieve_Action_Removeflag extends Ingo_Script_Sieve_Action_Flag
+{
+ /**
+ * Returns a script snippet representing this rule and any sub-rules.
+ *
+ * @return string A Sieve script snippet.
+ */
+ public function toCode()
+ {
+ return $this->_toCode('removeflag');
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * The Ingo_Script_Sieve_Action_Stop class represents a stop action.
+ *
+ * See the enclosed file LICENSE for license information (ASL). If you
+ * did not receive this file, see http://www.horde.org/licenses/asl.php.
+ *
+ * @author Mike Cochrane <mike@graftonhall.co.nz>
+ * @package Ingo
+ */
+class Ingo_Script_Sieve_Action_Stop extends Ingo_Script_Sieve_Action
+{
+ /**
+ * Returns a script snippet representing this rule and any sub-rules.
+ *
+ * @return string A Sieve script snippet.
+ */
+ public function toCode()
+ {
+ return 'stop;';
+ }
+
+ /**
+ * Checks if the rule parameters are valid.
+ *
+ * @return boolean|string True if this rule is valid, an error message
+ * otherwise.
+ */
+ public function check()
+ {
+ return true;
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * The Ingo_Script_Sieve_Action_Vacation class represents a vacation action.
+ *
+ * See the enclosed file LICENSE for license information (ASL). If you
+ * did not receive this file, see http://www.horde.org/licenses/asl.php.
+ *
+ * @author Mike Cochrane <mike@graftonhall.co.nz>
+ * @package Ingo
+ */
+class Ingo_Script_Sieve_Action_Vacation extends Ingo_Script_Sieve_Action
+{
+ /**
+ * Constructor.
+ *
+ * @param array $vars Any required parameters.
+ */
+ public function __construct($vars = array())
+ {
+ $this->_vars = array_merge(array(
+ 'days' => '',
+ 'addresses' => '',
+ 'subject' => '',
+ 'reason' => '',
+ 'start' => '',
+ 'start_year' => '',
+ 'start_month' => '',
+ 'start_day' => '',
+ 'end' => '',
+ 'end_year' => '',
+ 'end_month' => '',
+ 'end_day' => ''
+ ), $vars);
+ }
+
+ /**
+ * Returns a script snippet representing this rule and any sub-rules.
+ *
+ * @return string A Sieve script snippet.
+ */
+ public function toCode()
+ {
+ $start_year = $this->_vars['start_year'];
+ $start_month = $this->_vars['start_month'];
+ $start_day = $this->_vars['start_day'];
+
+ $end_year = $this->_vars['end_year'];
+ $end_month = $this->_vars['end_month'];
+ $end_day = $this->_vars['end_day'];
+
+ $code = '';
+
+ if (empty($this->_vars['start']) || empty($this->_vars['end'])) {
+ return $this->_vacationCode();
+ } elseif ($end_year > $start_year + 1) {
+ $code .= $this->_yearCheck($start_year + 1, $end_year - 1)
+ . $this->_vacationCode()
+ . "\n}\n"
+ . $this->_yearCheck($start_year, $start_year);
+ if ($start_month < 12) {
+ $code .= $this->_monthCheck($start_month + 1, 12)
+ . $this->_vacationCode()
+ . "\n}\n";
+ }
+ $code .= $this->_monthCheck($start_month, $start_month)
+ . $this->_dayCheck($start_day, 31)
+ . $this->_vacationCode()
+ . "\n}\n}\n}\n"
+ . $this->_yearCheck($end_year, $end_year);
+ if ($end_month > 1) {
+ $code .= $this->_monthCheck(1, $end_month - 1)
+ . $this->_vacationCode()
+ . "\n}\n";
+ }
+ $code .= $this->_monthCheck($end_month, $end_month)
+ . $this->_dayCheck(1, $end_day)
+ . $this->_vacationCode()
+ . "\n}\n}\n}\n";
+ } elseif ($end_year == $start_year + 1) {
+ $code .= $this->_yearCheck($start_year, $start_year);
+ if ($start_month < 12) {
+ $code .= $this->_monthCheck($start_month + 1, 12)
+ . $this->_vacationCode()
+ . "\n}\n";
+ }
+ $code .= $this->_monthCheck($start_month, $start_month)
+ . $this->_dayCheck($start_day, 31)
+ . $this->_vacationCode()
+ . "\n}\n}\n}\n"
+ . $this->_yearCheck($end_year, $end_year);
+ if ($end_month > 1) {
+ $code .= $this->_monthCheck(1, $end_month - 1)
+ . $this->_vacationCode()
+ . "\n}\n";
+ }
+ $code .= $this->_monthCheck($end_month, $end_month)
+ . $this->_dayCheck(1, $end_day)
+ . $this->_vacationCode()
+ . "\n}\n}\n}\n";
+ } elseif ($end_year == $start_year) {
+ $code .= $this->_yearCheck($start_year, $start_year);
+ if ($end_month > $start_month) {
+ if ($end_month > $start_month + 1) {
+ $code .= $this->_monthCheck($start_month + 1, $end_month - 1)
+ . $this->_vacationCode()
+ . "\n}\n";
+ }
+ $code .= $this->_monthCheck($start_month, $start_month)
+ . $this->_dayCheck($start_day, 31)
+ . $this->_vacationCode()
+ . "\n}\n}\n"
+ . $this->_monthCheck($end_month, $end_month)
+ . $this->_dayCheck(1, $end_day)
+ . $this->_vacationCode()
+ . "\n}\n}\n";
+ } elseif ($end_month == $start_month) {
+ $code .= $this->_monthCheck($start_month, $start_month)
+ . $this->_dayCheck($start_day, $end_day)
+ . $this->_vacationCode()
+ . "\n}\n}\n";
+ }
+ $code .= "}\n";
+ }
+
+ return $code;
+ }
+
+ /**
+ * Checks if the rule parameters are valid.
+ *
+ * @return boolean|string True if this rule is valid, an error message
+ * otherwise.
+ */
+ public function check()
+ {
+ return empty($this->_vars['reason'])
+ ? _("Missing reason in vacation.")
+ : true;
+ }
+
+ /**
+ * Returns a list of sieve extensions required for this rule and any
+ * sub-rules.
+ *
+ * @return array A Sieve extension list.
+ */
+ public function requires()
+ {
+ return array('vacation', 'regex');
+ }
+
+ /**
+ */
+ protected function _vacationCode()
+ {
+ $code = 'vacation :days ' . $this->_vars['days'] . ' ';
+ $addresses = $this->_vars['addresses'];
+ $stringlist = '';
+ if (count($addresses) > 1) {
+ foreach ($addresses as $address) {
+ $address = trim($address);
+ if (!empty($address)) {
+ $stringlist .= empty($stringlist) ? '"' : ', "';
+ $stringlist .= Ingo_Script_Sieve::escapeString($address) . '"';
+ }
+ }
+ $stringlist = "[" . $stringlist . "] ";
+ } elseif (count($addresses) == 1) {
+ $stringlist = '"' . Ingo_Script_Sieve::escapeString($addresses[0]) . '" ';
+ }
+
+ if (!empty($stringlist)) {
+ $code .= ':addresses ' . $stringlist;
+ }
+
+ if (!empty($this->_vars['subject'])) {
+ $code .= ':subject "' . Horde_Mime::encode(Ingo_Script_Sieve::escapeString($this->_vars['subject']), 'UTF-8') . '" ';
+ }
+ return $code
+ . '"' . Ingo_Script_Sieve::escapeString($this->_vars['reason'])
+ . '";';
+ }
+
+ /**
+ */
+ protected function _yearCheck($begin, $end)
+ {
+ $code = 'if header :regex "Received" "^.*(' . $begin;
+ for ($i = $begin + 1; $i <= $end; $i++) {
+ $code .= '|' . $i;
+ }
+ return $code
+ . ') (\\\\(.*\\\\) )?..:..:.. (\\\\(.*\\\\) )?((\\\\+|\\\\-)[[:digit:]]{4}|.{1,5})( \\\\(.*\\\\))?$" {'
+ . "\n ";
+ }
+
+ /**
+ */
+ protected function _monthCheck($begin, $end)
+ {
+ $months = array('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
+ 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec');
+ $code = 'if header :regex "Received" "^.*(' . $months[$begin - 1];
+ for ($i = $begin + 1; $i <= $end; $i++) {
+ $code .= '|' . $months[$i - 1];
+ }
+ return $code
+ . ') (\\\\(.*\\\\) )?.... (\\\\(.*\\\\) )?..:..:.. (\\\\(.*\\\\) )?((\\\\+|\\\\-)[[:digit:]]{4}|.{1,5})( \\\\(.*\\\\))?$" {'
+ . "\n ";
+ }
+
+ /**
+ */
+ protected function _dayCheck($begin, $end)
+ {
+ $code = 'if header :regex "Received" "^.*(' . str_repeat('[0 ]', 2 - strlen($begin)) . $begin;
+ for ($i = $begin + 1; $i <= $end; $i++) {
+ $code .= '|' . str_repeat('[0 ]', 2 - strlen($i)) . $i;
+ }
+ return $code
+ . ') (\\\\(.*\\\\) )?... (\\\\(.*\\\\) )?.... (\\\\(.*\\\\) )?..:..:.. (\\\\(.*\\\\) )?((\\\\+|\\\\-)[[:digit:]]{4}|.{1,5})( \\\\(.*\\\\))?$" {'
+ . "\n ";
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * A Comment.
+ *
+ * See the enclosed file LICENSE for license information (ASL). If you
+ * did not receive this file, see http://www.horde.org/licenses/asl.php.
+ *
+ * @author Mike Cochrane <mike@graftonhall.co.nz>
+ * @package Ingo
+ * @todo This and Sieve_If should really extends a Sieve_Block eventually.
+ */
+class Ingo_Script_Sieve_Comment
+{
+ /**
+ */
+ protected $_comment;
+
+ /**
+ * Constructor.
+ *
+ * @param string $comment The comment text.
+ */
+ public function __construct($comment)
+ {
+ $this->_comment = $comment;
+ }
+
+ /**
+ * Returns a script snippet representing this rule and any sub-rules.
+ *
+ * @return string A Sieve script snippet.
+ */
+ public function toCode()
+ {
+ $code = '';
+ $lines = preg_split('(\r\n|\n|\r)', $this->_comment);
+ foreach ($lines as $line) {
+ $line = trim($line);
+ if (strlen($line)) {
+ $code .= (empty($code) ? '' : "\n") . '# ' . $line;
+ }
+ }
+ return $code;
+ }
+
+ /**
+ * Checks if the rule parameters are valid.
+ *
+ * @return boolean|string True if this rule is valid, an error message
+ * otherwise.
+ */
+ public function check()
+ {
+ return true;
+ }
+
+ /**
+ * Returns a list of sieve extensions required for this rule and any
+ * sub-rules.
+ *
+ * @return array A Sieve extension list.
+ */
+ public function requires()
+ {
+ return array();
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * The Ingo_Script_Sieve_Else:: class represents a Sieve Else Statement.
+ *
+ * See the enclosed file LICENSE for license information (ASL). If you
+ * did not receive this file, see http://www.horde.org/licenses/asl.php.
+ *
+ * @author Mike Cochrane <mike@graftonhall.co.nz>
+ * @package Ingo
+ */
+class Ingo_Script_Sieve_Else
+{
+ /**
+ * A list of Ingo_Script_Sieve_Action objects that go into the else clause.
+ *
+ * @var array
+ */
+ protected $_actions = array();
+
+ /**
+ * Constructor.
+ *
+ * @param mixed $actions An Ingo_Script_Sieve_Action object or a list of
+ * Ingo_Script_Sieve_Action objects.
+ */
+ public function __construct($actions = null)
+ {
+ if (is_array($actions)) {
+ $this->_actions = $actions;
+ } elseif (!is_null($actions)) {
+ $this->_actions[] = $actions;
+ }
+ }
+
+ /**
+ * Returns a script snippet representing this rule and any sub-rules.
+ *
+ * @return string A Sieve script snippet.
+ */
+ public function toCode()
+ {
+ if (count($this->_actions) == 0) {
+ return '';
+ }
+
+ $code = 'else' . " { \n";
+ foreach ($this->_actions as $action) {
+ $code .= ' ' . $action->toCode() . "\n";
+ }
+ $code .= "} ";
+
+ return $code;
+ }
+
+ /**
+ */
+ public function setActions($actions)
+ {
+ $this->_actions = $actions;
+ }
+
+ /**
+ */
+ public function getActions()
+ {
+ return $this->_actions;
+ }
+
+ /**
+ * Checks if all sub-rules are valid.
+ *
+ * @return boolean|string True if all rules are valid, an error message
+ * otherwise.
+ */
+ public function check()
+ {
+ foreach ($this->_actions as $action) {
+ $res = $action->check();
+ if ($res !== true) {
+ return $res;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Returns a list of sieve extensions required for this rule and any
+ * sub-rules.
+ *
+ * @return array A Sieve extension list.
+ */
+ public function requires()
+ {
+ $requires = array();
+
+ foreach ($this->_actions as $action) {
+ $requires = array_merge($requires, $action->requires());
+ }
+
+ return $requires;
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * The Ingo_Script_Sieve_Elsif:: class represents a Sieve Elsif Statement.
+ *
+ * See the enclosed file LICENSE for license information (ASL). If you
+ * did not receive this file, see http://www.horde.org/licenses/asl.php.
+ *
+ * @author Mike Cochrane <mike@graftonhall.co.nz>
+ * @package Ingo
+ */
+class Ingo_Script_Sieve_Elsif
+{
+ /**
+ * The Ingo_Script_Sieve_Test object for the if test.
+ *
+ * @var Ingo_Script_Sieve_Test
+ */
+ protected $_test;
+
+ /**
+ * A list of Ingo_Script_Sieve_Action objects that go into the if clause.
+ *
+ * @var array
+ */
+ protected $_actions = array();
+
+ /**
+ * Constructor.
+ *
+ * @param Ingo_Script_Sieve_Test $test A Ingo_Script_Sieve_Test object.
+ */
+ public function __construct($test = null)
+ {
+ $this->_test = is_null($test)
+ ? new Ingo_Script_Sieve_Test_False()
+ : $test;
+ $this->_actions[] = new Ingo_Script_Sieve_Action_Keep();
+ }
+
+ /**
+ */
+ public function getTest()
+ {
+ return $this->_test;
+ }
+
+ /**
+ */
+ public function setTest($test)
+ {
+ $this->_test = $test;
+ }
+
+ /**
+ */
+ public function getActions()
+ {
+ return $this->_actions;
+ }
+
+ /**
+ */
+ public function setActions($actions)
+ {
+ $this->_actions = $actions;
+ }
+
+ /**
+ * Returns a script snippet representing this rule and any sub-rules.
+ *
+ * @return string A Sieve script snippet.
+ */
+ public function toCode()
+ {
+ $code = 'elsif ' . $this->_test->toCode() . " { \n";
+ foreach ($this->_actions as $action) {
+ $code .= ' ' . $action->toCode() . "\n";
+ }
+ $code .= "} ";
+
+ return $code;
+ }
+
+ /**
+ * Checks if all sub-rules are valid.
+ *
+ * @return boolean|string True if all rules are valid, an error message
+ * otherwise.
+ */
+ public function check()
+ {
+ $res = $this->_test->check();
+ if ($res !== true) {
+ return $res;
+ }
+
+ foreach ($this->_actions as $action) {
+ $res = $action->check();
+ if ($res !== true) {
+ return $res;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Returns a list of sieve extensions required for this rule and any
+ * sub-rules.
+ *
+ * @return array A Sieve extension list.
+ */
+ public function requires()
+ {
+ $requires = array();
+
+ foreach ($this->_actions as $action) {
+ $requires = array_merge($requires, $action->requires());
+ }
+
+ return array_merge($requires, $this->_test->requires());
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * The Ingo_Script_Sieve_If:: class represents a Sieve If Statement.
+ *
+ * See the enclosed file LICENSE for license information (ASL). If you
+ * did not receive this file, see http://www.horde.org/licenses/asl.php.
+ *
+ * @author Mike Cochrane <mike@graftonhall.co.nz>
+ * @package Ingo
+ */
+class Ingo_Script_Sieve_If
+{
+ /**
+ * The Ingo_Script_Sieve_Test object for the if test.
+ *
+ * @var Ingo_Script_Sieve_Test
+ */
+ protected $_test;
+
+ /**
+ * A list of Ingo_Script_Sieve_Action objects that go into the if clause.
+ *
+ * @var array
+ */
+ protected $_actions = array();
+
+ /**
+ * A list of Ingo_Script_Sieve_Elseif objects that create optional elsif
+ * clauses.
+ *
+ * @var array
+ */
+ protected $_elsifs = array();
+
+ /**
+ * A Ingo_Script_Sieve_Else object that creates an optional else clause.
+ *
+ * @var Ingo_Script_Sieve_Else
+ */
+ protected $_else;
+
+ /**
+ * Constructor.
+ *
+ * @param Ingo_Script_Sieve_Test $test A Ingo_Script_Sieve_Test object.
+ */
+ public function __construct($test = null)
+ {
+ $this->_test = is_null($test)
+ ? new Ingo_Script_Sieve_Test_False()
+ : $test;
+
+ $this->_actions[] = new Ingo_Script_Sieve_Action_Keep();
+ $this->_else = new Ingo_Script_Sieve_Else();
+ }
+
+ /**
+ */
+ public function getTest()
+ {
+ return $this->_test;
+ }
+
+ /**
+ */
+ public function setTest($test)
+ {
+ $this->_test = $test;
+ }
+
+ /**
+ */
+ public function getActions()
+ {
+ return $this->_actions;
+ }
+
+ /**
+ */
+ public function setActions($actions)
+ {
+ $this->_actions = $actions;
+ }
+
+ /**
+ */
+ public function getElsifs()
+ {
+ return $this->_elsifs;
+ }
+
+ /**
+ */
+ public function setElsifs($elsifs)
+ {
+ $this->_elsifs = $elsifs;
+ }
+
+ /**
+ */
+ public function addElsif($elsif)
+ {
+ $this->_elsifs[] = $elsif;
+ }
+
+ /**
+ */
+ public function getElse()
+ {
+ return $this->_else;
+ }
+
+ /**
+ */
+ public function setElse($else)
+ {
+ $this->_else = $else;
+ }
+
+ /**
+ * Returns a script snippet representing this rule and any sub-rules.
+ *
+ * @return string A Sieve script snippet.
+ */
+ public function toCode()
+ {
+ $code = 'if ' . $this->_test->toCode() . " { \n";
+ foreach ($this->_actions as $action) {
+ $code .= ' ' . $action->toCode() . "\n";
+ }
+ $code .= "} ";
+
+ foreach ($this->_elsifs as $elsif) {
+ $code .= $elsif->toCode();
+ }
+
+ $code .= $this->_else->toCode();
+
+ return $code . "\n";
+ }
+
+ /**
+ * Checks if all sub-rules are valid.
+ *
+ * @return boolean|string True if all rules are valid, an error message
+ * otherwise.
+ */
+ public function check()
+ {
+ $res = $this->_test->check();
+ if ($res !== true) {
+ return $res;
+ }
+
+ foreach ($this->_elsifs as $elsif) {
+ $res = $elsif->check();
+ if ($res !== true) {
+ return $res;
+ }
+ }
+
+ $res = $this->_else->check();
+ if ($res !== true) {
+ return $res;
+ }
+
+ foreach ($this->_actions as $action) {
+ $res = $action->check();
+ if ($res !== true) {
+ return $res;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Returns a list of sieve extensions required for this rule and any
+ * sub-rules.
+ *
+ * @return array A Sieve extension list.
+ */
+ public function requires()
+ {
+ $requires = array();
+
+ foreach ($this->_actions as $action) {
+ $requires = array_merge($requires, $action->requires());
+ }
+
+ foreach ($this->_elsifs as $elsif) {
+ $requires = array_merge($requires, $elsif->requires());
+ }
+
+ return array_merge($requires, $this->_test->requires(), $this->_else->requires());
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * The Ingo_Script_Sieve_Action class represents an action in a Sieve script.
+ *
+ * An action is anything that has a side effect eg: discard, redirect.
+ *
+ * See the enclosed file LICENSE for license information (ASL). If you
+ * did not receive this file, see http://www.horde.org/licenses/asl.php.
+ *
+ * @author Mike Cochrane <mike@graftonhall.co.nz>
+ * @package Ingo
+ */
+/**
+ * The Sieve_Action_Redirect class represents a redirect action.
+ *
+ * @author Mike Cochrane <mike@graftonhall.co.nz>
+ * @package Ingo
+ */
+class Sieve_Action_Redirect extends Sieve_Action {
+
+ /**
+ * Constructor.
+ *
+ * @param array $vars Any required parameters.
+ */
+ function Sieve_Action_Redirect($vars = array())
+ {
+ $this->_vars['address'] = (isset($vars['address'])) ? $vars['address'] : '';
+ }
+
+ function toCode($depth = 0)
+ {
+ return str_repeat(' ', $depth * 4) . 'redirect ' .
+ '"' . Ingo_Script_Sieve::escapeString($this->_vars['address']) . '";';
+ }
+
+ /**
+ * Checks if the rule parameters are valid.
+ *
+ * @return boolean|string True if this rule is valid, an error message
+ * otherwise.
+ */
+ function check()
+ {
+ if (empty($this->_vars['address'])) {
+ return _("Missing address to redirect message to");
+ }
+
+ return true;
+ }
+
+}
+
+/**
+ * The Sieve_Action_Reject class represents a reject action.
+ *
+ * @author Mike Cochrane <mike@graftonhall.co.nz>
+ * @package Ingo
+ */
+class Sieve_Action_Reject extends Sieve_Action {
+
+ /**
+ * Constructor.
+ *
+ * @param array $vars Any required parameters.
+ */
+ function Sieve_Action_Reject($vars = array())
+ {
+ $this->_vars['reason'] = (isset($vars['reason'])) ? $vars['reason'] : '';
+ }
+
+ /**
+ * Returns a script snippet representing this rule and any sub-rules.
+ *
+ * @return string A Sieve script snippet.
+ */
+ function toCode()
+ {
+ return 'reject "' . Ingo_Script_Sieve::escapeString($this->_vars['reason']) . '";';
+ }
+
+ /**
+ * Checks if the rule parameters are valid.
+ *
+ * @return boolean|string True if this rule is valid, an error message
+ * otherwise.
+ */
+ function check()
+ {
+ if (empty($this->_vars['reason'])) {
+ return _("Missing reason for reject");
+ }
+
+ return true;
+ }
+
+ /**
+ * Returns a list of sieve extensions required for this rule and any
+ * sub-rules.
+ *
+ * @return array A Sieve extension list.
+ */
+ function requires()
+ {
+ return array('reject');
+ }
+
+}
+
+/**
+ * The Sieve_Action_Keep class represents a keep action.
+ *
+ * @author Mike Cochrane <mike@graftonhall.co.nz>
+ * @package Ingo
+ */
+class Sieve_Action_Keep extends Sieve_Action {
+
+ /**
+ * Returns a script snippet representing this rule and any sub-rules.
+ *
+ * @return string A Sieve script snippet.
+ */
+ function toCode()
+ {
+ return 'keep;';
+ }
+
+ /**
+ * Checks if the rule parameters are valid.
+ *
+ * @return boolean|string True if this rule is valid, an error message
+ * otherwise.
+ */
+ function check()
+ {
+ return true;
+ }
+
+}
+
+/**
+ * The Sieve_Action_Discard class represents a discard action.
+ *
+ * @author Mike Cochrane <mike@graftonhall.co.nz>
+ * @package Ingo
+ */
+class Sieve_Action_Discard extends Sieve_Action {
+
+ /**
+ * Returns a script snippet representing this rule and any sub-rules.
+ *
+ * @return string A Sieve script snippet.
+ */
+ function toCode()
+ {
+ return 'discard;';
+ }
+
+ /**
+ * Checks if the rule parameters are valid.
+ *
+ * @return boolean|string True if this rule is valid, an error message
+ * otherwise.
+ */
+ function check()
+ {
+ return true;
+ }
+
+}
+
+/**
+ * The Sieve_Action_Stop class represents a stop action.
+ *
+ * @author Mike Cochrane <mike@graftonhall.co.nz>
+ * @package Ingo
+ */
+class Sieve_Action_Stop extends Sieve_Action {
+
+ /**
+ * Returns a script snippet representing this rule and any sub-rules.
+ *
+ * @return string A Sieve script snippet.
+ */
+ function toCode()
+ {
+ return 'stop;';
+ }
+
+ /**
+ * Checks if the rule parameters are valid.
+ *
+ * @return boolean|string True if this rule is valid, an error message
+ * otherwise.
+ */
+ function check()
+ {
+ return true;
+ }
+
+}
+
+/**
+ * The Sieve_Action_Fileinto class represents a fileinto action.
+ *
+ * @author Mike Cochrane <mike@graftonhall.co.nz>
+ * @package Ingo
+ */
+class Sieve_Action_Fileinto extends Sieve_Action {
+
+ /**
+ * Constructor.
+ *
+ * @param array $vars Any required parameters.
+ */
+ function Sieve_Action_Fileinto($vars = array())
+ {
+ $this->_vars['folder'] = (isset($vars['folder'])) ? $vars['folder'] : '';
+ if (!empty($vars['utf8'])) {
+ $this->_vars['folder'] = String::convertCharset($this->_vars['folder'], 'UTF7-IMAP', 'UTF-8');
+ }
+ }
+
+ /**
+ * Returns a script snippet representing this rule and any sub-rules.
+ *
+ * @return string A Sieve script snippet.
+ */
+ function toCode()
+ {
+ return 'fileinto "' . Ingo_Script_Sieve::escapeString($this->_vars['folder']) . '";';
+ }
+
+ /**
+ * Checks if the rule parameters are valid.
+ *
+ * @return boolean|string True if this rule is valid, an error message
+ * otherwise.
+ */
+ function check()
+ {
+ if (empty($this->_vars['folder'])) {
+ return _("Inexistant mailbox specified for message delivery.");
+ }
+
+ return true;
+ }
+
+ /**
+ * Returns a list of sieve extensions required for this rule and any
+ * sub-rules.
+ *
+ * @return array A Sieve extension list.
+ */
+ function requires()
+ {
+ return array('fileinto');
+ }
+
+}
+
+/**
+ * The Sieve_Action_Vacation class represents a vacation action.
+ *
+ * @author Mike Cochrane <mike@graftonhall.co.nz>
+ * @package Ingo
+ */
+class Sieve_Action_Vacation extends Sieve_Action {
+
+ /**
+ * Constructor.
+ *
+ * @param array $vars Any required parameters.
+ */
+ function Sieve_Action_Vacation($vars = array())
+ {
+ $this->_vars['days'] = isset($vars['days']) ? intval($vars['days']) : '';
+ $this->_vars['addresses'] = isset($vars['addresses']) ? $vars['addresses'] : '';
+ $this->_vars['subject'] = isset($vars['subject']) ? $vars['subject'] : '';
+ $this->_vars['reason'] = isset($vars['reason']) ? $vars['reason'] : '';
+ $this->_vars['start'] = isset($vars['start']) ? $vars['start'] : '';
+ $this->_vars['start_year'] = isset($vars['start_year']) ? $vars['start_year'] : '';
+ $this->_vars['start_month'] = isset($vars['start_month']) ? $vars['start_month'] : '';
+ $this->_vars['start_day'] = isset($vars['start_day']) ? $vars['start_day'] : '';
+ $this->_vars['end'] = isset($vars['end']) ? $vars['end'] : '';
+ $this->_vars['end_year'] = isset($vars['end_year']) ? $vars['end_year'] : '';
+ $this->_vars['end_month'] = isset($vars['end_month']) ? $vars['end_month'] : '';
+ $this->_vars['end_day'] = isset($vars['end_day']) ? $vars['end_day'] : '';
+ }
+
+ /**
+ * Returns a script snippet representing this rule and any sub-rules.
+ *
+ * @return string A Sieve script snippet.
+ */
+ function toCode()
+ {
+ $start_year = $this->_vars['start_year'];
+ $start_month = $this->_vars['start_month'];
+ $start_day = $this->_vars['start_day'];
+
+ $end_year = $this->_vars['end_year'];
+ $end_month = $this->_vars['end_month'];
+ $end_day = $this->_vars['end_day'];
+
+ $code = '';
+
+ if (empty($this->_vars['start']) || empty($this->_vars['end'])) {
+ return $this->_vacationCode();
+ } elseif ($end_year > $start_year + 1) {
+ $code .= $this->_yearCheck($start_year + 1, $end_year - 1)
+ . $this->_vacationCode()
+ . "\n}\n"
+ . $this->_yearCheck($start_year, $start_year);
+ if ($start_month < 12) {
+ $code .= $this->_monthCheck($start_month + 1, 12)
+ . $this->_vacationCode()
+ . "\n}\n";
+ }
+ $code .= $this->_monthCheck($start_month, $start_month)
+ . $this->_dayCheck($start_day, 31)
+ . $this->_vacationCode()
+ . "\n}\n}\n}\n"
+ . $this->_yearCheck($end_year, $end_year);
+ if ($end_month > 1) {
+ $code .= $this->_monthCheck(1, $end_month - 1)
+ . $this->_vacationCode()
+ . "\n}\n";
+ }
+ $code .= $this->_monthCheck($end_month, $end_month)
+ . $this->_dayCheck(1, $end_day)
+ . $this->_vacationCode()
+ . "\n}\n}\n}\n";
+ } elseif ($end_year == $start_year + 1) {
+ $code .= $this->_yearCheck($start_year, $start_year);
+ if ($start_month < 12) {
+ $code .= $this->_monthCheck($start_month + 1, 12)
+ . $this->_vacationCode()
+ . "\n}\n";
+ }
+ $code .= $this->_monthCheck($start_month, $start_month)
+ . $this->_dayCheck($start_day, 31)
+ . $this->_vacationCode()
+ . "\n}\n}\n}\n"
+ . $this->_yearCheck($end_year, $end_year);
+ if ($end_month > 1) {
+ $code .= $this->_monthCheck(1, $end_month - 1)
+ . $this->_vacationCode()
+ . "\n}\n";
+ }
+ $code .= $this->_monthCheck($end_month, $end_month)
+ . $this->_dayCheck(1, $end_day)
+ . $this->_vacationCode()
+ . "\n}\n}\n}\n";
+ } elseif ($end_year == $start_year) {
+ $code .= $this->_yearCheck($start_year, $start_year);
+ if ($end_month > $start_month) {
+ if ($end_month > $start_month + 1) {
+ $code .= $this->_monthCheck($start_month + 1, $end_month - 1)
+ . $this->_vacationCode()
+ . "\n}\n";
+ }
+ $code .= $this->_monthCheck($start_month, $start_month)
+ . $this->_dayCheck($start_day, 31)
+ . $this->_vacationCode()
+ . "\n}\n}\n"
+ . $this->_monthCheck($end_month, $end_month)
+ . $this->_dayCheck(1, $end_day)
+ . $this->_vacationCode()
+ . "\n}\n}\n";
+ } elseif ($end_month == $start_month) {
+ $code .= $this->_monthCheck($start_month, $start_month)
+ . $this->_dayCheck($start_day, $end_day)
+ . $this->_vacationCode()
+ . "\n}\n}\n";
+ }
+ $code .= "}\n";
+ }
+
+ return $code;
+ }
+
+ /**
+ * Checks if the rule parameters are valid.
+ *
+ * @return boolean|string True if this rule is valid, an error message
+ * otherwise.
+ */
+ function check()
+ {
+ if (empty($this->_vars['reason'])) {
+ return _("Missing reason in vacation.");
+ }
+
+ return true;
+ }
+
+ /**
+ * Returns a list of sieve extensions required for this rule and any
+ * sub-rules.
+ *
+ * @return array A Sieve extension list.
+ */
+ function requires()
+ {
+ return array('vacation', 'regex');
+ }
+
+ /**
+ */
+ function _vacationCode()
+ {
+ $code = 'vacation :days ' . $this->_vars['days'] . ' ';
+ $addresses = $this->_vars['addresses'];
+ $stringlist = '';
+ if (count($addresses) > 1) {
+ foreach ($addresses as $address) {
+ $address = trim($address);
+ if (!empty($address)) {
+ $stringlist .= empty($stringlist) ? '"' : ', "';
+ $stringlist .= Ingo_Script_Sieve::escapeString($address) . '"';
+ }
+ }
+ $stringlist = "[" . $stringlist . "] ";
+ } elseif (count($addresses) == 1) {
+ $stringlist = '"' . Ingo_Script_Sieve::escapeString($addresses[0]) . '" ';
+ }
+
+ if (!empty($stringlist)) {
+ $code .= ':addresses ' . $stringlist;
+ }
+
+ if (!empty($this->_vars['subject'])) {
+ $code .= ':subject "' . Horde_Mime::encode(Ingo_Script_Sieve::escapeString($this->_vars['subject']), 'UTF-8') . '" ';
+ }
+ return $code
+ . '"' . Ingo_Script_Sieve::escapeString($this->_vars['reason'])
+ . '";';
+ }
+
+ /**
+ */
+ function _yearCheck($begin, $end)
+ {
+ $code = 'if header :regex "Received" "^.*(' . $begin;
+ for ($i = $begin + 1; $i <= $end; $i++) {
+ $code .= '|' . $i;
+ }
+ return $code
+ . ') (\\\\(.*\\\\) )?..:..:.. (\\\\(.*\\\\) )?((\\\\+|\\\\-)[[:digit:]]{4}|.{1,5})( \\\\(.*\\\\))?$" {'
+ . "\n ";
+ }
+
+ /**
+ */
+ function _monthCheck($begin, $end)
+ {
+ $months = array('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
+ 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec');
+ $code = 'if header :regex "Received" "^.*(' . $months[$begin - 1];
+ for ($i = $begin + 1; $i <= $end; $i++) {
+ $code .= '|' . $months[$i - 1];
+ }
+ return $code
+ . ') (\\\\(.*\\\\) )?.... (\\\\(.*\\\\) )?..:..:.. (\\\\(.*\\\\) )?((\\\\+|\\\\-)[[:digit:]]{4}|.{1,5})( \\\\(.*\\\\))?$" {'
+ . "\n ";
+ }
+
+ /**
+ */
+ function _dayCheck($begin, $end)
+ {
+ $code = 'if header :regex "Received" "^.*(' . str_repeat('[0 ]', 2 - strlen($begin)) . $begin;
+ for ($i = $begin + 1; $i <= $end; $i++) {
+ $code .= '|' . str_repeat('[0 ]', 2 - strlen($i)) . $i;
+ }
+ return $code
+ . ') (\\\\(.*\\\\) )?... (\\\\(.*\\\\) )?.... (\\\\(.*\\\\) )?..:..:.. (\\\\(.*\\\\) )?((\\\\+|\\\\-)[[:digit:]]{4}|.{1,5})( \\\\(.*\\\\))?$" {'
+ . "\n ";
+ }
+
+}
+
+/**
+ * The Sieve_Action_Flag class is the base class for flag actions.
+ *
+ * @author Michael Slusarz <slusarz@horde.org>
+ * @package Ingo
+ */
+class Sieve_Action_Flag extends Sieve_Action {
+
+ /**
+ * Constructor.
+ *
+ * @params array $vars Any required parameters.
+ */
+ function Sieve_Action_Flag($vars = array())
+ {
+ if (isset($vars['flags'])) {
+ if ($vars['flags'] & Ingo_Storage::FLAG_ANSWERED) {
+ $this->_vars['flags'][] = '\Answered';
+ }
+ if ($vars['flags'] & Ingo_Storage::FLAG_DELETED) {
+ $this->_vars['flags'][] = '\Deleted';
+ }
+ if ($vars['flags'] & Ingo_Storage::FLAG_FLAGGED) {
+ $this->_vars['flags'][] = '\Flagged';
+ }
+ if ($vars['flags'] & Ingo_Storage::FLAG_SEEN) {
+ $this->_vars['flags'][] = '\Seen';
+ }
+ } else {
+ $this->_vars['flags'] = '';
+ }
+ }
+
+ /**
+ * Returns a script snippet representing this rule and any sub-rules.
+ *
+ * @param string $mode The sieve flag command to use. Either 'removeflag'
+ * or 'addflag'.
+ *
+ * @return string A Sieve script snippet.
+ */
+ function _toCode($mode)
+ {
+ $code = '';
+
+ if (is_array($this->_vars['flags']) && !empty($this->_vars['flags'])) {
+ $code .= $mode . ' ';
+ if (count($this->_vars['flags']) > 1) {
+ $stringlist = '';
+ foreach ($this->_vars['flags'] as $flag) {
+ $flag = trim($flag);
+ if (!empty($flag)) {
+ $stringlist .= empty($stringlist) ? '"' : ', "';
+ $stringlist .= Ingo_Script_Sieve::escapeString($flag) . '"';
+ }
+ }
+ $stringlist = '[' . $stringlist . ']';
+ $code .= $stringlist . ';';
+ } else {
+ $code .= '"' . Ingo_Script_Sieve::escapeString($this->_vars['flags'][0]) . '";';
+ }
+ }
+ return $code;
+ }
+
+ /**
+ * Checks if the rule parameters are valid.
+ *
+ * @return boolean|string True if this rule is valid, an error message
+ * otherwise.
+ */
+ function check()
+ {
+ return true;
+ }
+
+ /**
+ * Returns a list of sieve extensions required for this rule and any
+ * sub-rules.
+ *
+ * @return array A Sieve extension list.
+ */
+ function requires()
+ {
+ return array('imapflags');
+ }
+
+}
+
+/**
+ * The Sieve_Action_Addflag class represents an add flag action.
+ *
+ * @author Mike Cochrane <mike@graftonhall.co.nz>
+ * @package Ingo
+ */
+class Sieve_Action_Addflag extends Sieve_Action_Flag {
+
+ /**
+ * Returns a script snippet representing this rule and any sub-rules.
+ *
+ * @return string A Sieve script snippet.
+ */
+ function toCode()
+ {
+ return $this->_toCode('addflag');
+ }
+
+}
+
+/**
+ * The Sieve_Action_Removeflag class represents a remove flag action.
+ *
+ * @author Mike Cochrane <mike@graftonhall.co.nz>
+ * @package Ingo
+ */
+class Sieve_Action_Removeflag extends Sieve_Action_Flag {
+
+ /**
+ * Returns a script snippet representing this rule and any sub-rules.
+ *
+ * @return string A Sieve script snippet.
+ */
+ function toCode()
+ {
+ return $this->_toCode('removeflag');
+ }
+
+}
+
+/**
+ * The Sieve_Action_Notify class represents a notify action.
+ *
+ * @author Paul Wolstenholme <wolstena@sfu.ca>
+ * @package Ingo
+ */
+class Sieve_Action_Notify extends Sieve_Action {
+
+ /**
+ * Constructor.
+ *
+ * @param array $vars Any required parameters.
+ */
+ function Sieve_Action_Notify($vars = array())
+ {
+ $this->_vars['address'] = isset($vars['address']) ? $vars['address'] : '';
+ $this->_vars['name'] = isset($vars['name']) ? $vars['name'] : '';
+ }
+
+ /**
+ * Returns a script snippet representing this rule and any sub-rules.
+ *
+ * @return string A Sieve script snippet.
+ */
+ function toCode()
+ {
+ return 'notify :method "mailto" :options "' .
+ Ingo_Script_Sieve::escapeString($this->_vars['address']) .
+ '" :message "' .
+ _("You have received a new message") . "\n" .
+ _("From:") . " \$from\$ \n" .
+ _("Subject:") . " \$subject\$ \n" .
+ _("Rule:") . ' ' . $this->_vars['name'] . '";';
+ }
+
+ /**
+ * Checks if the rule parameters are valid.
+ *
+ * @return boolean|string True if this rule is valid, an error message
+ * otherwise.
+ */
+ function check()
+ {
+ if (empty($this->_vars['address'])) {
+ return _("Missing address to notify");
+ }
+
+ return true;
+ }
+
+ /**
+ * Returns a list of sieve extensions required for this rule and any
+ * sub-rules.
+ *
+ * @return array A Sieve extension list.
+ */
+ function requires()
+ {
+ return array('notify');
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * The Ingo_Script_Sieve_Test:: class represents a Sieve Test.
+ *
+ * A test is a piece of code that evaluates to true or false.
+ *
+ * See the enclosed file LICENSE for license information (ASL). If you
+ * did not receive this file, see http://www.horde.org/licenses/asl.php.
+ *
+ * @author Mike Cochrane <mike@graftonhall.co.nz>
+ * @package Ingo
+ */
+class Ingo_Script_Sieve_Test
+{
+ /**
+ * Any necessary test parameters.
+ *
+ * @var array
+ */
+ protected $_vars = array();
+
+ /**
+ * Returns a script snippet representing this rule and any sub-rules.
+ *
+ * @return string A Sieve script snippet.
+ */
+ public function toCode()
+ {
+ return 'toCode() Function Not Implemented in class ' . get_class($this);
+ }
+
+ /**
+ * Checks if the rule parameters are valid.
+ *
+ * @return boolean|string True if this rule is valid, an error message
+ * otherwise.
+ */
+ public function check()
+ {
+ return 'check() Function Not Implemented in class ' . get_class($this);
+ }
+
+ /**
+ * Returns a list of sieve extensions required for this rule and any
+ * sub-rules.
+ *
+ * @return array A Sieve extension list.
+ */
+ public function requires()
+ {
+ return array();
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * The Ingo_Script_Sieve_Test_Address class represents a test on parts or all
+ * of the addresses in the given fields.
+ *
+ * See the enclosed file LICENSE for license information (ASL). If you
+ * did not receive this file, see http://www.horde.org/licenses/asl.php.
+ *
+ * @author Mike Cochrane <mike@graftonhall.co.nz>
+ * @package Ingo
+ */
+class Ingo_Script_Sieve_Test_Address extends Ingo_Script_Sieve_Test
+{
+ /**
+ * Constructor.
+ *
+ * @param array $vars Any required parameters.
+ */
+ public function __construct($vars)
+ {
+ $this->_vars['headers'] = isset($vars['headers'])
+ ? $vars['headers']
+ : '';
+ $this->_vars['comparator'] = isset($vars['comparator'])
+ ? $vars['comparator']
+ : 'i;ascii-casemap';
+ $this->_vars['match-type'] = isset($vars['match-type'])
+ ? $vars['match-type']
+ : ':is';
+ $this->_vars['address-part'] = isset($vars['address-part'])
+ ? $vars['address-part']
+ : ':all';
+ $this->_vars['addresses'] = isset($vars['addresses'])
+ ? $vars['addresses']
+ : '';
+ }
+
+ /**
+ * Checks if the rule parameters are valid.
+ *
+ * @return boolean|string True if this rule is valid, an error message
+ * otherwise.
+ */
+ public function check()
+ {
+ return preg_split('(\r\n|\n|\r)', $this->_vars['headers']) &&
+ preg_split('(\r\n|\n|\r)', $this->_vars['addresses']);
+ }
+
+ /**
+ * Returns a script snippet representing this rule and any sub-rules.
+ *
+ * @return string A Sieve script snippet.
+ */
+ public function toCode()
+ {
+ $code = 'address ' .
+ $this->_vars['address-part'] . ' ' .
+ ':comparator "' . $this->_vars['comparator'] . '" ' .
+ $this->_vars['match-type'] . ' ';
+
+ $headers = preg_split('(\r\n|\n|\r|,)', $this->_vars['headers']);
+ $headers = array_filter($headers);
+ if (count($headers) > 1) {
+ $code .= "[";
+ $headerstr = '';
+ foreach ($headers as $header) {
+ $header = trim($header);
+ if (!empty($header)) {
+ $headerstr .= empty($headerstr) ? '"' : ', "';
+ $headerstr .= Ingo_Script_Sieve::escapeString($header, $this->_vars['match-type'] == ':regex') . '"';
+ }
+ }
+ $code .= $headerstr . "] ";
+ } elseif (count($headers) == 1) {
+ $code .= '"' . Ingo_Script_Sieve::escapeString($headers[0], $this->_vars['match-type'] == ':regex') . '" ';
+ } else {
+ return "No Headers Specified";
+ }
+
+ $addresses = preg_split('(\r\n|\n|\r)', $this->_vars['addresses']);
+ $addresses = array_filter($addresses);
+ if (count($addresses) > 1) {
+ $code .= "[";
+ $addressstr = '';
+ foreach ($addresses as $addr) {
+ $addr = trim($addr);
+ if (!empty($addr)) {
+ $addressstr .= empty($addressstr) ? '"' : ', "';
+ $addressstr .= Ingo_Script_Sieve::escapeString($addr, $this->_vars['match-type'] == ':regex') . '"';
+ }
+ }
+ $code .= $addressstr . "] ";
+ } elseif (count($addresses) == 1) {
+ $code .= '"' . Ingo_Script_Sieve::escapeString($addresses[0], $this->_vars['match-type'] == ':regex') . '" ';
+ } else {
+ return "No Addresses Specified";
+ }
+
+ return $code;
+ }
+
+ /**
+ * Returns a list of sieve extensions required for this rule and any
+ * sub-rules.
+ *
+ * @return array A Sieve extension list.
+ */
+ public function requires()
+ {
+ return ($this->_vars['match-type'] == ':regex')
+ ? array('regex')
+ : array();
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * The Ingo_Script_Sieve_Test_Allof class represents a Allof test structure.
+ *
+ * Equivalent to a logical AND of all the tests it contains.
+ *
+ * See the enclosed file LICENSE for license information (ASL). If you
+ * did not receive this file, see http://www.horde.org/licenses/asl.php.
+ *
+ * @author Mike Cochrane <mike@graftonhall.co.nz>
+ * @package Ingo
+ */
+class Ingo_Script_Sieve_Test_Allof extends Ingo_Script_Sieve_Test
+{
+ /**
+ */
+ protected $_tests = array();
+
+ /**
+ * Constructor.
+ *
+ * @param mixed $test A Ingo_Script_Sieve_Test object or a list of
+ * Ingo_Script_Sieve_Test objects.
+ */
+ public function __construct($test = null)
+ {
+ if (is_array($test)) {
+ $this->_tests = $test;
+ } elseif (!is_null($test)) {
+ $this->_tests[] = $test;
+ }
+ }
+
+ /**
+ * Returns a script snippet representing this rule and any sub-rules.
+ *
+ * @return string A Sieve script snippet.
+ */
+ public function toCode()
+ {
+ $code = '';
+ if (count($this->_tests) > 1) {
+ $testlist = '';
+ foreach ($this->_tests as $test) {
+ $testlist .= (empty($testlist)) ? '' : ', ';
+ $testlist .= trim($test->toCode());
+ }
+
+ $code = "allof ( $testlist )";
+ } elseif (count($this->_tests) == 1) {
+ $code = $this->_tests[0]->toCode();
+ } else {
+ return 'true';
+ }
+ return $code;
+ }
+
+ /**
+ * Checks if all sub-rules are valid.
+ *
+ * @return boolean|string True if all rules are valid, an error message
+ * otherwise.
+ */
+ public function check()
+ {
+ foreach ($this->_tests as $test) {
+ $res = $test->check();
+ if ($res !== true) {
+ return $res;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ */
+ public function addTest($test)
+ {
+ $this->_tests[] = $test;
+ }
+
+ /**
+ */
+ public function getTests()
+ {
+ return $this->_tests;
+ }
+
+ /**
+ * Returns a list of sieve extensions required for this rule and any
+ * sub-rules.
+ *
+ * @return array A Sieve extension list.
+ */
+ public function requires()
+ {
+ $requires = array();
+
+ foreach ($this->_tests as $test) {
+ $requires = array_merge($requires, $test->requires());
+ }
+
+ return $requires;
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * The Ingo_Script_Sieve_Test_Anyof class represents an Anyof test structure.
+ *
+ * Equivalent to a logical OR of all the tests it contains.
+ *
+ * See the enclosed file LICENSE for license information (ASL). If you
+ * did not receive this file, see http://www.horde.org/licenses/asl.php.
+ *
+ * @author Mike Cochrane <mike@graftonhall.co.nz>
+ * @package Ingo
+ */
+class Ingo_Script_Sieve_Test_Anyof extends Ingo_Script_Sieve_Test
+{
+ protected $_tests = array();
+
+ /**
+ * Constructor.
+ *
+ * @param mixed $test An Ingo_Script_Sieve_Test object or a list of
+ * Ingo_Script_Sieve_Test objects.
+ */
+ public function __construct($test = null)
+ {
+ if (is_array($test)) {
+ $this->_tests = $test;
+ } elseif (!is_null($test)) {
+ $this->_tests[] = $test;
+ }
+ }
+
+ /**
+ * Returns a script snippet representing this rule and any sub-rules.
+ *
+ * @return string A Sieve script snippet.
+ */
+ public function toCode()
+ {
+ $testlist = '';
+ if (count($this->_tests) > 1) {
+ $testlist = '';
+ foreach ($this->_tests as $test) {
+ $testlist .= (empty($testlist)) ? '' : ', ';
+ $testlist .= trim($test->toCode());
+ }
+
+ $code = "anyof ( $testlist )";
+ } elseif (count($this->_tests) == 1) {
+ $code = $this->_tests[0]->toCode();
+ } else {
+ return 'true';
+ }
+ return $code;
+ }
+
+ /**
+ */
+ public function addTest($test)
+ {
+ $this->_tests[] = $test;
+ }
+
+ /**
+ */
+ public function getTests()
+ {
+ return $this->_tests;
+ }
+
+ /**
+ * Checks if all sub-rules are valid.
+ *
+ * @return boolean|string True if all rules are valid, an error message
+ * otherwise.
+ */
+ public function check()
+ {
+ foreach ($this->_tests as $test) {
+ $res = $test->check();
+ if ($res !== true) {
+ return $res;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Returns a list of sieve extensions required for this rule and any
+ * sub-rules.
+ *
+ * @return array A Sieve extension list.
+ */
+ public function requires()
+ {
+ $requires = array();
+
+ foreach ($this->_tests as $test) {
+ $requires = array_merge($requires, $test->requires());
+ }
+
+ return $requires;
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * The Ingo_Script_Sieve_Test_Body class represents a test on the contents of
+ * the body in a message.
+ *
+ * See the enclosed file LICENSE for license information (ASL). If you
+ * did not receive this file, see http://www.horde.org/licenses/asl.php.
+ *
+ * @author Michael Menge <michael.menge@zdv.uni-tuebingen.de>
+ * @package Ingo
+ */
+class Ingo_Script_Sieve_Test_Body extends Ingo_Script_Sieve_Test
+{
+ /**
+ * Constructor.
+ *
+ * @param array $vars Any required parameters.
+ */
+ public function __construct($vars = array())
+ {
+ $this->_vars['comparator'] = isset($vars['comparator'])
+ ? $vars['comparator']
+ : 'i;ascii-casemap';
+ $this->_vars['match-type'] = isset($vars['match-type'])
+ ? $vars['match-type']
+ : ':is';
+ $this->_vars['strings'] = isset($vars['strings'])
+ ? $vars['strings']
+ : '';
+ }
+
+ /**
+ * Checks if the rule parameters are valid.
+ *
+ * @return boolean|string True if this rule is valid, an error message
+ * otherwise.
+ */
+ public function check()
+ {
+ return preg_split('((?<!\\\)\,|\r\n|\n|\r)', $this->_vars['strings']);
+ }
+
+ /**
+ * Returns a script snippet representing this rule and any sub-rules.
+ *
+ * @return string A Sieve script snippet.
+ */
+ public function toCode()
+ {
+ $code = 'body ' .
+ ':comparator "' . $this->_vars['comparator'] . '" ' .
+ $this->_vars['match-type'] . ' ';
+
+ $strings = preg_split('(\r\n|\n|\r)', $this->_vars['strings']);
+ $strings = array_filter($strings);
+ if (count($strings) > 1) {
+ $code .= "[";
+ $stringlist = '';
+ foreach ($strings as $str) {
+ $stringlist .= empty($stringlist) ? '"' : ', "';
+ $stringlist .= Ingo_Script_Sieve::escapeString($str, $this->_vars['match-type'] == ':regex') . '"';
+ }
+ $code .= $stringlist . "] ";
+ } elseif (count($strings) == 1) {
+ $code .= '"' . Ingo_Script_Sieve::escapeString($strings[0], $this->_vars['match-type'] == ':regex') . '" ';
+ } else {
+ return _("No strings specified");
+ }
+
+ return $code;
+ }
+
+ /**
+ * Returns a list of sieve extensions required for this rule and any
+ * sub-rules.
+ *
+ * @return array A Sieve extension list.
+ */
+ public function requires()
+ {
+ return ($this->_vars['match-type'] == ':regex')
+ ? array('regex', 'body')
+ : array('body');
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * The Ingo_Script_Sieve_Test_Exists class represents a test for the
+ * existence of one or more headers in a message.
+ *
+ * See the enclosed file LICENSE for license information (ASL). If you
+ * did not receive this file, see http://www.horde.org/licenses/asl.php.
+ *
+ * @author Mike Cochrane <mike@graftonhall.co.nz>
+ * @package Ingo
+ */
+class Ingo_Script_Sieve_Test_Exists extends Ingo_Script_Sieve_Test
+{
+ /**
+ * Constructor.
+ *
+ * @param array $vars Any required parameters.
+ */
+ public function __construct($vars = array())
+ {
+ $this->_vars['headers'] = isset($vars['headers'])
+ ? $vars['headers']
+ : '';
+ }
+
+ /**
+ * Checks if the rule parameters are valid.
+ *
+ * @return boolean|string True if this rule is valid, an error message
+ * otherwise.
+ */
+ public function check()
+ {
+ return preg_split('(\r\n|\n|\r)', $this->_vars['headers'])
+ ? true
+ : _("No headers specified");
+ }
+
+ /**
+ * Returns a script snippet representing this rule and any sub-rules.
+ *
+ * @return string A Sieve script snippet.
+ */
+ public function toCode()
+ {
+ $code = 'exists ';
+ $headers = preg_split('(\r\n|\n|\r)', $this->_vars['headers']);
+ if (count($headers) > 1) {
+ $code .= "[";
+ $headerstr = '';
+ foreach ($headers as $header) {
+ $headerstr .= (empty($headerstr) ? '"' : ', "') .
+ Ingo_Script_Sieve::escapeString($header) . '"';
+ }
+ $code .= $headerstr . "] ";
+ } elseif (count($headers) == 1) {
+ $code .= '"' . Ingo_Script_Sieve::escapeString($headers[0]) . '" ';
+ } else {
+ return "**error** No Headers Specified";
+ }
+
+ return $code;
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * The Ingo_Script_Sieve_Test_False class represents a test that always
+ * evaluates to false.
+ *
+ * See the enclosed file LICENSE for license information (ASL). If you
+ * did not receive this file, see http://www.horde.org/licenses/asl.php.
+ *
+ * @author Mike Cochrane <mike@graftonhall.co.nz>
+ * @package Ingo
+ */
+class Ingo_Script_Sieve_Test_False extends Ingo_Script_Sieve_Test
+{
+ /**
+ * Returns a script snippet representing this rule and any sub-rules.
+ *
+ * @return string A Sieve script snippet.
+ */
+ public function toCode()
+ {
+ return 'false';
+ }
+
+ /**
+ * Checks if the rule parameters are valid.
+ *
+ * @return boolean|string True if this rule is valid, an error message
+ * otherwise.
+ */
+ public function check()
+ {
+ return true;
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * The Ingo_Script_Sieve_Test_Header class represents a test on the contents
+ * of one or more headers in a message.
+ *
+ * See the enclosed file LICENSE for license information (ASL). If you
+ * did not receive this file, see http://www.horde.org/licenses/asl.php.
+ *
+ * @author Mike Cochrane <mike@graftonhall.co.nz>
+ * @package Ingo
+ */
+class Ingo_Script_Sieve_Test_Header extends Ingo_Script_Sieve_Test
+{
+ /**
+ * Constructor.
+ *
+ * @param array $vars Any required parameters.
+ */
+ public function __construct($vars = array())
+ {
+ $this->_vars['headers'] = isset($vars['headers'])
+ ? $vars['headers']
+ : 'Subject';
+ $this->_vars['comparator'] = isset($vars['comparator'])
+ ? $vars['comparator']
+ : 'i;ascii-casemap';
+ $this->_vars['match-type'] = isset($vars['match-type'])
+ ? $vars['match-type']
+ : ':is';
+ $this->_vars['strings'] = isset($vars['strings'])
+ ? $vars['strings']
+ : '';
+ }
+
+ /**
+ * Checks if the rule parameters are valid.
+ *
+ * @return boolean|string True if this rule is valid, an error message
+ * otherwise.
+ */
+ public function check()
+ {
+ return preg_split('((?<!\\\)\,|\r\n|\n|\r)', $this->_vars['headers']) &&
+ preg_split('((?<!\\\)\,|\r\n|\n|\r)', $this->_vars['strings']);
+ }
+
+ /**
+ * Returns a script snippet representing this rule and any sub-rules.
+ *
+ * @return string A Sieve script snippet.
+ */
+ public function toCode()
+ {
+ $code = 'header ' .
+ ':comparator "' . $this->_vars['comparator'] . '" ' .
+ $this->_vars['match-type'] . ' ';
+
+ $headers = preg_split('(\r\n|\n|\r)', $this->_vars['headers']);
+ $headers = array_filter($headers);
+ if (count($headers) > 1) {
+ $code .= "[";
+ $headerstr = '';
+ foreach ($headers as $header) {
+ $headerstr .= empty($headerstr) ? '"' : ', "';
+ $headerstr .= Ingo_Script_Sieve::escapeString($header, $this->_vars['match-type'] == ':regex') . '"';
+ }
+ $code .= $headerstr . "] ";
+ } elseif (count($headers) == 1) {
+ $code .= '"' . $headers[0] . '" ';
+ } else {
+ return _("No headers specified");
+ }
+
+ $strings = preg_split('(\r\n|\n|\r)', $this->_vars['strings']);
+ $strings = array_filter($strings);
+ if (count($strings) > 1) {
+ $code .= "[";
+ $stringlist = '';
+ foreach ($strings as $str) {
+ $stringlist .= empty($stringlist) ? '"' : ', "';
+ $stringlist .= Ingo_Script_Sieve::escapeString($str, $this->_vars['match-type'] == ':regex') . '"';
+ }
+ $code .= $stringlist . "] ";
+ } elseif (count($strings) == 1) {
+ $code .= '"' . Ingo_Script_Sieve::escapeString(reset($strings), $this->_vars['match-type'] == ':regex') . '" ';
+ } else {
+ return _("No strings specified");
+ }
+
+ return $code;
+ }
+
+ /**
+ * Returns a list of sieve extensions required for this rule and any
+ * sub-rules.
+ *
+ * @return array A Sieve extension list.
+ */
+ public function requires()
+ {
+ return ($this->_vars['match-type'] == ':regex')
+ ? array('regex')
+ : array();
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * The Ingo_Script_Sieve_Test_Not class represents the inverse of a given
+ * test.
+ *
+ * See the enclosed file LICENSE for license information (ASL). If you
+ * did not receive this file, see http://www.horde.org/licenses/asl.php.
+ *
+ * @author Mike Cochrane <mike@graftonhall.co.nz>
+ * @package Ingo
+ */
+class Ingo_Script_Sieve_Test_Not extends Ingo_Script_Sieve_Test
+{
+ /**
+ */
+ protected $_test = array();
+
+ /**
+ * Constructor.
+ *
+ * @param Ingo_Script_Sieve_Test $test An Ingo_Script_Sieve_Test object.
+ */
+ public function __construct($test)
+ {
+ $this->_test = $test;
+ }
+
+ /**
+ * Checks if the sub-rule is valid.
+ *
+ * @return boolean|string True if this rule is valid, an error message
+ * otherwise.
+ */
+ public function check()
+ {
+ return $this->_test->check();
+ }
+
+ /**
+ * Returns a script snippet representing this rule and any sub-rules.
+ *
+ * @return string A Sieve script snippet.
+ */
+ public function toCode()
+ {
+ return 'not ' . $this->_test->toCode();
+ }
+
+ /**
+ * Returns a list of sieve extensions required for this rule and any
+ * sub-rules.
+ *
+ * @return array A Sieve extension list.
+ */
+ public function requires()
+ {
+ return $this->_test->requires();
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * The Ingo_Script_Sieve_Test_Relational class represents a relational test.
+ *
+ * See the enclosed file LICENSE for license information (ASL). If you
+ * did not receive this file, see http://www.horde.org/licenses/asl.php.
+ *
+ * @author Todd Merritt <tmerritt@email.arizona.edu>
+ * @package Ingo
+ */
+class Ingo_Script_Sieve_Test_Relational extends Ingo_Script_Sieve_Test
+{
+ /**
+ * Constructor.
+ *
+ * @param array $vars Any required parameters.
+ */
+ public function __construct($vars = array())
+ {
+ $this->_vars['comparison'] = isset($vars['comparison'])
+ ? $vars['comparison']
+ : '';
+ $this->_vars['headers'] = isset($vars['headers'])
+ ? $vars['headers']
+ : '';
+ $this->_vars['value'] = isset($vars['value'])
+ ? $vars['value']
+ : 0;
+ }
+
+ /**
+ * Returns a script snippet representing this rule and any sub-rules.
+ *
+ * @return string A Sieve script snippet.
+ */
+ public function toCode()
+ {
+ $code = 'header :value "' .
+ $this->_vars['comparison'] . '" ' .
+ ':comparator "i;ascii-numeric" ';
+
+ $headers = preg_split('(\r\n|\n|\r)', $this->_vars['headers']);
+ $header_count = count($headers);
+
+ if ($header_count > 1) {
+ $code .= "[";
+ $headerstr = '';
+
+ foreach ($headers as $val) {
+ $headerstr .= (empty($headerstr) ? '"' : ', "') .
+ Ingo_Script_Sieve::escapeString($val) . '"';
+ }
+
+ $code .= $headerstr . '] ';
+ $headerstr = '[' . $headerstr . ']';
+ } elseif ($header_count == 1) {
+ $code .= '"' . Ingo_Script_Sieve::escapeString($headers[0]) . '" ';
+ $headerstr = Ingo_Script_Sieve::escapeString($headers[0]);
+ }
+
+ $code .= '["' . $this->_vars['value'] . '"]';
+
+ // Add workarounds for negative numbers - works only if the comparison
+ // value is positive. Sieve doesn't support comparisons of negative
+ // numbers at all so this is the best we can do.
+ switch ($this->_vars['comparison']) {
+ case 'gt':
+ case 'ge':
+ case 'eq':
+ // Greater than, greater or equal, equal: number must be
+ // non-negative.
+ return 'allof ( not header :comparator "i;ascii-casemap" :contains "'
+ . $headerstr . '" "-", ' . $code . ' )';
+
+ case 'lt':
+ case 'le':
+ case 'ne':
+ // Less than, less or equal, nonequal: also match negative numbers
+ return 'anyof ( header :comparator "i;ascii-casemap" :contains "'
+ . $headerstr . '" "-", ' . $code . ' )';
+ }
+ }
+
+ /**
+ * Checks if the rule parameters are valid.
+ *
+ * @return boolean|string True if this rule is valid, an error message
+ * otherwise.
+ */
+ public function check()
+ {
+ $headers = preg_split('(\r\n|\n|\r)', $this->_vars['headers']);
+ return $headers ? true : _("No headers specified");
+ }
+
+ /**
+ * Returns a list of sieve extensions required for this rule and any
+ * sub-rules.
+ *
+ * @return array A Sieve extension list.
+ */
+ public function requires()
+ {
+ return array('relational', 'comparator-i;ascii-numeric');
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * The Ingo_Script_Sieve_Test_Size class represents a message size test.
+ *
+ * See the enclosed file LICENSE for license information (ASL). If you
+ * did not receive this file, see http://www.horde.org/licenses/asl.php.
+ *
+ * @author Mike Cochrane <mike@graftonhall.co.nz>
+ * @package Ingo
+ */
+class Ingo_Script_Sieve_Test_Size extends Ingo_Script_Sieve_Test
+{
+ /**
+ * Constructor.
+ *
+ * @param array $vars Any required parameters.
+ */
+ public function __construct($vars = array())
+ {
+ $this->_vars['comparison'] = isset($vars['comparison'])
+ ? $vars['comparison']
+ : '';
+ $this->_vars['size'] = isset($vars['size'])
+ ? $vars['size']
+ : '';
+ }
+
+ /**
+ * Returns a script snippet representing this rule and any sub-rules.
+ *
+ * @return string A Sieve script snippet.
+ */
+ public function toCode()
+ {
+ return 'size ' . $this->_vars['comparison'] . ' ' . $this->_vars['size'];
+ }
+
+ /**
+ * Checks if the rule parameters are valid.
+ *
+ * @return boolean|string True if this rule is valid, an error message
+ * otherwise.
+ */
+ public function check()
+ {
+ if (!(isset($this->_vars['comparison']) &&
+ isset($this->_vars['size']))) {
+ return false;
+ }
+
+ return true;
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * The Ingo_Script_Sieve_Test_True class represents a test that always
+ * evaluates to true.
+ *
+ * See the enclosed file LICENSE for license information (ASL). If you
+ * did not receive this file, see http://www.horde.org/licenses/asl.php.
+ *
+ * @author Mike Cochrane <mike@graftonhall.co.nz>
+ * @package Ingo
+ */
+class Ingo_Script_Sieve_Test_True extends Ingo_Script_Sieve_Test
+{
+ /**
+ * Returns a script snippet representing this rule and any sub-rules.
+ *
+ * @return string A Sieve script snippet.
+ */
+ public function toCode()
+ {
+ return 'true';
+ }
+
+ /**
+ * Checks if the rule parameters are valid.
+ *
+ * @return boolean|string True if this rule is valid, an error message
+ * otherwise.
+ */
+ public function check()
+ {
+ return true;
+ }
+
+}
+++ /dev/null
-<?php
-/**
- * Functions required to start a Ingo session.
- *
- * Copyright 2004-2010 The Horde Project (http://www.horde.org/)
- *
- * See the enclosed file LICENSE for license information (ASL). If you
- * did not receive this file, see http://www.horde.org/licenses/asl.php.
- *
- * @author Michael Slusarz <slusarz@horde.org>
- * @package Ingo
- */
-class Ingo_Session
-{
- /**
- * Create an ingo session.
- * This function should only be called once, when the user first uses
- * Ingo in a session.
- *
- * Creates the $ingo session variable with the following entries:
- * 'backend' (array) - The backend configuration to use.
- * 'change' (integer) - The timestamp of the last time the rules were
- * altered.
- * 'storage' (array) - Used by Ingo_Storage:: for caching data.
- * 'script_categories' (array) - The list of available categories for the
- * Ingo_Script driver in use.
- * 'script_generate' (boolean) - Is the Ingo_Script::generate() call
- * available?
- *
- * @return boolean True on success, false on failure.
- */
- static public function createSession()
- {
- global $prefs;
-
- $_SESSION['ingo'] = array(
- 'change' => 0,
- 'storage' => array(),
- /* Get the backend. */
- 'backend' => Ingo::getBackend());
-
- /* Determine if the Ingo_Script:: generate() method is available. */
- $ingo_script = Ingo::loadIngoScript();
- $_SESSION['ingo']['script_generate'] = $ingo_script->generateAvailable();
-
- /* Disable categories as specified in preferences */
- $disabled = array();
- if ($prefs->isLocked('blacklist')) {
- $disabled[] = Ingo_Storage::ACTION_BLACKLIST;
- }
- if ($prefs->isLocked('whitelist')) {
- $disabled[] = Ingo_Storage::ACTION_WHITELIST;
- }
- if ($prefs->isLocked('vacation')) {
- $disabled[] = Ingo_Storage::ACTION_VACATION;
- }
- if ($prefs->isLocked('forward')) {
- $disabled[] = Ingo_Storage::ACTION_FORWARD;
- }
- if ($prefs->isLocked('spam')) {
- $disabled[] = Ingo_Storage::ACTION_SPAM;
- }
-
- /* Set the list of categories this driver supports. */
- $_SESSION['ingo']['script_categories'] =
- array_merge($ingo_script->availableActions(),
- array_diff($ingo_script->availableCategories(),
- $disabled));
- }
-
-}
* @param boolean $readonly Whether to disable any write operations.
*
* @return Ingo_Storage_Rule|Ingo_Storage_Filters The specified object.
+ * @throws Ingo_Exception
*/
public function retrieve($field, $cache = true, $readonly = false)
{
/**
* Retrieves the specified data from the storage backend.
*
- * @abstract
- *
* @param integer $field The field name of the desired data.
* See lib/Storage.php for the available fields.
* @param boolean $readonly Whether to disable any write operations.
* @param boolean $cache Cache the object?
*
* @return boolean True on success.
+ * @throws Ingo_Exception
*/
public function store(&$ob, $cache = true)
{
break;
}
$filters->addRule(array('action' => $type, 'name' => $name));
- $result = $this->store($filters, $cache);
- if (is_a($result, 'PEAR_Error')) {
- return $result;
- }
+ $this->store($filters, $cache);
}
}
/**
* Stores the specified data in the storage backend.
*
- * @abstract
- *
* @param Ingo_Storage_Rule|Ingo_Storage_Filters $ob The object to store.
*
* @return boolean True on success.
* Removes the user data from the storage backend.
* Stub for child class to override if it can implement.
*
- * @param string $user The user name to delete filters for.
+ * @param string $user The user name to delete filters for.
*
- * @return mixed True | PEAR_Error
+ * @throws Ingo_Exception
*/
- function removeUserData($user)
+ public function removeUserData($user)
{
- return PEAR::raiseError(_("Removing user data is not supported with the current filter storage backend."));
+ throw new Ingo_Exception(_("Removing user data is not supported with the current filter storage backend."));
}
}
* @param mixed $data The list of addresses (array or string).
* @param boolean $sort Sort the list?
*
- * @return mixed PEAR_Error on error, true on success.
+ * @return boolean True on success.
+ * @throws Ingo_Exception
*/
public function setBlacklist($data, $sort = true)
{
if (!empty($GLOBALS['conf']['storage']['maxblacklist'])) {
$addr_count = count($addr);
if ($addr_count > $GLOBALS['conf']['storage']['maxblacklist']) {
- return PEAR::raiseError(sprintf(_("Maximum number of blacklisted addresses exceeded (Total addresses: %s, Maximum addresses: %s). Could not add new addresses to blacklist."), $addr_count, $GLOBALS['conf']['storage']['maxblacklist']), 'horde.error');
+ throw new Ingo_Exception(sprintf(_("Maximum number of blacklisted addresses exceeded (Total addresses: %s, Maximum addresses: %s). Could not add new addresses to blacklist."), $addr_count, $GLOBALS['conf']['storage']['maxblacklist']), 'horde.error');
}
}
return true;
}
+ /**
+ */
public function setBlacklistFolder($data)
{
$this->_folder = $data;
}
+ /**
+ */
public function getBlacklist()
{
return empty($this->_addr)
: array_filter($this->_addr, array('Ingo', 'filterEmptyAddress'));
}
+ /**
+ */
public function getBlacklistFolder()
{
return $this->_folder;
*/
class Ingo_Storage_Forward extends Ingo_Storage_Rule
{
+ /**
+ */
protected $_addr = array();
+
+ /**
+ */
protected $_keep = true;
+
+ /**
+ */
protected $_obtype = Ingo_Storage::ACTION_FORWARD;
+ /**
+ */
public function setForwardAddresses($data, $sort = true)
{
$this->_addr = $this->_addressList($data, $sort);
}
+ /**
+ */
public function setForwardKeep($data)
{
$this->_keep = $data;
}
+ /**
+ */
public function getForwardAddresses()
{
if (is_array($this->_addr)) {
return $this->_addr;
}
+ /**
+ */
public function getForwardKeep()
{
return $this->_keep;
class Ingo_Storage_Mock extends Ingo_Storage
{
+ /**
+ */
protected $_data = array();
+ /**
+ */
protected function _retrieve($field)
{
if (empty($this->_data[$field])) {
return $this->_data[$field];
}
+ /**
+ */
protected function _store(&$ob)
{
$this->_data[$ob->obType()] = $ob;
$output = (empty($data)) ? array() : preg_split("/\s+/", $data);
}
- if ($sort) {
- $output = Horde_Array::prepareAddressList($output);
- }
-
- return $output;
+ return $sort
+ ? Horde_Array::prepareAddressList($output)
+ : $output;
}
}
*/
protected $_obtype = Ingo_Storage::ACTION_SPAM;
+ /**
+ */
protected $_folder = null;
+
+ /**
+ */
protected $_level = 5;
+ /**
+ */
public function setSpamFolder($folder)
{
$this->_folder = $folder;
}
+ /**
+ */
public function setSpamLevel($level)
{
$this->_level = $level;
}
+ /**
+ */
public function getSpamFolder()
{
return $this->_folder;
}
+ /**
+ */
public function getSpamLevel()
{
return $this->_level;
case self::ACTION_WHITELIST:
if ($field == self::ACTION_BLACKLIST) {
$ob = new Ingo_Storage_Blacklist();
- $filters = &$this->retrieve(self::ACTION_FILTERS);
- if (is_a($filters, 'PEAR_Error')) {
- return $filters;
- }
+ $filters = $this->retrieve(self::ACTION_FILTERS);
$rule = $filters->findRule($field);
if (isset($rule['action-value'])) {
$ob->setBlacklistFolder($rule['action-value']);
case self::ACTION_WHITELIST:
$is_blacklist = (int)($ob->obType() == self::ACTION_BLACKLIST);
if ($is_blacklist) {
- $filters = &$this->retrieve(self::ACTION_FILTERS);
- if (is_a($filters, 'PEAR_Error')) {
- return $filters;
- }
+ $filters = $this->retrieve(self::ACTION_FILTERS);
$id = $filters->findRuleId(self::ACTION_BLACKLIST);
if ($id !== null) {
$rule = $filters->getRule($id);
*
* @param string $user The user name to delete filters for.
*
- * @return mixed True | PEAR_Error
+ * @throws Ingo_Exception
*/
- function removeUserData($user)
+ public function removeUserData($user)
{
if (!Horde_Auth::isAdmin() && $user != Horde_Auth::getAuth()) {
- return PEAR::raiseError(_("Permission Denied"));
+ throw new Ingo_Exception(_("Permission Denied"));
}
$queries = array(sprintf('DELETE FROM %s WHERE rule_owner = ?',
foreach ($queries as $query) {
Horde::logMessage('Ingo_Storage_sql::removeUserData(): ' . $query, __FILE__, __LINE__, PEAR_LOG_DEBUG);
$result = $this->_write_db->query($query, $values);
- if (is_a($result, 'PEAR_Error')) {
- return $result;
+ if ($result instanceof PEAR_Error) {
+ throw new Ingo_Exception($result);
}
}
*/
class Ingo_Storage_Vacation extends Ingo_Storage_Rule
{
+
+ /**
+ */
protected $_addr = array();
+
+ /**
+ */
protected $_days = 7;
+
+ /**
+ */
protected $_excludes = array();
+
+ /**
+ */
protected $_ignorelist = true;
+
+ /**
+ */
protected $_reason = '';
+
+ /**
+ */
protected $_subject = '';
+
+ /**
+ */
protected $_start;
+
+ /**
+ */
protected $_end;
+
+ /**
+ */
protected $_obtype = Ingo_Storage::ACTION_VACATION;
+ /**
+ */
public function setVacationAddresses($data, $sort = true)
{
$this->_addr = $this->_addressList($data, $sort);
}
+ /**
+ */
public function setVacationDays($data)
{
$this->_days = $data;
}
+ /**
+ */
public function setVacationExcludes($data, $sort = true)
{
$this->_excludes = $this->_addressList($data, $sort);
}
+ /**
+ */
public function setVacationIgnorelist($data)
{
$this->_ignorelist = $data;
}
+ /**
+ */
public function setVacationReason($data)
{
$this->_reason = $data;
}
+ /**
+ */
public function setVacationSubject($data)
{
$this->_subject = $data;
}
+ /**
+ */
public function setVacationStart($data)
{
$this->_start = $data;
}
+ /**
+ */
public function setVacationEnd($data)
{
$this->_end = $data;
}
+ /**
+ */
public function getVacationAddresses()
{
try {
}
}
+ /**
+ */
public function getVacationDays()
{
return $this->_days;
}
+ /**
+ */
public function getVacationExcludes()
{
return $this->_excludes;
}
+ /**
+ */
public function getVacationIgnorelist()
{
return $this->_ignorelist;
}
+ /**
+ */
public function getVacationReason()
{
return $this->_reason;
}
+ /**
+ */
public function getVacationSubject()
{
return $this->_subject;
}
+ /**
+ */
public function getVacationStart()
{
return $this->_start;
}
+ /**
+ */
public function getVacationStartYear()
{
return date('Y', $this->_start);
}
+ /**
+ */
public function getVacationStartMonth()
{
return date('n', $this->_start);
}
+ /**
+ */
public function getVacationStartDay()
{
return date('j', $this->_start);
}
+ /**
+ */
public function getVacationEnd()
{
return $this->_end;
}
+ /**
+ */
public function getVacationEndYear()
{
return date('Y', $this->_end);
}
+ /**
+ */
public function getVacationEndMonth()
{
return date('n', $this->_end);
}
+ /**
+ */
public function getVacationEndDay()
{
return date('j', $this->_end);
*/
class Ingo_Storage_VacationTest extends Ingo_Storage_Vacation
{
+ /**
+ */
public function getVacationAddresses()
{
return $this->_addr;
}
+
}
*/
class Ingo_Storage_Whitelist extends Ingo_Storage_Rule
{
+ /**
+ */
protected $_addr = array();
+
+ /**
+ */
protected $_obtype = Ingo_Storage::ACTION_WHITELIST;
/**
* @param mixed $data The list of addresses (array or string).
* @param boolean $sort Sort the list?
*
- * @return mixed PEAR_Error on error, true on success.
+ * @return boolean True on success.
+ * @throws Ingo_Exception
*/
public function setWhitelist($data, $sort = true)
{
if (!empty($GLOBALS['conf']['storage']['maxwhitelist'])) {
$addr_count = count($addr);
if ($addr_count > $GLOBALS['conf']['storage']['maxwhitelist']) {
- return PEAR::raiseError(sprintf(_("Maximum number of whitelisted addresses exceeded (Total addresses: %s, Maximum addresses: %s). Could not add new addresses to whitelist."), $addr_count, $GLOBALS['conf']['storage']['maxwhitelist']), 'horde.error');
+ throw new Ingo_Exception(sprintf(_("Maximum number of whitelisted addresses exceeded (Total addresses: %s, Maximum addresses: %s). Could not add new addresses to whitelist."), $addr_count, $GLOBALS['conf']['storage']['maxwhitelist']), 'horde.error');
}
}
return true;
}
+ /**
+ */
public function getWhitelist()
{
return empty($this->_addr)
require INGO_BASE . '/config/fields.php';
/* Get the current rules. */
-$filters = &$ingo_storage->retrieve(Ingo_Storage::ACTION_FILTERS);
+$filters = $ingo_storage->retrieve(Ingo_Storage::ACTION_FILTERS);
/* Run through action handlers. */
-$actionID = Horde_Util::getFormData('actionID');
-$edit_number = Horde_Util::getFormData('edit');
-switch ($actionID) {
+$vars = Horde_Variables::getDefaultVariables();
+switch ($vars->actionID) {
case 'create_folder':
case 'rule_save':
case 'rule_update':
}
$rule = array(
- 'id' => Horde_Util::getFormData('id'),
- 'name' => Horde_Util::getFormData('name'),
- 'combine' => Horde_Util::getFormData('combine'),
+ 'id' => $vars->id,
+ 'name' => $vars->name,
+ 'combine' => $vars->combine,
'conditions' => array()
);
- $field = Horde_Util::getFormData('field');
- $match = Horde_Util::getFormData('match');
- $userheader = Horde_Util::getFormData('userheader');
- $value = Horde_Util::getFormData('value');
if ($ingo_script->caseSensitive()) {
- $casesensitive = Horde_Util::getFormData('case');
+ $casesensitive = $vars->case;
}
$valid = true;
- foreach ($field as $key => $val) {
+ foreach ($vars->field as $key => $val) {
if (!empty($val)) {
$condition = array();
if ($val == Ingo::USER_HEADER) {
- $condition['field'] = (empty($userheader[$key])) ? '' : $userheader[$key];
+ $condition['field'] = empty($vars->userheader[$key])
+ ? ''
+ : $vars->userheader[$key];
$condition['type'] = Ingo_Storage::TYPE_HEADER;
} elseif (!isset($ingo_fields[$val])) {
$condition['field'] = $val;
$condition['field'] = $val;
$condition['type'] = $ingo_fields[$val]['type'];
}
- $condition['match'] = isset($match[$key]) ? $match[$key] : '';
+ $condition['match'] = isset($vars->match[$key])
+ ? $vars->match[$key]
+ : '';
- if ($actionID == 'rule_save'
- && empty($value[$key])
- && $condition['match'] != 'exists'
- && $condition['match'] != 'not exist') {
+ if (($vars->actionID == 'rule_save') &&
+ empty($vars->value[$key]) &&
+ !in_array($condition['match'], array('exists', 'not exist'))) {
$notification->push(sprintf(_("You cannot create empty conditions. Please fill in a value for \"%s\"."), $condition['field']), 'horde.error');
$valid = false;
}
- $condition['value'] = isset($value[$key]) ? $value[$key] : '';
+ $condition['value'] = isset($vars->value[$key])
+ ? $vars->value[$key]
+ : '';
if (isset($casesensitive)) {
- $condition['case'] = isset($casesensitive[$key]) ? $casesensitive[$key] : '';
+ $condition['case'] = isset($casesensitive[$key])
+ ? $casesensitive[$key]
+ : '';
}
$rule['conditions'][] = $condition;
}
}
- if ($actionID == 'create_folder') {
- $rule['action-value'] = Ingo::createFolder(Horde_Util::getFormData('new_folder_name'));
- } else {
- $rule['action-value'] = Horde_Util::getFormData('actionvalue');
- }
+ $rule['action-value'] = ($vars->actionID == 'create_folder')
+ ? Ingo::createFolder($vars->new_folder_name)
+ : $vars->actionvalue;
- $rule['action'] = Horde_Util::getFormData('action');
- $rule['stop'] = Horde_Util::getFormData('stop');
+ $rule['action'] = $vars->action;
+ $rule['stop'] = $vars->stop;
$rule['flags'] = 0;
- $flags = Horde_Util::getFormData('flags', array());
+ $flags = $vars->flags || array();
if (!empty($flags)) {
foreach ($flags as $val) {
$rule['flags'] |= $val;
$_SESSION['ingo']['change'] = time();
/* Save the rule. */
- if ($actionID == 'rule_save' && $valid) {
- if (is_null($edit_number)) {
+ if ($vars->actionID == 'rule_save' && $valid) {
+ if (!isset($vars->edit)) {
if ($GLOBALS['perms']->hasAppPermission('max_rules') !== true &&
$GLOBALS['perms']->hasAppPermission('max_rules') <= count($filters->getFilterList())) {
header('Location: ' . Horde::applicationUrl('filters.php', true));
}
$filters->addRule($rule);
} else {
- $filters->updateRule($rule, $edit_number);
+ $filters->updateRule($rule, $vars->edit);
}
$ingo_storage->store($filters);
$notification->push(_("Changes saved."), 'horde.success');
header('Location: ' . Horde::applicationUrl('filters.php'));
exit;
- } elseif ($actionID == 'rule_delete') {
+ }
+
+ if ($vars->actionID == 'rule_delete') {
if (!Ingo::hasSharePermission(Horde_Perms::DELETE)) {
$notification->push(_("You do not have permission to delete filter rules."), 'horde.error');
header('Location: ' . Horde::applicationUrl('filters.php', true));
exit;
}
- $cond_num = Horde_Util::getFormData('conditionnumber');
- if (!is_null($cond_num)) {
- unset($rule['conditions'][$cond_num]);
+ if (isset($vars->conditionnumber)) {
+ unset($rule['conditions'][$vars->conditionnumner]);
$rule['conditions'] = array_values($rule['conditions']);
}
}
header('Location: ' . Horde::applicationUrl('filters.php', true));
exit;
}
- if (is_null($edit_number)) {
+ if (!isset($vars->edit)) {
if ($GLOBALS['perms']->hasAppPermission('max_rules') !== true &&
$GLOBALS['perms']->hasAppPermission('max_rules') <= count($filters->getFilterList())) {
try {
}
$rule = $filters->getDefaultRule();
} else {
- $rule = $filters->getRule($edit_number);
+ $rule = $filters->getRule($vars->edit);
}
break;
}
'<option value="' . Ingo::USER_HEADER . '"' . ((!$option_selected) ? ' selected="selected"' : '') . '>' . _("Self-Defined Header") . (($lastfield) ? '' : ':') . "</option>\n";
if (!$option_selected) {
$header_entry = true;
- $userheader = Horde_Util::getFormData('userheader');
- if (empty($userheader)) {
- $userheader = isset($condition['field']) ? $condition['field'] : '';
+ if (empty($vars->userheader)) {
+ $vars->userheader = isset($condition['field']) ? $condition['field'] : '';
} else {
- $userheader = $userheader[$cond_num];
+ $vars->userheader = $vars->userheader[$cond_num];
}
}
}
/* Get the Ingo_Script:: backend. */
$scriptor = Ingo::loadIngoScript();
-if ($scriptor) {
- /* Generate the script. */
- $script = $scriptor->generate();
-}
+
+/* Generate the script. */
+$script = $scriptor->generate();
/* Activate/deactivate script if requested.
activateScript() does its own $notification->push() on error. */
break;
case 'show_active':
- $script = Ingo::getScript();
- if (is_a($script, 'PEAR_Error')) {
- $notification->push($script, 'horde.error');
+ try {
+ $script = Ingo::getScript();
+ } catch (Ingo_Exception $e) {
+ $notification->push($e);
$script = '';
}
break;
// Retrieve the data.
$GLOBALS['auth']->setAuth($user, array());
$_SESSION['ingo']['current_share'] = ':' . $user;
- $wl = $GLOBALS['rules_storage']->retrieve(Ingo_Storage::ACTION_WHITELIST, false);
- $bl = $GLOBALS['rules_storage']->retrieve(Ingo_Storage::ACTION_BLACKLIST, false);
- // Fill in data from saved rules.
- if (!is_a($wl, 'PEAR_Error')) {
- $whitelists[$user] = $wl->getWhitelist();
- }
- if (!is_a($bl, 'PEAR_Error') && !$bl->getBlacklistFolder()) {
- // We will only reject email at delivery time if the user
- // wants blacklisted mail deleted completely, not filed
- // into a separate folder.
- $blacklists[$user] = $bl->getBlacklist();
- }
+ try {
+ $whitelists[$user] = $GLOBALS['rules_storage']->retrieve(Ingo_Storage::ACTION_WHITELIST, false)->getWhitelist();
+ } catch (Ingo_Exception $e) {}
+
+ try {
+ $bl = $GLOBALS['rules_storage']->retrieve(Ingo_Storage::ACTION_BLACKLIST, false);
+ if (!$bl->getBlacklistFolder()) {
+ // We will only reject email at delivery time if the user
+ // wants blacklisted mail deleted completely, not filed
+ // into a separate folder.
+ $blacklists[$user] = $bl->getBlacklist();
+ }
+ } catch (Ingo_Exception $e) {}
}
// Check whitelist rules first so that mistaken overlap doesn't
foreach ($rules as $rule) {
$filter = $prefs_storage->retrieve($rule, false);
if ($rule == Ingo_Storage::ACTION_FILTERS) {
- $new_filter = &$sql_storage->retrieve(Ingo_Storage::ACTION_FILTERS, true, true);
+ $new_filter = $sql_storage->retrieve(Ingo_Storage::ACTION_FILTERS, true, true);
foreach ($filter->getFilterList() as $rule) {
$new_filter->addRule($rule);
echo '.';
}
/* Get the spam object and rule. */
-$spam = &$ingo_storage->retrieve(Ingo_Storage::ACTION_SPAM);
-$filters = &$ingo_storage->retrieve(Ingo_Storage::ACTION_FILTERS);
+$spam = $ingo_storage->retrieve(Ingo_Storage::ACTION_SPAM);
+$filters = $ingo_storage->retrieve(Ingo_Storage::ACTION_FILTERS);
$spam_id = $filters->findRuleId(Ingo_Storage::ACTION_SPAM);
$spam_rule = $filters->getRule($spam_id);
-$vars = &Horde_Variables::getDefaultVariables();
-if ($vars->get('submitbutton') == _("Return to Rules List")) {
+$vars = Horde_Variables::getDefaultVariables();
+if ($vars->submitbutton == _("Return to Rules List")) {
header('Location: ' . Horde::applicationUrl('filters.php', true));
exit;
}
$form = new Horde_Form($vars);
$renderer = new Horde_Form_Renderer(array('varrenderer_driver' => array('ingo', 'ingo'), 'encode_title' => false));
-$v = &$form->addVariable(_("Spam Level:"), 'level', 'int', false, false, _("Messages with a likely spam score greater than or equal to this number will be treated as spam."));
+$v = $form->addVariable(_("Spam Level:"), 'level', 'int', false, false, _("Messages with a likely spam score greater than or equal to this number will be treated as spam."));
$v->setHelp('spam-level');
-$folder_var = &$form->addVariable(_("Folder to receive spam:"), 'folder', 'ingo_folders', false);
+$folder_var = $form->addVariable(_("Folder to receive spam:"), 'folder', 'ingo_folders', false);
$folder_var->setHelp('spam-folder');
$form->addHidden('', 'actionID', 'text', false);
$form->addHidden('', 'new_folder_name', 'text', false);
$success = true;
// Create a new folder if requested.
- if ($vars->get('actionID') == 'create_folder') {
+ if ($vars->actionID == 'create_folder') {
try {
- $result = Ingo::createFolder($vars->get('new_folder_name'));
+ $result = Ingo::createFolder($vars->new_folder_name);
if ($result) {
$spam->setSpamFolder($result);
} else {
}
} catch (Horde_Exception $e) {
$success = false;
- $notification->push($e->getMessage());
+ $notification->push($e);
}
} else {
- $spam->setSpamFolder($vars->get('folder'));
+ $spam->setSpamFolder($vars->folder);
}
- $spam->setSpamLevel($vars->get('level'));
+ $spam->setSpamLevel($vars->level);
- if (is_a($result = $ingo_storage->store($spam), 'PEAR_Error')) {
- $notification->push($result);
- $success = false;
- } else {
+ try {
+ $ingo_storage->store($spam):
$notification->push(_("Changes saved."), 'horde.success');
- if ($vars->get('submitbutton') == _("Save and Enable")) {
+ if ($vars->submitbutton == _("Save and Enable")) {
$filters->ruleEnable($spam_id);
- if (is_a($result = $ingo_storage->store($filters), 'PEAR_Error')) {
- $notification->push($result);
- $success = false;
- } else {
- $notification->push(_("Rule Enabled"), 'horde.success');
- $spam_rule['disable'] = false;
- }
- } elseif ($vars->get('submitbutton') == _("Save and Disable")) {
+ $ingo_storage->store($filters);
+ $notification->push(_("Rule Enabled"), 'horde.success');
+ $spam_rule['disable'] = false;
+ } elseif ($vars->submitbutton == _("Save and Disable")) {
$filters->ruleDisable($spam_id);
- if (is_a($result = $ingo_storage->store($filters), 'PEAR_Error')) {
- $notification->push($result);
- $success = false;
- } else {
- $notification->push(_("Rule Disabled"), 'horde.success');
- $spam_rule['disable'] = true;
- }
+ $ingo_storage->store($filters);
+ $notification->push(_("Rule Disabled"), 'horde.success');
+ $spam_rule['disable'] = true;
}
+ } catch (Ingo_Exception $e) {
+ $notification->push($result);
+ $success = false;
}
+
if ($success && $prefs->getValue('auto_update')) {
Ingo::updateScript();
}
/* Set default values. */
$folder_var->type->setFolder($spam->getSpamFolder());
if (!$form->isSubmitted()) {
- $vars->set('level', $spam->getSpamLevel());
- $vars->set('folder', $spam->getSpamFolder());
- $vars->set('actionID', '');
- $vars->set('new_folder_name', '');
+ $vars->level = $spam->getSpamLevel();
+ $vars->folder = $spam->getSpamFolder();
+ $vars->actionID = '';
+ $vars->new_folder_name = '';
}
/* Set form title. */
</select>
<?php if ($header_entry): ?>
<label for="userheader_<?php echo (int)$cond_num ?>" class="hidden"><?php echo _("User header") ?></label>
- <input id="userheader_<?php echo (int)$cond_num ?>" name="userheader[<?php echo (int)$cond_num ?>]" value="<?php echo htmlspecialchars($userheader) ?>" />
+ <input id="userheader_<?php echo (int)$cond_num ?>" name="userheader[<?php echo (int)$cond_num ?>]" value="<?php echo htmlspecialchars($vars->userheader) ?>" />
<?php endif; ?>
</td>
<?php if ($lastfield): ?>
<input type="hidden" name="actionID" value="rule_update" />
<input type="hidden" name="conditionnumber" value="-1" />
<input type="hidden" name="new_folder_name" value="" />
-<?php if (!is_null($edit_number)): ?>
-<input type="hidden" name="edit" value="<?php echo $edit_number ?>" />
+<?php if (isset($vars->edit)): ?>
+<input type="hidden" name="edit" value="<?php echo $vars->edit ?>" />
<?php endif; if (isset($rule['id'])): ?>
<input type="hidden" name="id" value="<?php echo $rule['id'] ?>" />
<?php endif; ?>
}
/* Get vacation object and rules. */
-$vacation = &$ingo_storage->retrieve(Ingo_Storage::ACTION_VACATION);
-$filters = &$ingo_storage->retrieve(Ingo_Storage::ACTION_FILTERS);
+$vacation = $ingo_storage->retrieve(Ingo_Storage::ACTION_VACATION);
+$filters = $ingo_storage->retrieve(Ingo_Storage::ACTION_FILTERS);
$vac_id = $filters->findRuleId(Ingo_Storage::ACTION_VACATION);
$vac_rule = $filters->getRule($vac_id);
/* Load libraries. */
$vars = Horde_Variables::getDefaultVariables();
-if ($vars->get('submitbutton') == _("Return to Rules List")) {
+if ($vars->submitbutton == _("Return to Rules List")) {
header('Location: ' . Horde::applicationUrl('filters.php', true));
exit;
}
$form = new Horde_Form($vars);
$form->setSection('basic', _("Basic Settings"));
-$v = &$form->addVariable(_("Start of vacation:"), 'start', 'monthdayyear', '');
+$v = $form->addVariable(_("Start of vacation:"), 'start', 'monthdayyear', '');
$v->setHelp('vacation-period');
$form->addVariable(_("End of vacation:"), 'end', 'monthdayyear', '');
-$v = &$form->addVariable(_("Subject of vacation message:"), 'subject', 'text', false);
+$v = $form->addVariable(_("Subject of vacation message:"), 'subject', 'text', false);
$v->setHelp('vacation-subject');
-$v = &$form->addVariable(_("Reason:"), 'reason', 'longtext', false, false, null, array(10, 40));
+$v = $form->addVariable(_("Reason:"), 'reason', 'longtext', false, false, null, array(10, 40));
$v->setHelp('vacation-reason');
$form->setSection('advanced', _("Advanced Settings"));
-$v = &$form->addVariable(_("My email addresses:"), 'addresses', 'longtext', true, false, null, array(5, 40));
+$v = $form->addVariable(_("My email addresses:"), 'addresses', 'longtext', true, false, null, array(5, 40));
$v->setHelp('vacation-myemail');
-$v = &$form->addVariable(_("Addresses to not send responses to:"), 'excludes', 'longtext', false, false, null, array(10, 40));
+$v = $form->addVariable(_("Addresses to not send responses to:"), 'excludes', 'longtext', false, false, null, array(10, 40));
$v->setHelp('vacation-noresponse');
-$v = &$form->addVariable(_("Do not send responses to bulk or list messages?"), 'ignorelist', 'boolean', false);
+$v = $form->addVariable(_("Do not send responses to bulk or list messages?"), 'ignorelist', 'boolean', false);
$v->setHelp('vacation-bulk');
-$v = &$form->addVariable(_("Number of days between vacation replies:"), 'days', 'int', false);
+$v = $form->addVariable(_("Number of days between vacation replies:"), 'days', 'int', false);
$v->setHelp('vacation-days');
$form->setButtons(_("Save"));
$vacation->setVacationEnd($info['end']);
$success = true;
- if (is_a($result = $ingo_storage->store($vacation), 'PEAR_Error')) {
- $notification->push($result);
- $success = false;
- } else {
+ try {
+ $ingo_storage->store($vacation);
$notification->push(_("Changes saved."), 'horde.success');
- if ($vars->get('submitbutton') == _("Save and Enable")) {
+ if ($vars->submitbutton == _("Save and Enable")) {
$filters->ruleEnable($vac_id);
- if (is_a($result = $ingo_storage->store($filters), 'PEAR_Error')) {
- $notification->push($result);
- $success = false;
- } else {
- $notification->push(_("Rule Enabled"), 'horde.success');
- $vac_rule['disable'] = false;
- }
+ $ingo_storage->store($filters);
+ $notification->push(_("Rule Enabled"), 'horde.success');
+ $vac_rule['disable'] = false;
} elseif ($vars->get('submitbutton') == _("Save and Disable")) {
$filters->ruleDisable($vac_id);
- if (is_a($result = $ingo_storage->store($filters), 'PEAR_Error')) {
- $notification->push($result);
- $success = false;
- } else {
- $notification->push(_("Rule Disabled"), 'horde.success');
- $vac_rule['disable'] = true;
- }
+ $ingo_storage->store($filters);
+ $notification->push(_("Rule Disabled"), 'horde.success');
+ $vac_rule['disable'] = true;
}
+ } catch (Ingo_Exception $e) {
+ $notification->push($result);
+ $success = false;
}
if ($success && $prefs->getValue('auto_update')) {
exit;
}
-$whitelist = &$ingo_storage->retrieve(Ingo_Storage::ACTION_WHITELIST);
+$whitelist = $ingo_storage->retrieve(Ingo_Storage::ACTION_WHITELIST);
/* Perform requested actions. */
-$actionID = Horde_Util::getFormData('actionID');
-switch ($actionID) {
+switch (Horde_Util::getFormData('actionID')) {
case 'rule_update':
- $ret = $whitelist->setWhitelist(Horde_Util::getFormData('whitelist'));
- if (is_a($ret, 'PEAR_Error')) {
- $notification->push($ret, $ret->getCode());
- } else {
+ try {
+ $whitelist->setWhitelist(Horde_Util::getFormData('whitelist'));
if (!$ingo_storage->store($whitelist)) {
$notification->push("Error saving changes.", 'horde.error');
} else {
/* Update the timestamp for the rules. */
$_SESSION['ingo']['change'] = time();
+ } catch (Ingo_Exception $e) {
+ $notification->push($e);
}
-
break;
}
/* Get the whitelist rule. */
-$filters = &$ingo_storage->retrieve(Ingo_Storage::ACTION_FILTERS);
+$filters = $ingo_storage->retrieve(Ingo_Storage::ACTION_FILTERS);
$wl_rule = $filters->findRule(Ingo_Storage::ACTION_WHITELIST);
$title = _("Whitelist Edit");