PageRenderTime 40ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/sources/subs/Categories.subs.php

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