0009768: Use ModelConfig for Timetracker models
[tine20] / tine20 / Timetracker / Model / TimesheetFilter.php
1 <?php
2 /**
3  * Tine 2.0
4  * 
5  * @package     Tinebase
6  * @subpackage  Filter
7  * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
8  * @copyright   Copyright (c) 2007-2012 Metaways Infosystems GmbH (http://www.metaways.de)
9  * @author      Cornelius Weiss <c.weiss@metaways.de>
10  */
11
12 /**
13  * Tinebase_Model_Filter_FilterGroup
14  * 
15  * @package     Timetracker
16  * @subpackage  Filter
17  * 
18  * @todo refactor this to comply to default acl filtering (@see Tinebase_Controller_Record_Abstract::checkFilterACL)
19  */
20 class Timetracker_Model_TimesheetFilter extends Tinebase_Model_Filter_FilterGroup implements Tinebase_Model_Filter_AclFilter 
21 {
22     /**
23      * if this is set, the filtergroup will be created using the configurationObject for this model
24      *
25      * @var string
26      */
27     protected $_configuredModel = 'Timetracker_Model_Timesheet';
28     
29     /**
30      * is resolved
31      *
32      * @var boolean
33      */
34     protected $_isResolved = FALSE;
35     
36     /**
37      * @var array one of these grants must be met
38      */
39     protected $_requiredGrants = array(
40         Timetracker_Model_TimeaccountGrants::BOOK_OWN,
41         // NOTE: this is needed to make the search for other users timesheets work
42         Timetracker_Model_TimeaccountGrants::VIEW_ALL,
43     );
44     
45     /**
46      * sets the grants this filter needs to assure
47      *
48      * @param array $_grants
49      */
50     public function setRequiredGrants(array $_grants)
51     {
52         $this->_requiredGrants = $_grants;
53         $this->_isResolved = FALSE;
54     }
55     
56     /**
57      * appends custom filters to a given select object
58      * 
59      * @param  Zend_Db_Select                    $_select
60      * @param  Tinebase_Backend_Sql_Abstract     $_backend
61      * @return void
62      * 
63      * @todo replace custom filter!
64      */
65     public function appendFilterSql($_select, $_backend)
66     {
67         $this->_appendAclSqlFilter($_select);
68
69         $db = $_backend->getAdapter();
70         foreach ($this->_customData as $customData) {
71             $value = $customData['value'];
72             if ($customData['field'] == 'is_cleared') {
73                 $_select->joinLeft(
74                     /* table  */ array('ta' => $db->table_prefix . 'timetracker_timeaccount'), 
75                     /* on     */ $db->quoteIdentifier('ta.id') . ' = ' . $db->quoteIdentifier('timetracker_timesheet.timeaccount_id'),
76                     /* select */ array()
77                 );
78                 
79                 $opStatus = $value ? '=' : '<>';
80                 $op = $value ? ' OR ' : ' AND ';
81                 $_select->where(
82                     $db->quoteInto($customData['field']  . ' = ?', $value) . $op .
83                     $db->quoteInto('ta.status' . $opStatus . ' ? ', 'billed')
84                 );
85             }
86         }
87     }
88     
89     /**
90      * append acl filter
91      *
92      * @param Zend_Db_Select $_select
93      */
94     protected function _appendAclSqlFilter($_select)
95     {
96         if ($this->getCondition() === self::CONDITION_OR) {
97             // ACL filter with OR condition is useless and delivers wrong results!
98             if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' '
99                 . ' No ACL filter for OR condition!');
100             return;
101         }
102         
103         if (Timetracker_Controller_Timesheet::getInstance()->checkRight(Timetracker_Acl_Rights::MANAGE_TIMEACCOUNTS, FALSE, FALSE)) {
104             if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' '
105                 . ' No ACL filter for MANAGE_TIMEACCOUNTS right!');
106             return;
107         }
108         
109         if (! $this->_isResolved) {
110             // get all timeaccounts user has required grants for
111             $result = array();
112             foreach ($this->_requiredGrants as $grant) {
113                 if ($grant != Timetracker_Model_TimeaccountGrants::BOOK_OWN) {
114                     $result = array_merge($result, Timetracker_Model_TimeaccountGrants::getTimeaccountsByAcl($grant, TRUE));
115                 }
116             }
117             $this->_validTimeaccounts = array_unique($result);
118             if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ 
119                 . ' valid timeaccounts' . print_r($this->_validTimeaccounts, TRUE) . ' for required grants: ' . print_r($this->_requiredGrants, TRUE));
120             $this->_isResolved = TRUE;
121         }
122         
123         $db = Tinebase_Core::getDb();
124         
125         $field = $db->quoteIdentifier('timeaccount_id');
126         $where = $db->quoteInto("$field IN (?)", empty($this->_validTimeaccounts) ? array('') : $this->_validTimeaccounts);
127         
128         // get timeaccounts with BOOK_OWN right (get only if no manual filter is set)
129         $bookOwnTS = Timetracker_Model_TimeaccountGrants::getTimeaccountsByAcl(Timetracker_Model_TimeaccountGrants::BOOK_OWN, TRUE);
130         if (! empty($bookOwnTS)) {
131             $where .= ' OR (' . $db->quoteInto($field . ' IN (?)', $bookOwnTS)
132                 . ' AND ' . $db->quoteInto($db->quoteIdentifier('account_id'). ' = ?', Tinebase_Core::getUser()->getId()) .')';
133         }
134         
135         $_select->where($where);
136         
137         if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__
138             . ' ACL filter: ' . $where);
139     }
140 }