1<?php
2	class Categories_BO
3	{
4		var $so;
5		var $currentcats;
6
7		function Categories_BO()
8		{
9			//all sitemgr BOs should be instantiated via a globalized Common_BO object,
10			$this->so = CreateObject('sitemgr.Categories_SO', True);
11		}
12
13		//since we need this information several times we store it once,
14		//this function is called by Sites_BO after the current site is defined
15		function setcurrentcats()
16		{
17			$this->currentcats = $this->getpermittedcats(CURRENT_SITE_ID,'active',True);
18			$this->readablecats = $this->getpermittedcatsRead();
19		}
20
21		function getCategoryOptionList()
22		{
23			$retval[] = array('value'=>0,'display'=>'[No Parent]');
24			$list = $this->getpermittedcatsWrite();
25			foreach($list as $cat_id)
26			{
27				$cat = $this->getCategory($cat_id);
28				$padding = str_pad('',12*($cat->depth-1),'&nbsp;');
29				$retval[] = array('value'=>$cat->id, 'display'=>$padding.$cat->name);
30			}
31			return $retval;
32		}
33
34		function getpermittedcatsRead($cat_id=False,$recurse=true)
35		{
36			if (!$cat_id)
37			{
38				$cat_id = CURRENT_SITE_ID;
39			}
40			if ($cat_id != CURRENT_SITE_ID)
41			{
42				$this->check($cat_id);
43			}
44			return $this->getpermittedcats($cat_id,'read',$recurse);
45		}
46		function getpermittedcatsWrite($cat_id=False,$recurse=true)
47		{
48			if (!$cat_id)
49			{
50				$cat_id = CURRENT_SITE_ID;
51			}
52			if ($cat_id != CURRENT_SITE_ID)
53			{
54				$this->check($cat_id);
55			}
56			return $this->getpermittedcats($cat_id,'write',$recurse);
57		}
58		function getpermittedcatsCommitable()
59		{
60			return $this->getpermittedcats(CURRENT_SITE_ID,'commitable',true);
61		}
62
63		function getpermittedcatsArchived()
64		{
65			return $this->getpermittedcats(CURRENT_SITE_ID,'archived',true);
66		}
67
68		function getpermittedcats($cat_id,$check,$recurse)
69		{
70			$root_list = $this->so->getChildrenIDList($cat_id);
71			$permitted_list=array();
72			while(list(,$root_cat) = @each($root_list))
73			{
74				switch ($check)
75				{
76					case 'commitable':
77						$permitted = (
78							$this->so->isactive($root_cat,$GLOBALS['Common_BO']->getstates('Commit')) &&
79							$GLOBALS['Common_BO']->acl->is_admin()
80						);
81						break;
82					case 'archived':
83						$permitted = (
84							$this->so->isactive($root_cat,$GLOBALS['Common_BO']->getstates('Archive')) &&
85							$GLOBALS['Common_BO']->acl->is_admin()
86						);
87						break;
88					case 'active':
89						$permitted = $this->so->isactive($root_cat);
90						break;
91					case 'read':
92						$permitted = (in_array($root_cat,$this->currentcats) && $GLOBALS['Common_BO']->acl->can_read_category($root_cat));
93						break;
94					case 'write':
95						$permitted = (in_array($root_cat,$this->currentcats) && $GLOBALS['Common_BO']->acl->can_write_category($root_cat));
96				}
97
98				if ($permitted)
99				{
100					$permitted_list[]=$root_cat;
101				}
102				//subcategories can be readable/writeable even when parent is not, but when parent is inactive subcats are too.
103				elseif ($check == 'active')
104				{
105					continue;
106				}
107				if ($recurse)
108				{
109					$sub_list = $this->getpermittedcats($root_cat,$check,true);
110					if (count($sub_list)>0)
111					{
112						//array_push($permitted_list, $sub_list);
113						$permitted_list=array_merge($permitted_list, $sub_list);
114					}
115				}
116			}
117			return $permitted_list;
118		}
119
120		function addCategory($name, $description, $parent=False)
121		{
122			if (!$parent)
123			{
124				$parent = CURRENT_SITE_ID;
125			}
126
127			if ($GLOBALS['Common_BO']->acl->is_admin())
128			{
129				$cat_id = $this->so->addCategory($name, $description, $parent);
130				$this->currentcats[] = $cat_id;
131				return $cat_id;
132			}
133			else
134			{
135				return false;
136			}
137		}
138
139		//$force for use by Sites_BO, since when we are editing the files list, the concept of admin of a current site does not apply
140		//$frecurse also removes subcats
141		function removeCategory($cat_id,$force=False,$recurse=False)
142		{
143			if (!$force)
144			{
145				$this->check($cat_id);
146
147				if (!$GLOBALS['Common_BO']->acl->is_admin())
148				{
149					return False;
150				}
151			}
152			if ($recurse)
153			{
154				$children = $this->so->getChildrenIDList($cat_id);
155				while (list($null,$subcat) = @each($children))
156				{
157					$this->removeCategory($subcat,True,True);
158				}
159			}
160			/********************************************\
161			* We have to remove the category, all the    *
162			* associated pages, and all the associated   *
163			* acl stuff too.  not to forget blocks       *
164			\********************************************/
165			$GLOBALS['Common_BO']->content->removeBlocksInPageOrCat($cat_id,0,True);
166			$GLOBALS['Common_BO']->pages->removePagesInCat($cat_id,True);
167			$this->so->removeCategory($cat_id);
168			$GLOBALS['Common_BO']->acl->remove_location($cat_id);
169
170			return True;
171		}
172
173		function saveCategoryInfo($cat_id, $cat_name, $cat_description, $lang, $sort_order, $state, $parent=False, $old_parent=False)
174		{
175			if (!$parent)
176			{
177				$parent = CURRENT_SITE_ID;
178			}
179			$cat_info = CreateObject('sitemgr.Category_SO', True);
180			$cat_info->id = $cat_id;
181			$cat_info->name = $cat_name;
182			$cat_info->description = $cat_description;
183			$cat_info->sort_order = $sort_order;
184			$cat_info->state = $state;
185			$cat_info->parent = $parent;
186			$cat_info->old_parent = $old_parent ? $old_parent : $parent;
187
188			if ($GLOBALS['Common_BO']->acl->can_write_category($cat_id))
189			{
190				if ($this->so->saveCategory($cat_info));
191				{
192					if ($this->so->saveCategoryLang($cat_id, $cat_name, $cat_description, $lang))
193					{
194						//reflect changes
195						$this->setcurrentcats();
196						return true;
197					}
198				}
199			}
200			return false;
201		}
202
203		function saveCategoryLang($cat_id, $cat_name, $cat_description, $lang)
204		{
205			if ($this->so->saveCategoryLang($cat_id, $cat_name, $cat_description, $lang))
206			{
207				return true;
208			}
209			return false;
210		}
211
212		//$force is for bypassing ACL when we called from Sites_UI for building up the info for the currentsite
213		//and for getting at archived categories that are not listed in current nor readablecats
214		function getCategory($cat_id,$lang=False,$force=False)
215		{
216			if ($force || ($this->check($cat_id) && in_array($cat_id,$this->readablecats)))
217			{
218				return $this->so->getCategory($cat_id,$lang);
219			}
220			else
221			{
222				return false;
223			}
224		}
225
226		function getCategoryancestorids($cat_id,$permittedonly=False)
227		{
228			if (!$cat_id)
229			{
230				$cat_id = CURRENT_SITE_ID;
231			}
232			if ($cat_id != CURRENT_SITE_ID)
233			{
234				$this->check($cat_id);
235			}
236			$result = array();
237			while ($cat_id != CURRENT_SITE_ID)
238			{
239				if (!$permittedonly || in_array($cat_id,$this->readablecats))
240				{
241					$result[] = $cat_id;
242				}
243				$cat_info = $this->so->getCategory($cat_id);
244				$cat_id = $cat_info->parent;
245			}
246			return $result;
247		}
248
249		function getlangarrayforcategory($cat_id)
250		{
251			return $this->so->getlangarrayforcategory($cat_id);
252		}
253
254		function saveCategoryPerms($cat_id, $group_access, $user_access)
255		{
256			if ($GLOBALS['Common_BO']->acl->is_admin())
257			{
258				$group_access=array_merge_recursive($GLOBALS['Common_BO']->acl->get_simple_group_list(),$group_access);
259				$user_access=array_merge_recursive($GLOBALS['Common_BO']->acl->get_simple_user_list(),$user_access);
260				$this->saveCatPermsGeneric($cat_id, $group_access);
261				$this->saveCatPermsGeneric($cat_id, $user_access);
262				return true;
263			}
264			else
265			{
266				return false;
267			}
268		}
269
270		function saveCatPermsGeneric($cat_id, $user_access)
271		{
272			if (is_array($user_access))
273			{
274				reset($user_access);
275				while (list($acctid, $perm_array) = each($user_access))
276				{
277					if (substr($acctid,0,1))
278					{
279						$acctid = (int) substr($acctid,1);
280					}
281					if (is_array($perm_array))
282					{
283						reset($perm_array);
284						$can_read = 0;
285						$can_write = 0;
286						while(list($permtype, $permvalue) = each($perm_array))
287						{
288							switch($permtype)
289							{
290								case 'read':
291									$can_read = true;
292									break;
293								case 'write':
294									//write access implies read access, otherwise editing blocks would not work
295									$can_read = true;
296									$can_write = true;
297									break;
298								default:
299									echo 'hmmmmmm: ' . $permtype . '<br>';
300							}
301						}
302					}
303					$GLOBALS['Common_BO']->acl->grant_permissions($acctid, $cat_id, $can_read, $can_write);
304				}
305			}
306			else
307			{
308				echo 'wth!';
309			}
310		}
311
312		function saveCategoryPermsfromparent($cat_id)
313		{
314			$cat=$this->getCategory($cat_id);
315			$parent=$cat->parent;
316			if ($parent)
317			{
318				$GLOBALS['Common_BO']->acl->copy_permissions($parent,$cat_id);
319			}
320		}
321
322		function applyCategoryPermstosubs($cat_id)
323		{
324			$sublist = $this->getpermittedcatsWrite($cat_id);
325
326			while (list(,$sub) = @each($sublist))
327			{
328				$GLOBALS['Common_BO']->acl->copy_permissions($cat_id,$sub);
329			}
330		}
331
332		function removealllang($lang)
333		{
334			$this->so->removealllang($lang);
335		}
336
337		function migratealllang($oldlang,$newlang)
338		{
339			$this->so->migratealllang($oldlang,$newlang);
340		}
341
342		//make sure cat_id belongs to current site
343		function check($cat_id)
344		{
345			if (in_array($cat_id,$this->currentcats))
346			{
347				return True;
348			}
349			else
350			{
351print_r($this->currentcats);
352var_dump(debug_backtrace());
353				echo '<p><center><b>'.lang('Attempt to access information outside current website').'</b></center>';
354				$GLOBALS['phpgw']->common->phpgw_exit(True);
355			}
356		}
357
358		function commit($cat_id)
359		{
360			if ($GLOBALS['Common_BO']->acl->is_admin())
361			{
362				$this->so->commit($cat_id);
363			}
364		}
365
366		function reactivate($cat_id)
367		{
368			if ($GLOBALS['Common_BO']->acl->is_admin())
369			{
370				$this->so->reactivate($cat_id);
371			}
372		}
373	}
374?>
375