Tinebase_Model_Filter_GrantsFilterGroup - fix recursive join issue
[tine20] / tine20 / Tinebase / Model / Tree / Node / Filter.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  * @author      Lars Kneschke <l.kneschke@metaways.de>
9  * @copyright   Copyright (c) 2010-2017 Metaways Infosystems GmbH (http://www.metaways.de)
10  */
11
12 /**
13  * tree node filter class
14  * 
15  * @package     Tinebase
16  * @subpackage  Filter
17  */
18 class Tinebase_Model_Tree_Node_Filter extends Tinebase_Model_Filter_GrantsFilterGroup
19 {
20     /**
21      * @var string class name of this filter group
22      *      this is needed to overcome the static late binding
23      *      limitation in php < 5.3
24      */
25     protected $_className = 'Tinebase_Model_Tree_Node_Filter';
26     
27     /**
28      * @var string application of this filter group
29      */
30     protected $_applicationName = 'Tinebase';
31     
32     /**
33      * @var string name of model this filter group is designed for
34      */
35     protected $_modelName = 'Tinebase_Model_Tree_Node';
36
37     /**
38      * @var string acl table name
39      */
40     protected $_aclTableName = 'tree_node_acl';
41
42     /**
43      * @var string acl record column for join with acl table
44      */
45     protected $_aclIdColumn = 'acl_node';
46
47     /**
48      * @var bool
49      */
50     protected $_ignorePinProtection = false;
51
52     /**
53      * @var array filter model fieldName => definition
54      */
55     protected $_filterModel = array(
56         'query'                 => array(
57             'filter' => 'Tinebase_Model_Filter_Query', 
58             'options' => array('fields' => array('name', 'content', 'description'))
59         ),
60         'id'                    => array('filter' => 'Tinebase_Model_Filter_Id'),
61         'path'                  => array('filter' => 'Tinebase_Model_Tree_Node_PathFilter'),
62         'parent_id'             => array('filter' => 'Tinebase_Model_Filter_Text'),
63         'name'                  => array(
64             'filter' => 'Tinebase_Model_Filter_Text',
65             'options' => array('binary' => true)
66         ),
67         'object_id'             => array('filter' => 'Tinebase_Model_Filter_Text'),
68         'acl_node'              => array('filter' => 'Tinebase_Model_Filter_Text'),
69     // tree_fileobjects table
70         'last_modified_time'    => array(
71             'filter' => 'Tinebase_Model_Filter_Date',
72             'options' => array('tablename' => 'tree_fileobjects')
73         ),
74         'deleted_time'          => array(
75             'filter' => 'Tinebase_Model_Filter_DateTime',
76             'options' => array('tablename' => 'tree_fileobjects')
77         ),
78         'creation_time'         => array(
79             'filter' => 'Tinebase_Model_Filter_Date',
80             'options' => array('tablename' => 'tree_fileobjects')
81         ),
82         'last_modified_by'      => array(
83             'filter' => 'Tinebase_Model_Filter_User',
84             'options' => array('tablename' => 'tree_fileobjects'
85         )),
86         'created_by'            => array(
87             'filter' => 'Tinebase_Model_Filter_User',
88             'options' => array('tablename' => 'tree_fileobjects')
89         ),
90         'type'                  => array(
91             'filter' => 'Tinebase_Model_Filter_Text', 
92             'options' => array('tablename' => 'tree_fileobjects')
93         ),
94         'contenttype'           => array(
95             'filter' => 'Tinebase_Model_Filter_Text',
96             'options' => array('tablename' => 'tree_fileobjects')
97         ),
98         'description'           => array(
99             'filter' => 'Tinebase_Model_Filter_FullText',
100             'options' => array('tablename' => 'tree_fileobjects')
101         ),
102     // tree_filerevisions table
103         'size'                  => array(
104             'filter' => 'Tinebase_Model_Filter_Int',
105             'options' => array('tablename' => 'tree_filerevisions')
106         ),
107     // recursive search
108         'recursive'             => array(
109             'filter' => 'Tinebase_Model_Filter_Bool'
110         ),
111         'tag'                   => array('filter' => 'Tinebase_Model_Filter_Tag', 'options' => array(
112             'idProperty' => 'tree_nodes.id',
113             'applicationName' => 'Tinebase',
114         )),
115     // fulltext search
116         'content'               => array(
117             'filter'                => 'Tinebase_Model_Filter_ExternalFullText',
118             'options'               => array(
119                 'idProperty'            => 'object_id',
120             )
121         ),
122         'isIndexed'             => array(
123             'filter'                => 'Tinebase_Model_Tree_Node_IsIndexedFilter',
124         ),
125         'is_deleted'            => array(
126             'filter'                => 'Tinebase_Model_Filter_Bool'
127         )
128     );
129
130     /**
131      * set options
132      *
133      * @param array $_options
134      */
135     protected function _setOptions(array $_options)
136     {
137         if (isset($_options['nameCaseInSensitive']) && $_options['nameCaseInSensitive']) {
138             $this->_filterModel['name']['options']['caseSensitive'] = false;
139         }
140         parent::_setOptions($_options);
141     }
142
143     /**
144      * append grants acl filter
145      *
146      * @param Zend_Db_Select $select
147      * @param Tinebase_Backend_Sql_Abstract $backend
148      * @param Tinebase_Model_User $user
149      */
150     protected function _appendGrantsFilter($select, $backend, $user = null)
151     {
152         parent::_appendGrantsFilter($select, $backend, $user);
153
154         if (!$this->_ignorePinProtection && !Tinebase_Auth_SecondFactor_Abstract::hasValidSecondFactor()) {
155             $db = $backend->getAdapter();
156             $uniqueId = uniqid('pinProtected');
157             $select->joinLeft(array(
158                 /* table  */ $uniqueId => SQL_TABLE_PREFIX . $backend->getTableName()),
159                 /* on     */ "{$db->quoteIdentifier($uniqueId . '.id')} = {$db->quoteIdentifier($backend->getTableName() . '.' . $this->_aclIdColumn)}",
160                 /* select */ array()
161             );
162             $select->where("{$db->quoteIdentifier($uniqueId . '.pin_protected')} = 0 OR {$db->quoteIdentifier($uniqueId . '.pin_protected')} IS NULL");
163         }
164
165         // TODO do something when acl_node = NULL?
166     }
167
168     public function ignorePinProtection($_value = true)
169     {
170         $this->_ignorePinProtection = $_value;
171     }
172
173     /**
174      * return folder + parent_id filter with ignore acl
175      *
176      * @param $folderId
177      * @return Tinebase_Model_Tree_Node_Filter
178      */
179     public static function getFolderParentIdFilterIgnoringAcl($folderId)
180     {
181         return new Tinebase_Model_Tree_Node_Filter(array(
182             array(
183                 'field'     => 'parent_id',
184                 'operator'  => $folderId === null ? 'isnull' : 'equals',
185                 'value'     => $folderId
186             ), array(
187                 'field'     => 'type',
188                 'operator'  => 'equals',
189                 'value'     => Tinebase_Model_Tree_FileObject::TYPE_FOLDER
190             )
191         ), Tinebase_Model_Filter_FilterGroup::CONDITION_AND, array('ignoreAcl' => true));
192     }
193 }