1 <?php
3 class userFilter extends plugin
4 {
5 public $pathTitle= "Filter";
7 public $filters = array();
8 protected $availableCategories = array();
10 public $objectclasses = array('gosaProperties');
11 public $attributes = array('gosaUserDefinedFilter');
12 public $gosaUserDefinedFilter = array();
14 private $listing = NULL;
15 private $fixedFilter = NULL;
17 /*! \brief Returns true if we are able to read and write userFilters
18 * (schema has to be present, gosaProperties)
19 */
20 static function userFilteringAvailable()
21 {
22 if(!session::is_set('userFilter::userFilteringAvailable')){
23 global $config;
24 $ldap = $config->get_ldap_link();
25 $ocs = $ldap->get_objectclasses();
26 session::set('userFilter::userFilteringAvailable', isset($ocs['gosaProperties']));
27 }
28 return(session::get('userFilter::userFilteringAvailable'));
29 }
32 /*! \brief Initiates the filter editing dialog.
33 */
34 function __construct($config, $listing)
35 {
36 // Initialize this plugin with the users dn to gather user defined filters.
37 $ui = get_userinfo();
38 plugin::plugin($config, $ui->dn);
39 $this->listing = &$listing;
40 $filter= $this->listing->getFilter();
41 $this->fixedFilter = $filter->getFixedFilters();
43 // Keep list of currently managed categories.
44 $this->availableCategories = array_unique($this->listing->categories);
46 // Load list of filters
47 if(isset($this->attrs['gosaUserDefinedFilter'])){
48 for($i=0; $i< $this->attrs['gosaUserDefinedFilter']['count']; $i++){
49 $tmp = userFilter::explodeFilterString($this->attrs['gosaUserDefinedFilter'][$i]);
50 if(isset($tmp['name'])){
51 $this->filters[$tmp['name']]= $tmp;
52 }
53 }
54 }
56 // Create the filter list
57 $this->filterWidget= new sortableListing($this->filters, $this->convertFilterList());
58 $this->filterWidget->setDeleteable(true);
59 $this->filterWidget->setEditable(true);
60 $this->filterWidget->setWidth("100%");
61 $this->filterWidget->setHeight("270px");
62 $this->filterWidget->setHeader(array(_("Parent filter"),_("Name"),_("Description"),_("Category"),_("Options"),""));
63 $this->filterWidget->setColspecs(array('80px', '100px', '200px', '120px','150px'));
64 $this->filterWidget->setAcl($ui->get_permissions($ui->dn,'users/user','gosaUserDefinedFilter'));
65 }
68 /*! \brief Parses a filter string into an array.
69 */
70 static function explodeFilterString($filterStr)
71 {
72 list($parent,$categories, $name, $description, $filterList, $flags) = split(";", $filterStr);
74 // Ensure that we no empty category in our category list.
75 if(empty($categories)){
76 $categories = array();
77 }else{
78 $categories = split(',', $categories);
79 }
81 // Ensure that we no empty entry in out flags list.
82 if(empty($flags)){
83 $flags = array();
84 }else{
85 $flags = preg_split('/,/', $flags);
86 }
88 // Get filters and their backends
89 $queries = array();
90 foreach(split(",", $filterList) as $data){
91 list($filter, $backend) = preg_split('/:/', $data);
92 $queries[] = array('backend' => $backend, 'filter' => base64_decode($filter));
93 }
95 // build up filter entry.
96 $tmp = array(
97 'parent' => $parent,
98 'name' => $name,
99 'categories' => $categories,
100 'description' => base64_decode($description),
101 'queries' => $queries,
102 'flags' => $flags);
104 return($tmp);
105 }
108 /*! \brief Converts the list of filters ($this->filters) into data which is useable
109 * for the sortableList object ($this->filterWidget).
110 * @return Array An array containg data useable for sortableLists ($this->filterWidget)
111 */
112 function convertFilterList()
113 {
114 $data = array();
115 foreach($this->filters as $name => $filter){
116 $data[$name] = array('data' =>
117 array(
118 $filter['parent'],
119 $filter['name'],
120 $filter['description'],
121 implode(", ",$filter['categories']),
122 implode(", ",$filter['flags'])));
123 }
124 return($data);
125 }
128 /*! \brief Display the user-filter overview as HTML content.
129 * @return string HTML-content showing the user-filter editing dialog.
130 */
131 function execute()
132 {
133 plugin::execute();
135 // Let the filter widget update itself
136 $this->filterWidget->update();
138 // Cancel filter modifications (edit dialog)
139 if(isset($_POST['cancelFilterSettings'])){
140 $this->dialog = NULL;
141 }
143 // Save modified filter entries (edit dialog)
144 if(isset($_POST['saveFilterSettings']) && $this->dialog instanceOf userFilterEditor){
145 $this->dialog->save_object();
146 $msgs = $this->dialog->check();
147 if(count($msgs)){
148 msg_dialog::displayChecks($msgs);
149 }else{
150 $orig_name = $this->dialog->getOriginalName();
151 $new_name = $this->dialog->getCurrentName();
153 // The object was renamed and
154 if($orig_name != $new_name && isset($this->filters[$new_name])){
155 $msgs = array(msgPool::duplicated(_("Name")));
156 msg_dialog::displayChecks($msgs);
157 }else{
159 // Remove old entry if filter was renamed
160 if($orig_name != "" && isset($this->filters[$orig_name])){
161 unset($this->filters[$orig_name]);
162 }
164 // Now append the new filter object.
165 $this->filters[$new_name] = $this->dialog->save();
166 $this->dialog = NULL;
167 $this->filterWidget->setListData($this->filters, $this->convertFilterList());
168 $this->filterWidget->update();
169 }
170 }
171 }
173 // Act on edit requests
174 $this->filterWidget->save_object();
175 $action = $this->filterWidget->getAction();
176 if($action['action'] == 'edit' && count($action['targets']) == 1){
177 $key= $this->filterWidget->getKey($action['targets'][0]);
178 if(isset($this->filters[$key])){
179 $this->dialog=new userFilterEditor($this->filters[$key], $this->availableCategories, $this->fixedFilter);
180 }
181 }
183 // Act on new requests
184 if(isset($_POST['addFilter'])){
185 $this->dialog=new userFilterEditor(array(), $this->availableCategories, $this->fixedFilter);
186 }
188 // Act on remove requests
189 $action = $this->filterWidget->getAction();
190 if($action['action'] == 'delete' && count($action['targets']) == 1){
191 $key= $this->filterWidget->getKey($action['targets'][0]);
192 if(isset($this->filters[$key])){
193 unset($this->filters[$key]);
194 $this->filterWidget->update();
195 }
196 }
198 // Display edit dialog
199 if($this->dialog instanceOf userFilterEditor){
200 $this->dialog->save_object();
201 return($this->dialog->execute());
202 }
204 $smarty = get_smarty();
205 $smarty->assign("list", $this->filterWidget->render());
206 return($smarty->fetch(get_template_path('userFilter.tpl', FALSE)));
207 }
210 /*! \brief Returns user defined filter for a given list of categories,
211 * if no categories were specified all enabled filters will be returned.
212 */
213 static function getFilter($category=array())
214 {
215 global $config;
216 $ldap=$config->get_ldap_link();
217 $ui = get_userinfo();
218 $ldap->cd($config->current['BASE']);
219 $ldap->search("(&(objectClass=gosaProperties)(gosaUserDefinedFilter=*))",array('gosaUserDefinedFilter'));
220 $filter = array();
221 while($attrs = $ldap->fetch()){
222 for($i=0; $i < $attrs['gosaUserDefinedFilter']['count']; $i++){
223 $tmp = userFilter::explodeFilterString($attrs['gosaUserDefinedFilter'][$i]);
224 if(!isset($tmp['name'])) continue;
226 // Remove line breaks from the filter, which may were added for better reading.
227 $c = preg_split('/\n/',$tmp['filter']);
229 foreach($c as $key => $str) $c[$key] = trim($str);
230 $tmp['filter'] = implode($c);
232 // The filter is visible if it is shared or if is one of our own creations.
233 // ... and enabled.
234 $visible = in_array('enable', $tmp['flags']) &&
235 ($attrs['dn'] == $ui->dn || in_array('share', $tmp['flags']));
237 // Convert filter encoding
238 $tmp['filter'] = mb_convert_encoding($tmp['filter'], 'UTF-8');
240 // Add filter if it matches the category list
241 if($visible && (count($category) == 0 || array_intersect($category, $tmp['categories']))){
242 $filter[$tmp['name']] = $tmp;
243 }
244 }
245 }
246 return($filter);
247 }
250 /*! \brief Write user-filter modifications back to the ldap.
251 */
252 function save()
253 {
254 // Build up new list of filters
255 $attrs = array();
256 foreach($this->filters as $filter){
257 $tmp = $filter['parent'].";";
258 $tmp.= implode(',', $filter['categories']).";";
259 $tmp.= $filter['name'].";";
260 $tmp.= base64_encode($filter['description']).";";
262 // Add queries
263 foreach($filter['queries'] as $query){
264 $tmp.= base64_encode($query['filter']).":".$query['backend'].",";
265 }
266 $tmp = trim($tmp,",").";";
267 $tmp.= implode(',', $filter['flags']);
268 $attrs[] = $tmp;
269 }
270 $this->gosaUserDefinedFilter = $attrs;
272 plugin::save();
274 $ldap = $this->config->get_ldap_link();
275 $ldap->cd($this->dn);
276 $ldap->modify($this->attrs);
278 new log("modify","users/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
280 if (!$ldap->success()){
281 msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn, LDAP_MOD, get_class()));
282 }
283 }
286 /*! \brief Do not save any posted values here.
287 */
288 function save_object(){}
289 }
291 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
292 ?>