Overview

Packages

  • Horde
    • Icalendar
      • UnitTests
  • Ingo
    • UnitTests
  • None

Classes

  • Horde_Core_Ui_VarRenderer_Ingo
  • Ingo
  • Ingo_Api
  • Ingo_Exception
  • Ingo_Exception_Pear
  • Ingo_LoginTasks_SystemTask_Upgrade
  • Ingo_Script
  • Ingo_Script_Imap
  • Ingo_Script_Imap_Api
  • Ingo_Script_Imap_Live
  • Ingo_Script_Maildrop
  • Ingo_Script_Maildrop_Comment
  • Ingo_Script_Maildrop_Recipe
  • Ingo_Script_Maildrop_Variable
  • Ingo_Script_Procmail
  • Ingo_Script_Procmail_Comment
  • Ingo_Script_Procmail_Recipe
  • Ingo_Script_Procmail_Variable
  • Ingo_Script_Sieve
  • Ingo_Script_Sieve_Action
  • Ingo_Script_Sieve_Action_Addflag
  • Ingo_Script_Sieve_Action_Discard
  • Ingo_Script_Sieve_Action_Fileinto
  • Ingo_Script_Sieve_Action_Flag
  • Ingo_Script_Sieve_Action_Keep
  • Ingo_Script_Sieve_Action_Notify
  • Ingo_Script_Sieve_Action_Redirect
  • Ingo_Script_Sieve_Action_Reject
  • Ingo_Script_Sieve_Action_Removeflag
  • Ingo_Script_Sieve_Action_Stop
  • Ingo_Script_Sieve_Action_Vacation
  • Ingo_Script_Sieve_Comment
  • Ingo_Script_Sieve_Else
  • Ingo_Script_Sieve_Elsif
  • Ingo_Script_Sieve_If
  • Ingo_Script_Sieve_Test
  • Ingo_Script_Sieve_Test_Address
  • Ingo_Script_Sieve_Test_Allof
  • Ingo_Script_Sieve_Test_Anyof
  • Ingo_Script_Sieve_Test_Body
  • Ingo_Script_Sieve_Test_Exists
  • Ingo_Script_Sieve_Test_False
  • Ingo_Script_Sieve_Test_Header
  • Ingo_Script_Sieve_Test_Not
  • Ingo_Script_Sieve_Test_Relational
  • Ingo_Script_Sieve_Test_Size
  • Ingo_Script_Sieve_Test_True
  • Ingo_Storage
  • Ingo_Storage_Blacklist
  • Ingo_Storage_Filters
  • Ingo_Storage_Filters_Sql
  • Ingo_Storage_Forward
  • Ingo_Storage_Mock
  • Ingo_Storage_Prefs
  • Ingo_Storage_Rule
  • Ingo_Storage_Spam
  • Ingo_Storage_Sql
  • Ingo_Storage_Vacation
  • Ingo_Storage_VacationTest
  • Ingo_Storage_Whitelist
  • Ingo_Test
  • Ingo_Transport
  • Ingo_Transport_Ldap
  • Ingo_Transport_Null
  • Ingo_Transport_Sivtest
  • Ingo_Transport_Timsieved
  • Ingo_Transport_Vfs
  • Overview
  • Package
  • Class
  • Tree
  1: <?php
  2: /**
  3:  * The Ingo_Script_Procmail:: class represents a Procmail script generator.
  4:  *
  5:  * Copyright 2003-2012 Horde LLC (http://www.horde.org/)
  6:  *
  7:  * See the enclosed file LICENSE for license information (ASL).  If you
  8:  * did not receive this file, see http://www.horde.org/licenses/apache.
  9:  *
 10:  * @author  Brent J. Nordquist <bjn@horde.org>
 11:  * @author  Ben Chavet <ben@horde.org>
 12:  * @package Ingo
 13:  */
 14: class Ingo_Script_Procmail extends Ingo_Script
 15: {
 16:     /**
 17:      * The list of actions allowed (implemented) for this driver.
 18:      *
 19:      * @var array
 20:      */
 21:     protected $_actions = array(
 22:         Ingo_Storage::ACTION_KEEP,
 23:         Ingo_Storage::ACTION_MOVE,
 24:         Ingo_Storage::ACTION_DISCARD,
 25:         Ingo_Storage::ACTION_REDIRECT,
 26:         Ingo_Storage::ACTION_REDIRECTKEEP,
 27:         Ingo_Storage::ACTION_REJECT
 28:     );
 29: 
 30:     /**
 31:      * The categories of filtering allowed.
 32:      *
 33:      * @var array
 34:      */
 35:     protected $_categories = array(
 36:         Ingo_Storage::ACTION_BLACKLIST,
 37:         Ingo_Storage::ACTION_WHITELIST,
 38:         Ingo_Storage::ACTION_VACATION,
 39:         Ingo_Storage::ACTION_FORWARD
 40:     );
 41: 
 42:     /**
 43:      * The types of tests allowed (implemented) for this driver.
 44:      *
 45:      * @var array
 46:      */
 47:     protected $_types = array(
 48:         Ingo_Storage::TYPE_HEADER,
 49:         Ingo_Storage::TYPE_BODY
 50:     );
 51: 
 52:     /**
 53:      * A list of any special types that this driver supports.
 54:      *
 55:      * @var array
 56:      */
 57:     protected $_special_types = array(
 58:         'Destination',
 59:     );
 60: 
 61:     /**
 62:      * The list of tests allowed (implemented) for this driver.
 63:      *
 64:      * @var array
 65:      */
 66:     protected $_tests = array(
 67:         'contains',
 68:         'not contain',
 69:         'begins with',
 70:         'not begins with',
 71:         'ends with',
 72:         'not ends with',
 73:         'regex'
 74:     );
 75: 
 76:     /**
 77:      * Can tests be case sensitive?
 78:      *
 79:      * @var boolean
 80:      */
 81:     protected $_casesensitive = true;
 82: 
 83:     /**
 84:      * Does the driver support the stop-script option?
 85:      *
 86:      * @var boolean
 87:      */
 88:     protected $_supportStopScript = true;
 89: 
 90:     /**
 91:      * Does the driver require a script file to be generated?
 92:      *
 93:      * @var boolean
 94:      */
 95:     protected $_scriptfile = true;
 96: 
 97:     /**
 98:      * The recipes that make up the code.
 99:      *
100:      * @var array
101:      */
102:     protected $_recipes = array();
103: 
104:     /**
105:      * Constructor.
106:      *
107:      * @param array $params  A hash containing parameters needed.
108:      */
109:     public function __construct($params = array())
110:     {
111:         parent::__construct($params);
112: 
113:         // Bug #10113: Need to explicitly define these variables instead of
114:         // relying on system defaults.
115:         if ($this->_params['path_style'] == 'maildir') {
116:             if (!isset($this->_params['variables']['DEFAULT'])) {
117:                 $this->_params['variables']['DEFAULT'] = '$HOME/Maildir/';
118:             }
119:             if (!isset($this->_params['variables']['MAILDIR'])) {
120:                 $this->_params['variables']['MAILDIR'] = '$HOME/Maildir';
121:             }
122:         }
123:     }
124: 
125:     /**
126:      * Returns a script previously generated with generate().
127:      *
128:      * @return string  The procmail script.
129:      */
130:     public function toCode()
131:     {
132:         $code = '';
133:         foreach ($this->_recipes as $item) {
134:             $code .= $item->generate() . "\n";
135:         }
136: 
137:         // If an external delivery program is used, add final rule
138:         // to deliver to $DEFAULT
139:         if (isset($this->_params['delivery_agent'])) {
140:             $code .= ":0 w\n";
141:             $code .= isset($this->_params['delivery_mailbox_prefix']) ?
142:                 '| ' . $this->_params['delivery_agent'] . ' ' . $this->_params['delivery_mailbox_prefix'] . '$DEFAULT' :
143:                 '| ' . $this->_params['delivery_agent'] . ' $DEFAULT';
144:         }
145: 
146:         return rtrim($code) . "\n";
147:     }
148: 
149:     /**
150:      * Generates the procmail script to do the filtering specified in the
151:      * rules.
152:      *
153:      * @return string  The procmail script.
154:      */
155:     public function generate()
156:     {
157:         $filters = $GLOBALS['ingo_storage']->retrieve(Ingo_Storage::ACTION_FILTERS);
158: 
159:         $this->addItem(new Ingo_Script_Procmail_Comment(_("procmail script generated by Ingo") . ' (' . date('F j, Y, g:i a') . ')'));
160: 
161:         /* Add variable information, if present. */
162:         if (!empty($this->_params['variables']) &&
163:             is_array($this->_params['variables'])) {
164:             foreach ($this->_params['variables'] as $key => $val) {
165:                 $this->addItem(new Ingo_Script_Procmail_Variable(array('name' => $key, 'value' => $val)));
166:             }
167:         }
168: 
169:         foreach ($filters->getFilterList() as $filter) {
170:             switch ($filter['action']) {
171:             case Ingo_Storage::ACTION_BLACKLIST:
172:                 $this->generateBlacklist(!empty($filter['disable']));
173:                 break;
174: 
175:             case Ingo_Storage::ACTION_WHITELIST:
176:                 $this->generateWhitelist(!empty($filter['disable']));
177:                 break;
178: 
179:             case Ingo_Storage::ACTION_VACATION:
180:                 $this->generateVacation(!empty($filter['disable']));
181:                 break;
182: 
183:             case Ingo_Storage::ACTION_FORWARD:
184:                 $this->generateForward(!empty($filter['disable']));
185:                 break;
186: 
187:             default:
188:                 if (in_array($filter['action'], $this->_actions)) {
189:                     /* Create filter if using AND. */
190:                     if ($filter['combine'] == Ingo_Storage::COMBINE_ALL) {
191:                         $recipe = new Ingo_Script_Procmail_Recipe($filter, $this->_params);
192:                         if (!$filter['stop']) {
193:                             $recipe->addFlag('c');
194:                         }
195:                         foreach ($filter['conditions'] as $condition) {
196:                             $recipe->addCondition($condition);
197:                         }
198:                         $this->addItem(new Ingo_Script_Procmail_Comment($filter['name'], !empty($filter['disable']), true));
199:                         $this->addItem($recipe);
200:                     } else {
201:                         /* Create filter if using OR */
202:                         $this->addItem(new Ingo_Script_Procmail_Comment($filter['name'], !empty($filter['disable']), true));
203:                         $loop = 0;
204:                         foreach ($filter['conditions'] as $condition) {
205:                             $recipe = new Ingo_Script_Procmail_Recipe($filter, $this->_params);
206:                             if ($loop++) {
207:                                 $recipe->addFlag('E');
208:                             }
209:                             if (!$filter['stop']) {
210:                                 $recipe->addFlag('c');
211:                             }
212:                             $recipe->addCondition($condition);
213:                             $this->addItem($recipe);
214:                         }
215:                     }
216:                 }
217:             }
218:         }
219: 
220:         return $this->toCode();
221:     }
222: 
223:     /**
224:      * Generates the procmail script to handle the blacklist specified in
225:      * the rules.
226:      *
227:      * @param boolean $disable  Disable the blacklist?
228:      */
229:     public function generateBlacklist($disable = false)
230:     {
231:         $blacklist = $GLOBALS['ingo_storage']->retrieve(Ingo_Storage::ACTION_BLACKLIST);
232:         $bl_addr = $blacklist->getBlacklist();
233:         $bl_folder = $blacklist->getBlacklistFolder();
234: 
235:         $bl_type = empty($bl_folder)
236:             ? Ingo_Storage::ACTION_DISCARD
237:             : Ingo_Storage::ACTION_MOVE;
238: 
239:         if (!empty($bl_addr)) {
240:             $this->addItem(new Ingo_Script_Procmail_Comment(_("Blacklisted Addresses"), $disable, true));
241:             $params = array('action-value' => $bl_folder,
242:                             'action' => $bl_type,
243:                             'disable' => $disable);
244: 
245:             foreach ($bl_addr as $address) {
246:                 if (!empty($address)) {
247:                     $recipe = new Ingo_Script_Procmail_Recipe($params, $this->_params);
248:                     $recipe->addCondition(array('field' => 'From', 'value' => $address, 'match' => 'address'));
249:                     $this->addItem($recipe);
250:                 }
251:             }
252:         }
253:     }
254: 
255:     /**
256:      * Generates the procmail script to handle the whitelist specified in
257:      * the rules.
258:      *
259:      * @param boolean $disable  Disable the whitelist?
260:      */
261:     public function generateWhitelist($disable = false)
262:     {
263:         $whitelist = $GLOBALS['ingo_storage']->retrieve(Ingo_Storage::ACTION_WHITELIST);
264:         $wl_addr = $whitelist->getWhitelist();
265: 
266:         if (!empty($wl_addr)) {
267:             $this->addItem(new Ingo_Script_Procmail_Comment(_("Whitelisted Addresses"), $disable, true));
268:             foreach ($wl_addr as $address) {
269:                 if (!empty($address)) {
270:                     $recipe = new Ingo_Script_Procmail_Recipe(array('action' => Ingo_Storage::ACTION_KEEP, 'disable' => $disable), $this->_params);
271:                     $recipe->addCondition(array('field' => 'From', 'value' => $address, 'match' => 'address'));
272:                     $this->addItem($recipe);
273:                 }
274:             }
275:         }
276:     }
277: 
278:     /**
279:      * Generates the procmail script to handle vacation.
280:      *
281:      * @param boolean $disable  Disable vacation?
282:      */
283:     public function generateVacation($disable = false)
284:     {
285:         $vacation = $GLOBALS['ingo_storage']->retrieve(Ingo_Storage::ACTION_VACATION);
286:         $addresses = $vacation->getVacationAddresses();
287:         $actionval = array(
288:             'addresses' => $addresses,
289:             'subject' => $vacation->getVacationSubject(),
290:             'days' => $vacation->getVacationDays(),
291:             'reason' => $vacation->getVacationReason(),
292:             'ignorelist' => $vacation->getVacationIgnorelist(),
293:             'excludes' => $vacation->getVacationExcludes(),
294:             'start' => $vacation->getVacationStart(),
295:             'end' => $vacation->getVacationEnd(),
296:         );
297: 
298:         if (!empty($addresses)) {
299:             $this->addItem(new Ingo_Script_Procmail_Comment(_("Vacation"), $disable, true));
300:             $params = array('action' => Ingo_Storage::ACTION_VACATION,
301:                             'action-value' => $actionval,
302:                             'disable' => $disable);
303:             $recipe = new Ingo_Script_Procmail_Recipe($params, $this->_params);
304:             $this->addItem($recipe);
305:         }
306:     }
307: 
308:     /**
309:      * Generates the procmail script to handle mail forwards.
310:      *
311:      * @param boolean $disable  Disable forwarding?
312:      */
313:     public function generateForward($disable = false)
314:     {
315:         $forward = $GLOBALS['ingo_storage']->retrieve(Ingo_Storage::ACTION_FORWARD);
316:         $addresses = $forward->getForwardAddresses();
317: 
318:         if (!empty($addresses)) {
319:             $this->addItem(new Ingo_Script_Procmail_Comment(_("Forwards"), $disable, true));
320:             $params = array('action' => Ingo_Storage::ACTION_FORWARD,
321:                             'action-value' => $addresses,
322:                             'disable' => $disable);
323:             $recipe = new Ingo_Script_Procmail_Recipe($params, $this->_params);
324:             if ($forward->getForwardKeep()) {
325:                 $recipe->addFlag('c');
326:             }
327:             $this->addItem($recipe);
328:         }
329:     }
330: 
331:     /**
332:      * Returns any additional scripts that need to be sent to the transport
333:      * layer.
334:      *
335:      * @return array  A list of scripts with script names as keys and script
336:      *                code as values.
337:      */
338:     public function additionalScripts()
339:     {
340:         if (isset($this->_params['forward_file']) &&
341:             isset($this->_params['forward_string'])) {
342:             return array($this->_params['forward_file'] => $this->_params['forward_string']);
343:         }
344:         return array();
345:     }
346: 
347:     /**
348:      * Adds an item to the recipe list.
349:      *
350:      * @param object $item  The item to add to the recipe list.
351:      *                      The object should have a generate() function.
352:      */
353:     public function addItem($item)
354:     {
355:         $this->_recipes[] = $item;
356:     }
357: 
358: }
359: 
API documentation generated by ApiGen