Overview

Packages

  • Horde
    • Form
    • MIME
      • Viewer
    • Scheduler
  • None
  • Whups
    • UnitTests

Classes

  • Horde_Core_Ui_VarRenderer_whups
  • Whups
  • Whups_Ajax_Imple_ContactAutoCompleter
  • Whups_Api
  • Whups_Driver
  • Whups_Driver_Sql
  • Whups_Form_AddComment
  • Whups_Form_Admin_AddAttribute
  • Whups_Form_Admin_AddPriority
  • Whups_Form_Admin_AddQueue
  • Whups_Form_Admin_AddReply
  • Whups_Form_Admin_AddState
  • Whups_Form_Admin_AddType
  • Whups_Form_Admin_AddUser
  • Whups_Form_Admin_AddVersion
  • Whups_Form_Admin_CloneType
  • Whups_Form_Admin_DefaultPriority
  • Whups_Form_Admin_DefaultState
  • Whups_Form_Admin_DeleteAttribute
  • Whups_Form_Admin_DeletePriority
  • Whups_Form_Admin_DeleteQueue
  • Whups_Form_Admin_DeleteReply
  • Whups_Form_Admin_DeleteState
  • Whups_Form_Admin_DeleteType
  • Whups_Form_Admin_DeleteVersion
  • Whups_Form_Admin_EditAttributeStepOne
  • Whups_Form_Admin_EditAttributeStepTwo
  • Whups_Form_Admin_EditPriorityStepOne
  • Whups_Form_Admin_EditPriorityStepTwo
  • Whups_Form_Admin_EditQueueStepOne
  • Whups_Form_Admin_EditQueueStepTwo
  • Whups_Form_Admin_EditReplyStepOne
  • Whups_Form_Admin_EditReplyStepTwo
  • Whups_Form_Admin_EditStateStepOne
  • Whups_Form_Admin_EditStateStepTwo
  • Whups_Form_Admin_EditTypeStepOne
  • Whups_Form_Admin_EditTypeStepTwo
  • Whups_Form_Admin_EditUser
  • Whups_Form_Admin_EditVersionStepOne
  • Whups_Form_Admin_EditVersionStepTwo
  • Whups_Form_InsertBranch
  • Whups_Form_Query_AttributeCriterion
  • Whups_Form_Query_ChooseNameForLoad
  • Whups_Form_Query_ChooseNameForSave
  • Whups_Form_Query_DateCriterion
  • Whups_Form_Query_Delete
  • Whups_Form_Query_GroupCriterion
  • Whups_Form_Query_Parameter
  • Whups_Form_Query_PropertyCriterion
  • Whups_Form_Query_TextCriterion
  • Whups_Form_Query_UserCriterion
  • Whups_Form_Renderer_Comment
  • Whups_Form_Search
  • Whups_Form_SendReminder
  • Whups_Form_Ticket_CreateStepFour
  • Whups_Form_Ticket_CreateStepOne
  • Whups_Form_Ticket_CreateStepThree
  • Whups_Form_Ticket_CreateStepTwo
  • Whups_Form_Ticket_Edit
  • Whups_Form_TicketDetails
  • Whups_LoginTasks_SystemTask_Upgrade
  • Whups_Mail
  • Whups_Query
  • Whups_Query_Manager
  • Whups_Reports
  • Whups_Ticket
  • Whups_View_Base
  • Whups_View_Results
  • Whups_View_SavedQueries
  • Overview
  • Package
  • Class
  • Tree
  1: <?php
  2: /**
  3:  * Copyright 2001-2002 Robert E. Coyle <robertecoyle@hotmail.com>
  4:  * Copyright 2001-2012 Horde LLC (http://www.horde.org/)
  5:  *
  6:  * See the enclosed file LICENSE for license information (BSD). If you
  7:  * did not receive this file, see http://www.horde.org/licenses/bsdl.php.
  8:  *
  9:  * @author  Robert E. Coyle <robertecoyle@hotmail.com>
 10:  * @author  Jan Schneider <jan@horde.org>
 11:  * @package Whups
 12:  */
 13: 
 14: /**
 15:  * array(
 16:  *     'type'      => Whups_Query::TYPE_...
 17:  *     'children'  => array(...) unless type == Whups_Query::TYPE_CRITERION
 18:  *     'criterion' => Whups_Query::CRITERION_... if  type == Whups_Query::TYPE_CRITERION
 19:  *     'operator'  => Whups_Query::OPERATOR_...  if  type == Whups_Query::TYPE_CRITERION
 20:  *     'value'     => other argument to operator of criterion
 21:  */
 22: 
 23: /**
 24:  * @package Whups
 25:  */
 26: class Whups_Query
 27: {
 28: 
 29:     /** Mode types. */
 30:     const TYPE_AND = 1;
 31:     const TYPE_OR = 2;
 32:     const TYPE_NOT = 3;
 33:     const TYPE_CRITERION = 4;
 34: 
 35:     /** Criterion types. */
 36:     const CRITERION_ID = 1;
 37:     const CRITERION_QUEUE = 2;
 38:     const CRITERION_TYPE = 3;
 39:     const CRITERION_STATE = 4;
 40:     const CRITERION_PRIORITY = 5;
 41:     const CRITERION_OWNERS = 7;
 42:     const CRITERION_REQUESTER = 8;
 43:     const CRITERION_GROUPS = 9;
 44:     const CRITERION_ADDED_COMMENT = 11;
 45:     const CRITERION_COMMENT = 12;
 46:     const CRITERION_SUMMARY = 13;
 47:     const CRITERION_ATTRIBUTE = 14;
 48:     const CRITERION_VERSION = 15;
 49:     const CRITERION_TIMESTAMP = 16;
 50:     const CRITERION_UPDATED = 17;
 51:     const CRITERION_RESOLVED = 18;
 52:     const CRITERION_ASSIGNED = 19;
 53:     const CRITERION_DUE = 20;
 54: 
 55:     /** Operators for integer fields. */
 56:     const OPERATOR_GREATER = 1;
 57:     const OPERATOR_LESS = 2;
 58:     const OPERATOR_EQUAL = 3;
 59: 
 60:     /** Operators for text fields. */
 61:     const OPERATOR_CI_SUBSTRING = 4;
 62:     const OPERATOR_CS_SUBSTRING = 5;
 63:     const OPERATOR_WORD =  6;
 64:     const OPERATOR_PATTERN = 7;
 65: 
 66:     /**
 67:      * @var Whups_Query_Manager
 68:      */
 69:     protected $_qManager;
 70: 
 71:     /**
 72:      * Query id.
 73:      *
 74:      * @var integer
 75:      */
 76:     public $id;
 77: 
 78:     /**
 79:      * The full name of the query.
 80:      *
 81:      * @var string
 82:      */
 83:     public $name;
 84: 
 85:     /**
 86:      * The query slug (short name).
 87:      *
 88:      * @var string
 89:      */
 90:     public $slug;
 91: 
 92:     /**
 93:      * @var array
 94:      */
 95:     public $query = array(
 96:         'type' => Whups_Query::TYPE_AND,
 97:         'children' => array());
 98: 
 99:     /**
100:      * @var array
101:      */
102:     public $parameters = array();
103: 
104:     /**
105:      * Constructor
106:      *
107:      * @param Whups_Query_Manager $qManager
108:      * @param array $qDetails
109:      */
110:     function __construct(Whups_Query_Manager &$qManager, array $qDetails = array())
111:     {
112:         $this->_qManager = &$qManager;
113:         if (isset($qDetails['query_id'])) {
114:             $this->id = $qDetails['query_id'];
115:         }
116:         if (isset($qDetails['query_name'])) {
117:             $this->name = $qDetails['query_name'];
118:         }
119:         if (isset($qDetails['query_slug'])) {
120:             $this->slug = $qDetails['query_slug'];
121:         }
122:         if (isset($qDetails['query_object'])) {
123:             $this->query = @unserialize($qDetails['query_object']);
124:         }
125:         if (isset($qDetails['query_parameters'])) {
126:             $this->parameters = @unserialize($qDetails['query_parameters']);
127:         }
128:     }
129: 
130:     /**
131:      * @static
132:      */
133:     public static function pathToString(&$path)
134:     {
135:         return implode(',', $path);
136:     }
137: 
138:     /**
139:      * @static
140:      */
141:     public static function stringToPath($pathstring)
142:     {
143:         if (!strlen($pathstring)) {
144:             return array();
145:         }
146: 
147:         return explode(',', $pathstring);
148:     }
149: 
150:     /**
151:      * Returns human readable descriptions of all operator types.
152:      *
153:      * @static
154:      *
155:      * @return array  Hash with operator types and descriptions.
156:      */
157:     public static function textOperators()
158:     {
159:         return array(
160:             Whups_Query::OPERATOR_EQUAL        => _("Exact Match"),
161:             Whups_Query::OPERATOR_CI_SUBSTRING => _("Case Insensitive Substring"),
162:             Whups_Query::OPERATOR_CS_SUBSTRING => _("Case Sensitive Substring"),
163:             Whups_Query::OPERATOR_WORD         => _("Match Word"),
164:             Whups_Query::OPERATOR_PATTERN      => _("Match Pattern"));
165:     }
166: 
167:     /**
168:      * Checks to see if a user has a given permission.
169:      *
170:      * @param string $userid       The userid of the user.
171:      * @param integer $permission  A Horde_Perms::* constant to test for.
172:      * @param string $creator      The creator of the event.
173:      *
174:      * @return boolean  Whether or not $userid has $permission.
175:      */
176:     public function hasPermission($userid, $permission, $creator = null)
177:     {
178:         return $this->_qManager->hasPermission($this->id, $userid, $permission, $creator);
179:     }
180: 
181:     /**
182:      * Saves any changes to this object to the backend
183:      * permanently. New objects are added instead.
184:      *
185:      */
186:     public function save()
187:     {
188:         $this->_qManager->save($this);
189:     }
190: 
191:     /**
192:      * Delete this object from the backend permanently.
193:      *
194:      */
195:     public function delete()
196:     {
197:         $this->_qManager->delete($this);
198:     }
199: 
200:     /**
201:      * Returns a <link> tag for this query's feed.
202:      *
203:      * @return string  A full <link> tag.
204:      */
205:     public function feedLink()
206:     {
207:         return '<link rel="alternate" type="application/rss+xml" title="' . htmlspecialchars($this->name) . '" href="' . Whups::urlFor('query_rss', empty($this->slug) ? array('id' => $this->id) : array('slug' => $this->slug), true, -1) . '" />';
208:     }
209: 
210:     /**
211:      * Tab operations for this query.
212:      *
213:      * @params Horde_Variables
214:      */
215:     public function getTabs(Horde_Variables $vars)
216:     {
217:         // Create a few variables that are reused.
218:         $queryurl = Horde::url('query/index.php');
219:         $edit = $this->hasPermission($GLOBALS['registry']->getAuth(), Horde_Perms::EDIT);
220:         $delete = $this->hasPermission($GLOBALS['registry']->getAuth(), Horde_Perms::DELETE);
221: 
222:         $tabs = new Horde_Core_Ui_Tabs('action', $vars);
223:         $tabs->addTab(_("Ne_w Query"), $queryurl, 'new');
224:         if (!$this->id || $edit) {
225:             $tabs->addTab(_("_Edit Query"), $queryurl, 'edit');
226:         }
227:         if ($this->id && $edit && empty($GLOBALS['conf']['share']['no_sharing'])) {
228:             Horde::addScriptFile('popup.js', 'horde', true);
229: 
230:             $permsurl = $GLOBALS['registry']->get('webroot', 'horde') . '/services/shares/edit.php';
231:             $permsurl = Horde_Util::addParameter(
232:                 $permsurl,
233:                 array(
234:                     'app' => 'whups',
235:                     'cid' => $this->id));
236:             $tabs->addTab(
237:                 _("Edit _Permissions"),
238:                 $permsurl,
239:                 array(
240:                     'tabname' => 'perms',
241:                     'onclick' => 'popup(\'' . $permsurl . '\'); return false;',
242:                     'target' => '_blank'));
243:         }
244:         $tabs->addTab(_("E_xecute Query"), Horde::url('query/run.php'), 'run');
245:         $tabs->addTab(_("_Load Query"), $queryurl, 'load');
246:         if ((!$this->id && $GLOBALS['registry']->getAuth()) ||
247:             ($this->id && $edit)) {
248:             $tabs->addTab(_("Sa_ve Query"), $queryurl, 'save');
249:         }
250:         if ($this->id && $delete) {
251:             $tabs->addTab(_("_Delete Query"), $queryurl, 'delete');
252:         }
253: 
254:         return $tabs;
255:     }
256: 
257:     /**
258:      * Path to form
259:      *
260:      * @param Horde_Variables $vars
261:      *
262:      * @return string
263:      * @throws Whups_Exception
264:      */
265:     public function pathToForm(&$vars)
266:     {
267:         $path = Whups_Query::stringToPath($vars->get('path'));
268:         $parent = null;
269:         $qobj = $this->query;
270: 
271:         for ($i = 0, $c = count($path); $i < $c; $i++) {
272:             $parent = $qobj;
273:             $qobj = $qobj['children'][$path[$i]];
274:         }
275: 
276:         if ($qobj['type'] != Whups_Query::TYPE_CRITERION) {
277:             // Search for any criteria that have been combined automatically
278:             // with an AND or OR.
279:             switch ($qobj['type']) {
280:             case Whups_Query::TYPE_OR:
281:                 // Search for multiple ids.
282:                 $criteria = array();
283:                 foreach ($qobj['children'] as $child) {
284:                     if ($child['type'] != Whups_Query::TYPE_CRITERION ||
285:                         $child['criterion'] != Whups_Query::CRITERION_ID) {
286:                         $criteria = false;
287:                         break;
288:                     }
289:                     $criteria[] = $child['value'];
290:                 }
291:                 if ($criteria) {
292:                     $vars->set('id', implode(',', $criteria));
293:                     return 'props';
294:                 }
295: 
296:                 // Search for user criteria.
297:                 $criteria = array();
298:                 $operator = $value = null;
299:                 foreach ($qobj['children'] as $child) {
300:                     if ($child['type'] != Whups_Query::TYPE_CRITERION ||
301:                         ($child['criterion'] != Whups_Query::CRITERION_OWNERS &&
302:                          $child['criterion'] != Whups_Query::CRITERION_REQUESTER &&
303:                          $child['criterion'] != Whups_Query::CRITERION_ADDED_COMMENT) ||
304:                         (isset($operator) && $operator != $child['operator']) ||
305:                         (isset($value) && $value != $child['value'])) {
306:                         $criteria = false;
307:                         break;
308:                     }
309:                     $criteria[] = $child['criterion'];
310:                     $operator = $child['operator'];
311:                     $value = $child['value'];
312:                 }
313:                 if ($criteria) {
314:                     $vars->set('user', $value);
315:                     $vars->set('operator', $operator);
316:                     foreach ($criteria as $criterion) {
317:                         switch ($criterion) {
318:                         case Whups_Query::CRITERION_OWNERS:
319:                             $vars->set('owners', true);
320:                             break;
321:                         case Whups_Query::CRITERION_REQUESTER:
322:                             $vars->set('requester', true);
323:                             break;
324:                         case Whups_Query::CRITERION_ADDED_COMMENT:
325:                             $vars->set('comments', true);
326:                             break;
327:                         }
328:                     }
329:                     return 'user';
330:                 }
331: 
332:                 // Search for text criteria.
333:                 $criteria = array();
334:                 $operator = $value = null;
335:                 foreach ($qobj['children'] as $child) {
336:                     if ($child['type'] != Whups_Query::TYPE_CRITERION ||
337:                         ($child['criterion'] != Whups_Query::CRITERION_COMMENT &&
338:                          $child['criterion'] != Whups_Query::CRITERION_SUMMARY) ||
339:                         (isset($operator) && $operator != $child['operator']) ||
340:                         (isset($value) && $value != $child['value'])) {
341:                         $criteria = false;
342:                         break;
343:                     }
344:                     $criteria[] = $child['criterion'];
345:                     $operator = $child['operator'];
346:                     $value = $child['value'];
347:                 }
348:                 if ($criteria) {
349:                     $vars->set('text', $value);
350:                     $vars->set('operator', $operator);
351:                     foreach ($criteria as $criterion) {
352:                         if ($criterion == Whups_Query::CRITERION_COMMENT) {
353:                             $vars->set('comments', true);
354:                         } elseif ($criterion == Whups_Query::CRITERION_SUMMARY) {
355:                             $vars->set('summary', true);
356:                         }
357:                     }
358:                     return 'text';
359:                 }
360: 
361:                 // Search for attributes.
362:                 $attribs = array_keys($GLOBALS['whups_driver']->getAttributesForType());
363:                 $criteria = array();
364:                 $operator = $value = null;
365:                 foreach ($qobj['children'] as $child) {
366:                     if ($child['type'] != Whups_Query::TYPE_CRITERION ||
367:                         $child['criterion'] != Whups_Query::CRITERION_ATTRIBUTE ||
368:                         (isset($operator) && $operator != $child['operator']) ||
369:                         (isset($value) && $value != $child['value']) ||
370:                         !in_array($child['cvalue'], $attribs)) {
371:                         $criteria = false;
372:                         break;
373:                     }
374:                     $criteria[] = $child['cvalue'];
375:                     $operator = $child['operator'];
376:                     $value = $child['value'];
377:                 }
378:                 if ($criteria) {
379:                     $vars->set('text', $value);
380:                     $vars->set('operator', $operator);
381:                     foreach ($criteria as $criterion) {
382:                         $vars->set('a' . $criterion, true);
383:                     }
384:                     return 'attribs';
385:                 }
386:                 break;
387: 
388:             case Whups_Query::TYPE_AND:
389:                 // Search for date criteria.
390:                 $criteria = false;
391:                 foreach ($qobj['children'] as $child) {
392:                     if ($child['type'] != Whups_Query::TYPE_CRITERION ||
393:                         ($child['criterion'] != Whups_Query::CRITERION_TIMESTAMP &&
394:                          $child['criterion'] != Whups_Query::CRITERION_UPDATED &&
395:                          $child['criterion'] != Whups_Query::CRITERION_RESOLVED &&
396:                          $child['criterion'] != Whups_Query::CRITERION_ASSIGNED &&
397:                          $child['criterion'] != Whups_Query::CRITERION_DUE)) {
398:                         $criteria = false;
399:                         break;
400:                     }
401:                     $criteria = true;
402:                 }
403:                 if ($criteria) {
404:                     foreach ($qobj['children'] as $child) {
405:                         switch ($child['criterion'] . $child['operator']) {
406:                         case Whups_Query::CRITERION_TIMESTAMP . Whups_Query::OPERATOR_GREATER:
407:                             $vars->set('ticket_timestamp[from]', $child['value']);
408:                             break;
409:                         case Whups_Query::CRITERION_TIMESTAMP . Whups_Query::OPERATOR_LESS:
410:                             $vars->set('ticket_timestamp[to]', $child['value']);
411:                             break;
412:                         case Whups_Query::CRITERION_UPDATED . Whups_Query::OPERATOR_GREATER:
413:                             $vars->set('date_updated[from]', $child['value']);
414:                             break;
415:                         case Whups_Query::CRITERION_UPDATED . Whups_Query::OPERATOR_LESS:
416:                             $vars->set('date_updated[to]', $child['value']);
417:                             break;
418:                         case Whups_Query::CRITERION_RESOLVED . Whups_Query::OPERATOR_GREATER:
419:                             $vars->set('date_resolved[from]', $child['value']);
420:                             break;
421:                         case Whups_Query::CRITERION_RESOLVED . Whups_Query::OPERATOR_LESS:
422:                             $vars->set('date_resolved[to]', $child['value']);
423:                             break;
424:                         case Whups_Query::CRITERION_ASSIGNED . Whups_Query::OPERATOR_GREATER:
425:                             $vars->set('date_assigned[from]', $child['value']);
426:                             break;
427:                         case Whups_Query::CRITERION_ASSIGNED . Whups_Query::OPERATOR_LESS:
428:                             $vars->set('date_assigned[to]', $child['value']);
429:                             break;
430:                         case Whups_Query::CRITERION_DUE . Whups_Query::OPERATOR_GREATER:
431:                             $vars->set('ticket_due[from]', $child['value']);
432:                             break;
433:                         case Whups_Query::CRITERION_DUE . Whups_Query::OPERATOR_LESS:
434:                             $vars->set('ticket_due[to]', $child['value']);
435:                             break;
436:                         }
437:                     }
438:                     return 'date';
439:                 }
440: 
441:                 // Search for version criterion.
442:                 if (count($qobj['children']) == 2 &&
443:                     $qobj['children'][0]['type'] == Whups_Query::TYPE_CRITERION &&
444:                     $qobj['children'][0]['criterion'] == Whups_Query::CRITERION_QUEUE &&
445:                     $qobj['children'][1]['type'] == Whups_Query::TYPE_CRITERION &&
446:                     $qobj['children'][1]['criterion'] == Whups_Query::CRITERION_VERSION) {
447:                     $vars->set('queue', $qobj['children'][0]['value']);
448:                     $vars->set('version', $qobj['children'][1]['value']);
449:                     return 'props';
450:                 }
451:                 break;
452:             }
453:             throw new Whups_Exception(_("This query element cannot be edited."));
454:         }
455: 
456:         switch ($qobj['criterion']) {
457:         case Whups_Query::CRITERION_ID:
458:             $multiple = false;
459:             if ($parent && $parent['type'] == Whups_Query::TYPE_OR) {
460:                 $multiple = array();
461:                 foreach ($parent['children'] as $child) {
462:                     if ($child['type'] != Whups_Query::TYPE_CRITERION ||
463:                         $child['criterion'] != Whups_Query::CRITERION_ID) {
464:                         $multiple = false;
465:                         break;
466:                     }
467:                     $multiple[] = $child['value'];
468:                 }
469:             }
470:             if ($multiple) {
471:                 array_pop($path);
472:                 $vars->set('path', Whups_Query::pathToString($path));
473:                 $vars->set('id', implode(',', $multiple));
474:             } else {
475:                 $vars->set('id', $qobj['value']);
476:             }
477:             return 'props';
478: 
479:         case Whups_Query::CRITERION_QUEUE:
480:             if ($parent && $parent['type'] == Whups_Query::TYPE_AND &&
481:                 count($parent['children']) == 2 &&
482:                 $parent['children'][1]['type'] == Whups_Query::TYPE_CRITERION &&
483:                 $parent['children'][1]['criterion'] == Whups_Query::CRITERION_VERSION) {
484:                 array_pop($path);
485:                 $vars->set('path', Whups_Query::pathToString($path));
486:                 $vars->set('version', $parent['children'][1]['value']);
487:             }
488:             $vars->set('queue', $qobj['value']);
489:             return 'props';
490: 
491:         case Whups_Query::CRITERION_VERSION:
492:             array_pop($path);
493:             $vars->set('path', Whups_Query::pathToString($path));
494:             $vars->set('queue', $parent['children'][0]['value']);
495:             $vars->set('version', $qobj['value']);
496:             return 'props';
497: 
498:         case Whups_Query::CRITERION_TYPE:
499:             $vars->set('ttype', $qobj['value']);
500:             return 'props';
501: 
502:         case Whups_Query::CRITERION_STATE:
503:             $vars->set('state', $qobj['value']);
504:             return 'props';
505: 
506:         case Whups_Query::CRITERION_PRIORITY:
507:             $vars->set('priority', $qobj['value']);
508:             return 'props';
509: 
510:         case Whups_Query::CRITERION_TIMESTAMP:
511:         case Whups_Query::CRITERION_UPDATED:
512:         case Whups_Query::CRITERION_RESOLVED:
513:         case Whups_Query::CRITERION_ASSIGNED:
514:         case Whups_Query::CRITERION_DUE:
515:             $criteria = false;
516:             if ($parent && $parent['type'] == Whups_Query::TYPE_AND) {
517:                 foreach ($parent['children'] as $child) {
518:                     if ($child['type'] != Whups_Query::TYPE_CRITERION ||
519:                         ($child['criterion'] != Whups_Query::CRITERION_TIMESTAMP &&
520:                          $child['criterion'] != Whups_Query::CRITERION_UPDATED &&
521:                          $child['criterion'] != Whups_Query::CRITERION_RESOLVED &&
522:                          $child['criterion'] != Whups_Query::CRITERION_ASSIGNED &&
523:                          $child['criterion'] != Whups_Query::CRITERION_DUE)) {
524:                         $criteria = false;
525:                         break;
526:                     }
527:                     $criteria = true;
528:                 }
529:             }
530:             if ($criteria) {
531:                 array_pop($path);
532:                 $vars->set('path', Whups_Query::pathToString($path));
533:                 foreach ($parent['children'] as $child) {
534:                     switch ($child['criterion'] . $child['operator']) {
535:                     case Whups_Query::CRITERION_TIMESTAMP . Whups_Query::OPERATOR_GREATER:
536:                         $vars->set('ticket_timestamp[from]', $child['value']);
537:                         break;
538:                     case Whups_Query::CRITERION_TIMESTAMP . Whups_Query::OPERATOR_LESS:
539:                         $vars->set('ticket_timestamp[to]', $child['value']);
540:                         break;
541:                     case Whups_Query::CRITERION_UPDATED . Whups_Query::OPERATOR_GREATER:
542:                         $vars->set('date_updated[from]', $child['value']);
543:                         break;
544:                     case Whups_Query::CRITERION_UPDATED . Whups_Query::OPERATOR_LESS:
545:                         $vars->set('date_updated[to]', $child['value']);
546:                         break;
547:                     case Whups_Query::CRITERION_RESOLVED . Whups_Query::OPERATOR_GREATER:
548:                         $vars->set('date_resolved[from]', $child['value']);
549:                         break;
550:                     case Whups_Query::CRITERION_RESOLVED . Whups_Query::OPERATOR_LESS:
551:                         $vars->set('date_resolved[to]', $child['value']);
552:                         break;
553:                     case Whups_Query::CRITERION_ASSIGNED . Whups_Query::OPERATOR_GREATER:
554:                         $vars->set('date_assigned[from]', $child['value']);
555:                         break;
556:                     case Whups_Query::CRITERION_ASSIGNED . Whups_Query::OPERATOR_LESS:
557:                         $vars->set('date_assigned[to]', $child['value']);
558:                         break;
559:                     case Whups_Query::CRITERION_DUE . Whups_Query::OPERATOR_GREATER:
560:                         $vars->set('ticket_due[from]', $child['value']);
561:                         break;
562:                     case Whups_Query::CRITERION_DUE . Whups_Query::OPERATOR_LESS:
563:                         $vars->set('ticket_due[to]', $child['value']);
564:                         break;
565:                     }
566:                 }
567:             }
568:             return 'date';
569: 
570:         case Whups_Query::CRITERION_OWNERS:
571:         case Whups_Query::CRITERION_REQUESTER:
572:         case Whups_Query::CRITERION_ADDED_COMMENT:
573:             $criteria = false;
574:             if ($parent && $parent['type'] == Whups_Query::TYPE_OR) {
575:                 $criteria = array();
576:                 foreach ($parent['children'] as $child) {
577:                     if ($child['type'] != Whups_Query::TYPE_CRITERION ||
578:                         !in_array($child['criterion'], array(Whups_Query::CRITERION_OWNERS, Whups_Query::CRITERION_REQUESTER, Whups_Query::CRITERION_ADDED_COMMENT))) {
579:                         $criteria = false;
580:                         break;
581:                     }
582:                     $criteria[] = $child['criterion'];
583:                 }
584:                 if ($criteria) {
585:                     array_pop($path);
586:                     $vars->set('path', Whups_Query::pathToString($path));
587:                 }
588:             }
589:             if (!$criteria) {
590:                 $criteria = array($qobj['criterion']);
591:             }
592:             $vars->set('user', $qobj['value']);
593:             $vars->set('operator', $qobj['operator']);
594:             foreach ($criteria as $criterion) {
595:                 switch ($criterion) {
596:                 case Whups_Query::CRITERION_OWNERS:
597:                     $vars->set('owners', true);
598:                     break;
599:                 case Whups_Query::CRITERION_REQUESTER:
600:                     $vars->set('requester', true);
601:                     break;
602:                 case Whups_Query::CRITERION_ADDED_COMMENT:
603:                     $vars->set('comments', true);
604:                     break;
605:                 }
606:             }
607:             return 'user';
608: 
609:         case Whups_Query::CRITERION_GROUPS:
610:             $vars->set('groups', $qobj['value']);
611:             return 'group';
612: 
613:         case Whups_Query::CRITERION_COMMENT:
614:         case Whups_Query::CRITERION_SUMMARY:
615:             $criteria = false;
616:             if ($parent && $parent['type'] == Whups_Query::TYPE_OR) {
617:                 $criteria = array();
618:                 $operator = $value = null;
619:                 foreach ($parent['children'] as $child) {
620:                     if ($child['type'] != Whups_Query::TYPE_CRITERION ||
621:                         ($child['criterion'] != Whups_Query::CRITERION_COMMENT &&
622:                          $child['criterion'] != Whups_Query::CRITERION_SUMMARY) ||
623:                         (isset($operator) && $operator != $child['operator']) ||
624:                         (isset($value) && $value != $child['value'])) {
625:                         $criteria = false;
626:                         break;
627:                     }
628:                     $criteria[] = $child['criterion'];
629:                     $operator = $child['operator'];
630:                     $value = $child['value'];
631:                 }
632:                 if ($criteria) {
633:                     array_pop($path);
634:                     $vars->set('path', Whups_Query::pathToString($path));
635:                 }
636:             } else {
637:                 $operator = $qobj['operator'];
638:                 $value = $qobj['value'];
639:             }
640:             if (!$criteria) {
641:                 $criteria = array($qobj['criterion']);
642:             }
643:             $vars->set('text', $value);
644:             $vars->set('operator', $operator);
645:             foreach ($criteria as $criterion) {
646:                 if ($criterion == Whups_Query::CRITERION_COMMENT) {
647:                     $vars->set('comments', true);
648:                 } elseif ($criterion == Whups_Query::CRITERION_SUMMARY) {
649:                     $vars->set('summary', true);
650:                 }
651:             }
652:             return 'text';
653: 
654:         case Whups_Query::CRITERION_ATTRIBUTE:
655:             $attribs = array_keys($GLOBALS['whups_driver']->getAttributesForType());
656:             $criteria = false;
657:             if ($parent && $parent['type'] == Whups_Query::TYPE_OR) {
658:                 $criteria = array();
659:                 $operator = $value = null;
660:                 foreach ($parent['children'] as $child) {
661:                     if ($child['type'] != Whups_Query::TYPE_CRITERION ||
662:                         $child['criterion'] != Whups_Query::CRITERION_ATTRIBUTE ||
663:                         (isset($operator) && $operator != $child['operator']) ||
664:                         (isset($value) && $value != $child['value']) ||
665:                         !in_array($child['cvalue'], $attribs)) {
666:                         $criteria = false;
667:                         break;
668:                     }
669:                     $criteria[] = $child['cvalue'];
670:                     $operator = $child['operator'];
671:                     $value = $child['value'];
672:                 }
673:                 if ($criteria) {
674:                     array_pop($path);
675:                     $vars->set('path', Whups_Query::pathToString($path));
676:                 }
677:             } else {
678:                 $operator = $qobj['operator'];
679:                 $value = $qobj['value'];
680:             }
681:             if (!$criteria) {
682:                 $criteria = array($qobj['cvalue']);
683:             }
684:             $vars->set('text', $value);
685:             $vars->set('operator', $operator);
686:             foreach ($criteria as $criterion) {
687:                 $vars->set('a' . $criterion, true);
688:             }
689:             return 'attribs';
690:         }
691: 
692:         throw new Whups_Exception(_("This query element cannot be edited."));
693:     }
694: 
695:     public function deleteNode($pathstring)
696:     {
697:         $path = Whups_Query::stringToPath($pathstring);
698:         $qobj = &$this->query;
699: 
700:         if (!strlen($pathstring)) {
701:             // Deleting the root node isn't supported.
702:             $GLOBALS['notification']->push(_("Choose New Query instead of deleting the root node."), 'horde.warning');
703:             return false;
704:         } else {
705:             $count = count($path) - 1;
706:             for ($i = 0; $i < $count; $i++) {
707:                 $qobj = &$qobj['children'][$path[$i]];
708:             }
709: 
710:             if (!empty($qobj['children'][$path[$count]]['value']) &&
711:                 $this->_getParameterName($qobj['children'][$path[$count]]['value']) !== null) {
712:                 unset($this->parameters[array_search($pn, $this->parameters)]);
713:             }
714: 
715:             array_splice($qobj['children'], $path[$count], 1);
716:         }
717:     }
718: 
719:     public function hoist($pathstring)
720:     {
721:         $path = Whups_Query::stringToPath($pathstring);
722:         $qobj = &$this->query;
723: 
724:         if (!strlen($pathstring)) {
725:             // Can't hoist the root node.
726:         } else {
727:             $count = count($path) - 1;
728: 
729:             for ($i = 0; $i < $count; $i++) {
730:                 $qobj = &$qobj['children'][$path[$i]];
731:             }
732: 
733:             $cobj = &$qobj['children'][$path[$count]];
734: 
735:             // TODO: make sure we're hoisting a branch.
736:             array_splice($qobj['children'], $path[$count], 0, $cobj['children']);
737:             array_splice($cobj['children'], 0, count($cobj['children']));
738:         }
739:     }
740: 
741:     public function insertBranch($pathstring, $type)
742:     {
743:         $path = Whups_Query::stringToPath($pathstring);
744:         $qobj = &$this->query;
745: 
746:         $newbranch = array(
747:             'type'     => $type,
748:             'children' => array());
749: 
750:         $count = count($path);
751: 
752:         for ($i = 0; $i < $count; $i++) {
753:             $qobj = &$qobj['children'][$path[$i]];
754:         }
755: 
756:         if (!isset($qobj['children']) ||
757:             !is_array($qobj['children'])) {
758:             $qobj['children'] = array();
759:         }
760: 
761:         $qobj['children'][] = $newbranch;
762:         $path[] = count($qobj['children']) - 1;
763: 
764:         return Whups_Query::pathToString($path);
765:     }
766: 
767:     public function insertCriterion($pathstring, $criterion, $cvalue, $operator, $value)
768:     {
769:         $path = Whups_Query::stringToPath($pathstring);
770:         $qobj = &$this->query;
771: 
772:         $value = trim($value);
773:         if ($value[0] == '"') {
774:             // FIXME: The last character should be '"' as well.
775:             $value = substr($value, 1, -1);
776:         } else {
777:             $pn = $this->_getParameterName($value);
778:             if ($pn !== null) {
779:                 $this->parameters[] = $pn;
780:             }
781:         }
782: 
783:         $newbranch = array(
784:             'type'      => Whups_Query::TYPE_CRITERION,
785:             'criterion' => $criterion,
786:             'cvalue'    => $cvalue,
787:             'operator'  => $operator,
788:             'value'     => $value);
789: 
790:         $count = count($path);
791:         for ($i = 0; $i < $count; $i++) {
792:             $qobj = &$qobj['children'][$path[$i]];
793:         }
794: 
795:         $qobj['children'][] = $newbranch;
796:     }
797: 
798:     /**
799:      * Top down traversal.
800:      */
801:     public function walk(&$obj, $method)
802:     {
803:         $path = array();
804:         $more = array();
805:         $this->_walk($this->query, $more, $path, $obj, $method);
806:     }
807: 
808:     /**
809:      * @access private
810:      */
811:     protected function _walk(&$node, &$more, &$path, &$obj, $method)
812:     {
813:         if ($node['type'] == Whups_Query::TYPE_CRITERION) {
814:             $obj->$method($more, $path, Whups_Query::TYPE_CRITERION, $node['criterion'],
815:                           $node['cvalue'], $node['operator'], $node['value']);
816:         } else {
817:             $obj->$method($more, $path, $node['type'], null, null, null, null);
818:         }
819: 
820:         if (isset($node['children'])) {
821:             $count = count($node['children']);
822: 
823:             for ($i = 0; $i < $count; $i++) {
824:                 $path[] = $i;
825:                 $more[] = ($i < $count - 1);
826:                 $this->_walk($node['children'][$i], $more, $path, $obj, $method);
827:                 array_pop($more);
828:                 array_pop($path);
829:             }
830:         }
831:     }
832: 
833:     /**
834:      * Bottom up traversal.
835:      */
836:     public function reduce($method, &$vars)
837:     {
838:         return $this->_reduce($this->query, $method, $vars);
839:     }
840: 
841:     /**
842:      * @access private
843:      */
844:     protected function _reduce(&$node, $method, &$vars)
845:     {
846:         $args = array();
847: 
848:         if (isset($node['children'])) {
849:             $count = count($node['children']);
850: 
851:             for ($i = 0; $i < $count; $i++) {
852:                 $result = $this->_reduce($node['children'][$i], $method, $vars);
853:                 $args[] = $result;
854:             }
855:         }
856: 
857:         if ($node['type'] == Whups_Query::TYPE_CRITERION) {
858:             $value = $node['value'];
859: 
860:             $pn = $this->_getParameterName($value);
861:             if ($pn !== null) {
862:                 $value = $vars->get($pn);
863:             }
864: 
865:             return call_user_func(
866:                 $method, $args, Whups_Query::TYPE_CRITERION, $node['criterion'],
867:                 $node['cvalue'], $node['operator'], $value);
868:         }
869: 
870:         return call_user_func($method, $args, $node['type'], null, null, null, null);
871:     }
872: 
873:     /**
874:      * @access private
875:      */
876:     protected function _getParameterName($value)
877:     {
878:         if (strcmp(substr($value, 0, 2), '${'))
879:             return null;
880: 
881:         $pn = substr($value, 2, -1);
882:         if (!is_string($pn))
883:             $pn = null;
884: 
885:         return $pn;
886:     }
887: 
888: }
889: 
API documentation generated by ApiGen