Subs-Categories.php 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. <?php
  2. /**
  3. * Simple Machines Forum (SMF)
  4. *
  5. * @package SMF
  6. * @author Simple Machines http://www.simplemachines.org
  7. * @copyright 2011 Simple Machines
  8. * @license http://www.simplemachines.org/about/smf/license.php BSD
  9. *
  10. * @version 2.0
  11. */
  12. if (!defined('SMF'))
  13. die('Hacking attempt...');
  14. /* This file contains the functions to add, modify, remove, collapse and expand
  15. categories.
  16. void modifyCategory(int category_id, array catOptions)
  17. - general function to modify the settings and position of a category.
  18. - used by ManageBoards.php to change the settings of a category.
  19. int createCategory(array catOptions)
  20. - general function to create a new category and set its position.
  21. - allows (almost) the same options as the modifyCat() function.
  22. - returns the ID of the newly created category.
  23. void deleteCategories(array categories_to_remove, moveChildrenTo = null)
  24. - general function to delete one or more categories.
  25. - allows to move all boards in the categories to a different category
  26. before deleting them.
  27. - if moveChildrenTo is set to null, all boards inside the given
  28. categorieswill be deleted.
  29. - deletes all information that's associated with the given categories.
  30. - updates the statistics to reflect the new situation.
  31. void collapseCategories(array categories, string new_status, array members = null, bool check_collapsable = true)
  32. - collapses or expands one or more categories for one or more members.
  33. - if members is null, the category is collapsed/expanded for all members.
  34. - allows three changes to the status: 'expand', 'collapse' and 'toggle'.
  35. - if check_collapsable is set, only category allowed to be collapsed,
  36. will be collapsed.
  37. */
  38. // Edit the position and properties of a category.
  39. function modifyCategory($category_id, $catOptions)
  40. {
  41. global $sourcedir, $smcFunc;
  42. $catUpdates = array();
  43. $catParameters = array();
  44. // Wanna change the categories position?
  45. if (isset($catOptions['move_after']))
  46. {
  47. // Store all categories in the proper order.
  48. $cats = array();
  49. $cat_order = array();
  50. // Setting 'move_after' to '0' moves the category to the top.
  51. if ($catOptions['move_after'] == 0)
  52. $cats[] = $category_id;
  53. // Grab the categories sorted by cat_order.
  54. $request = $smcFunc['db_query']('', '
  55. SELECT id_cat, cat_order
  56. FROM {db_prefix}categories
  57. ORDER BY cat_order',
  58. array(
  59. )
  60. );
  61. while ($row = $smcFunc['db_fetch_assoc']($request))
  62. {
  63. if ($row['id_cat'] != $category_id)
  64. $cats[] = $row['id_cat'];
  65. if ($row['id_cat'] == $catOptions['move_after'])
  66. $cats[] = $category_id;
  67. $cat_order[$row['id_cat']] = $row['cat_order'];
  68. }
  69. $smcFunc['db_free_result']($request);
  70. // Set the new order for the categories.
  71. foreach ($cats as $index => $cat)
  72. if ($index != $cat_order[$cat])
  73. $smcFunc['db_query']('', '
  74. UPDATE {db_prefix}categories
  75. SET cat_order = {int:new_order}
  76. WHERE id_cat = {int:current_category}',
  77. array(
  78. 'new_order' => $index,
  79. 'current_category' => $cat,
  80. )
  81. );
  82. // If the category order changed, so did the board order.
  83. require_once($sourcedir . '/Subs-Boards.php');
  84. reorderBoards();
  85. }
  86. if (isset($catOptions['cat_name']))
  87. {
  88. $catUpdates[] = 'name = {string:cat_name}';
  89. $catParameters['cat_name'] = $catOptions['cat_name'];
  90. }
  91. // Can a user collapse this category or is it too important?
  92. if (isset($catOptions['is_collapsible']))
  93. {
  94. $catUpdates[] = 'can_collapse = {int:is_collapsible}';
  95. $catParameters['is_collapsible'] = $catOptions['is_collapsible'] ? 1 : 0;
  96. }
  97. // Do the updates (if any).
  98. if (!empty($catUpdates))
  99. {
  100. $smcFunc['db_query']('', '
  101. UPDATE {db_prefix}categories
  102. SET
  103. ' . implode(',
  104. ', $catUpdates) . '
  105. WHERE id_cat = {int:current_category}',
  106. array_merge($catParameters, array(
  107. 'current_category' => $category_id,
  108. ))
  109. );
  110. if (empty($catOptions['dont_log']))
  111. logAction('edit_cat', array('catname' => isset($catOptions['cat_name']) ? $catOptions['cat_name'] : $category_id), 'admin');
  112. }
  113. }
  114. // Create a new category.
  115. function createCategory($catOptions)
  116. {
  117. global $smcFunc;
  118. // Check required values.
  119. if (!isset($catOptions['cat_name']) || trim($catOptions['cat_name']) == '')
  120. trigger_error('createCategory(): A category name is required', E_USER_ERROR);
  121. // Set default values.
  122. if (!isset($catOptions['move_after']))
  123. $catOptions['move_after'] = 0;
  124. if (!isset($catOptions['is_collapsible']))
  125. $catOptions['is_collapsible'] = true;
  126. // Don't log an edit right after.
  127. $catOptions['dont_log'] = true;
  128. // Add the category to the database.
  129. $smcFunc['db_insert']('',
  130. '{db_prefix}categories',
  131. array(
  132. 'name' => 'string-48',
  133. ),
  134. array(
  135. $catOptions['cat_name'],
  136. ),
  137. array('id_cat')
  138. );
  139. // Grab the new category ID.
  140. $category_id = $smcFunc['db_insert_id']('{db_prefix}categories', 'id_cat');
  141. // Set the given properties to the newly created category.
  142. modifyCategory($category_id, $catOptions);
  143. logAction('add_cat', array('catname' => $catOptions['cat_name']), 'admin');
  144. // Return the database ID of the category.
  145. return $category_id;
  146. }
  147. // Remove one or more categories.
  148. function deleteCategories($categories, $moveBoardsTo = null)
  149. {
  150. global $sourcedir, $smcFunc, $cat_tree;
  151. require_once($sourcedir . '/Subs-Boards.php');
  152. getBoardTree();
  153. // With no category set to move the boards to, delete them all.
  154. if ($moveBoardsTo === null)
  155. {
  156. $request = $smcFunc['db_query']('', '
  157. SELECT id_board
  158. FROM {db_prefix}boards
  159. WHERE id_cat IN ({array_int:category_list})',
  160. array(
  161. 'category_list' => $categories,
  162. )
  163. );
  164. $boards_inside = array();
  165. while ($row = $smcFunc['db_fetch_assoc']($request))
  166. $boards_inside[] = $row['id_board'];
  167. $smcFunc['db_free_result']($request);
  168. if (!empty($boards_inside))
  169. deleteBoards($boards_inside, null);
  170. }
  171. // Make sure the safe category is really safe.
  172. elseif (in_array($moveBoardsTo, $categories))
  173. trigger_error('deleteCategories(): You cannot move the boards to a category that\'s being deleted', E_USER_ERROR);
  174. // Move the boards inside the categories to a safe category.
  175. else
  176. $smcFunc['db_query']('', '
  177. UPDATE {db_prefix}boards
  178. SET id_cat = {int:new_parent_cat}
  179. WHERE id_cat IN ({array_int:category_list})',
  180. array(
  181. 'category_list' => $categories,
  182. 'new_parent_cat' => $moveBoardsTo,
  183. )
  184. );
  185. // Noone will ever be able to collapse these categories anymore.
  186. $smcFunc['db_query']('', '
  187. DELETE FROM {db_prefix}collapsed_categories
  188. WHERE id_cat IN ({array_int:category_list})',
  189. array(
  190. 'category_list' => $categories,
  191. )
  192. );
  193. // Do the deletion of the category itself
  194. $smcFunc['db_query']('', '
  195. DELETE FROM {db_prefix}categories
  196. WHERE id_cat IN ({array_int:category_list})',
  197. array(
  198. 'category_list' => $categories,
  199. )
  200. );
  201. // Log what we've done.
  202. foreach ($categories as $category)
  203. logAction('delete_cat', array('catname' => $cat_tree[$category]['node']['name']), 'admin');
  204. // Get all boards back into the right order.
  205. reorderBoards();
  206. }
  207. // Collapse, expand or toggle one or more categories for one or more members.
  208. function collapseCategories($categories, $new_status, $members = null, $check_collapsable = true)
  209. {
  210. global $smcFunc;
  211. // Collapse or expand the categories.
  212. if ($new_status === 'collapse' || $new_status === 'expand')
  213. {
  214. $smcFunc['db_query']('', '
  215. DELETE FROM {db_prefix}collapsed_categories
  216. WHERE id_cat IN ({array_int:category_list})' . ($members === null ? '' : '
  217. AND id_member IN ({array_int:member_list})'),
  218. array(
  219. 'category_list' => $categories,
  220. 'member_list' => $members,
  221. )
  222. );
  223. if ($new_status === 'collapse')
  224. $smcFunc['db_query']('', '
  225. INSERT INTO {db_prefix}collapsed_categories
  226. (id_cat, id_member)
  227. SELECT c.id_cat, mem.id_member
  228. FROM {db_prefix}categories AS c
  229. INNER JOIN {db_prefix}members AS mem ON (' . ($members === null ? '1=1' : '
  230. mem.id_member IN ({array_int:member_list})') . ')
  231. WHERE c.id_cat IN ({array_int:category_list})' . ($check_collapsable ? '
  232. AND c.can_collapse = {int:is_collapsible}' : ''),
  233. array(
  234. 'member_list' => $members,
  235. 'category_list' => $categories,
  236. 'is_collapsible' => 1,
  237. )
  238. );
  239. }
  240. // Toggle the categories: collapsed get expanded and expanded get collapsed.
  241. elseif ($new_status === 'toggle')
  242. {
  243. // Get the current state of the categories.
  244. $updates = array(
  245. 'insert' => array(),
  246. 'remove' => array(),
  247. );
  248. $request = $smcFunc['db_query']('', '
  249. SELECT mem.id_member, c.id_cat, IFNULL(cc.id_cat, 0) AS is_collapsed, c.can_collapse
  250. FROM {db_prefix}members AS mem
  251. INNER JOIN {db_prefix}categories AS c ON (c.id_cat IN ({array_int:category_list}))
  252. LEFT JOIN {db_prefix}collapsed_categories AS cc ON (cc.id_cat = c.id_cat AND cc.id_member = mem.id_member)
  253. ' . ($members === null ? '' : '
  254. WHERE mem.id_member IN ({array_int:member_list})'),
  255. array(
  256. 'category_list' => $categories,
  257. 'member_list' => $members,
  258. )
  259. );
  260. while ($row = $smcFunc['db_fetch_assoc']($request))
  261. {
  262. if (empty($row['is_collapsed']) && (!empty($row['can_collapse']) || !$check_collapsable))
  263. $updates['insert'][] = array($row['id_member'], $row['id_cat']);
  264. elseif (!empty($row['is_collapsed']))
  265. $updates['remove'][] = '(id_member = ' . $row['id_member'] . ' AND id_cat = ' . $row['id_cat'] . ')';
  266. }
  267. $smcFunc['db_free_result']($request);
  268. // Collapse the ones that were originally expanded...
  269. if (!empty($updates['insert']))
  270. $smcFunc['db_insert']('replace',
  271. '{db_prefix}collapsed_categories',
  272. array(
  273. 'id_cat' => 'int', 'id_member' => 'int',
  274. ),
  275. $updates['insert'],
  276. array('id_cat', 'id_member')
  277. );
  278. // And expand the ones that were originally collapsed.
  279. if (!empty($updates['remove']))
  280. $smcFunc['db_query']('', '
  281. DELETE FROM {db_prefix}collapsed_categories
  282. WHERE ' . implode(' OR ', $updates['remove']),
  283. array(
  284. )
  285. );
  286. }
  287. }
  288. ?>