diff --git a/phpBB/includes/group_positions.php b/phpBB/includes/groupposition/legend.php similarity index 58% rename from phpBB/includes/group_positions.php rename to phpBB/includes/groupposition/legend.php index 74de3516cb..4bd4d43ece 100644 --- a/phpBB/includes/group_positions.php +++ b/phpBB/includes/groupposition/legend.php @@ -2,7 +2,7 @@ /** * * @package phpBB3 -* @copyright (c) 2011 phpBB Group +* @copyright (c) 2012 phpBB Group * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ @@ -16,13 +16,14 @@ if (!defined('IN_PHPBB')) } /** -* Group Position class, containing all functions to manage the groups in the teampage and legend. +* Legend group position class * -* group_teampage/group_legend is an ascending list 1, 2, ..., n for groups which are displayed. 1 is the first group, n the last. +* group_legend is an ascending list 1, 2, ..., n for groups which are displayed. 1 is the first group, n the last. * If the value is 0 (self::GROUP_DISABLED) the group is not displayed. +* * @package phpBB3 */ -class phpbb_group_positions +class phpbb_groupposition_legend implements phpbb_groupposition_interface { /** * Group is not displayed @@ -32,12 +33,12 @@ class phpbb_group_positions /** * phpbb-database object */ - public $db = null; + private $db = null; /** - * Name of the field we want to handle: either 'teampage' or 'legend' + * phpbb-user object */ - private $field = ''; + private $user = null; /** * URI for the adm_back_link when there was an error. @@ -46,32 +47,29 @@ class phpbb_group_positions /** * Constructor + * + * @param phpbb_dbal $db Database object + * @param string $adm_back_link Return URL to use after an error occured */ - public function __construct ($db, $field, $adm_back_link = '') + public function __construct($db, phpbb_user $user, $adm_back_link = '') { $this->adm_back_link = $adm_back_link; - - if (!in_array($field, array('teampage', 'legend'))) - { - $this->error('NO_MODE'); - } - $this->db = $db; - $this->field = $field; + $this->user = $user; } /** - * Returns the group_{$this->field} for a given group, if the group exists. - * @param int $group_id group_id of the group to be selected - * @return int position of the group + * Returns the group_legend for a given group, if the group exists. + * + * {@inheritDoc} */ public function get_group_value($group_id) { - $sql = 'SELECT group_' . $this->field . ' + $sql = 'SELECT group_legend FROM ' . GROUPS_TABLE . ' WHERE group_id = ' . (int) $group_id; $result = $this->db->sql_query($sql); - $current_value = $this->db->sql_fetchfield('group_' . $this->field); + $current_value = $this->db->sql_fetchfield('group_legend'); $this->db->sql_freeresult($result); if ($current_value === false) @@ -84,27 +82,26 @@ class phpbb_group_positions } /** - * Get number of groups, displayed on the teampage/legend + * Get number of groups, displayed on the legend * - * @return int value of the last group displayed + * {@inheritDoc} */ public function get_group_count() { - $sql = 'SELECT group_' . $this->field . ' + $sql = 'SELECT group_legend FROM ' . GROUPS_TABLE . ' - ORDER BY group_' . $this->field . ' DESC'; + ORDER BY group_legend DESC'; $result = $this->db->sql_query_limit($sql, 1); - $group_count = (int) $this->db->sql_fetchfield('group_' . $this->field); + $group_count = (int) $this->db->sql_fetchfield('group_legend'); $this->db->sql_freeresult($result); return $group_count; } /** - * Addes a group by group_id + * Adds a group by group_id * - * @param int $group_id group_id of the group to be added - * @return void + * {@inheritDoc} */ public function add_group($group_id) { @@ -116,8 +113,8 @@ class phpbb_group_positions $next_value = 1 + $this->get_group_count(); $sql = 'UPDATE ' . GROUPS_TABLE . ' - SET group_' . $this->field . ' = ' . $next_value . ' - WHERE group_' . $this->field . ' = ' . self::GROUP_DISABLED . ' + SET group_legend = ' . $next_value . ' + WHERE group_legend = ' . self::GROUP_DISABLED . ' AND group_id = ' . (int) $group_id; $this->db->sql_query($sql); } @@ -126,9 +123,7 @@ class phpbb_group_positions /** * Deletes a group by setting the field to self::GROUP_DISABLED and closing the gap in the list. * - * @param int $group_id group_id of the group to be deleted - * @param bool $skip_group Skip setting the group to GROUP_DISABLED, to save the query, when you need to update it anyway. - * @return void + * {@inheritDoc} */ public function delete_group($group_id, $skip_group = false) { @@ -139,14 +134,14 @@ class phpbb_group_positions $this->db->sql_transaction('begin'); $sql = 'UPDATE ' . GROUPS_TABLE . ' - SET group_' . $this->field . ' = group_' . $this->field . ' - 1 - WHERE group_' . $this->field . ' > ' . $current_value; + SET group_legend = group_legend - 1 + WHERE group_legend > ' . $current_value; $this->db->sql_query($sql); if (!$skip_group) { $sql = 'UPDATE ' . GROUPS_TABLE . ' - SET group_' . $this->field . ' = ' . self::GROUP_DISABLED . ' + SET group_legend = ' . self::GROUP_DISABLED . ' WHERE group_id = ' . (int) $group_id; $this->db->sql_query($sql); } @@ -158,8 +153,7 @@ class phpbb_group_positions /** * Moves a group up by group_id * - * @param int $group_id group_id of the group to be moved - * @return void + * {@inheritDoc} */ public function move_up($group_id) { @@ -169,8 +163,7 @@ class phpbb_group_positions /** * Moves a group down by group_id * - * @param int $group_id group_id of the group to be moved - * @return void + * {@inheritDoc} */ public function move_down($group_id) { @@ -180,11 +173,7 @@ class phpbb_group_positions /** * Moves a group up/down * - * @param int $group_id group_id of the group to be moved - * @param int $delta number of steps: - * - positive = move up - * - negative = move down - * @return void + * {@inheritDoc} */ public function move($group_id, $delta) { @@ -203,10 +192,10 @@ class phpbb_group_positions // First we move all groups between our current value and the target value up/down 1, // so we have a gap for our group to move. $sql = 'UPDATE ' . GROUPS_TABLE . ' - SET group_' . $this->field . ' = group_' . $this->field . (($move_up) ? ' + 1' : ' - 1') . ' - WHERE group_' . $this->field . ' > ' . self::GROUP_DISABLED . ' - AND group_' . $this->field . (($move_up) ? ' >= ' : ' <= ') . ($current_value - $delta) . ' - AND group_' . $this->field . (($move_up) ? ' < ' : ' > ') . $current_value; + SET group_legend = group_legend' . (($move_up) ? ' + 1' : ' - 1') . ' + WHERE group_legend > ' . self::GROUP_DISABLED . ' + AND group_legend' . (($move_up) ? ' >= ' : ' <= ') . ($current_value - $delta) . ' + AND group_legend' . (($move_up) ? ' < ' : ' > ') . $current_value; $this->db->sql_query($sql); // Because there might be fewer groups above/below the group than we wanted to move, @@ -218,7 +207,7 @@ class phpbb_group_positions // And now finally, when we moved some other groups and built a gap, // we can move the desired group to it. $sql = 'UPDATE ' . GROUPS_TABLE . ' - SET group_' . $this->field . ' = group_' . $this->field . (($move_up) ? ' - ' : ' + ') . $delta . ' + SET group_legend = group_legend ' . (($move_up) ? ' - ' : ' + ') . $delta . ' WHERE group_id = ' . (int) $group_id; $this->db->sql_query($sql); } @@ -227,11 +216,21 @@ class phpbb_group_positions } } + /** + * Error + * + * {@inheritDoc} + */ + public function error($message) + { + trigger_error($this->user->lang[$message] . (($this->adm_back_link) ? adm_back_link($this->adm_back_link) : ''), E_USER_WARNING); + } + /** * Get group type language var * * @param int $group_type group_type from the groups-table - * @return string name of the language variable for the given group-type. + * @return string name of the language variable for the given group-type. */ static public function group_type_language($group_type) { @@ -249,13 +248,4 @@ class phpbb_group_positions return 'GROUP_OPEN'; } } - - /** - * Error - */ - public function error($message) - { - global $user; - trigger_error($user->lang[$message] . (($this->adm_back_link) ? adm_back_link($this->adm_back_link) : ''), E_USER_WARNING); - } } diff --git a/phpBB/includes/groupposition/teampage.php b/phpBB/includes/groupposition/teampage.php new file mode 100644 index 0000000000..60e07f650e --- /dev/null +++ b/phpBB/includes/groupposition/teampage.php @@ -0,0 +1,548 @@ +adm_back_link = $adm_back_link; + $this->db = $db; + $this->user = $user; + } + + /** + * Returns the teampage position for a given group, if the group exists. + * + * {@inheritDoc} + */ + public function get_group_value($group_id) + { + $sql = 'SELECT g.group_id, t.teampage_position + FROM ' . GROUPS_TABLE . ' g + LEFT JOIN ' . TEAMPAGE_TABLE . ' t + ON (t.group_id = g.group_id) + WHERE g.group_id = ' . (int) $group_id; + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + if ($row === false) + { + // Group not found. + $this->error('NO_GROUP'); + } + + return (int) $row['teampage_position']; + } + + /** + * Returns the row for a given group, if the group exists. + * + * @param int $group_id group_id of the group to be selected + * @return array Data row of the group + */ + public function get_group_values($group_id) + { + $sql = 'SELECT * + FROM ' . GROUPS_TABLE . ' g + LEFT JOIN ' . TEAMPAGE_TABLE . ' t + ON (t.group_id = g.group_id) + WHERE g.group_id = ' . (int) $group_id; + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + if ($row === false) + { + // Group not found. + $this->error('NO_GROUP'); + } + + return $row; + } + + /** + * Returns the teampage position for a given teampage item, if the item exists. + * + * @param int $teampage_id Teampage_id of the selected item + * @return int Teampage position of the item + */ + public function get_teampage_value($teampage_id) + { + $sql = 'SELECT teampage_position + FROM ' . TEAMPAGE_TABLE . ' + WHERE teampage_id = ' . (int) $teampage_id; + $result = $this->db->sql_query($sql); + $current_value = $this->db->sql_fetchfield('teampage_position'); + $this->db->sql_freeresult($result); + + if ($current_value === false) + { + // Group not found. + $this->error('NO_GROUP'); + } + + return (int) $current_value; + } + + /** + * Returns the teampage row for a given teampage item, if the item exists. + * + * @param int $teampage_id Teampage_id of the selected item + * @return array Teampage row of the item + */ + public function get_teampage_values($teampage_id) + { + $sql = 'SELECT teampage_position, teampage_parent + FROM ' . TEAMPAGE_TABLE . ' + WHERE teampage_id = ' . (int) $teampage_id; + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + if ($row === false) + { + // Group not found. + $this->error('NO_GROUP'); + } + + return $row; + } + + + /** + * Get number of items displayed + * + * {@inheritDoc} + */ + public function get_group_count() + { + $sql = 'SELECT teampage_position + FROM ' . TEAMPAGE_TABLE . ' + ORDER BY teampage_position DESC'; + $result = $this->db->sql_query_limit($sql, 1); + $group_count = (int) $this->db->sql_fetchfield('teampage_position'); + $this->db->sql_freeresult($result); + + return $group_count; + } + + /** + * Adds a group by group_id + * + * {@inheritDoc} + */ + public function add_group($group_id) + { + $this->add_group_teampage($group_id, self::NO_PARENT); + } + + /** + * Adds a group by group_id + * + * @param int $group_id group_id of the group to be added + * @param int $parent_id Teampage ID of the parent item + * @return null + */ + public function add_group_teampage($group_id, $parent_id) + { + $current_value = $this->get_group_value($group_id); + + if ($current_value == self::GROUP_DISABLED) + { + if ($parent_id != self::NO_PARENT) + { + // Get value of last child from this parent and add group there + $sql = 'SELECT teampage_position + FROM ' . TEAMPAGE_TABLE . ' + WHERE teampage_parent = ' . (int) $parent_id . ' + OR teampage_id = ' . (int) $parent_id . ' + ORDER BY teampage_position DESC'; + $result = $this->db->sql_query_limit($sql, 1); + $new_position = (int) $this->db->sql_fetchfield('teampage_position'); + $this->db->sql_freeresult($result); + + $sql = 'UPDATE ' . TEAMPAGE_TABLE . ' + SET teampage_position = teampage_position + 1 + WHERE teampage_position > ' . $new_position; + $this->db->sql_query($sql); + + } + else + { + // Add group at the end + $new_position = $this->get_group_count(); + } + + $sql_ary = array( + 'group_id' => $group_id, + 'teampage_position' => $new_position + 1, + 'teampage_parent' => $parent_id, + ); + + $sql = 'INSERT INTO ' . TEAMPAGE_TABLE . ' ' . $this->db->sql_build_array('INSERT', $sql_ary); + $this->db->sql_query($sql); + } + } + + /** + * Adds a new category + * + * @param string $category_name Name of the category to be added + * @return null + */ + public function add_category_teampage($category_name) + { + $num_entries = $this->get_group_count(); + + $sql_ary = array( + 'group_id' => 0, + 'teampage_position' => $num_entries + 1, + 'teampage_parent' => 0, + 'teampage_name' => $category_name, + ); + + $sql = 'INSERT INTO ' . TEAMPAGE_TABLE . ' ' . $this->db->sql_build_array('INSERT', $sql_ary); + $this->db->sql_query($sql); + } + + /** + * Deletes a group from the list and closes the gap in the position list. + * + * {@inheritDoc} + */ + public function delete_group($group_id, $skip_group = false) + { + $current_value = $this->get_group_value($group_id); + + if ($current_value != self::GROUP_DISABLED) + { + $sql = 'UPDATE ' . TEAMPAGE_TABLE . ' + SET teampage_position = teampage_position - 1 + WHERE teampage_position > ' . $current_value; + $this->db->sql_query($sql); + + $sql = 'DELETE FROM ' . TEAMPAGE_TABLE . ' + WHERE group_id = ' . $group_id; + $this->db->sql_query($sql); + } + } + + /** + * Deletes an item from the list and closes the gap in the position list. + * + * @param int $teampage_id teampage_id of the item to be deleted + * @param bool $skip_group Skip setting the group to GROUP_DISABLED, to save the query, when you need to update it anyway. + * @return null + */ + public function delete_teampage($teampage_id, $skip_group = false) + { + $current_value = $this->get_teampage_value($teampage_id); + + if ($current_value != self::GROUP_DISABLED) + { + $sql = 'DELETE FROM ' . TEAMPAGE_TABLE . ' + WHERE teampage_id = ' . $teampage_id . ' + OR teampage_parent = ' . $teampage_id; + $this->db->sql_query($sql); + + $delta = (int) $this->db->sql_affectedrows(); + + $sql = 'UPDATE ' . TEAMPAGE_TABLE . ' + SET teampage_position = teampage_position - ' . $delta . ' + WHERE teampage_position > ' . $current_value; + $this->db->sql_query($sql); + } + } + + /** + * Moves a group up by group_id + * + * {@inheritDoc} + */ + public function move_up($group_id) + { + $this->move($group_id, 1); + } + + /** + * Moves an item up by teampage_id + * + * @param int $group_id group_id of the group to be moved + * @return null + */ + public function move_up_teampage($teampage_id) + { + $this->move_teampage($teampage_id, 1); + } + + /** + * Moves a group down by group_id + * + * {@inheritDoc} + */ + public function move_down($group_id) + { + $this->move($group_id, -1); + } + + /** + * Movesan item down by teampage_id + * + * @param int $group_id group_id of the group to be moved + * @return null + */ + public function move_down_teampage($teampage_id) + { + $this->move_teampage($teampage_id, -1); + } + + /** + * Moves a group up/down + * + * {@inheritDoc} + */ + public function move($group_id, $delta) + { + if (!is_int($delta) || !$delta) + { + return; + } + + $move_up = ($delta > 0) ? true : false; + $data = $this->get_group_values($group_id); + + $current_value = (int) $data['teampage_position']; + if ($current_value != self::GROUP_DISABLED) + { + $this->db->sql_transaction('begin'); + + if (!$move_up && $data['teampage_parent'] == self::NO_PARENT) + { + // If we move items down, we need to grab the one sibling more, + // so we do not ignore the children of the previous sibling. + // We will remove the additional sibling later on. + $delta = abs($delta) + 1; + } + + $sql = 'SELECT teampage_position + FROM ' . TEAMPAGE_TABLE . ' + WHERE teampage_parent = ' . (int) $data['teampage_parent'] . ' + AND teampage_position' . (($move_up) ? ' < ' : ' > ') . $current_value . ' + ORDER BY teampage_position' . (($move_up) ? ' DESC' : ' ASC'); + $result = $this->db->sql_query_limit($sql, $delta); + + // Reset the delta, as we recalculate the new real delta + $delta = 0; + while ($row = $this->db->sql_fetchrow($result)) + { + $delta = $current_value - $row['teampage_position']; + if (!$move_up && $data['teampage_parent'] == self::NO_PARENT) + { + // Remove the additional sibling we added previously + $delta++; + } + } + $this->db->sql_freeresult($result); + + if ($delta) + { + // First we move all items between our current value and the target value up/down 1, + // so we have a gap for our item to move. + $sql = 'UPDATE ' . TEAMPAGE_TABLE . ' + SET teampage_position = teampage_position' . (($move_up) ? ' + 1' : ' - 1') . ' + WHERE teampage_position' . (($move_up) ? ' >= ' : ' <= ') . ($current_value - $delta) . ' + AND teampage_position' . (($move_up) ? ' < ' : ' > ') . $current_value; + $this->db->sql_query($sql); + + // And now finally, when we moved some other items and built a gap, + // we can move the desired item to it. + $sql = 'UPDATE ' . TEAMPAGE_TABLE . ' + SET teampage_position = teampage_position ' . (($move_up) ? ' - ' : ' + ') . abs($delta) . ' + WHERE group_id = ' . (int) $group_id; + $this->db->sql_query($sql); + } + + $this->db->sql_transaction('commit'); + } + } + + /** + * Moves an item up/down + * + * @param int $teampage_id teampage_id of the item to be moved + * @param int $delta number of steps: + * - positive = move up + * - negative = move down + * @return null + */ + public function move_teampage($teampage_id, $delta) + { + if (!is_int($delta) || !$delta) + { + return; + } + + $move_up = ($delta > 0) ? true : false; + $data = $this->get_teampage_values($teampage_id); + + $current_value = (int) $data['teampage_position']; + if ($current_value != self::GROUP_DISABLED) + { + $this->db->sql_transaction('begin'); + + if (!$move_up && $data['teampage_parent'] == self::NO_PARENT) + { + // If we move items down, we need to grab the one sibling more, + // so we do not ignore the children of the previous sibling. + // We will remove the additional sibling later on. + $delta = abs($delta) + 1; + } + + $sql = 'SELECT teampage_id, teampage_position + FROM ' . TEAMPAGE_TABLE . ' + WHERE teampage_parent = ' . (int) $data['teampage_parent'] . ' + AND teampage_position' . (($move_up) ? ' < ' : ' > ') . $current_value . ' + ORDER BY teampage_position' . (($move_up) ? ' DESC' : ' ASC'); + $result = $this->db->sql_query_limit($sql, $delta); + + $sibling_count = 0; + $sibling_limit = $delta; + + // Reset the delta, as we recalculate the new real delta + $delta = 0; + while ($row = $this->db->sql_fetchrow($result)) + { + $sibling_count++; + $delta = $current_value - $row['teampage_position']; + + // Remove the additional sibling we added previously + // But only, if we included it, this is not be the case + // when we reached the end of our list + if (!$move_up && $data['teampage_parent'] == self::NO_PARENT && $sibling_count == $sibling_limit) + { + $delta++; + } + } + $this->db->sql_freeresult($result); + + if ($delta) + { + $sql = 'SELECT COUNT(teampage_id) as num_items + FROM ' . TEAMPAGE_TABLE . ' + WHERE teampage_id = ' . (int) $teampage_id . ' + OR teampage_parent = ' . (int) $teampage_id; + $result = $this->db->sql_query($sql); + $num_items = (int) $this->db->sql_fetchfield('num_items'); + $this->db->sql_freeresult($result); + + // First we move all items between our current value and the target value up/down 1, + // so we have a gap for our item to move. + $sql = 'UPDATE ' . TEAMPAGE_TABLE . ' + SET teampage_position = teampage_position' . (($move_up) ? ' + ' : ' - ') . $num_items . ' + WHERE teampage_position' . (($move_up) ? ' >= ' : ' <= ') . ($current_value - $delta) . ' + AND teampage_position' . (($move_up) ? ' < ' : ' > ') . $current_value . ' + AND NOT (teampage_id = ' . (int) $teampage_id . ' + OR teampage_parent = ' . (int) $teampage_id . ')'; + $this->db->sql_query($sql); + + $delta = (!$move_up && $data['teampage_parent'] == self::NO_PARENT) ? (abs($delta) - ($num_items - 1)) : abs($delta); + + // And now finally, when we moved some other items and built a gap, + // we can move the desired item to it. + $sql = 'UPDATE ' . TEAMPAGE_TABLE . ' + SET teampage_position = teampage_position ' . (($move_up) ? ' - ' : ' + ') . $delta . ' + WHERE teampage_id = ' . (int) $teampage_id . ' + OR teampage_parent = ' . (int) $teampage_id; + $this->db->sql_query($sql); + } + + $this->db->sql_transaction('commit'); + } + } + + /** + * Error + * + * {@inheritDoc} + */ + public function error($message) + { + trigger_error($this->user->lang[$message] . (($this->adm_back_link) ? adm_back_link($this->adm_back_link) : ''), E_USER_WARNING); + } + + /** + * Get group type language var + * + * @param int $group_type group_type from the groups-table + * @return string name of the language variable for the given group-type. + */ + static public function group_type_language($group_type) + { + switch ($group_type) + { + case GROUP_OPEN: + return 'GROUP_REQUEST'; + case GROUP_CLOSED: + return 'GROUP_CLOSED'; + case GROUP_HIDDEN: + return 'GROUP_HIDDEN'; + case GROUP_SPECIAL: + return 'GROUP_SPECIAL'; + case GROUP_FREE: + return 'GROUP_OPEN'; + } + } +}