PageRenderTime 58ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/includes/class_auth_admin.php

http://github.com/MightyGorgon/icy_phoenix
PHP | 1380 lines | 996 code | 212 blank | 172 comment | 181 complexity | fc1b77da2a7e9b887e9cb0b89db86daf MD5 | raw file
Possible License(s): AGPL-1.0
  1. <?php
  2. /**
  3. *
  4. * @package Icy Phoenix
  5. * @version $Id$
  6. * @copyright (c) 2008 Icy Phoenix
  7. * @license http://opensource.org/licenses/gpl-license.php GNU Public License
  8. *
  9. */
  10. /**
  11. *
  12. * @Icy Phoenix is based on phpBB
  13. * @copyright (c) 2008 phpBB Group
  14. *
  15. */
  16. if (!defined('IN_ICYPHOENIX'))
  17. {
  18. die('Hacking attempt');
  19. }
  20. /**
  21. * ACP Permission/Auth class
  22. * @package phpBB3
  23. */
  24. class auth_admin extends auth
  25. {
  26. /**
  27. * Init auth settings
  28. */
  29. function __construct()
  30. {
  31. global $db, $cache;
  32. if (($this->acl_options = $cache->get('_acl_options')) === false)
  33. {
  34. $sql = 'SELECT auth_option_id, auth_option, is_global, is_local
  35. FROM ' . ACL_OPTIONS_TABLE . '
  36. ORDER BY auth_option_id';
  37. $result = $db->sql_query($sql);
  38. $global = $local = 0;
  39. $this->acl_options = array();
  40. while ($row = $db->sql_fetchrow($result))
  41. {
  42. if ($row['is_global'])
  43. {
  44. $this->acl_options['global'][$row['auth_option']] = $global++;
  45. }
  46. if ($row['is_local'])
  47. {
  48. $this->acl_options['local'][$row['auth_option']] = $local++;
  49. }
  50. $this->acl_options['id'][$row['auth_option']] = (int) $row['auth_option_id'];
  51. $this->acl_options['option'][(int) $row['auth_option_id']] = $row['auth_option'];
  52. }
  53. $db->sql_freeresult($result);
  54. $cache->put('_acl_options', $this->acl_options);
  55. }
  56. }
  57. /**
  58. * Get permission mask
  59. * This function only supports getting permissions of one type (for example a_)
  60. *
  61. * @param set|view $mode defines the permissions we get, view gets effective permissions (checking user AND group permissions), set only gets the user or group permission set alone
  62. * @param mixed $user_id user ids to search for (a user_id or a group_id has to be specified at least)
  63. * @param mixed $group_id group ids to search for, return group related settings (a user_id or a group_id has to be specified at least)
  64. * @param mixed $forum_id forum_ids to search for. Defining a forum id also means getting local settings
  65. * @param string $auth_option the auth_option defines the permission setting to look for (a_ for example)
  66. * @param local|global $scope the scope defines the permission scope. If local, a forum_id is additionally required
  67. * @param ACL_NEVER|ACL_NO|ACL_YES $acl_fill defines the mode those permissions not set are getting filled with
  68. */
  69. function get_mask($mode, $user_id = false, $group_id = false, $forum_id = false, $auth_option = false, $scope = false, $acl_fill = ACL_NEVER)
  70. {
  71. global $db, $user;
  72. // Mighty Gorgon: we need to define this here to be allowed to use the class later...
  73. global $cms_permissions;
  74. $hold_ary = array();
  75. $view_user_mask = ($mode == 'view' && $group_id === false) ? true : false;
  76. if (($auth_option === false) || ($scope === false))
  77. {
  78. return array();
  79. }
  80. $acl_user_function = ($mode == 'set') ? 'acl_user_raw_data' : 'acl_raw_data';
  81. if (!$view_user_mask)
  82. {
  83. if ($forum_id !== false)
  84. {
  85. $hold_ary = ($group_id !== false) ? $this->acl_group_raw_data($group_id, $auth_option . '%', $forum_id) : $this->$acl_user_function($user_id, $auth_option . '%', $forum_id);
  86. }
  87. else
  88. {
  89. $hold_ary = ($group_id !== false) ? $this->acl_group_raw_data($group_id, $auth_option . '%', ($scope == 'global') ? 0 : false) : $this->$acl_user_function($user_id, $auth_option . '%', ($scope == 'global') ? 0 : false);
  90. }
  91. }
  92. // Make sure hold_ary is filled with every setting (prevents missing forums/users/groups)
  93. $ug_id = ($group_id !== false) ? ((!is_array($group_id)) ? array($group_id) : $group_id) : ((!is_array($user_id)) ? array($user_id) : $user_id);
  94. $forum_ids = ($forum_id !== false) ? ((!is_array($forum_id)) ? array($forum_id) : $forum_id) : (($scope == 'global') ? array(0) : array());
  95. // Only those options we need
  96. $compare_options = array_diff(preg_replace('/^((?!' . $auth_option . ').+)|(' . $auth_option . ')$/', '', array_keys($this->acl_options[$scope])), array(''));
  97. // If forum_ids is false and the scope is local we actually want to have all forums within the array
  98. if (($scope == 'local') && !sizeof($forum_ids))
  99. {
  100. // Mighty Gorgon: phpBB only uses local for forums, while we want to use this magic feature also for CMS!!!
  101. if (!empty($cms_permissions->id_type) && method_exists($cms_permissions, 'check_existence'))
  102. {
  103. $ids = array();
  104. $ids_data = $cms_permissions->check_existence($cms_permissions->id_type, $ids, true);
  105. foreach ($ids_data as $id_data)
  106. {
  107. $forum_ids[] = (int) $id_data['id'];
  108. }
  109. }
  110. else
  111. {
  112. $sql = 'SELECT forum_id
  113. FROM ' . FORUMS_TABLE;
  114. $result = $db->sql_query($sql, 120);
  115. while ($row = $db->sql_fetchrow($result))
  116. {
  117. $forum_ids[] = (int) $row['forum_id'];
  118. }
  119. $db->sql_freeresult($result);
  120. }
  121. }
  122. if ($view_user_mask)
  123. {
  124. $auth2 = null;
  125. $sql = 'SELECT user_id, user_permissions, user_type
  126. FROM ' . USERS_TABLE . '
  127. WHERE ' . $db->sql_in_set('user_id', $ug_id);
  128. $result = $db->sql_query($sql);
  129. while ($userdata = $db->sql_fetchrow($result))
  130. {
  131. if ($user->data['user_id'] != $userdata['user_id'])
  132. {
  133. $auth2 = new auth();
  134. $auth2->acl($userdata);
  135. }
  136. else
  137. {
  138. global $auth;
  139. $auth2 = &$auth;
  140. }
  141. $hold_ary[$userdata['user_id']] = array();
  142. foreach ($forum_ids as $f_id)
  143. {
  144. $hold_ary[$userdata['user_id']][$f_id] = array();
  145. foreach ($compare_options as $option)
  146. {
  147. $hold_ary[$userdata['user_id']][$f_id][$option] = $auth2->acl_get($option, $f_id);
  148. }
  149. }
  150. }
  151. $db->sql_freeresult($result);
  152. unset($userdata);
  153. unset($auth2);
  154. }
  155. foreach ($ug_id as $_id)
  156. {
  157. if (!isset($hold_ary[$_id]))
  158. {
  159. $hold_ary[$_id] = array();
  160. }
  161. foreach ($forum_ids as $f_id)
  162. {
  163. if (!isset($hold_ary[$_id][$f_id]))
  164. {
  165. $hold_ary[$_id][$f_id] = array();
  166. }
  167. }
  168. }
  169. // Now, we need to fill the gaps with $acl_fill. ;)
  170. // Now switch back to keys
  171. if (sizeof($compare_options))
  172. {
  173. $compare_options = array_combine($compare_options, array_fill(1, sizeof($compare_options), $acl_fill));
  174. }
  175. // Defining the user-function here to save some memory
  176. $return_acl_fill = create_function('$value', 'return ' . $acl_fill . ';');
  177. // Actually fill the gaps
  178. if (sizeof($hold_ary))
  179. {
  180. foreach ($hold_ary as $ug_id => $row)
  181. {
  182. foreach ($row as $id => $options)
  183. {
  184. // Do not include the global auth_option
  185. unset($options[$auth_option]);
  186. // Not a "fine" solution, but at all it's a 1-dimensional
  187. // array_diff_key function filling the resulting array values with zeros
  188. // The differences get merged into $hold_ary (all permissions having $acl_fill set)
  189. $hold_ary[$ug_id][$id] = array_merge($options,
  190. array_map($return_acl_fill,
  191. array_flip(
  192. array_diff(
  193. array_keys($compare_options), array_keys($options)
  194. )
  195. )
  196. )
  197. );
  198. }
  199. }
  200. }
  201. else
  202. {
  203. $hold_ary[($group_id !== false) ? $group_id : $user_id][(int) $forum_id] = $compare_options;
  204. }
  205. // Mighty Gorgon: phpBB only uses forum_id to identify ids for permissions, we use a trick to make sure we set only the proper permission for the required id... maybe not elegant, but functional!
  206. // Found another workaround... temporarily disabled!
  207. /*
  208. if (($scope == 'local') && !empty($cms_permissions->id_type))
  209. {
  210. $this->sanitize_permissions_array($hold_ary, $cms_permissions->id_type);
  211. }
  212. */
  213. return $hold_ary;
  214. }
  215. /**
  216. * Sanitize $hold_ary to filter proper local permission in CMS
  217. */
  218. function sanitize_permissions_array(&$hold_ary, $id_type = 'forum')
  219. {
  220. switch ($id_type)
  221. {
  222. case 'forum':
  223. $p_id_unset_array = array('cmsl_', 'cmss_', 'cmsb_');
  224. break;
  225. case 'layout':
  226. $p_id_unset_array = array('f_', 'cmss_', 'cmsb_');
  227. break;
  228. case 'layout_special':
  229. $p_id_unset_array = array('f_', 'cmsl_', 'cmsb_');
  230. break;
  231. case 'block':
  232. $p_id_unset_array = array('f_', 'cmsl_', 'cmss_');
  233. break;
  234. }
  235. foreach ($hold_ary as $ug_id => $row)
  236. {
  237. foreach ($row as $id => $options)
  238. {
  239. foreach ($options as $option_id => $option_value)
  240. {
  241. foreach ($p_id_unset_array as $id_prefix)
  242. {
  243. if (strpos($option_id, $id_prefix) === 0)
  244. {
  245. unset($hold_ary[$ug_id][$id][$option_id]);
  246. }
  247. }
  248. }
  249. }
  250. }
  251. }
  252. /**
  253. * Get permission mask for roles
  254. * This function only supports getting masks for one role
  255. */
  256. function get_role_mask($role_id)
  257. {
  258. global $db;
  259. $hold_ary = array();
  260. // Get users having this role set...
  261. $sql = 'SELECT user_id, forum_id
  262. FROM ' . ACL_USERS_TABLE . '
  263. WHERE auth_role_id = ' . $role_id . '
  264. ORDER BY forum_id';
  265. $result = $db->sql_query($sql);
  266. while ($row = $db->sql_fetchrow($result))
  267. {
  268. $hold_ary[$row['forum_id']]['users'][] = $row['user_id'];
  269. }
  270. $db->sql_freeresult($result);
  271. // Now grab groups...
  272. $sql = 'SELECT group_id, forum_id
  273. FROM ' . ACL_GROUPS_TABLE . '
  274. WHERE auth_role_id = ' . $role_id . '
  275. ORDER BY forum_id';
  276. $result = $db->sql_query($sql);
  277. while ($row = $db->sql_fetchrow($result))
  278. {
  279. $hold_ary[$row['forum_id']]['groups'][] = $row['group_id'];
  280. }
  281. $db->sql_freeresult($result);
  282. return $hold_ary;
  283. }
  284. /**
  285. * Display permission mask (assign to template)
  286. */
  287. function display_mask($mode, $permission_type, &$hold_ary, $user_mode = 'user', $local = false, $group_display = true)
  288. {
  289. global $db, $template, $user, $lang;
  290. // Define names for template loops, might be able to be set
  291. $tpl_pmask = 'p_mask';
  292. $tpl_fmask = 'f_mask';
  293. $tpl_category = 'category';
  294. $tpl_mask = 'mask';
  295. $l_acl_type = (isset($user->lang['ACL_TYPE_' . (($local) ? 'LOCAL' : 'GLOBAL') . '_' . strtoupper($permission_type)])) ? $user->lang['ACL_TYPE_' . (($local) ? 'LOCAL' : 'GLOBAL') . '_' . strtoupper($permission_type)] : 'ACL_TYPE_' . (($local) ? 'LOCAL' : 'GLOBAL') . '_' . strtoupper($permission_type);
  296. // Allow trace for viewing permissions and in user mode
  297. $show_trace = ($mode == 'view' && $user_mode == 'user') ? true : false;
  298. // Get names
  299. if ($user_mode == 'user')
  300. {
  301. $sql = 'SELECT user_id as ug_id, username as ug_name
  302. FROM ' . USERS_TABLE . '
  303. WHERE ' . $db->sql_in_set('user_id', array_keys($hold_ary)) . '
  304. ORDER BY username_clean ASC';
  305. }
  306. else
  307. {
  308. $sql = 'SELECT group_id as ug_id, group_name as ug_name
  309. FROM ' . GROUPS_TABLE . '
  310. WHERE ' . $db->sql_in_set('group_id', array_keys($hold_ary)) . '
  311. AND group_single_user = 0
  312. ORDER BY group_type DESC, group_name ASC';
  313. }
  314. $result = $db->sql_query($sql);
  315. $ug_names_ary = array();
  316. while ($row = $db->sql_fetchrow($result))
  317. {
  318. $ug_names_ary[$row['ug_id']] = $row['ug_name'];
  319. }
  320. $db->sql_freeresult($result);
  321. // Get used forums
  322. $forum_ids = array();
  323. foreach ($hold_ary as $ug_id => $row)
  324. {
  325. $forum_ids = array_merge($forum_ids, array_keys($row));
  326. }
  327. $forum_ids = array_unique($forum_ids);
  328. $forum_names_ary = array();
  329. if ($local)
  330. {
  331. global $cms_permissions;
  332. if (!empty($cms_permissions->id_type) && method_exists($cms_permissions, 'check_existence'))
  333. {
  334. $ids = array();
  335. $ids_data = $cms_permissions->check_existence($cms_permissions->id_type, $ids, true);
  336. $forum_names_ary = array();
  337. foreach ($ids_data as $id_data)
  338. {
  339. $forum_names_ary[$id_data['id']] = array('forum_name' => $id_data['name']);
  340. }
  341. }
  342. else
  343. {
  344. $forum_names_ary = make_forum_select(false, false, true, false, false, false, true);
  345. // Remove the disabled ones, since we do not create an option field here...
  346. foreach ($forum_names_ary as $key => $value)
  347. {
  348. if (!$value['disabled'])
  349. {
  350. continue;
  351. }
  352. unset($forum_names_ary[$key]);
  353. }
  354. }
  355. }
  356. else
  357. {
  358. $forum_names_ary[0] = $l_acl_type;
  359. }
  360. // Get available roles
  361. $sql = 'SELECT *
  362. FROM ' . ACL_ROLES_TABLE . "
  363. WHERE role_type = '" . $db->sql_escape($permission_type) . "'
  364. ORDER BY role_order ASC";
  365. $result = $db->sql_query($sql);
  366. $roles = array();
  367. while ($row = $db->sql_fetchrow($result))
  368. {
  369. $roles[$row['role_id']] = $row;
  370. }
  371. $db->sql_freeresult($result);
  372. $cur_roles = $this->acl_role_data($user_mode, $permission_type, array_keys($hold_ary));
  373. // Build js roles array (role data assignments)
  374. $s_role_js_array = '';
  375. if (sizeof($roles))
  376. {
  377. $s_role_js_array = array();
  378. // Make sure every role (even if empty) has its array defined
  379. foreach ($roles as $_role_id => $null)
  380. {
  381. $s_role_js_array[$_role_id] = "\n" . 'role_options[' . $_role_id . '] = new Array();' . "\n";
  382. }
  383. $sql = 'SELECT r.role_id, o.auth_option, r.auth_setting
  384. FROM ' . ACL_ROLES_DATA_TABLE . ' r, ' . ACL_OPTIONS_TABLE . ' o
  385. WHERE o.auth_option_id = r.auth_option_id
  386. AND ' . $db->sql_in_set('r.role_id', array_keys($roles));
  387. $result = $db->sql_query($sql);
  388. while ($row = $db->sql_fetchrow($result))
  389. {
  390. $flag = substr($row['auth_option'], 0, strpos($row['auth_option'], '_') + 1);
  391. if ($flag == $row['auth_option'])
  392. {
  393. continue;
  394. }
  395. $s_role_js_array[$row['role_id']] .= 'role_options[' . $row['role_id'] . '][\'' . addslashes($row['auth_option']) . '\'] = ' . $row['auth_setting'] . '; ';
  396. }
  397. $db->sql_freeresult($result);
  398. $s_role_js_array = implode('', $s_role_js_array);
  399. }
  400. $template->assign_var('S_ROLE_JS_ARRAY', $s_role_js_array);
  401. unset($s_role_js_array);
  402. // Now obtain memberships
  403. $user_groups_default = $user_groups_custom = array();
  404. if ($user_mode == 'user' && $group_display)
  405. {
  406. $sql = 'SELECT group_id, group_name
  407. FROM ' . GROUPS_TABLE . '
  408. WHERE group_single_user = 0
  409. ORDER BY group_name ASC';
  410. $result = $db->sql_query($sql);
  411. $groups = array();
  412. while ($row = $db->sql_fetchrow($result))
  413. {
  414. $groups[$row['group_id']] = $row;
  415. }
  416. $db->sql_freeresult($result);
  417. $memberships = group_memberships(false, array_keys($hold_ary), false);
  418. // User is not a member of any group? Bad admin, bad bad admin...
  419. if ($memberships)
  420. {
  421. foreach ($memberships as $row)
  422. {
  423. $user_groups_custom[$row['user_id']][] = $groups[$row['group_id']]['group_name'];
  424. }
  425. }
  426. unset($memberships, $groups);
  427. }
  428. // If we only have one forum id to display or being in local mode and more than one user/group to display,
  429. // we switch the complete interface to group by user/usergroup instead of grouping by forum
  430. // To achieve this, we need to switch the array a bit
  431. if (sizeof($forum_ids) == 1 || ($local && sizeof($ug_names_ary) > 1))
  432. {
  433. $hold_ary_temp = $hold_ary;
  434. $hold_ary = array();
  435. foreach ($hold_ary_temp as $ug_id => $row)
  436. {
  437. foreach ($forum_names_ary as $forum_id => $forum_row)
  438. {
  439. if (isset($row[$forum_id]))
  440. {
  441. $hold_ary[$forum_id][$ug_id] = $row[$forum_id];
  442. }
  443. }
  444. }
  445. unset($hold_ary_temp);
  446. foreach ($hold_ary as $forum_id => $forum_array)
  447. {
  448. $content_array = $categories = array();
  449. $this->build_permission_array($hold_ary[$forum_id], $content_array, $categories, array_keys($ug_names_ary));
  450. $template->assign_block_vars($tpl_pmask, array(
  451. 'NAME' => ($forum_id == 0) ? $forum_names_ary[0] : $forum_names_ary[$forum_id]['forum_name'],
  452. 'PADDING' => ($forum_id == 0) ? '' : $forum_names_ary[$forum_id]['padding'],
  453. 'CATEGORIES' => implode('</th><th>', $categories),
  454. 'L_ACL_TYPE' => $l_acl_type,
  455. 'S_LOCAL' => ($local) ? true : false,
  456. 'S_GLOBAL' => (!$local) ? true : false,
  457. 'S_NUM_CATS' => sizeof($categories),
  458. 'S_VIEW' => ($mode == 'view') ? true : false,
  459. 'S_NUM_OBJECTS' => sizeof($content_array),
  460. 'S_USER_MODE' => ($user_mode == 'user') ? true : false,
  461. 'S_GROUP_MODE' => ($user_mode == 'group') ? true : false
  462. )
  463. );
  464. @reset($content_array);
  465. while (list($ug_id, $ug_array) = each($content_array))
  466. {
  467. // Build role dropdown options
  468. $current_role_id = (isset($cur_roles[$ug_id][$forum_id])) ? $cur_roles[$ug_id][$forum_id] : 0;
  469. $s_role_options = '';
  470. @reset($roles);
  471. while (list($role_id, $role_row) = each($roles))
  472. {
  473. $role_description = (!empty($user->lang[$role_row['role_description']])) ? $user->lang[$role_row['role_description']] : nl2br($role_row['role_description']);
  474. $role_name = (!empty($user->lang[$role_row['role_name']])) ? $user->lang[$role_row['role_name']] : $role_row['role_name'];
  475. $title = ($role_description) ? ' title="' . $role_description . '"' : '';
  476. $s_role_options .= '<option value="' . $role_id . '"' . (($role_id == $current_role_id) ? ' selected="selected"' : '') . $title . '>' . $role_name . '</option>';
  477. }
  478. if ($s_role_options)
  479. {
  480. $s_role_options = '<option value="0"' . ((!$current_role_id) ? ' selected="selected"' : '') . ' title="' . htmlspecialchars($user->lang['NO_ROLE_ASSIGNED_EXPLAIN']) . '">' . $user->lang['NO_ROLE_ASSIGNED'] . '</option>' . $s_role_options;
  481. }
  482. if (!$current_role_id && $mode != 'view')
  483. {
  484. $s_custom_permissions = false;
  485. foreach ($ug_array as $key => $value)
  486. {
  487. if ($value['S_NEVER'] || $value['S_YES'])
  488. {
  489. $s_custom_permissions = true;
  490. break;
  491. }
  492. }
  493. }
  494. else
  495. {
  496. $s_custom_permissions = false;
  497. }
  498. $template->assign_block_vars($tpl_pmask . '.' . $tpl_fmask, array(
  499. 'NAME' => $ug_names_ary[$ug_id],
  500. 'S_ROLE_OPTIONS' => $s_role_options,
  501. 'UG_ID' => $ug_id,
  502. 'S_CUSTOM' => $s_custom_permissions,
  503. 'FORUM_ID' => $forum_id)
  504. );
  505. $this->assign_cat_array($ug_array, $tpl_pmask . '.' . $tpl_fmask . '.' . $tpl_category, $tpl_mask, $ug_id, $forum_id, $show_trace, ($mode == 'view'));
  506. unset($content_array[$ug_id]);
  507. }
  508. unset($hold_ary[$forum_id]);
  509. }
  510. }
  511. else
  512. {
  513. foreach ($ug_names_ary as $ug_id => $ug_name)
  514. {
  515. if (!isset($hold_ary[$ug_id]))
  516. {
  517. continue;
  518. }
  519. $content_array = $categories = array();
  520. $this->build_permission_array($hold_ary[$ug_id], $content_array, $categories, array_keys($forum_names_ary));
  521. $template->assign_block_vars($tpl_pmask, array(
  522. 'NAME' => $ug_name,
  523. 'CATEGORIES' => implode('</th><th>', $categories),
  524. 'USER_GROUPS_DEFAULT' => (($user_mode == 'user') && isset($user_groups_default[$ug_id]) && sizeof($user_groups_default[$ug_id])) ? implode(', ', $user_groups_default[$ug_id]) : '',
  525. 'USER_GROUPS_CUSTOM' => (($user_mode == 'user') && isset($user_groups_custom[$ug_id]) && sizeof($user_groups_custom[$ug_id])) ? implode(', ', $user_groups_custom[$ug_id]) : '',
  526. 'L_ACL_TYPE' => $l_acl_type,
  527. 'S_LOCAL' => ($local) ? true : false,
  528. 'S_GLOBAL' => (!$local) ? true : false,
  529. 'S_NUM_CATS' => sizeof($categories),
  530. 'S_VIEW' => ($mode == 'view') ? true : false,
  531. 'S_NUM_OBJECTS' => sizeof($content_array),
  532. 'S_USER_MODE' => ($user_mode == 'user') ? true : false,
  533. 'S_GROUP_MODE' => ($user_mode == 'group') ? true : false
  534. )
  535. );
  536. @reset($content_array);
  537. while (list($forum_id, $forum_array) = each($content_array))
  538. {
  539. // Build role dropdown options
  540. $current_role_id = (isset($cur_roles[$ug_id][$forum_id])) ? $cur_roles[$ug_id][$forum_id] : 0;
  541. $s_role_options = '';
  542. @reset($roles);
  543. while (list($role_id, $role_row) = each($roles))
  544. {
  545. $role_description = (!empty($user->lang[$role_row['role_description']])) ? $user->lang[$role_row['role_description']] : nl2br($role_row['role_description']);
  546. $role_name = (!empty($user->lang[$role_row['role_name']])) ? $user->lang[$role_row['role_name']] : $role_row['role_name'];
  547. $title = ($role_description) ? ' title="' . $role_description . '"' : '';
  548. $s_role_options .= '<option value="' . $role_id . '"' . (($role_id == $current_role_id) ? ' selected="selected"' : '') . $title . '>' . $role_name . '</option>';
  549. }
  550. if ($s_role_options)
  551. {
  552. $s_role_options = '<option value="0"' . ((!$current_role_id) ? ' selected="selected"' : '') . ' title="' . htmlspecialchars($user->lang['NO_ROLE_ASSIGNED_EXPLAIN']) . '">' . $user->lang['NO_ROLE_ASSIGNED'] . '</option>' . $s_role_options;
  553. }
  554. if (!$current_role_id && $mode != 'view')
  555. {
  556. $s_custom_permissions = false;
  557. foreach ($forum_array as $key => $value)
  558. {
  559. if ($value['S_NEVER'] || $value['S_YES'])
  560. {
  561. $s_custom_permissions = true;
  562. break;
  563. }
  564. }
  565. }
  566. else
  567. {
  568. $s_custom_permissions = false;
  569. }
  570. $template->assign_block_vars($tpl_pmask . '.' . $tpl_fmask, array(
  571. 'NAME' => ($forum_id == 0) ? $forum_names_ary[0] : $forum_names_ary[$forum_id]['forum_name'],
  572. 'PADDING' => ($forum_id == 0) ? '' : $forum_names_ary[$forum_id]['padding'],
  573. 'S_ROLE_OPTIONS' => $s_role_options,
  574. 'S_CUSTOM' => $s_custom_permissions,
  575. 'UG_ID' => $ug_id,
  576. 'FORUM_ID' => $forum_id)
  577. );
  578. $this->assign_cat_array($forum_array, $tpl_pmask . '.' . $tpl_fmask . '.' . $tpl_category, $tpl_mask, $ug_id, $forum_id, $show_trace, ($mode == 'view'));
  579. }
  580. unset($hold_ary[$ug_id], $ug_names_ary[$ug_id]);
  581. }
  582. }
  583. }
  584. /**
  585. * Display permission mask for roles
  586. */
  587. function display_role_mask(&$hold_ary)
  588. {
  589. global $db, $template, $user, $lang, $phpbb_admin_path;
  590. if (!sizeof($hold_ary))
  591. {
  592. return;
  593. }
  594. // Get forum names
  595. $sql = 'SELECT forum_id, forum_name
  596. FROM ' . FORUMS_TABLE . '
  597. WHERE ' . $db->sql_in_set('forum_id', array_keys($hold_ary)) . '
  598. ORDER BY left_id';
  599. $result = $db->sql_query($sql);
  600. // If the role is used globally, then reflect that
  601. $forum_names = (isset($hold_ary[0])) ? array(0 => '') : array();
  602. while ($row = $db->sql_fetchrow($result))
  603. {
  604. $forum_names[$row['forum_id']] = $row['forum_name'];
  605. }
  606. $db->sql_freeresult($result);
  607. foreach ($forum_names as $forum_id => $forum_name)
  608. {
  609. $auth_ary = $hold_ary[$forum_id];
  610. $template->assign_block_vars('role_mask', array(
  611. 'NAME' => ($forum_id == 0) ? $user->lang['GLOBAL_MASK'] : $forum_name,
  612. 'FORUM_ID' => $forum_id
  613. )
  614. );
  615. if (isset($auth_ary['users']) && sizeof($auth_ary['users']))
  616. {
  617. $sql = 'SELECT user_id, username, user_color, user_active
  618. FROM ' . USERS_TABLE . '
  619. WHERE ' . $db->sql_in_set('user_id', $auth_ary['users']) . '
  620. ORDER BY username_clean ASC';
  621. $result = $db->sql_query($sql);
  622. while ($row = $db->sql_fetchrow($result))
  623. {
  624. $template->assign_block_vars('role_mask.users', array(
  625. 'USER_ID' => $row['user_id'],
  626. 'USERNAME' => $row['username'],
  627. 'U_PROFILE' => append_sid(IP_ROOT_PATH . CMS_PAGE_PROFILE . '?mode=viewprofile&amp;' . POST_USERS_URL . '=' . $row['user_id']),
  628. 'USERNAME_FULL' => colorize_username($row['user_id'], $row['username'], $row['user_color'], $row['user_active']),
  629. )
  630. );
  631. }
  632. $db->sql_freeresult($result);
  633. }
  634. if (isset($auth_ary['groups']) && sizeof($auth_ary['groups']))
  635. {
  636. $sql = 'SELECT group_id, group_name, group_color
  637. FROM ' . GROUPS_TABLE . '
  638. WHERE ' . $db->sql_in_set('group_id', $auth_ary['groups']) . '
  639. ORDER BY group_type ASC, group_name';
  640. $result = $db->sql_query($sql);
  641. while ($row = $db->sql_fetchrow($result))
  642. {
  643. $template->assign_block_vars('role_mask.groups', array(
  644. 'GROUP_ID' => $row['group_id'],
  645. 'GROUP_NAME' => $row['group_name'],
  646. 'GROUP_COLOR' => $row['group_color'],
  647. 'GROUP_FULL' => '<a href="' . append_sid('groupcp.' . PHP_EXT . '?' . POST_GROUPS_URL . '=' . $row['group_id']) . '" style="font-weight: bold; text-decoration: none;' . (check_valid_color($row['group_color']) ? ('color: ' . check_valid_color($row['group_color']) . ';') : '') . '">' . $row['group_name'] . '</a>',
  648. 'U_PROFILE' => append_sid(IP_ROOT_PATH . CMS_PAGE_GROUP_CP . '?' . POST_GROUPS_URL . '=' . $row['group_id'])
  649. )
  650. );
  651. }
  652. $db->sql_freeresult($result);
  653. }
  654. }
  655. }
  656. /**
  657. * NOTE: this function is not in use atm
  658. * Add a new option to the list ... $options is a hash of form ->
  659. * $options = array(
  660. * 'local' => array('option1', 'option2', ...),
  661. * 'global' => array('optionA', 'optionB', ...)
  662. * );
  663. */
  664. function acl_add_option($options)
  665. {
  666. global $db, $cache;
  667. if (!is_array($options))
  668. {
  669. return false;
  670. }
  671. $cur_options = array();
  672. // Determine current options
  673. $sql = 'SELECT auth_option, is_global, is_local
  674. FROM ' . ACL_OPTIONS_TABLE . '
  675. ORDER BY auth_option_id';
  676. $result = $db->sql_query($sql);
  677. while ($row = $db->sql_fetchrow($result))
  678. {
  679. $cur_options[$row['auth_option']] = ($row['is_global'] && $row['is_local']) ? 'both' : (($row['is_global']) ? 'global' : 'local');
  680. }
  681. $db->sql_freeresult($result);
  682. // Here we need to insert new options ... this requires discovering whether
  683. // an options is global, local or both and whether we need to add an permission
  684. // set flag (x_)
  685. $new_options = array('local' => array(), 'global' => array());
  686. foreach ($options as $type => $option_ary)
  687. {
  688. $option_ary = array_unique($option_ary);
  689. foreach ($option_ary as $option_value)
  690. {
  691. $new_options[$type][] = $option_value;
  692. $flag = substr($option_value, 0, strpos($option_value, '_') + 1);
  693. if (!in_array($flag, $new_options[$type]))
  694. {
  695. $new_options[$type][] = $flag;
  696. }
  697. }
  698. }
  699. unset($options);
  700. $options = array();
  701. $options['local'] = array_diff($new_options['local'], $new_options['global']);
  702. $options['global'] = array_diff($new_options['global'], $new_options['local']);
  703. $options['both'] = array_intersect($new_options['local'], $new_options['global']);
  704. // Now check which options to add/update
  705. $add_options = $update_options = array();
  706. // First local ones...
  707. foreach ($options as $type => $option_ary)
  708. {
  709. foreach ($option_ary as $option)
  710. {
  711. if (!isset($cur_options[$option]))
  712. {
  713. $add_options[] = array(
  714. 'auth_option' => (string) $option,
  715. 'is_global' => ($type == 'global' || $type == 'both') ? 1 : 0,
  716. 'is_local' => ($type == 'local' || $type == 'both') ? 1 : 0
  717. );
  718. continue;
  719. }
  720. // Else, update existing entry if it is changed...
  721. if ($type === $cur_options[$option])
  722. {
  723. continue;
  724. }
  725. // New type is always both:
  726. // If is now both, we set both.
  727. // If it was global the new one is local and we need to set it to both
  728. // If it was local the new one is global and we need to set it to both
  729. $update_options[] = $option;
  730. }
  731. }
  732. if (!empty($add_options))
  733. {
  734. $db->sql_multi_insert(ACL_OPTIONS_TABLE, $add_options);
  735. }
  736. if (!empty($update_options))
  737. {
  738. $sql = "UPDATE " . ACL_OPTIONS_TABLE . "
  739. SET is_global = 1, is_local = 1
  740. WHERE " . $db->sql_in_set('auth_option', $update_options);
  741. $db->sql_query($sql);
  742. }
  743. $cache->destroy('_acl_options');
  744. $this->acl_clear_prefetch();
  745. // Because we just changed the options and also purged the options cache, we instantly update/regenerate it for later calls to succeed.
  746. $this->acl_options = array();
  747. $this->auth_admin();
  748. return true;
  749. }
  750. /**
  751. * Set a user or group ACL record
  752. */
  753. function acl_set($ug_type, $forum_id, $ug_id, $auth, $role_id = 0, $clear_prefetch = true)
  754. {
  755. global $db;
  756. // One or more forums
  757. if (!is_array($forum_id))
  758. {
  759. $forum_id = array($forum_id);
  760. }
  761. // One or more users
  762. if (!is_array($ug_id))
  763. {
  764. $ug_id = array($ug_id);
  765. }
  766. $ug_id_sql = $db->sql_in_set($ug_type . '_id', array_map('intval', $ug_id));
  767. $forum_sql = $db->sql_in_set('forum_id', array_map('intval', $forum_id));
  768. // Instead of updating, inserting, removing we just remove all current settings and re-set everything...
  769. $table = ($ug_type == 'user') ? ACL_USERS_TABLE : ACL_GROUPS_TABLE;
  770. $id_field = $ug_type . '_id';
  771. // Get any flags as required
  772. reset($auth);
  773. $flag = key($auth);
  774. $flag = substr($flag, 0, strpos($flag, '_') + 1);
  775. // This ID (the any-flag) is set if one or more permissions are true...
  776. $any_option_id = (int) $this->acl_options['id'][$flag];
  777. // Remove any-flag from auth ary
  778. if (isset($auth[$flag]))
  779. {
  780. unset($auth[$flag]);
  781. }
  782. // Remove current auth options...
  783. $auth_option_ids = array((int)$any_option_id);
  784. foreach ($auth as $auth_option => $auth_setting)
  785. {
  786. $auth_option_ids[] = (int) $this->acl_options['id'][$auth_option];
  787. }
  788. $sql = "DELETE FROM $table
  789. WHERE $forum_sql
  790. AND $ug_id_sql
  791. AND " . $db->sql_in_set('auth_option_id', $auth_option_ids);
  792. $db->sql_query($sql);
  793. // Remove those having a role assigned... the correct type of course...
  794. $sql = 'SELECT role_id
  795. FROM ' . ACL_ROLES_TABLE . "
  796. WHERE role_type = '" . $db->sql_escape($flag) . "'";
  797. $result = $db->sql_query($sql);
  798. $role_ids = array();
  799. while ($row = $db->sql_fetchrow($result))
  800. {
  801. $role_ids[] = $row['role_id'];
  802. }
  803. $db->sql_freeresult($result);
  804. if (sizeof($role_ids))
  805. {
  806. $sql = "DELETE FROM $table
  807. WHERE $forum_sql
  808. AND $ug_id_sql
  809. AND auth_option_id = 0
  810. AND " . $db->sql_in_set('auth_role_id', $role_ids);
  811. $db->sql_query($sql);
  812. }
  813. // Ok, include the any-flag if one or more auth options are set to yes...
  814. foreach ($auth as $auth_option => $setting)
  815. {
  816. if ($setting == ACL_YES && (!isset($auth[$flag]) || $auth[$flag] == ACL_NEVER))
  817. {
  818. $auth[$flag] = ACL_YES;
  819. }
  820. }
  821. $sql_ary = array();
  822. foreach ($forum_id as $forum)
  823. {
  824. $forum = (int) $forum;
  825. if ($role_id)
  826. {
  827. foreach ($ug_id as $id)
  828. {
  829. $sql_ary[] = array(
  830. $id_field => (int) $id,
  831. 'forum_id' => (int) $forum,
  832. 'auth_option_id' => 0,
  833. 'auth_setting' => 0,
  834. 'auth_role_id' => (int) $role_id,
  835. );
  836. }
  837. }
  838. else
  839. {
  840. foreach ($auth as $auth_option => $setting)
  841. {
  842. $auth_option_id = (int) $this->acl_options['id'][$auth_option];
  843. if ($setting != ACL_NO)
  844. {
  845. foreach ($ug_id as $id)
  846. {
  847. $sql_ary[] = array(
  848. $id_field => (int) $id,
  849. 'forum_id' => (int) $forum,
  850. 'auth_option_id' => (int) $auth_option_id,
  851. 'auth_setting' => (int) $setting
  852. );
  853. }
  854. }
  855. }
  856. }
  857. }
  858. $db->sql_multi_insert($table, $sql_ary);
  859. if ($clear_prefetch)
  860. {
  861. $this->acl_clear_prefetch();
  862. }
  863. }
  864. /**
  865. * Set a role-specific ACL record
  866. */
  867. function acl_set_role($role_id, $auth)
  868. {
  869. global $db;
  870. // Get any-flag as required
  871. reset($auth);
  872. $flag = key($auth);
  873. $flag = substr($flag, 0, strpos($flag, '_') + 1);
  874. // Remove any-flag from auth ary
  875. if (isset($auth[$flag]))
  876. {
  877. unset($auth[$flag]);
  878. }
  879. // Re-set any flag...
  880. foreach ($auth as $auth_option => $setting)
  881. {
  882. if ($setting == ACL_YES && (!isset($auth[$flag]) || $auth[$flag] == ACL_NEVER))
  883. {
  884. $auth[$flag] = ACL_YES;
  885. }
  886. }
  887. $sql_ary = array();
  888. foreach ($auth as $auth_option => $setting)
  889. {
  890. $auth_option_id = (int) $this->acl_options['id'][$auth_option];
  891. if ($setting != ACL_NO)
  892. {
  893. $sql_ary[] = array(
  894. 'role_id' => (int) $role_id,
  895. 'auth_option_id' => (int) $auth_option_id,
  896. 'auth_setting' => (int) $setting
  897. );
  898. }
  899. }
  900. // If no data is there, we set the any-flag to ACL_NEVER...
  901. if (!sizeof($sql_ary))
  902. {
  903. $sql_ary[] = array(
  904. 'role_id' => (int) $role_id,
  905. 'auth_option_id' => (int) $this->acl_options['id'][$flag],
  906. 'auth_setting' => ACL_NEVER
  907. );
  908. }
  909. // Remove current auth options...
  910. $sql = 'DELETE FROM ' . ACL_ROLES_DATA_TABLE . '
  911. WHERE role_id = ' . $role_id;
  912. $db->sql_query($sql);
  913. // Now insert the new values
  914. $db->sql_multi_insert(ACL_ROLES_DATA_TABLE, $sql_ary);
  915. $this->acl_clear_prefetch();
  916. }
  917. /**
  918. * Remove local permission
  919. */
  920. function acl_delete($mode, $ug_id = false, $forum_id = false, $permission_type = false)
  921. {
  922. global $db;
  923. if ($ug_id === false && $forum_id === false)
  924. {
  925. return;
  926. }
  927. $option_id_ary = array();
  928. $table = ($mode == 'user') ? ACL_USERS_TABLE : ACL_GROUPS_TABLE;
  929. $id_field = $mode . '_id';
  930. $where_sql = array();
  931. if ($forum_id !== false)
  932. {
  933. $where_sql[] = (!is_array($forum_id)) ? 'forum_id = ' . (int) $forum_id : $db->sql_in_set('forum_id', array_map('intval', $forum_id));
  934. }
  935. if ($ug_id !== false)
  936. {
  937. $where_sql[] = (!is_array($ug_id)) ? $id_field . ' = ' . (int) $ug_id : $db->sql_in_set($id_field, array_map('intval', $ug_id));
  938. }
  939. // There seem to be auth options involved, therefore we need to go through the list and make sure we capture roles correctly
  940. if ($permission_type !== false)
  941. {
  942. // Get permission type
  943. $sql = "SELECT auth_option, auth_option_id
  944. FROM " . ACL_OPTIONS_TABLE . "
  945. WHERE auth_option " . $db->sql_like_expression($permission_type . $db->any_char);
  946. $result = $db->sql_query($sql);
  947. $auth_id_ary = array();
  948. while ($row = $db->sql_fetchrow($result))
  949. {
  950. $option_id_ary[] = $row['auth_option_id'];
  951. $auth_id_ary[$row['auth_option']] = ACL_NO;
  952. }
  953. $db->sql_freeresult($result);
  954. // First of all, lets grab the items having roles with the specified auth options assigned
  955. $sql = "SELECT auth_role_id, $id_field, forum_id
  956. FROM $table, " . ACL_ROLES_TABLE . " r
  957. WHERE auth_role_id <> 0
  958. AND auth_role_id = r.role_id
  959. AND r.role_type = '{$permission_type}'
  960. AND " . implode(' AND ', $where_sql) . '
  961. ORDER BY auth_role_id';
  962. $result = $db->sql_query($sql);
  963. $cur_role_auth = array();
  964. while ($row = $db->sql_fetchrow($result))
  965. {
  966. $cur_role_auth[$row['auth_role_id']][$row['forum_id']][] = $row[$id_field];
  967. }
  968. $db->sql_freeresult($result);
  969. // Get role data for resetting data
  970. if (sizeof($cur_role_auth))
  971. {
  972. $sql = 'SELECT ao.auth_option, rd.role_id, rd.auth_setting
  973. FROM ' . ACL_OPTIONS_TABLE . ' ao, ' . ACL_ROLES_DATA_TABLE . ' rd
  974. WHERE ao.auth_option_id = rd.auth_option_id
  975. AND ' . $db->sql_in_set('rd.role_id', array_keys($cur_role_auth));
  976. $result = $db->sql_query($sql);
  977. $auth_settings = array();
  978. while ($row = $db->sql_fetchrow($result))
  979. {
  980. // We need to fill all auth_options, else setting it will fail...
  981. if (!isset($auth_settings[$row['role_id']]))
  982. {
  983. $auth_settings[$row['role_id']] = $auth_id_ary;
  984. }
  985. $auth_settings[$row['role_id']][$row['auth_option']] = $row['auth_setting'];
  986. }
  987. $db->sql_freeresult($result);
  988. // Set the options
  989. foreach ($cur_role_auth as $role_id => $auth_row)
  990. {
  991. foreach ($auth_row as $f_id => $ug_row)
  992. {
  993. $this->acl_set($mode, $f_id, $ug_row, $auth_settings[$role_id], 0, false);
  994. }
  995. }
  996. }
  997. }
  998. // Now, normally remove permissions...
  999. if ($permission_type !== false)
  1000. {
  1001. $where_sql[] = $db->sql_in_set('auth_option_id', array_map('intval', $option_id_ary));
  1002. }
  1003. $sql = "DELETE FROM $table
  1004. WHERE " . implode(' AND ', $where_sql);
  1005. $db->sql_query($sql);
  1006. $this->acl_clear_prefetch();
  1007. }
  1008. /**
  1009. * Assign category to template
  1010. * used by display_mask()
  1011. */
  1012. function assign_cat_array(&$category_array, $tpl_cat, $tpl_mask, $ug_id, $forum_id, $show_trace = false, $s_view)
  1013. {
  1014. global $template, $user, $phpbb_admin_path;
  1015. @reset($category_array);
  1016. while (list($cat, $cat_array) = each($category_array))
  1017. {
  1018. $template->assign_block_vars($tpl_cat, array(
  1019. 'S_YES' => ($cat_array['S_YES'] && !$cat_array['S_NEVER'] && !$cat_array['S_NO']) ? true : false,
  1020. 'S_NEVER' => ($cat_array['S_NEVER'] && !$cat_array['S_YES'] && !$cat_array['S_NO']) ? true : false,
  1021. 'S_NO' => ($cat_array['S_NO'] && !$cat_array['S_NEVER'] && !$cat_array['S_YES']) ? true : false,
  1022. 'CAT_NAME' => $user->lang['permission_cat'][$cat]
  1023. )
  1024. );
  1025. /* Sort permissions by name (more naturaly and user friendly than sorting by a primary key)
  1026. * Commented out due to it's memory consumption and time needed
  1027. *
  1028. $key_array = array_intersect(array_keys($user->lang), array_map(create_function('$a', 'return "acl_" . $a;'), array_keys($cat_array['permissions'])));
  1029. $values_array = $cat_array['permissions'];
  1030. $cat_array['permissions'] = array();
  1031. foreach ($key_array as $key)
  1032. {
  1033. $key = str_replace('acl_', '', $key);
  1034. $cat_array['permissions'][$key] = $values_array[$key];
  1035. }
  1036. unset($key_array, $values_array);
  1037. */
  1038. @reset($cat_array['permissions']);
  1039. while (list($permission, $allowed) = each($cat_array['permissions']))
  1040. {
  1041. if ($s_view)
  1042. {
  1043. $template->assign_block_vars($tpl_cat . '.' . $tpl_mask, array(
  1044. 'S_YES' => ($allowed == ACL_YES) ? true : false,
  1045. 'S_NEVER' => ($allowed == ACL_NEVER) ? true : false,
  1046. 'UG_ID' => $ug_id,
  1047. 'FORUM_ID' => $forum_id,
  1048. 'FIELD_NAME' => $permission,
  1049. 'S_FIELD_NAME' => 'setting[' . $ug_id . '][' . $forum_id . '][' . $permission . ']',
  1050. 'U_TRACE' => ($show_trace) ? append_sid("{$phpbb_admin_path}index." . PHP_EXT, "i=permissions&amp;mode=trace&amp;u=$ug_id&amp;f=$forum_id&amp;auth=$permission") : '',
  1051. 'UA_TRACE' => ($show_trace) ? append_sid("{$phpbb_admin_path}index." . PHP_EXT, "i=permissions&mode=trace&u=$ug_id&f=$forum_id&auth=$permission", false) : '',
  1052. 'PERMISSION' => $user->lang['acl_' . $permission]['lang']
  1053. )
  1054. );
  1055. }
  1056. else
  1057. {
  1058. $template->assign_block_vars($tpl_cat . '.' . $tpl_mask, array(
  1059. 'S_YES' => ($allowed == ACL_YES) ? true : false,
  1060. 'S_NEVER' => ($allowed == ACL_NEVER) ? true : false,
  1061. 'S_NO' => ($allowed == ACL_NO) ? true : false,
  1062. 'UG_ID' => $ug_id,
  1063. 'FORUM_ID' => $forum_id,
  1064. 'FIELD_NAME' => $permission,
  1065. 'S_FIELD_NAME' => 'setting[' . $ug_id . '][' . $forum_id . '][' . $permission . ']',
  1066. 'U_TRACE' => ($show_trace) ? append_sid("{$phpbb_admin_path}index." . PHP_EXT, "i=permissions&amp;mode=trace&amp;u=$ug_id&amp;f=$forum_id&amp;auth=$permission") : '',
  1067. 'UA_TRACE' => ($show_trace) ? append_sid("{$phpbb_admin_path}index." . PHP_EXT, "i=permissions&mode=trace&u=$ug_id&f=$forum_id&auth=$permission", false) : '',
  1068. 'PERMISSION' => $user->lang['acl_' . $permission]['lang']
  1069. )
  1070. );
  1071. }
  1072. }
  1073. }
  1074. }
  1075. /**
  1076. * Building content array from permission rows with explicit key ordering
  1077. * used by display_mask()
  1078. */
  1079. function build_permission_array(&$permission_row, &$content_array, &$categories, $key_sort_array)
  1080. {
  1081. global $user;
  1082. foreach ($key_sort_array as $forum_id)
  1083. {
  1084. if (!isset($permission_row[$forum_id]))
  1085. {
  1086. continue;
  1087. }
  1088. $permissions = $permission_row[$forum_id];
  1089. ksort($permissions);
  1090. @reset($permissions);
  1091. while (list($permission, $auth_setting) = each($permissions))
  1092. {
  1093. if (!isset($user->lang['acl_' . $permission]))
  1094. {
  1095. $user->lang['acl_' . $permission] = array(
  1096. 'cat' => 'misc',
  1097. 'lang' => '{ acl_' . $permission . ' }'
  1098. );
  1099. }
  1100. $cat = $user->lang['acl_' . $permission]['cat'];
  1101. // Build our categories array
  1102. if (!isset($categories[$cat]))
  1103. {
  1104. $categories[$cat] = $user->lang['permission_cat'][$cat];
  1105. }
  1106. // Build our content array
  1107. if (!isset($content_array[$forum_id]))
  1108. {
  1109. $content_array[$forum_id] = array();
  1110. }
  1111. if (!isset($content_array[$forum_id][$cat]))
  1112. {
  1113. $content_array[$forum_id][$cat] = array(
  1114. 'S_YES' => false,
  1115. 'S_NEVER' => false,
  1116. 'S_NO' => false,
  1117. 'permissions' => array(),
  1118. );
  1119. }
  1120. $content_array[$forum_id][$cat]['S_YES'] |= ($auth_setting == ACL_YES) ? true : false;
  1121. $content_array[$forum_id][$cat]['S_NEVER'] |= ($auth_setting == ACL_NEVER) ? true : false;
  1122. $content_array[$forum_id][$cat]['S_NO'] |= ($auth_setting == ACL_NO) ? true : false;
  1123. $content_array[$forum_id][$cat]['permissions'][$permission] = $auth_setting;
  1124. }
  1125. }
  1126. }
  1127. /**
  1128. * Use permissions from another user. This transferes a permission set from one user to another.
  1129. * The other user is always able to revert back to his permission set.
  1130. * This function does not check for lower/higher permissions, it is possible for the user to gain
  1131. * "more" permissions by this.
  1132. * Admin permissions will not be copied.
  1133. */
  1134. function ghost_permissions($from_user_id, $to_user_id)
  1135. {
  1136. global $db;
  1137. if ($to_user_id == ANONYMOUS)
  1138. {
  1139. return false;
  1140. }
  1141. $hold_ary = $this->acl_raw_data_single_user($from_user_id);
  1142. // Key 0 in $hold_ary are global options, all others are forum_ids
  1143. // We disallow copying admin permissions
  1144. foreach ($this->acl_options['global'] as $opt => $id)
  1145. {
  1146. if (strpos($opt, 'a_') === 0)
  1147. {
  1148. $hold_ary[0][$this->acl_options['id'][$opt]] = ACL_NEVER;
  1149. }
  1150. }
  1151. // Force a_switchperm to be allowed
  1152. $hold_ary[0][$this->acl_options['id']['a_switchperm']] = ACL_YES;
  1153. $user_permissions = $this->build_bitstring($hold_ary);
  1154. if (!$user_permissions)
  1155. {
  1156. return false;
  1157. }
  1158. $sql = "UPDATE " . USERS_TABLE . "
  1159. SET user_permissions = '" . $db->sql_escape($user_permissions) . "',
  1160. user_perm_from = $from_user_id
  1161. WHERE user_id = " . $to_user_id;
  1162. $db->sql_query($sql);
  1163. return true;
  1164. }
  1165. }
  1166. ?>