aboutsummaryrefslogtreecommitdiffstats
path: root/phpBB/includes
diff options
context:
space:
mode:
Diffstat (limited to 'phpBB/includes')
-rw-r--r--phpBB/includes/acp/acp_board.php31
-rw-r--r--phpBB/includes/acp/acp_groups.php371
-rw-r--r--phpBB/includes/acp/acp_modules.php4
-rw-r--r--phpBB/includes/acp/acp_users.php150
-rw-r--r--phpBB/includes/avatar/driver/driver.php138
-rw-r--r--phpBB/includes/avatar/driver/gravatar.php172
-rw-r--r--phpBB/includes/avatar/driver/interface.php116
-rw-r--r--phpBB/includes/avatar/driver/local.php197
-rw-r--r--phpBB/includes/avatar/driver/remote.php164
-rw-r--r--phpBB/includes/avatar/driver/upload.php159
-rw-r--r--phpBB/includes/avatar/manager.php292
-rw-r--r--phpBB/includes/constants.php1
-rw-r--r--phpBB/includes/db/migration/data/310/avatars.php67
-rw-r--r--phpBB/includes/db/migration/data/310/teampage.php104
-rw-r--r--phpBB/includes/db/migration/tool/config.php4
-rw-r--r--phpBB/includes/db/migration/tool/module.php6
-rw-r--r--phpBB/includes/db/migration/tool/permission.php8
-rw-r--r--phpBB/includes/db/migrator.php201
-rw-r--r--phpBB/includes/extension/manager.php32
-rw-r--r--phpBB/includes/functions.php72
-rw-r--r--phpBB/includes/functions_admin.php281
-rw-r--r--phpBB/includes/functions_compatibility.php50
-rw-r--r--phpBB/includes/functions_container.php1
-rw-r--r--phpBB/includes/functions_display.php118
-rw-r--r--phpBB/includes/functions_user.php605
-rw-r--r--phpBB/includes/groupposition/exception.php23
-rw-r--r--phpBB/includes/groupposition/interface.php84
-rw-r--r--phpBB/includes/groupposition/legend.php (renamed from phpBB/includes/group_positions.php)134
-rw-r--r--phpBB/includes/groupposition/teampage.php604
-rw-r--r--phpBB/includes/log/interface.php106
-rw-r--r--phpBB/includes/log/log.php739
-rw-r--r--phpBB/includes/mcp/mcp_notes.php4
-rw-r--r--phpBB/includes/mcp/mcp_warn.php8
-rw-r--r--phpBB/includes/ucp/info/ucp_profile.php2
-rw-r--r--phpBB/includes/ucp/ucp_groups.php160
-rw-r--r--phpBB/includes/ucp/ucp_pm_viewmessage.php4
-rw-r--r--phpBB/includes/ucp/ucp_profile.php158
37 files changed, 3945 insertions, 1425 deletions
diff --git a/phpBB/includes/acp/acp_board.php b/phpBB/includes/acp/acp_board.php
index a213102cc6..6543427677 100644
--- a/phpBB/includes/acp/acp_board.php
+++ b/phpBB/includes/acp/acp_board.php
@@ -28,7 +28,7 @@ class acp_board
{
global $db, $user, $auth, $template;
global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx;
- global $cache;
+ global $cache, $phpbb_container;
$user->add_lang('acp/board');
@@ -107,6 +107,23 @@ class acp_board
break;
case 'avatar':
+ $phpbb_avatar_manager = $phpbb_container->get('avatar.manager');
+ $avatar_drivers = $phpbb_avatar_manager->get_all_drivers();
+
+ $avatar_vars = array();
+ foreach ($avatar_drivers as $current_driver)
+ {
+ $driver = $phpbb_avatar_manager->get_driver($current_driver, false);
+
+ /*
+ * First grab the settings for enabling/disabling the avatar
+ * driver and afterwards grab additional settings the driver
+ * might have.
+ */
+ $avatar_vars += $phpbb_avatar_manager->get_avatar_settings($driver);
+ $avatar_vars += $driver->prepare_form_acp($user);
+ }
+
$display_vars = array(
'title' => 'ACP_AVATAR_SETTINGS',
'vars' => array(
@@ -118,17 +135,15 @@ class acp_board
'avatar_max_height' => array('lang' => 'MAX_AVATAR_SIZE', 'validate' => 'int:0', 'type' => false, 'method' => false, 'explain' => false),
'allow_avatar' => array('lang' => 'ALLOW_AVATARS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
- 'allow_avatar_local' => array('lang' => 'ALLOW_LOCAL', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
- 'allow_avatar_remote' => array('lang' => 'ALLOW_REMOTE', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
- 'allow_avatar_upload' => array('lang' => 'ALLOW_UPLOAD', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
- 'allow_avatar_remote_upload'=> array('lang' => 'ALLOW_REMOTE_UPLOAD', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
- 'avatar_filesize' => array('lang' => 'MAX_FILESIZE', 'validate' => 'int:0', 'type' => 'text:4:10', 'explain' => true, 'append' => ' ' . $user->lang['BYTES']),
'avatar_min' => array('lang' => 'MIN_AVATAR_SIZE', 'validate' => 'int:0', 'type' => 'dimension:3:4', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']),
'avatar_max' => array('lang' => 'MAX_AVATAR_SIZE', 'validate' => 'int:0', 'type' => 'dimension:3:4', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']),
- 'avatar_path' => array('lang' => 'AVATAR_STORAGE_PATH', 'validate' => 'rwpath', 'type' => 'text:20:255', 'explain' => true),
- 'avatar_gallery_path' => array('lang' => 'AVATAR_GALLERY_PATH', 'validate' => 'rpath', 'type' => 'text:20:255', 'explain' => true),
)
);
+
+ if (!empty($avatar_vars))
+ {
+ $display_vars['vars'] += $avatar_vars;
+ }
break;
case 'message':
diff --git a/phpBB/includes/acp/acp_groups.php b/phpBB/includes/acp/acp_groups.php
index 21b1d4b837..8cae0151c8 100644
--- a/phpBB/includes/acp/acp_groups.php
+++ b/phpBB/includes/acp/acp_groups.php
@@ -26,7 +26,7 @@ class acp_groups
{
global $config, $db, $user, $auth, $template, $cache;
global $phpbb_root_path, $phpbb_admin_path, $phpEx, $table_prefix, $file_uploads;
- global $request;
+ global $request, $phpbb_container;
$user->add_lang('acp/groups');
$this->tpl_name = 'acp_groups';
@@ -55,15 +55,16 @@ class acp_groups
// Clear some vars
- $can_upload = (file_exists($phpbb_root_path . $config['avatar_path']) && phpbb_is_writable($phpbb_root_path . $config['avatar_path']) && $file_uploads) ? true : false;
$group_row = array();
// Grab basic data for group, if group_id is set and exists
if ($group_id)
{
- $sql = 'SELECT *
- FROM ' . GROUPS_TABLE . "
- WHERE group_id = $group_id";
+ $sql = 'SELECT g.*, t.teampage_position AS group_teampage
+ FROM ' . GROUPS_TABLE . ' g
+ LEFT JOIN ' . TEAMPAGE_TABLE . ' t
+ ON (t.group_id = g.group_id)
+ WHERE g.group_id = ' . $group_id;
$result = $db->sql_query($sql);
$group_row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
@@ -300,8 +301,21 @@ class acp_groups
$error = array();
$user->add_lang('ucp');
- $avatar_select = basename(request_var('avatar_select', ''));
- $category = basename(request_var('category', ''));
+ // Setup avatar data for later
+ $avatars_enabled = false;
+ $avatar_drivers = null;
+ $avatar_data = null;
+ $avatar_error = array();
+
+ if ($config['allow_avatar'])
+ {
+ $phpbb_avatar_manager = $phpbb_container->get('avatar.manager');
+ $avatar_drivers = $phpbb_avatar_manager->get_enabled_drivers();
+
+ // This is normalised data, without the group_ prefix
+ $avatar_data = phpbb_avatar_manager::clean_row($group_row);
+ }
+
// Did we submit?
if ($update)
@@ -319,12 +333,6 @@ class acp_groups
$allow_desc_urls = request_var('desc_parse_urls', false);
$allow_desc_smilies = request_var('desc_parse_smilies', false);
- $data['uploadurl'] = request_var('uploadurl', '');
- $data['remotelink'] = request_var('remotelink', '');
- $data['width'] = request_var('width', '');
- $data['height'] = request_var('height', '');
- $delete = request_var('delete', '');
-
$submit_ary = array(
'colour' => request_var('group_colour', ''),
'rank' => request_var('group_rank', 0),
@@ -342,81 +350,35 @@ class acp_groups
$submit_ary['founder_manage'] = isset($_REQUEST['group_founder_manage']) ? 1 : 0;
}
- $uploadfile = $request->file('uploadfile');
- if (!empty($uploadfile['tmp_name']) || $data['uploadurl'] || $data['remotelink'])
+ if ($config['allow_avatar'])
{
- // Avatar stuff
- $var_ary = array(
- 'uploadurl' => array('string', true, 5, 255),
- 'remotelink' => array('string', true, 5, 255),
- 'width' => array('string', true, 1, 3),
- 'height' => array('string', true, 1, 3),
- );
+ // Handle avatar
+ $driver_name = $phpbb_avatar_manager->clean_driver_name($request->variable('avatar_driver', ''));
- if (!($error = validate_data($data, $var_ary)))
- {
- $data['user_id'] = "g$group_id";
-
- if ((!empty($uploadfile['tmp_name']) || $data['uploadurl']) && $can_upload)
- {
- list($submit_ary['avatar_type'], $submit_ary['avatar'], $submit_ary['avatar_width'], $submit_ary['avatar_height']) = avatar_upload($data, $error);
- }
- else if ($data['remotelink'])
- {
- list($submit_ary['avatar_type'], $submit_ary['avatar'], $submit_ary['avatar_width'], $submit_ary['avatar_height']) = avatar_remote($data, $error);
- }
- }
- }
- else if ($avatar_select && $config['allow_avatar_local'])
- {
- // check avatar gallery
- if (is_dir($phpbb_root_path . $config['avatar_gallery_path'] . '/' . $category))
+ if (in_array($driver_name, $avatar_drivers) && !$request->is_set_post('avatar_delete'))
{
- $submit_ary['avatar_type'] = AVATAR_GALLERY;
+ $driver = $phpbb_avatar_manager->get_driver($driver_name);
+ $result = $driver->process_form($request, $template, $user, $avatar_data, $avatar_error);
- list($submit_ary['avatar_width'], $submit_ary['avatar_height']) = getimagesize($phpbb_root_path . $config['avatar_gallery_path'] . '/' . $category . '/' . $avatar_select);
- $submit_ary['avatar'] = $category . '/' . $avatar_select;
- }
- }
- else if ($delete)
- {
- $submit_ary['avatar'] = '';
- $submit_ary['avatar_type'] = $submit_ary['avatar_width'] = $submit_ary['avatar_height'] = 0;
- }
- else if ($data['width'] && $data['height'])
- {
- // Only update the dimensions?
- if ($config['avatar_max_width'] || $config['avatar_max_height'])
- {
- if ($data['width'] > $config['avatar_max_width'] || $data['height'] > $config['avatar_max_height'])
+ if ($result && empty($avatar_error))
{
- $error[] = phpbb_avatar_error_wrong_size($data['width'], $data['height']);
+ $result['avatar_type'] = $driver_name;
+ $submit_ary = array_merge($submit_ary, $result);
}
}
-
- if (!sizeof($error))
+ else
{
- if ($config['avatar_min_width'] || $config['avatar_min_height'])
+ $driver = $phpbb_avatar_manager->get_driver($user->data['user_avatar_type']);
+ if ($driver)
{
- if ($data['width'] < $config['avatar_min_width'] || $data['height'] < $config['avatar_min_height'])
- {
- $error[] = phpbb_avatar_error_wrong_size($data['width'], $data['height']);
- }
+ $driver->delete($avatar_data);
}
- }
- if (!sizeof($error))
- {
- $submit_ary['avatar_width'] = $data['width'];
- $submit_ary['avatar_height'] = $data['height'];
- }
- }
-
- if ((isset($submit_ary['avatar']) && $submit_ary['avatar'] && (!isset($group_row['group_avatar']))) || $delete)
- {
- if (isset($group_row['group_avatar']) && $group_row['group_avatar'])
- {
- avatar_delete('group', $group_row, true);
+ // Removing the avatar
+ $submit_ary['avatar_type'] = '';
+ $submit_ary['avatar'] = '';
+ $submit_ary['avatar_width'] = 0;
+ $submit_ary['avatar_height'] = 0;
}
}
@@ -443,7 +405,7 @@ class acp_groups
'rank' => 'int',
'colour' => 'string',
'avatar' => 'string',
- 'avatar_type' => 'int',
+ 'avatar_type' => 'string',
'avatar_width' => 'int',
'avatar_height' => 'int',
'receive_pm' => 'int',
@@ -514,7 +476,7 @@ class acp_groups
}
}
- $cache->destroy('sql', GROUPS_TABLE);
+ $cache->destroy('sql', array(GROUPS_TABLE, TEAMPAGE_TABLE));
$message = ($action == 'edit') ? 'GROUP_UPDATED' : 'GROUP_CREATED';
trigger_error($user->lang[$message] . adm_back_link($this->u_action));
@@ -573,15 +535,43 @@ class acp_groups
$type_closed = ($group_type == GROUP_CLOSED) ? ' checked="checked"' : '';
$type_hidden = ($group_type == GROUP_HIDDEN) ? ' checked="checked"' : '';
- $avatar_img = (!empty($group_row['group_avatar'])) ? get_user_avatar($group_row['group_avatar'], $group_row['group_avatar_type'], $group_row['group_avatar_width'], $group_row['group_avatar_height'], 'GROUP_AVATAR') : '<img src="' . $phpbb_admin_path . 'images/no_avatar.gif" alt="" />';
+ // Load up stuff for avatars
+ if ($config['allow_avatar'])
+ {
+ $avatars_enabled = false;
+ $selected_driver = $phpbb_avatar_manager->clean_driver_name($request->variable('avatar_driver', $avatar_data['avatar_type']));
- $display_gallery = (isset($_POST['display_gallery'])) ? true : false;
+ foreach ($avatar_drivers as $current_driver)
+ {
+ $driver = $phpbb_avatar_manager->get_driver($current_driver);
- if ($config['allow_avatar_local'] && $display_gallery)
- {
- avatar_gallery($category, $avatar_select, 4);
+ $avatars_enabled = true;
+ $config_name = $phpbb_avatar_manager->get_driver_config_name($driver);
+ $template->set_filenames(array(
+ 'avatar' => "acp_avatar_options_{$config_name}.html",
+ ));
+
+ if ($driver->prepare_form($request, $template, $user, $avatar_data, $avatar_error))
+ {
+ $driver_name = $phpbb_avatar_manager->prepare_driver_name($current_driver);
+ $driver_upper = strtoupper($driver_name);
+ $template->assign_block_vars('avatar_drivers', array(
+ 'L_TITLE' => $user->lang($driver_upper . '_TITLE'),
+ 'L_EXPLAIN' => $user->lang($driver_upper . '_EXPLAIN'),
+
+ 'DRIVER' => $driver_name,
+ 'SELECTED' => $current_driver == $selected_driver,
+ 'OUTPUT' => $template->assign_display('avatar'),
+ ));
+ }
+ }
}
+ $avatar = phpbb_get_group_avatar($group_row, 'GROUP_AVATAR', true);
+
+ // Merge any avatar errors into the primary error array
+ $error = array_merge($error, $phpbb_avatar_manager->localize_errors($user, $avatar_error));
+
$back_link = request_var('back_link', '');
switch ($back_link)
@@ -600,12 +590,10 @@ class acp_groups
'S_ADD_GROUP' => ($action == 'add') ? true : false,
'S_GROUP_PERM' => ($action == 'add' && $auth->acl_get('a_authgroups') && $auth->acl_gets('a_aauth', 'a_fauth', 'a_mauth', 'a_uauth')) ? true : false,
'S_INCLUDE_SWATCH' => true,
- 'S_CAN_UPLOAD' => $can_upload,
'S_ERROR' => (sizeof($error)) ? true : false,
'S_SPECIAL_GROUP' => ($group_type == GROUP_SPECIAL) ? true : false,
- 'S_DISPLAY_GALLERY' => ($config['allow_avatar_local'] && !$display_gallery) ? true : false,
- 'S_IN_GALLERY' => ($config['allow_avatar_local'] && $display_gallery) ? true : false,
'S_USER_FOUNDER' => ($user->data['user_type'] == USER_FOUNDER) ? true : false,
+ 'S_AVATARS_ENABLED' => ($config['allow_avatar'] && $avatars_enabled),
'ERROR_MSG' => (sizeof($error)) ? implode('<br />', $error) : '',
'GROUP_NAME' => ($group_type == GROUP_SPECIAL) ? $user->lang['G_' . $group_name] : $group_name,
@@ -626,8 +614,7 @@ class acp_groups
'S_RANK_OPTIONS' => $rank_options,
'S_GROUP_OPTIONS' => group_select_options(false, false, (($user->data['user_type'] == USER_FOUNDER) ? false : 0)),
- 'AVATAR' => $avatar_img,
- 'AVATAR_IMAGE' => $avatar_img,
+ 'AVATAR' => empty($avatar) ? '<img src="' . $phpbb_admin_path . 'images/no_avatar.gif" alt="" />' : $avatar,
'AVATAR_MAX_FILESIZE' => $config['avatar_filesize'],
'AVATAR_WIDTH' => (isset($group_row['group_avatar_width'])) ? $group_row['group_avatar_width'] : '',
'AVATAR_HEIGHT' => (isset($group_row['group_avatar_height'])) ? $group_row['group_avatar_height'] : '',
@@ -829,56 +816,112 @@ class acp_groups
public function manage_position()
{
- global $config, $db, $template, $user;
+ global $config, $db, $template, $user, $request, $phpbb_container;
$this->tpl_name = 'acp_groups_position';
$this->page_title = 'ACP_GROUPS_POSITION';
- $field = request_var('field', '');
- $action = request_var('action', '');
- $group_id = request_var('g', 0);
+ $field = $request->variable('field', '');
+ $action = $request->variable('action', '');
+ $group_id = $request->variable('g', 0);
+ $teampage_id = $request->variable('t', 0);
+ $category_id = $request->variable('c', 0);
if ($field && !in_array($field, array('legend', 'teampage')))
{
// Invalid mode
trigger_error($user->lang['NO_MODE'] . adm_back_link($this->u_action), E_USER_WARNING);
}
- else if ($field)
+ else if ($field && in_array($field, array('legend', 'teampage')))
{
- $group_position = new phpbb_group_positions($db, $field, $this->u_action);
+
+ $group_position = $phpbb_container->get('groupposition.' . $field);
}
- switch ($action)
+ if ($field == 'teampage')
{
- case 'set_config_legend':
- set_config('legend_sort_groupname', request_var('legend_sort_groupname', 0));
- break;
+ try
+ {
+ switch ($action)
+ {
+ case 'add':
+ $group_position->add_group_teampage($group_id, $category_id);
+ break;
- case 'set_config_teampage':
- set_config('teampage_forums', request_var('teampage_forums', 0));
- set_config('teampage_memberships', request_var('teampage_memberships', 0));
- break;
+ case 'add_category':
+ $group_position->add_category_teampage($request->variable('category_name', '', true));
+ break;
- case 'add':
- $group_position->add_group($group_id);
- break;
+ case 'delete':
+ $group_position->delete_teampage($teampage_id);
+ break;
- case 'delete':
- $group_position->delete_group($group_id);
- break;
+ case 'move_up':
+ $group_position->move_up_teampage($teampage_id);
+ break;
- case 'move_up':
- $group_position->move_up($group_id);
- break;
+ case 'move_down':
+ $group_position->move_down_teampage($teampage_id);
+ break;
+ }
+ }
+ catch (phpbb_groupposition_exception $exception)
+ {
+ trigger_error($user->lang($exception->getMessage()) . adm_back_link($this->u_action), E_USER_WARNING);
+ }
+ }
+ else if ($field == 'legend')
+ {
+ try
+ {
+ switch ($action)
+ {
+ case 'add':
+ $group_position->add_group($group_id);
+ break;
- case 'move_down':
- $group_position->move_down($group_id);
- break;
+ case 'delete':
+ $group_position->delete_group($group_id);
+ break;
+
+ case 'move_up':
+ $group_position->move_up($group_id);
+ break;
+
+ case 'move_down':
+ $group_position->move_down($group_id);
+ break;
+ }
+ }
+ catch (phpbb_groupposition_exception $exception)
+ {
+ trigger_error($user->lang($exception->getMessage()) . adm_back_link($this->u_action), E_USER_WARNING);
+ }
+ }
+ else
+ {
+ switch ($action)
+ {
+ case 'set_config_teampage':
+ $config->set('teampage_forums', $request->variable('teampage_forums', 0));
+ $config->set('teampage_memberships', $request->variable('teampage_memberships', 0));
+ break;
+
+ case 'set_config_legend':
+ $config->set('legend_sort_groupname', $request->variable('legend_sort_groupname', 0));
+ break;
+ }
+ }
+
+ if (($action == 'move_up' || $action == 'move_down') && $request->is_ajax())
+ {
+ $json_response = new phpbb_json_response;
+ $json_response->send(array('success' => true));
}
$sql = 'SELECT group_id, group_name, group_colour, group_type, group_legend
FROM ' . GROUPS_TABLE . '
- ORDER BY group_legend, group_name ASC';
+ ORDER BY group_legend ASC, group_type DESC, group_name ASC';
$result = $db->sql_query($sql);
$s_group_select_legend = '';
@@ -888,57 +931,99 @@ class acp_groups
if ($row['group_legend'])
{
$template->assign_block_vars('legend', array(
- 'GROUP_NAME' => $group_name,
- 'GROUP_COLOUR' => ($row['group_colour']) ? ' style="color: #' . $row['group_colour'] . '"' : '',
- 'GROUP_TYPE' => $user->lang[phpbb_group_positions::group_type_language($row['group_type'])],
+ 'GROUP_NAME' => $group_name,
+ 'GROUP_COLOUR' => ($row['group_colour']) ? '#' . $row['group_colour'] : '',
+ 'GROUP_TYPE' => $user->lang[phpbb_groupposition_legend::group_type_language($row['group_type'])],
- 'U_MOVE_DOWN' => "{$this->u_action}&amp;field=legend&amp;action=move_down&amp;g=" . $row['group_id'],
- 'U_MOVE_UP' => "{$this->u_action}&amp;field=legend&amp;action=move_up&amp;g=" . $row['group_id'],
- 'U_DELETE' => "{$this->u_action}&amp;field=legend&amp;action=delete&amp;g=" . $row['group_id'],
+ 'U_MOVE_DOWN' => "{$this->u_action}&amp;field=legend&amp;action=move_down&amp;g=" . $row['group_id'],
+ 'U_MOVE_UP' => "{$this->u_action}&amp;field=legend&amp;action=move_up&amp;g=" . $row['group_id'],
+ 'U_DELETE' => "{$this->u_action}&amp;field=legend&amp;action=delete&amp;g=" . $row['group_id'],
));
}
else
{
- $s_group_select_legend .= '<option value="' . (int) $row['group_id'] . '">' . $group_name . '</option>';
+ $template->assign_block_vars('add_legend', array(
+ 'GROUP_ID' => (int) $row['group_id'],
+ 'GROUP_NAME' => $group_name,
+ 'GROUP_SPECIAL' => ($row['group_type'] == GROUP_SPECIAL),
+ ));
}
}
$db->sql_freeresult($result);
- $sql = 'SELECT group_id, group_name, group_colour, group_type, group_teampage
- FROM ' . GROUPS_TABLE . '
- ORDER BY group_teampage, group_name ASC';
+ $category_url_param = (($category_id) ? '&amp;c=' . $category_id : '');
+
+ $sql = 'SELECT t.*, g.group_name, g.group_colour, g.group_type
+ FROM ' . TEAMPAGE_TABLE . ' t
+ LEFT JOIN ' . GROUPS_TABLE . ' g
+ ON (t.group_id = g.group_id)
+ WHERE t.teampage_parent = ' . $category_id . '
+ OR t.teampage_id = ' . $category_id . '
+ ORDER BY t.teampage_position ASC';
$result = $db->sql_query($sql);
- $s_group_select_teampage = '';
+ $category_data = array();
while ($row = $db->sql_fetchrow($result))
{
- $group_name = ($row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $row['group_name']] : $row['group_name'];
- if ($row['group_teampage'])
+ if ($row['teampage_id'] == $category_id)
{
- $template->assign_block_vars('teampage', array(
- 'GROUP_NAME' => $group_name,
- 'GROUP_COLOUR' => ($row['group_colour']) ? ' style="color: #' . $row['group_colour'] . '"' : '',
- 'GROUP_TYPE' => $user->lang[phpbb_group_positions::group_type_language($row['group_type'])],
-
- 'U_MOVE_DOWN' => "{$this->u_action}&amp;field=teampage&amp;action=move_down&amp;g=" . $row['group_id'],
- 'U_MOVE_UP' => "{$this->u_action}&amp;field=teampage&amp;action=move_up&amp;g=" . $row['group_id'],
- 'U_DELETE' => "{$this->u_action}&amp;field=teampage&amp;action=delete&amp;g=" . $row['group_id'],
+ $template->assign_vars(array(
+ 'CURRENT_CATEGORY_NAME' => $row['teampage_name'],
));
+ continue;
+ }
+
+ if ($row['group_id'])
+ {
+ $group_name = ($row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $row['group_name']] : $row['group_name'];
+ $group_type = $user->lang[phpbb_groupposition_teampage::group_type_language($row['group_type'])];
}
else
{
- $s_group_select_teampage .= '<option value="' . (int) $row['group_id'] . '">' . $group_name . '</option>';
+ $group_name = $row['teampage_name'];
+ $group_type = '';
}
+
+ $template->assign_block_vars('teampage', array(
+ 'GROUP_NAME' => $group_name,
+ 'GROUP_COLOUR' => ($row['group_colour']) ? '#' . $row['group_colour'] : '',
+ 'GROUP_TYPE' => $group_type,
+
+ 'U_CATEGORY' => (!$row['group_id']) ? "{$this->u_action}&amp;c=" . $row['teampage_id'] : '',
+ 'U_MOVE_DOWN' => "{$this->u_action}&amp;field=teampage&amp;action=move_down{$category_url_param}&amp;t=" . $row['teampage_id'],
+ 'U_MOVE_UP' => "{$this->u_action}&amp;field=teampage&amp;action=move_up{$category_url_param}&amp;t=" . $row['teampage_id'],
+ 'U_DELETE' => "{$this->u_action}&amp;field=teampage&amp;action=delete{$category_url_param}&amp;t=" . $row['teampage_id'],
+ ));
+ }
+ $db->sql_freeresult($result);
+
+ $sql = 'SELECT g.group_id, g.group_name, g.group_colour, g.group_type
+ FROM ' . GROUPS_TABLE . ' g
+ LEFT JOIN ' . TEAMPAGE_TABLE . ' t
+ ON (t.group_id = g.group_id)
+ WHERE t.teampage_id IS NULL
+ ORDER BY g.group_type DESC, g.group_name ASC';
+ $result = $db->sql_query($sql);
+
+ $s_group_select_teampage = '';
+ while ($row = $db->sql_fetchrow($result))
+ {
+ $group_name = ($row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $row['group_name']] : $row['group_name'];
+ $template->assign_block_vars('add_teampage', array(
+ 'GROUP_ID' => (int) $row['group_id'],
+ 'GROUP_NAME' => $group_name,
+ 'GROUP_SPECIAL' => ($row['group_type'] == GROUP_SPECIAL),
+ ));
}
$db->sql_freeresult($result);
$template->assign_vars(array(
- 'U_ACTION' => $this->u_action,
- 'U_ACTION_LEGEND' => $this->u_action . '&amp;field=legend',
- 'U_ACTION_TEAMPAGE' => $this->u_action . '&amp;field=teampage',
+ 'U_ACTION' => $this->u_action,
+ 'U_ACTION_LEGEND' => $this->u_action . '&amp;field=legend',
+ 'U_ACTION_TEAMPAGE' => $this->u_action . '&amp;field=teampage' . $category_url_param,
+ 'U_ACTION_TEAMPAGE_CAT' => $this->u_action . '&amp;field=teampage_cat',
- 'S_GROUP_SELECT_LEGEND' => $s_group_select_legend,
- 'S_GROUP_SELECT_TEAMPAGE' => $s_group_select_teampage,
+ 'S_TEAMPAGE_CATEGORY' => $category_id,
'DISPLAY_FORUMS' => ($config['teampage_forums']) ? true : false,
'DISPLAY_MEMBERSHIPS' => $config['teampage_memberships'],
'LEGEND_SORT_GROUPNAME' => ($config['legend_sort_groupname']) ? true : false,
diff --git a/phpBB/includes/acp/acp_modules.php b/phpBB/includes/acp/acp_modules.php
index fce26bf45f..7c2ea86122 100644
--- a/phpBB/includes/acp/acp_modules.php
+++ b/phpBB/includes/acp/acp_modules.php
@@ -600,11 +600,11 @@ class acp_modules
if (!class_exists($info_class))
{
- if (file_exists($directory . $module . '.' . $phpEx))
+ $info_class = $module . '_info';
+ if (!class_exists($info_class) && file_exists($directory . $module . '.' . $phpEx))
{
include($directory . $module . '.' . $phpEx);
}
- $info_class = $module . '_info';
}
// Get module title tag
diff --git a/phpBB/includes/acp/acp_users.php b/phpBB/includes/acp/acp_users.php
index 3dd57905ed..9fcff665b1 100644
--- a/phpBB/includes/acp/acp_users.php
+++ b/phpBB/includes/acp/acp_users.php
@@ -33,6 +33,7 @@ class acp_users
global $config, $db, $user, $auth, $template, $cache;
global $phpbb_root_path, $phpbb_admin_path, $phpEx, $table_prefix, $file_uploads;
global $phpbb_dispatcher, $request;
+ global $phpbb_container;
$user->add_lang(array('posting', 'ucp', 'acp/users'));
$this->tpl_name = 'acp_users';
@@ -456,7 +457,7 @@ class acp_users
$sql_ary = array(
'user_avatar' => '',
- 'user_avatar_type' => 0,
+ 'user_avatar_type' => '',
'user_avatar_width' => 0,
'user_avatar_height' => 0,
);
@@ -467,9 +468,11 @@ class acp_users
$db->sql_query($sql);
// Delete old avatar if present
- if ($user_row['user_avatar'] && $user_row['user_avatar_type'] != AVATAR_GALLERY)
+ $phpbb_avatar_manager = $phpbb_container->get('avatar.manager');
+ $driver = $phpbb_avatar_manager->get_driver($user_row['user_avatar_type']);
+ if ($driver)
{
- avatar_delete('user', $user_row);
+ $driver->delete($user_row);
}
add_log('admin', 'LOG_USER_DEL_AVATAR', $user_row['username']);
@@ -1730,65 +1733,120 @@ class acp_users
case 'avatar':
include($phpbb_root_path . 'includes/functions_display.' . $phpEx);
- include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
- $can_upload = (file_exists($phpbb_root_path . $config['avatar_path']) && phpbb_is_writable($phpbb_root_path . $config['avatar_path']) && $file_uploads) ? true : false;
+ $avatars_enabled = false;
- if ($submit)
+ if ($config['allow_avatar'])
{
+ $phpbb_avatar_manager = $phpbb_container->get('avatar.manager');
+ $avatar_drivers = $phpbb_avatar_manager->get_enabled_drivers();
- if (!check_form_key($form_name))
+ // This is normalised data, without the user_ prefix
+ $avatar_data = phpbb_avatar_manager::clean_row($user_row);
+
+ if ($submit)
{
+ if (check_form_key($form_name))
+ {
+ $driver_name = $phpbb_avatar_manager->clean_driver_name($request->variable('avatar_driver', ''));
+
+ if (in_array($driver_name, $avatar_drivers) && !$request->is_set_post('avatar_delete'))
+ {
+ $driver = $phpbb_avatar_manager->get_driver($driver_name);
+ $result = $driver->process_form($request, $template, $user, $avatar_data, $error);
+
+ if ($result && empty($error))
+ {
+ // Success! Lets save the result in the database
+ $result = array(
+ 'user_avatar_type' => $driver_name,
+ 'user_avatar' => $result['avatar'],
+ 'user_avatar_width' => $result['avatar_width'],
+ 'user_avatar_height' => $result['avatar_height'],
+ );
+
+ $sql = 'UPDATE ' . USERS_TABLE . '
+ SET ' . $db->sql_build_array('UPDATE', $result) . '
+ WHERE user_id = ' . (int) $user_id;
+
+ $db->sql_query($sql);
+ trigger_error($user->lang['USER_AVATAR_UPDATED'] . adm_back_link($this->u_action . '&amp;u=' . $user_id));
+ }
+ }
+ else
+ {
+ $driver = $phpbb_avatar_manager->get_driver($user->data['user_avatar_type']);
+ if ($driver)
+ {
+ $driver->delete($avatar_data);
+ }
+
+ // Removing the avatar
+ $result = array(
+ 'user_avatar' => '',
+ 'user_avatar_type' => '',
+ 'user_avatar_width' => 0,
+ 'user_avatar_height' => 0,
+ );
+
+ $sql = 'UPDATE ' . USERS_TABLE . '
+ SET ' . $db->sql_build_array('UPDATE', $result) . '
+ WHERE user_id = ' . (int) $user_id;
+
+ $db->sql_query($sql);
+ trigger_error($user->lang['USER_AVATAR_UPDATED'] . adm_back_link($this->u_action . '&amp;u=' . $user_id));
+ }
+ }
+ else
+ {
trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action . '&amp;u=' . $user_id), E_USER_WARNING);
+ }
}
- if (avatar_process_user($error, $user_row, $can_upload))
- {
- trigger_error($user->lang['USER_AVATAR_UPDATED'] . adm_back_link($this->u_action . '&amp;u=' . $user_row['user_id']));
- }
+ $selected_driver = $phpbb_avatar_manager->clean_driver_name($request->variable('avatar_driver', $user_row['user_avatar_type']));
- // Replace "error" strings with their real, localised form
- $error = array_map(array($user, 'lang'), $error);
- }
+ foreach ($avatar_drivers as $current_driver)
+ {
+ $driver = $phpbb_avatar_manager->get_driver($current_driver);
- if (!$config['allow_avatar'] && $user_row['user_avatar_type'])
- {
- $error[] = $user->lang['USER_AVATAR_NOT_ALLOWED'];
- }
- else if ((($user_row['user_avatar_type'] == AVATAR_UPLOAD) && !$config['allow_avatar_upload']) ||
- (($user_row['user_avatar_type'] == AVATAR_REMOTE) && !$config['allow_avatar_remote']) ||
- (($user_row['user_avatar_type'] == AVATAR_GALLERY) && !$config['allow_avatar_local']))
- {
- $error[] = $user->lang['USER_AVATAR_TYPE_NOT_ALLOWED'];
- }
+ $avatars_enabled = true;
+ $config_name = $phpbb_avatar_manager->get_driver_config_name($driver);
+ $template->set_filenames(array(
+ 'avatar' => "acp_avatar_options_{$config_name}.html",
+ ));
- // Generate users avatar
- $avatar_img = ($user_row['user_avatar']) ? get_user_avatar($user_row['user_avatar'], $user_row['user_avatar_type'], $user_row['user_avatar_width'], $user_row['user_avatar_height'], 'USER_AVATAR', true) : '<img src="' . $phpbb_admin_path . 'images/no_avatar.gif" alt="" />';
+ if ($driver->prepare_form($request, $template, $user, $avatar_data, $error))
+ {
+ $driver_name = $phpbb_avatar_manager->prepare_driver_name($current_driver);
+ $driver_upper = strtoupper($driver_name);
- $display_gallery = (isset($_POST['display_gallery'])) ? true : false;
- $avatar_select = basename(request_var('avatar_select', ''));
- $category = basename(request_var('category', ''));
+ $template->assign_block_vars('avatar_drivers', array(
+ 'L_TITLE' => $user->lang($driver_upper . '_TITLE'),
+ 'L_EXPLAIN' => $user->lang($driver_upper . '_EXPLAIN'),
- if ($config['allow_avatar_local'] && $display_gallery)
- {
- avatar_gallery($category, $avatar_select, 4);
+ 'DRIVER' => $driver_name,
+ 'SELECTED' => $current_driver == $selected_driver,
+ 'OUTPUT' => $template->assign_display('avatar'),
+ ));
+ }
+ }
}
+ // Replace "error" strings with their real, localised form
+ $error = $phpbb_avatar_manager->localize_errors($user, $error);
+
+ $avatar = phpbb_get_user_avatar($user_row, 'USER_AVATAR', true);
+
$template->assign_vars(array(
- 'S_AVATAR' => true,
- 'S_CAN_UPLOAD' => $can_upload,
- 'S_UPLOAD_FILE' => ($config['allow_avatar'] && $can_upload && $config['allow_avatar_upload']) ? true : false,
- 'S_REMOTE_UPLOAD' => ($config['allow_avatar'] && $can_upload && $config['allow_avatar_remote_upload']) ? true : false,
- 'S_ALLOW_REMOTE' => ($config['allow_avatar'] && $config['allow_avatar_remote']) ? true : false,
- 'S_DISPLAY_GALLERY' => ($config['allow_avatar'] && $config['allow_avatar_local'] && !$display_gallery) ? true : false,
- 'S_IN_GALLERY' => ($config['allow_avatar'] && $config['allow_avatar_local'] && $display_gallery) ? true : false,
-
- 'AVATAR_IMAGE' => $avatar_img,
- 'AVATAR_MAX_FILESIZE' => $config['avatar_filesize'],
- 'USER_AVATAR_WIDTH' => $user_row['user_avatar_width'],
- 'USER_AVATAR_HEIGHT' => $user_row['user_avatar_height'],
-
- 'L_AVATAR_EXPLAIN' => phpbb_avatar_explanation_string(),
+ 'S_AVATAR' => true,
+ 'ERROR' => (!empty($error)) ? implode('<br />', $error) : '',
+ 'AVATAR' => (empty($avatar) ? '<img src="' . $phpbb_admin_path . 'images/no_avatar.gif" alt="" />' : $avatar),
+
+ 'S_FORM_ENCTYPE' => ' enctype="multipart/form-data"',
+
+ 'L_AVATAR_EXPLAIN' => sprintf($user->lang['AVATAR_EXPLAIN'], $config['avatar_max_width'], $config['avatar_max_height'], $config['avatar_filesize'] / 1024),
+
+ 'S_AVATARS_ENABLED' => ($config['allow_avatar'] && $avatars_enabled),
));
break;
diff --git a/phpBB/includes/avatar/driver/driver.php b/phpBB/includes/avatar/driver/driver.php
new file mode 100644
index 0000000000..29c58d4e62
--- /dev/null
+++ b/phpBB/includes/avatar/driver/driver.php
@@ -0,0 +1,138 @@
+<?php
+/**
+*
+* @package phpBB3
+* @copyright (c) 2011 phpBB Group
+* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+*
+*/
+
+/**
+* @ignore
+*/
+if (!defined('IN_PHPBB'))
+{
+ exit;
+}
+
+/**
+* Base class for avatar drivers
+* @package phpBB3
+*/
+abstract class phpbb_avatar_driver implements phpbb_avatar_driver_interface
+{
+ /**
+ * Avatar driver name
+ * @var string
+ */
+ protected $name;
+
+ /**
+ * Current board configuration
+ * @var phpbb_config
+ */
+ protected $config;
+
+ /**
+ * Current $phpbb_root_path
+ * @var string
+ */
+ protected $phpbb_root_path;
+
+ /**
+ * Current $php_ext
+ * @var string
+ */
+ protected $php_ext;
+
+ /**
+ * Cache driver
+ * @var phpbb_cache_driver_interface
+ */
+ protected $cache;
+
+ /**
+ * Array of allowed avatar image extensions
+ * Array is used for setting the allowed extensions in the fileupload class
+ * and as a base for a regex of allowed extensions, which will be formed by
+ * imploding the array with a "|".
+ *
+ * @var array
+ */
+ protected $allowed_extensions = array(
+ 'gif',
+ 'jpg',
+ 'jpeg',
+ 'png',
+ );
+
+ /**
+ * Construct a driver object
+ *
+ * @param phpbb_config $config phpBB configuration
+ * @param phpbb_request $request Request object
+ * @param string $phpbb_root_path Path to the phpBB root
+ * @param string $php_ext PHP file extension
+ * @param phpbb_cache_driver_interface $cache Cache driver
+ */
+ public function __construct(phpbb_config $config, $phpbb_root_path, $php_ext, phpbb_cache_driver_interface $cache = null)
+ {
+ $this->config = $config;
+ $this->phpbb_root_path = $phpbb_root_path;
+ $this->php_ext = $php_ext;
+ $this->cache = $cache;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function get_custom_html($user, $row, $alt = '')
+ {
+ return '';
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function prepare_form_acp($user)
+ {
+ return array();
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function delete($row)
+ {
+ return true;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function get_template_name()
+ {
+ $driver = preg_replace('#^phpbb_avatar_driver_#', '', get_class($this));
+ $template = "ucp_avatar_options_$driver.html";
+
+ return $template;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function get_name()
+ {
+ return $this->name;
+ }
+
+ /**
+ * Sets the name of the driver.
+ *
+ * @param string $name Driver name
+ */
+ public function set_name($name)
+ {
+ $this->name = $name;
+ }
+}
diff --git a/phpBB/includes/avatar/driver/gravatar.php b/phpBB/includes/avatar/driver/gravatar.php
new file mode 100644
index 0000000000..2e2ae2071f
--- /dev/null
+++ b/phpBB/includes/avatar/driver/gravatar.php
@@ -0,0 +1,172 @@
+<?php
+/**
+*
+* @package phpBB3
+* @copyright (c) 2012 phpBB Group
+* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+*
+*/
+
+/**
+* @ignore
+*/
+if (!defined('IN_PHPBB'))
+{
+ exit;
+}
+
+/**
+* Handles avatars hosted at gravatar.com
+* @package phpBB3
+*/
+class phpbb_avatar_driver_gravatar extends phpbb_avatar_driver
+{
+ /**
+ * The URL for the gravatar service
+ */
+ const GRAVATAR_URL = '//secure.gravatar.com/avatar/';
+
+ /**
+ * @inheritdoc
+ */
+ public function get_data($row)
+ {
+ return array(
+ 'src' => $row['avatar'],
+ 'width' => $row['avatar_width'],
+ 'height' => $row['avatar_height'],
+ );
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function get_custom_html($user, $row, $alt = '')
+ {
+ return '<img src="' . $this->get_gravatar_url($row) . '" ' .
+ ($row['avatar_width'] ? ('width="' . $row['avatar_width'] . '" ') : '') .
+ ($row['avatar_height'] ? ('height="' . $row['avatar_height'] . '" ') : '') .
+ 'alt="' . ((!empty($user->lang[$alt])) ? $user->lang[$alt] : $alt) . '" />';
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function prepare_form($request, $template, $user, $row, &$error)
+ {
+ $template->assign_vars(array(
+ 'AVATAR_GRAVATAR_WIDTH' => (($row['avatar_type'] == $this->get_name() || $row['avatar_type'] == 'gravatar') && $row['avatar_width']) ? $row['avatar_width'] : $request->variable('avatar_gravatar_width', 0),
+ 'AVATAR_GRAVATAR_HEIGHT' => (($row['avatar_type'] == $this->get_name() || $row['avatar_type'] == 'gravatar') && $row['avatar_height']) ? $row['avatar_height'] : $request->variable('avatar_gravatar_width', 0),
+ 'AVATAR_GRAVATAR_EMAIL' => (($row['avatar_type'] == $this->get_name() || $row['avatar_type'] == 'gravatar') && $row['avatar']) ? $row['avatar'] : '',
+ ));
+
+ return true;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function process_form($request, $template, $user, $row, &$error)
+ {
+ $row['avatar'] = $request->variable('avatar_gravatar_email', '');
+ $row['avatar_width'] = $request->variable('avatar_gravatar_width', 0);
+ $row['avatar_height'] = $request->variable('avatar_gravatar_height', 0);
+
+ if (!function_exists('validate_data'))
+ {
+ require($this->phpbb_root_path . 'includes/functions_user' . $this->php_ext);
+ }
+
+ $validate_array = validate_data(
+ array(
+ 'email' => $row['avatar'],
+ ),
+ array(
+ 'email' => array(
+ array('string', false, 6, 60),
+ array('email'))
+ )
+ );
+
+ $error = array_merge($error, $validate_array);
+
+ if (!empty($error))
+ {
+ return false;
+ }
+
+ // Make sure getimagesize works...
+ if (function_exists('getimagesize') && ($row['avatar_width'] <= 0 || $row['avatar_height'] <= 0))
+ {
+ /**
+ * default to the minimum of the maximum allowed avatar size if the size
+ * is not or only partially entered
+ */
+ $row['avatar_width'] = $row['avatar_height'] = min($this->config['avatar_max_width'], $this->config['avatar_max_height']);
+ $url = $this->get_gravatar_url($row);
+
+ if (($row['avatar_width'] <= 0 || $row['avatar_height'] <= 0) && (($image_data = getimagesize($url)) === false))
+ {
+ $error[] = 'UNABLE_GET_IMAGE_SIZE';
+ return false;
+ }
+
+ if (!empty($image_data) && ($image_data[0] <= 0 || $image_data[1] <= 0))
+ {
+ $error[] = 'AVATAR_NO_SIZE';
+ return false;
+ }
+
+ $row['avatar_width'] = ($row['avatar_width'] && $row['avatar_height']) ? $row['avatar_width'] : $image_data[0];
+ $row['avatar_height'] = ($row['avatar_width'] && $row['avatar_height']) ? $row['avatar_height'] : $image_data[1];
+ }
+
+ if ($row['avatar_width'] <= 0 || $row['avatar_height'] <= 0)
+ {
+ $error[] = 'AVATAR_NO_SIZE';
+ return false;
+ }
+
+ if ($this->config['avatar_max_width'] || $this->config['avatar_max_height'])
+ {
+ if ($row['avatar_width'] > $this->config['avatar_max_width'] || $row['avatar_height'] > $this->config['avatar_max_height'])
+ {
+ $error[] = array('AVATAR_WRONG_SIZE', $this->config['avatar_min_width'], $this->config['avatar_min_height'], $this->config['avatar_max_width'], $this->config['avatar_max_height'], $row['avatar_width'], $row['avatar_height']);
+ return false;
+ }
+ }
+
+ if ($this->config['avatar_min_width'] || $this->config['avatar_min_height'])
+ {
+ if ($row['avatar_width'] < $this->config['avatar_min_width'] || $row['avatar_height'] < $this->config['avatar_min_height'])
+ {
+ $error[] = array('AVATAR_WRONG_SIZE', $this->config['avatar_min_width'], $this->config['avatar_min_height'], $this->config['avatar_max_width'], $this->config['avatar_max_height'], $row['avatar_width'], $row['avatar_height']);
+ return false;
+ }
+ }
+
+ return array(
+ 'avatar' => $row['avatar'],
+ 'avatar_width' => $row['avatar_width'],
+ 'avatar_height' => $row['avatar_height'],
+ );
+ }
+
+ /**
+ * Build gravatar URL for output on page
+ *
+ * @return string Gravatar URL
+ */
+ protected function get_gravatar_url($row)
+ {
+ $url = self::GRAVATAR_URL;
+ $url .= md5(strtolower(trim($row['avatar'])));
+
+ if ($row['avatar_width'] || $row['avatar_height'])
+ {
+ $url .= '?s=' . max($row['avatar_width'], $row['avatar_height']);
+ }
+
+ return $url;
+ }
+}
diff --git a/phpBB/includes/avatar/driver/interface.php b/phpBB/includes/avatar/driver/interface.php
new file mode 100644
index 0000000000..3d62969aef
--- /dev/null
+++ b/phpBB/includes/avatar/driver/interface.php
@@ -0,0 +1,116 @@
+<?php
+/**
+*
+* @package phpBB3
+* @copyright (c) 2011 phpBB Group
+* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+*
+*/
+
+/**
+* @ignore
+*/
+if (!defined('IN_PHPBB'))
+{
+ exit;
+}
+
+/**
+* Interface for avatar drivers
+* @package phpBB3
+*/
+interface phpbb_avatar_driver_interface
+{
+ /**
+ * Returns the name of the driver.
+ *
+ * @return string Name of driver.
+ */
+ public function get_name();
+
+ /**
+ * Get the avatar url and dimensions
+ *
+ * @param array $row User data or group data that has been cleaned with
+ * phpbb_avatar_manager::clean_row
+ * @return array Avatar data, must have keys src, width and height, e.g.
+ * ['src' => '', 'width' => 0, 'height' => 0]
+ */
+ public function get_data($row);
+
+ /**
+ * Returns custom html if it is needed for displaying this avatar
+ *
+ * @param phpbb_user $user phpBB user object
+ * @param array $row User data or group data that has been cleaned with
+ * phpbb_avatar_manager::clean_row
+ * @param string $alt Alternate text for avatar image
+ *
+ * @return string HTML
+ */
+ public function get_custom_html($user, $row, $alt = '');
+
+ /**
+ * Prepare form for changing the settings of this avatar
+ *
+ * @param phpbb_request $request Request object
+ * @param phpbb_template $template Template object
+ * @param phpbb_user $user User object
+ * @param array $row User data or group data that has been cleaned with
+ * phpbb_avatar_manager::clean_row
+ * @param array &$error Reference to an error array that is filled by this
+ * function. Key values can either be a string with a language key or
+ * an array that will be passed to vsprintf() with the language key in
+ * the first array key.
+ *
+ * @return bool True if form has been successfully prepared
+ */
+ public function prepare_form($request, $template, $user, $row, &$error);
+
+ /**
+ * Prepare form for changing the acp settings of this avatar
+ *
+ * @param phpbb_user $user phpBB user object
+ *
+ * @return array Array of configuration options as consumed by acp_board.
+ * The setting for enabling/disabling the avatar will be handled by
+ * the avatar manager.
+ */
+ public function prepare_form_acp($user);
+
+ /**
+ * Process form data
+ *
+ * @param phpbb_request $request Request object
+ * @param phpbb_template $template Template object
+ * @param phpbb_user $user User object
+ * @param array $row User data or group data that has been cleaned with
+ * phpbb_avatar_manager::clean_row
+ * @param array &$error Reference to an error array that is filled by this
+ * function. Key values can either be a string with a language key or
+ * an array that will be passed to vsprintf() with the language key in
+ * the first array key.
+ *
+ * @return array Array containing the avatar data as follows:
+ * ['avatar'], ['avatar_width'], ['avatar_height']
+ */
+ public function process_form($request, $template, $user, $row, &$error);
+
+ /**
+ * Delete avatar
+ *
+ * @param array $row User data or group data that has been cleaned with
+ * phpbb_avatar_manager::clean_row
+ *
+ * @return bool True if avatar has been deleted or there is no need to delete,
+ * i.e. when the avatar is not hosted locally.
+ */
+ public function delete($row);
+
+ /**
+ * Get the avatar driver's template name
+ *
+ * @return string Avatar driver's template name
+ */
+ public function get_template_name();
+}
diff --git a/phpBB/includes/avatar/driver/local.php b/phpBB/includes/avatar/driver/local.php
new file mode 100644
index 0000000000..f4bcd4ce74
--- /dev/null
+++ b/phpBB/includes/avatar/driver/local.php
@@ -0,0 +1,197 @@
+<?php
+/**
+*
+* @package phpBB3
+* @copyright (c) 2011 phpBB Group
+* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+*
+*/
+
+/**
+* @ignore
+*/
+if (!defined('IN_PHPBB'))
+{
+ exit;
+}
+
+/**
+* Handles avatars selected from the board gallery
+* @package phpBB3
+*/
+class phpbb_avatar_driver_local extends phpbb_avatar_driver
+{
+ /**
+ * @inheritdoc
+ */
+ public function get_data($row)
+ {
+ return array(
+ 'src' => $this->phpbb_root_path . $this->config['avatar_gallery_path'] . '/' . $row['avatar'],
+ 'width' => $row['avatar_width'],
+ 'height' => $row['avatar_height'],
+ );
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function prepare_form($request, $template, $user, $row, &$error)
+ {
+ $avatar_list = $this->get_avatar_list($user);
+ $category = $request->variable('avatar_local_cat', '');
+
+ foreach ($avatar_list as $cat => $null)
+ {
+ if (!empty($avatar_list[$cat]))
+ {
+ $template->assign_block_vars('avatar_local_cats', array(
+ 'NAME' => $cat,
+ 'SELECTED' => ($cat == $category),
+ ));
+ }
+
+ if ($cat != $category)
+ {
+ unset($avatar_list[$cat]);
+ }
+ }
+
+ if (!empty($avatar_list[$category]))
+ {
+ $template->assign_vars(array(
+ 'AVATAR_LOCAL_SHOW' => true,
+ ));
+
+ $table_cols = isset($row['avatar_gallery_cols']) ? $row['avatar_gallery_cols'] : 4;
+ $row_count = $col_count = $avatar_pos = 0;
+ $avatar_count = sizeof($avatar_list[$category]);
+
+ reset($avatar_list[$category]);
+
+ while ($avatar_pos < $avatar_count)
+ {
+ $img = current($avatar_list[$category]);
+ next($avatar_list[$category]);
+
+ if ($col_count == 0)
+ {
+ ++$row_count;
+ $template->assign_block_vars('avatar_local_row', array(
+ ));
+ }
+
+ $template->assign_block_vars('avatar_local_row.avatar_local_col', array(
+ 'AVATAR_IMAGE' => $this->phpbb_root_path . $this->config['avatar_gallery_path'] . '/' . $img['file'],
+ 'AVATAR_NAME' => $img['name'],
+ 'AVATAR_FILE' => $img['filename'],
+ ));
+
+ $template->assign_block_vars('avatar_local_row.avatar_local_option', array(
+ 'AVATAR_FILE' => $img['filename'],
+ 'S_OPTIONS_AVATAR' => $img['filename']
+ ));
+
+ $col_count = ($col_count + 1) % $table_cols;
+
+ ++$avatar_pos;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function prepare_form_acp($user)
+ {
+ return array(
+ 'avatar_gallery_path' => array('lang' => 'AVATAR_GALLERY_PATH', 'validate' => 'rpath', 'type' => 'text:20:255', 'explain' => true),
+ );
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function process_form($request, $template, $user, $row, &$error)
+ {
+ $avatar_list = $this->get_avatar_list($user);
+ $category = $request->variable('avatar_local_cat', '');
+
+ $file = $request->variable('avatar_local_file', '');
+
+ if (empty($category) || empty($file))
+ {
+ $error[] = 'NO_AVATAR_SELECTED';
+ return false;
+ }
+
+ if (!isset($avatar_list[$category][urldecode($file)]))
+ {
+ $error[] = 'AVATAR_URL_NOT_FOUND';
+ return false;
+ }
+
+ return array(
+ 'avatar' => ($category != $user->lang['MAIN']) ? $category . '/' . $file : $file,
+ 'avatar_width' => $avatar_list[$category][urldecode($file)]['width'],
+ 'avatar_height' => $avatar_list[$category][urldecode($file)]['height'],
+ );
+ }
+
+ /**
+ * Get a list of avatars that are locally available
+ * Results get cached for 24 hours (86400 seconds)
+ *
+ * @param phpbb_user $user User object
+ *
+ * @return array Array containing the locally available avatars
+ */
+ protected function get_avatar_list($user)
+ {
+ $avatar_list = ($this->cache == null) ? false : $this->cache->get('avatar_local_list');
+
+ if ($avatar_list === false)
+ {
+ $avatar_list = array();
+ $path = $this->phpbb_root_path . $this->config['avatar_gallery_path'];
+
+ $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS | FilesystemIterator::UNIX_PATHS), RecursiveIteratorIterator::SELF_FIRST);
+ foreach ($iterator as $file_info)
+ {
+ $file_path = $file_info->getPath();
+ $image = $file_info->getFilename();
+
+ // Match all images in the gallery folder
+ if (preg_match('#^[^&\'"<>]+\.(?:' . implode('|', $this->allowed_extensions) . ')$#i', $image) && is_file($file_path . '/' . $image))
+ {
+ if (function_exists('getimagesize'))
+ {
+ $dims = getimagesize($file_path . '/' . $image);
+ }
+ else
+ {
+ $dims = array(0, 0);
+ }
+ $cat = ($path == $file_path) ? $user->lang['MAIN'] : str_replace("$path/", '', $file_path);
+ $avatar_list[$cat][$image] = array(
+ 'file' => ($cat != $user->lang['MAIN']) ? rawurlencode($cat) . '/' . rawurlencode($image) : rawurlencode($image),
+ 'filename' => rawurlencode($image),
+ 'name' => ucfirst(str_replace('_', ' ', preg_replace('#^(.*)\..*$#', '\1', $image))),
+ 'width' => $dims[0],
+ 'height' => $dims[1],
+ );
+ }
+ }
+ ksort($avatar_list);
+
+ if ($this->cache != null)
+ {
+ $this->cache->put('avatar_local_list', $avatar_list, 86400);
+ }
+ }
+
+ return $avatar_list;
+ }
+}
diff --git a/phpBB/includes/avatar/driver/remote.php b/phpBB/includes/avatar/driver/remote.php
new file mode 100644
index 0000000000..3661e16160
--- /dev/null
+++ b/phpBB/includes/avatar/driver/remote.php
@@ -0,0 +1,164 @@
+<?php
+/**
+*
+* @package phpBB3
+* @copyright (c) 2011 phpBB Group
+* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+*
+*/
+
+/**
+* @ignore
+*/
+if (!defined('IN_PHPBB'))
+{
+ exit;
+}
+
+/**
+* Handles avatars hosted remotely
+* @package phpBB3
+*/
+class phpbb_avatar_driver_remote extends phpbb_avatar_driver
+{
+ /**
+ * @inheritdoc
+ */
+ public function get_data($row)
+ {
+ return array(
+ 'src' => $row['avatar'],
+ 'width' => $row['avatar_width'],
+ 'height' => $row['avatar_height'],
+ );
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function prepare_form($request, $template, $user, $row, &$error)
+ {
+ $template->assign_vars(array(
+ 'AVATAR_REMOTE_WIDTH' => ((in_array($row['avatar_type'], array(AVATAR_REMOTE, $this->get_name(), 'remote'))) && $row['avatar_width']) ? $row['avatar_width'] : $request->variable('avatar_remote_width', 0),
+ 'AVATAR_REMOTE_HEIGHT' => ((in_array($row['avatar_type'], array(AVATAR_REMOTE, $this->get_name(), 'remote'))) && $row['avatar_height']) ? $row['avatar_height'] : $request->variable('avatar_remote_width', 0),
+ 'AVATAR_REMOTE_URL' => ((in_array($row['avatar_type'], array(AVATAR_REMOTE, $this->get_name(), 'remote'))) && $row['avatar']) ? $row['avatar'] : '',
+ ));
+
+ return true;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function process_form($request, $template, $user, $row, &$error)
+ {
+ $url = $request->variable('avatar_remote_url', '');
+ $width = $request->variable('avatar_remote_width', 0);
+ $height = $request->variable('avatar_remote_height', 0);
+
+ if (!preg_match('#^(http|https|ftp)://#i', $url))
+ {
+ $url = 'http://' . $url;
+ }
+
+ if (!function_exists('validate_data'))
+ {
+ require($this->phpbb_root_path . 'includes/functions_user' . $this->php_ext);
+ }
+
+ $validate_array = validate_data(
+ array(
+ 'url' => $url,
+ ),
+ array(
+ 'url' => array('string', true, 5, 255),
+ )
+ );
+
+ $error = array_merge($error, $validate_array);
+
+ if (!empty($error))
+ {
+ return false;
+ }
+
+ // Check if this url looks alright
+ // This isn't perfect, but it's what phpBB 3.0 did, and might as well make sure everything is compatible
+ if (!preg_match('#^(http|https|ftp)://(?:(.*?\.)*?[a-z0-9\-]+?\.[a-z]{2,4}|(?:\d{1,3}\.){3,5}\d{1,3}):?([0-9]*?).*?\.('. implode('|', $this->allowed_extensions) . ')$#i', $url))
+ {
+ $error[] = 'AVATAR_URL_INVALID';
+ return false;
+ }
+
+ // Make sure getimagesize works...
+ if (function_exists('getimagesize'))
+ {
+ if (($width <= 0 || $height <= 0) && (($image_data = getimagesize($url)) === false))
+ {
+ $error[] = 'UNABLE_GET_IMAGE_SIZE';
+ return false;
+ }
+
+ if (!empty($image_data) && ($image_data[0] <= 0 || $image_data[1] <= 0))
+ {
+ $error[] = 'AVATAR_NO_SIZE';
+ return false;
+ }
+
+ $width = ($width && $height) ? $width : $image_data[0];
+ $height = ($width && $height) ? $height : $image_data[1];
+ }
+
+ if ($width <= 0 || $height <= 0)
+ {
+ $error[] = 'AVATAR_NO_SIZE';
+ return false;
+ }
+
+ if (!class_exists('fileupload'))
+ {
+ include($this->phpbb_root_path . 'includes/functions_upload' . $this->php_ext);
+ }
+
+ $types = fileupload::image_types();
+ $extension = strtolower(filespec::get_extension($url));
+
+ if (!empty($image_data) && (!isset($types[$image_data[2]]) || !in_array($extension, $types[$image_data[2]])))
+ {
+ if (!isset($types[$image_data[2]]))
+ {
+ $error[] = 'UNABLE_GET_IMAGE_SIZE';
+ }
+ else
+ {
+ $error[] = array('IMAGE_FILETYPE_MISMATCH', $types[$image_data[2]][0], $extension);
+ }
+
+ return false;
+ }
+
+ if ($this->config['avatar_max_width'] || $this->config['avatar_max_height'])
+ {
+ if ($width > $this->config['avatar_max_width'] || $height > $this->config['avatar_max_height'])
+ {
+ $error[] = array('AVATAR_WRONG_SIZE', $this->config['avatar_min_width'], $this->config['avatar_min_height'], $this->config['avatar_max_width'], $this->config['avatar_max_height'], $width, $height);
+ return false;
+ }
+ }
+
+ if ($this->config['avatar_min_width'] || $this->config['avatar_min_height'])
+ {
+ if ($width < $this->config['avatar_min_width'] || $height < $this->config['avatar_min_height'])
+ {
+ $error[] = array('AVATAR_WRONG_SIZE', $this->config['avatar_min_width'], $this->config['avatar_min_height'], $this->config['avatar_max_width'], $this->config['avatar_max_height'], $width, $height);
+ return false;
+ }
+ }
+
+ return array(
+ 'avatar' => $url,
+ 'avatar_width' => $width,
+ 'avatar_height' => $height,
+ );
+ }
+}
diff --git a/phpBB/includes/avatar/driver/upload.php b/phpBB/includes/avatar/driver/upload.php
new file mode 100644
index 0000000000..f91d170d7c
--- /dev/null
+++ b/phpBB/includes/avatar/driver/upload.php
@@ -0,0 +1,159 @@
+<?php
+/**
+*
+* @package phpBB3
+* @copyright (c) 2011 phpBB Group
+* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+*
+*/
+
+/**
+* @ignore
+*/
+if (!defined('IN_PHPBB'))
+{
+ exit;
+}
+
+/**
+* Handles avatars uploaded to the board
+* @package phpBB3
+*/
+class phpbb_avatar_driver_upload extends phpbb_avatar_driver
+{
+ /**
+ * @inheritdoc
+ */
+ public function get_data($row, $ignore_config = false)
+ {
+ return array(
+ 'src' => $this->phpbb_root_path . 'download/file' . $this->php_ext . '?avatar=' . $row['avatar'],
+ 'width' => $row['avatar_width'],
+ 'height' => $row['avatar_height'],
+ );
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function prepare_form($request, $template, $user, $row, &$error)
+ {
+ if (!$this->can_upload())
+ {
+ return false;
+ }
+
+ $template->assign_vars(array(
+ 'S_UPLOAD_AVATAR_URL' => ($this->config['allow_avatar_remote_upload']) ? true : false,
+ 'AVATAR_UPLOAD_SIZE' => $this->config['avatar_filesize'],
+ ));
+
+ return true;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function process_form($request, $template, $user, $row, &$error)
+ {
+ if (!$this->can_upload())
+ {
+ return false;
+ }
+
+ if (!class_exists('fileupload'))
+ {
+ include($this->phpbb_root_path . 'includes/functions_upload' . $this->php_ext);
+ }
+
+ $upload = new fileupload('AVATAR_', $this->allowed_extensions, $this->config['avatar_filesize'], $this->config['avatar_min_width'], $this->config['avatar_min_height'], $this->config['avatar_max_width'], $this->config['avatar_max_height'], (isset($this->config['mime_triggers']) ? explode('|', $this->config['mime_triggers']) : false));
+
+ $url = $request->variable('avatar_upload_url', '');
+ $upload_file = $request->file('avatar_upload_file');
+
+ if (!empty($upload_file['name']))
+ {
+ $file = $upload->form_upload('avatar_upload_file');
+ }
+ elseif (!empty($this->config['allow_avatar_remote_upload']) && !empty($url))
+ {
+ $file = $upload->remote_upload($url);
+ }
+ else
+ {
+ $error[] = 'NO_AVATAR_SELECTED';
+ return false;
+ }
+
+ $prefix = $this->config['avatar_salt'] . '_';
+ $file->clean_filename('avatar', $prefix, $row['id']);
+
+ $destination = $this->config['avatar_path'];
+
+ // Adjust destination path (no trailing slash)
+ if (substr($destination, -1, 1) == '/' || substr($destination, -1, 1) == '\\')
+ {
+ $destination = substr($destination, 0, -1);
+ }
+
+ $destination = str_replace(array('../', '..\\', './', '.\\'), '', $destination);
+ if ($destination && ($destination[0] == '/' || $destination[0] == "\\"))
+ {
+ $destination = '';
+ }
+
+ // Move file and overwrite any existing image
+ $file->move_file($destination, true);
+
+ if (sizeof($file->error))
+ {
+ $file->remove();
+ $error = array_merge($error, $file->error);
+ return false;
+ }
+
+ return array(
+ 'avatar' => $row['id'] . '_' . time() . '.' . $file->get('extension'),
+ 'avatar_width' => $file->get('width'),
+ 'avatar_height' => $file->get('height'),
+ );
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function prepare_form_acp($user)
+ {
+ return array(
+ 'allow_avatar_remote_upload'=> array('lang' => 'ALLOW_REMOTE_UPLOAD', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
+ 'avatar_filesize' => array('lang' => 'MAX_FILESIZE', 'validate' => 'int:0', 'type' => 'text:4:10', 'explain' => true, 'append' => ' ' . $user->lang['BYTES']),
+ 'avatar_path' => array('lang' => 'AVATAR_STORAGE_PATH', 'validate' => 'rwpath', 'type' => 'text:20:255', 'explain' => true),
+ );
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function delete($row)
+ {
+ $ext = substr(strrchr($row['avatar'], '.'), 1);
+ $filename = $this->phpbb_root_path . $this->config['avatar_path'] . '/' . $this->config['avatar_salt'] . '_' . $row['id'] . '.' . $ext;
+
+ if (file_exists($filename))
+ {
+ @unlink($filename);
+ }
+
+ return true;
+ }
+
+ /**
+ * Check if user is able to upload an avatar
+ *
+ * @return bool True if user can upload, false if not
+ */
+ protected function can_upload()
+ {
+ return (file_exists($this->phpbb_root_path . $this->config['avatar_path']) && phpbb_is_writable($this->phpbb_root_path . $this->config['avatar_path']) && (@ini_get('file_uploads') || strtolower(@ini_get('file_uploads')) == 'on'));
+ }
+}
diff --git a/phpBB/includes/avatar/manager.php b/phpBB/includes/avatar/manager.php
new file mode 100644
index 0000000000..9c60436de8
--- /dev/null
+++ b/phpBB/includes/avatar/manager.php
@@ -0,0 +1,292 @@
+<?php
+/**
+*
+* @package phpBB3
+* @copyright (c) 2011 phpBB Group
+* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+*
+*/
+
+/**
+* @ignore
+*/
+if (!defined('IN_PHPBB'))
+{
+ exit;
+}
+
+/**
+* @package avatar
+*/
+class phpbb_avatar_manager
+{
+ /**
+ * phpBB configuration
+ * @var phpbb_config
+ */
+ protected $config;
+
+ /**
+ * Array that contains a list of enabled drivers
+ * @var array
+ */
+ static protected $enabled_drivers = false;
+
+ /**
+ * Array that contains all available avatar drivers which are passed via the
+ * service container
+ * @var array
+ */
+ protected $avatar_drivers;
+
+ /**
+ * Service container object
+ * @var object
+ */
+ protected $container;
+
+ /**
+ * Construct an avatar manager object
+ *
+ * @param phpbb_config $config phpBB configuration
+ * @param array $avatar_drivers Avatar drivers passed via the service container
+ * @param object $container Container object
+ */
+ public function __construct(phpbb_config $config, $avatar_drivers, $container)
+ {
+ $this->config = $config;
+ $this->avatar_drivers = $avatar_drivers;
+ $this->container = $container;
+ }
+
+ /**
+ * Get the driver object specified by the avatar type
+ *
+ * @param string $avatar_type Avatar type; by default an avatar's service container name
+ * @param bool $load_enabled Load only enabled avatars
+ *
+ * @return object Avatar driver object
+ */
+ public function get_driver($avatar_type, $load_enabled = true)
+ {
+ if (self::$enabled_drivers === false)
+ {
+ $this->load_enabled_drivers();
+ }
+
+ $avatar_drivers = ($load_enabled) ? self::$enabled_drivers : $this->get_all_drivers();
+
+ // Legacy stuff...
+ switch ($avatar_type)
+ {
+ case AVATAR_GALLERY:
+ $avatar_type = 'avatar.driver.local';
+ break;
+ case AVATAR_UPLOAD:
+ $avatar_type = 'avatar.driver.upload';
+ break;
+ case AVATAR_REMOTE:
+ $avatar_type = 'avatar.driver.remote';
+ break;
+ }
+
+ if (!isset($avatar_drivers[$avatar_type]))
+ {
+ return null;
+ }
+
+ /*
+ * There is no need to handle invalid avatar types as the following code
+ * will cause a ServiceNotFoundException if the type does not exist
+ */
+ $driver = $this->container->get($avatar_type);
+
+ return $driver;
+ }
+
+ /**
+ * Load the list of enabled drivers
+ * This is executed once and fills self::$enabled_drivers
+ */
+ protected function load_enabled_drivers()
+ {
+ if (!empty($this->avatar_drivers))
+ {
+ self::$enabled_drivers = array();
+ foreach ($this->avatar_drivers as $driver)
+ {
+ if ($this->is_enabled($driver))
+ {
+ self::$enabled_drivers[$driver->get_name()] = $driver->get_name();
+ }
+ }
+ asort(self::$enabled_drivers);
+ }
+ }
+
+ /**
+ * Get a list of all avatar drivers
+ *
+ * As this function will only be called in the ACP avatar settings page, it
+ * doesn't make much sense to cache the list of all avatar drivers like the
+ * list of the enabled drivers.
+ *
+ * @return array Array containing a list of all avatar drivers
+ */
+ public function get_all_drivers()
+ {
+ $drivers = array();
+
+ if (!empty($this->avatar_drivers))
+ {
+ foreach ($this->avatar_drivers as $driver)
+ {
+ $drivers[$driver->get_name()] = $driver->get_name();
+ }
+ asort($drivers);
+ }
+
+ return $drivers;
+ }
+
+ /**
+ * Get a list of enabled avatar drivers
+ *
+ * @return array Array containing a list of the enabled avatar drivers
+ */
+ public function get_enabled_drivers()
+ {
+ if (self::$enabled_drivers === false)
+ {
+ $this->load_enabled_drivers();
+ }
+
+ return self::$enabled_drivers;
+ }
+
+ /**
+ * Strip out user_ and group_ prefixes from keys
+ *
+ * @param array $row User data or group data
+ *
+ * @return array User data or group data with keys that have been
+ * stripped from the preceding "user_" or "group_"
+ */
+ static public function clean_row($row)
+ {
+ $keys = array_keys($row);
+ $values = array_values($row);
+
+ $keys = array_map(array('phpbb_avatar_manager', 'strip_prefix'), $keys);
+
+ return array_combine($keys, $values);
+ }
+
+ /**
+ * Strip prepending user_ or group_ prefix from key
+ *
+ * @param string Array key
+ * @return string Key that has been stripped from its prefix
+ */
+ static protected function strip_prefix($key)
+ {
+ return preg_replace('#^(?:user_|group_)#', '', $key);
+ }
+
+ /**
+ * Clean driver names that are returned from template files
+ * Underscores are replaced with dots
+ *
+ * @param string $name Driver name
+ *
+ * @return string Cleaned driver name
+ */
+ static public function clean_driver_name($name)
+ {
+ return str_replace('_', '.', $name);
+ }
+
+ /**
+ * Prepare driver names for use in template files
+ * Dots are replaced with underscores
+ *
+ * @param string $name Clean driver name
+ *
+ * @return string Prepared driver name
+ */
+ static public function prepare_driver_name($name)
+ {
+ return str_replace('.', '_', $name);
+ }
+
+ /**
+ * Check if avatar is enabled
+ *
+ * @param object $driver Avatar driver object
+ *
+ * @return bool True if avatar is enabled, false if it's disabled
+ */
+ public function is_enabled($driver)
+ {
+ $config_name = $this->get_driver_config_name($driver);
+
+ return $this->config["allow_avatar_{$config_name}"];
+ }
+
+ /**
+ * Get the settings array for enabling/disabling an avatar driver
+ *
+ * @param object $driver Avatar driver object
+ *
+ * @return array Array of configuration options as consumed by acp_board
+ */
+ public function get_avatar_settings($driver)
+ {
+ $config_name = $this->get_driver_config_name($driver);
+
+ return array(
+ 'allow_avatar_' . $config_name => array('lang' => 'ALLOW_' . strtoupper($config_name), 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
+ );
+ }
+
+ /**
+ * Get the config name of an avatar driver
+ *
+ * @param object $driver Avatar driver object
+ *
+ * @return string Avatar driver config name
+ */
+ public function get_driver_config_name($driver)
+ {
+ return preg_replace('#^phpbb_avatar_driver_#', '', get_class($driver));
+ }
+
+ /**
+ * Replace "error" strings with their real, localized form
+ *
+ * @param phpbb_user phpBB User object
+ * @param array $error Array containing error strings
+ * Key values can either be a string with a language key or an array
+ * that will be passed to vsprintf() with the language key in the
+ * first array key.
+ *
+ * @return array Array containing the localized error strings
+ */
+ public function localize_errors(phpbb_user $user, $error)
+ {
+ foreach ($error as $key => $lang)
+ {
+ if (is_array($lang))
+ {
+ $lang_key = array_shift($lang);
+ $error[$key] = vsprintf($user->lang($lang_key), $lang);
+ }
+ else
+ {
+ $error[$key] = $user->lang("$lang");
+ }
+ }
+
+ return $error;
+ }
+}
diff --git a/phpBB/includes/constants.php b/phpBB/includes/constants.php
index d0deb36a89..5c4c5f4327 100644
--- a/phpBB/includes/constants.php
+++ b/phpBB/includes/constants.php
@@ -274,6 +274,7 @@ define('STYLES_TEMPLATE_DATA_TABLE',$table_prefix . 'styles_template_data');
define('STYLES_THEME_TABLE', $table_prefix . 'styles_theme');
define('STYLES_IMAGESET_TABLE', $table_prefix . 'styles_imageset');
define('STYLES_IMAGESET_DATA_TABLE',$table_prefix . 'styles_imageset_data');
+define('TEAMPAGE_TABLE', $table_prefix . 'teampage');
define('TOPICS_TABLE', $table_prefix . 'topics');
define('TOPICS_POSTED_TABLE', $table_prefix . 'topics_posted');
define('TOPICS_TRACK_TABLE', $table_prefix . 'topics_track');
diff --git a/phpBB/includes/db/migration/data/310/avatars.php b/phpBB/includes/db/migration/data/310/avatars.php
new file mode 100644
index 0000000000..79547337f7
--- /dev/null
+++ b/phpBB/includes/db/migration/data/310/avatars.php
@@ -0,0 +1,67 @@
+<?php
+/**
+*
+* @package migration
+* @copyright (c) 2013 phpBB Group
+* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+*
+*/
+
+class phpbb_db_migration_data_310_avatars extends phpbb_db_migration
+{
+ public function effectively_installed()
+ {
+ return isset($this->config['allow_avatar_gravatar']);
+ }
+
+ static public function depends_on()
+ {
+ return array('phpbb_db_migration_data_30x_3_0_11');
+ }
+
+ public function update_schema()
+ {
+ return array(
+ 'change_columns' => array(
+ $this->table_prefix . 'users' => array(
+ 'user_avatar_type' => array('VCHAR:255', ''),
+ ),
+ $this->table_prefix . 'groups' => array(
+ 'group_avatar_type' => array('VCHAR:255', ''),
+ ),
+ ),
+ );
+ }
+
+ public function revert_schema()
+ {
+ return array(
+ 'change_columns' => array(
+ $this->table_prefix . 'users' => array(
+ 'user_avatar_type' => array('TINT:2', ''),
+ ),
+ $this->table_prefix . 'groups' => array(
+ 'group_avatar_type' => array('TINT:2', ''),
+ ),
+ ),
+ );
+ }
+
+ public function update_data()
+ {
+ return array(
+ array('config.add', array('allow_avatar_gravatar', 0)),
+ array('custom', array(array($this, 'update_module_auth'))),
+ );
+ }
+
+ public function update_module_auth()
+ {
+ $sql = 'UPDATE ' . $this->table_prefix . "modules
+ SET module_auth = 'cfg_allow_avatar'
+ WHERE module_class = 'ucp'
+ AND module_basename = 'ucp_profile'
+ AND module_mode = 'avatar'";
+ $this->db->sql_query($sql);
+ }
+}
diff --git a/phpBB/includes/db/migration/data/310/teampage.php b/phpBB/includes/db/migration/data/310/teampage.php
new file mode 100644
index 0000000000..4e77da17b7
--- /dev/null
+++ b/phpBB/includes/db/migration/data/310/teampage.php
@@ -0,0 +1,104 @@
+<?php
+/**
+*
+* @package migration
+* @copyright (c) 2012 phpBB Group
+* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+*
+*/
+
+class phpbb_db_migration_data_310_teampage extends phpbb_db_migration
+{
+ public function effectively_installed()
+ {
+ return $this->db_tools->sql_table_exists($this->table_prefix . 'teampage');
+ }
+
+ static public function depends_on()
+ {
+ return array('phpbb_db_migration_data_310_dev');
+ }
+
+ public function update_schema()
+ {
+ return array(
+ 'add_tables' => array(
+ $this->table_prefix . 'teampage' => array(
+ 'COLUMNS' => array(
+ 'teampage_id' => array('UINT', NULL, 'auto_increment'),
+ 'group_id' => array('UINT', 0),
+ 'teampage_name' => array('VCHAR_UNI:255', ''),
+ 'teampage_position' => array('UINT', 0),
+ 'teampage_parent' => array('UINT', 0),
+ ),
+ 'PRIMARY_KEY' => 'teampage_id',
+ ),
+ ),
+ 'drop_columns' => array(
+ $this->table_prefix . 'groups' => array(
+ 'group_teampage',
+ ),
+ ),
+ );
+ }
+
+ public function revert_schema()
+ {
+ return array(
+ 'drop_tables' => array(
+ $this->table_prefix . 'teampage',
+ ),
+ 'add_columns' => array(
+ $this->table_prefix . 'groups' => array(
+ 'group_teampage' => array('UINT', 0, 'after' => 'group_legend'),
+ ),
+ ),
+ );
+ }
+
+ public function update_data()
+ {
+ return array(
+ array('custom', array(array($this, 'add_groups_teampage'))),
+ );
+ }
+
+ public function add_groups_teampage()
+ {
+ $sql = 'SELECT teampage_id
+ FROM ' . TEAMPAGE_TABLE;
+ $result = $this->db->sql_query_limit($sql, 1);
+ $added_groups_teampage = (bool) $this->db->sql_fetchfield('teampage_id');
+ $this->db->sql_freeresult($result);
+
+ if (!$added_groups_teampage)
+ {
+ $sql = 'SELECT *
+ FROM ' . GROUPS_TABLE . '
+ WHERE group_type = ' . GROUP_SPECIAL . "
+ AND (group_name = 'ADMINISTRATORS'
+ OR group_name = 'GLOBAL_MODERATORS')
+ ORDER BY group_name ASC";
+ $result = $this->db->sql_query($sql);
+
+ $teampage_entries = array();
+ while ($row = $this->db->sql_fetchrow($result))
+ {
+ $teampage_entries[] = array(
+ 'group_id' => (int) $row['group_id'],
+ 'teampage_name' => '',
+ 'teampage_position' => sizeof($teampage_entries) + 1,
+ 'teampage_parent' => 0,
+ );
+ }
+ $this->db->sql_freeresult($result);
+
+ if (sizeof($teampage_entries))
+ {
+ $this->db->sql_multi_insert(TEAMPAGE_TABLE, $teampage_entries);
+ }
+ unset($teampage_entries);
+ }
+
+ }
+}
diff --git a/phpBB/includes/db/migration/tool/config.php b/phpBB/includes/db/migration/tool/config.php
index 458a25fb66..0b626bf455 100644
--- a/phpBB/includes/db/migration/tool/config.php
+++ b/phpBB/includes/db/migration/tool/config.php
@@ -49,7 +49,7 @@ class phpbb_db_migration_tool_config implements phpbb_db_migration_tool_interfac
{
if (isset($this->config[$config_name]))
{
- throw new phpbb_db_migration_exception('CONFIG_ALREADY_EXIST', $config_name);
+ return;
}
$this->config->set($config_name, $config_value, !$is_dynamic);
@@ -105,7 +105,7 @@ class phpbb_db_migration_tool_config implements phpbb_db_migration_tool_interfac
{
if (!isset($this->config[$config_name]))
{
- throw new phpbb_db_migration_exception('CONFIG_NOT_EXIST', $config_name);
+ return;
}
$this->config->delete($config_name);
diff --git a/phpBB/includes/db/migration/tool/module.php b/phpBB/includes/db/migration/tool/module.php
index ad94c5aadb..ec683d36af 100644
--- a/phpBB/includes/db/migration/tool/module.php
+++ b/phpBB/includes/db/migration/tool/module.php
@@ -236,7 +236,7 @@ class phpbb_db_migration_tool_module implements phpbb_db_migration_tool_interfac
if ($this->exists($class, $parent, $data['module_langname']))
{
- throw new phpbb_db_migration_exception('MODULE_ALREADY_EXIST', $data['module_langname']);
+ return;
}
if (!class_exists('acp_modules'))
@@ -369,7 +369,7 @@ class phpbb_db_migration_tool_module implements phpbb_db_migration_tool_interfac
{
if (!$this->exists($class, $parent, $module))
{
- throw new phpbb_db_migration_exception('MODULE_NOT_EXIST', ((isset($this->user->lang[$module])) ? $this->user->lang[$module] : $module));
+ return;
}
$parent_sql = '';
@@ -442,7 +442,7 @@ class phpbb_db_migration_tool_module implements phpbb_db_migration_tool_interfac
$result = $acp_modules->delete_module($module_id);
if (!empty($result))
{
- throw new phpbb_db_migration_exception('MODULE_NOT_REMOVABLE', $module_id, $result);
+ return;
}
}
diff --git a/phpBB/includes/db/migration/tool/permission.php b/phpBB/includes/db/migration/tool/permission.php
index 4231fbe1dd..2f09c0ac72 100644
--- a/phpBB/includes/db/migration/tool/permission.php
+++ b/phpBB/includes/db/migration/tool/permission.php
@@ -107,7 +107,7 @@ class phpbb_db_migration_tool_permission implements phpbb_db_migration_tool_inte
{
if ($this->exists($auth_option, $global))
{
- throw new phpbb_db_migration_exception('PERMISSION_ALREADY_EXIST', $auth_option);
+ return;
}
// We've added permissions, so set to true to notify the user.
@@ -190,7 +190,7 @@ class phpbb_db_migration_tool_permission implements phpbb_db_migration_tool_inte
{
if (!$this->exists($auth_option, $global))
{
- throw new phpbb_db_migration_exception('PERMISSION_NOT_EXIST', $auth_option);
+ return;
}
if ($global)
@@ -315,7 +315,7 @@ class phpbb_db_migration_tool_permission implements phpbb_db_migration_tool_inte
if (!$role_id)
{
- throw new phpbb_db_migration_exception('ROLE_NOT_EXIST', $role_name);
+ return;
}
$sql = 'DELETE FROM ' . ACL_ROLES_DATA_TABLE . '
@@ -422,7 +422,7 @@ class phpbb_db_migration_tool_permission implements phpbb_db_migration_tool_inte
$this->db->sql_query($sql);
$role_name = $this->db->sql_fetchfield('role_name');
- return $this->set($role_name, $auth_option, 'role', $has_permission);
+ return $this->permission_set($role_name, $auth_option, 'role', $has_permission);
}
$sql = 'SELECT auth_option_id, auth_setting
diff --git a/phpBB/includes/db/migrator.php b/phpBB/includes/db/migrator.php
index de9c06948c..9d7cede95b 100644
--- a/phpBB/includes/db/migrator.php
+++ b/phpBB/includes/db/migrator.php
@@ -31,9 +31,6 @@ class phpbb_db_migrator
/** @var phpbb_db_tools */
protected $db_tools;
- /** @var phpbb_extension_manager */
- protected $extension_manager;
-
/** @var string */
protected $table_prefix;
@@ -63,7 +60,9 @@ class phpbb_db_migrator
protected $migrations = array();
/**
- * 'name' and 'class' of the last migration run
+ * 'name,' 'class,' and 'state' of the last migration run
+ *
+ * 'effectively_installed' set and set to true if the migration was effectively_installed
*
* @var array
*/
@@ -94,16 +93,6 @@ class phpbb_db_migrator
}
/**
- * Set Extension Manager (required)
- *
- * Not in constructor to prevent circular reference error
- */
- public function set_extension_manager(phpbb_extension_manager $extension_manager)
- {
- $this->extension_manager = $extension_manager;
- }
-
- /**
* Loads all migrations and their application state from the database.
*
* @return null
@@ -146,98 +135,6 @@ class phpbb_db_migrator
}
/**
- * This function adds all migrations in a specified directory to the migrations table
- *
- * THIS SHOULD NOT GENERALLY BE USED! THIS IS FOR THE PHPBB INSTALLER.
- * THIS WILL THROW ERRORS IF MIGRATIONS ALREADY EXIST IN THE TABLE, DO NOT CALL MORE THAN ONCE!
- *
- * @param string $path Path to migration data files
- * @param bool $recursive Set to true to also load data files from subdirectories
- * @return null
- */
- public function populate_migrations_from_directory($path, $recursive = true)
- {
- $existing_migrations = $this->migrations;
-
- $this->migrations = array();
- $this->load_migrations($path, true, $recursive);
-
- foreach ($this->migrations as $name)
- {
- if ($this->migration_state($name) === false)
- {
- $state = array(
- 'migration_depends_on' => $name::depends_on(),
- 'migration_schema_done' => true,
- 'migration_data_done' => true,
- 'migration_data_state' => '',
- 'migration_start_time' => time(),
- 'migration_end_time' => time(),
- );
- $this->insert_migration($name, $state);
- }
- }
-
- $this->migrations = $existing_migrations;
- }
-
- /**
- * Load migration data files from a directory
- *
- * Migration data files loaded with this function MUST contain
- * ONLY ONE class in them (or an exception will be thrown).
- *
- * @param string $path Path to migration data files
- * @param bool $check_fulfillable If TRUE (default), we will check
- * if all of the migrations are fulfillable after loading them.
- * If FALSE, we will not check. You SHOULD check at least once
- * to prevent errors (if including multiple directories, check
- * with the last call to prevent throwing errors unnecessarily).
- * @return array Array of migration names
- */
- public function load_migrations($path, $check_fulfillable = true)
- {
- if (!is_dir($path))
- {
- throw new phpbb_db_migration_exception('DIRECTORY INVALID', $path);
- }
-
- $migrations = array();
-
- $finder = $this->extension_manager->get_finder();
- $files = $finder
- ->extension_directory("/")
- ->find_from_paths(array('/' => $path));
- foreach ($files as $file)
- {
- $migrations[$file['path'] . $file['filename']] = '';
- }
- $migrations = $finder->get_classes_from_files($migrations);
-
- foreach ($migrations as $migration)
- {
- if (!in_array($migration, $this->migrations))
- {
- $this->migrations[] = $migration;
- }
- }
-
- if ($check_fulfillable)
- {
- foreach ($this->migrations as $name)
- {
- $unfulfillable = $this->unfulfillable($name);
- if ($unfulfillable !== false)
- {
- throw new phpbb_db_migration_exception('MIGRATION_NOT_FULFILLABLE', $name, $unfulfillable);
- }
- }
- }
-
- return $this->migrations;
- }
-
- /**
* Runs a single update step from the next migration to be applied.
*
* The update step can either be a schema or a (partial) data update. To
@@ -304,6 +201,7 @@ class phpbb_db_migrator
$this->last_run_migration = array(
'name' => $name,
'class' => $migration,
+ 'state' => $state,
);
if (!isset($this->migration_state[$name]))
@@ -318,6 +216,8 @@ class phpbb_db_migrator
'migration_start_time' => 0,
'migration_end_time' => 0,
);
+
+ $this->last_run_migration['effectively_installed'] = true;
}
else
{
@@ -350,7 +250,7 @@ class phpbb_db_migrator
}
}
- $this->insert_migration($name, $state);
+ $this->set_migration_state($name, $state);
return true;
}
@@ -422,7 +322,7 @@ class phpbb_db_migrator
$state['migration_data_done'] = ($result === true) ? false : true;
}
- $this->insert_migration($name, $state);
+ $this->set_migration_state($name, $state);
}
else
{
@@ -641,7 +541,7 @@ class phpbb_db_migrator
* @param array $state
* @return null
*/
- protected function insert_migration($name, $state)
+ protected function set_migration_state($name, $state)
{
$migration_row = $state;
$migration_row['migration_depends_on'] = serialize($state['migration_depends_on']);
@@ -662,6 +562,8 @@ class phpbb_db_migrator
}
$this->migration_state[$name] = $state;
+
+ $this->last_run_migration['state'] = $state;
}
/**
@@ -754,4 +656,85 @@ class phpbb_db_migrator
{
return new $name($this->config, $this->db, $this->db_tools, $this->phpbb_root_path, $this->php_ext, $this->table_prefix);
}
+
+ /**
+ * This function adds all migrations sent to it to the migrations table
+ *
+ * THIS SHOULD NOT GENERALLY BE USED! THIS IS FOR THE PHPBB INSTALLER.
+ * THIS WILL THROW ERRORS IF MIGRATIONS ALREADY EXIST IN THE TABLE, DO NOT CALL MORE THAN ONCE!
+ *
+ * @param array $migrations Array of migrations (names) to add to the migrations table
+ * @return null
+ */
+ public function populate_migrations($migrations)
+ {
+ foreach ($migrations as $name)
+ {
+ if ($this->migration_state($name) === false)
+ {
+ $state = array(
+ 'migration_depends_on' => $name::depends_on(),
+ 'migration_schema_done' => true,
+ 'migration_data_done' => true,
+ 'migration_data_state' => '',
+ 'migration_start_time' => time(),
+ 'migration_end_time' => time(),
+ );
+ $this->set_migration_state($name, $state);
+ }
+ }
+ }
+
+ /**
+ * Load migration data files from a directory
+ *
+ * @param phpbb_extension_finder $finder
+ * @param string $path Path to migration data files
+ * @param bool $check_fulfillable If TRUE (default), we will check
+ * if all of the migrations are fulfillable after loading them.
+ * If FALSE, we will not check. You SHOULD check at least once
+ * to prevent errors (if including multiple directories, check
+ * with the last call to prevent throwing errors unnecessarily).
+ * @return array Array of migration names
+ */
+ public function load_migrations(phpbb_extension_finder $finder, $path, $check_fulfillable = true)
+ {
+ if (!is_dir($path))
+ {
+ throw new phpbb_db_migration_exception('DIRECTORY INVALID', $path);
+ }
+
+ $migrations = array();
+
+ $files = $finder
+ ->extension_directory("/")
+ ->find_from_paths(array('/' => $path));
+ foreach ($files as $file)
+ {
+ $migrations[$file['path'] . $file['filename']] = '';
+ }
+ $migrations = $finder->get_classes_from_files($migrations);
+
+ foreach ($migrations as $migration)
+ {
+ if (!in_array($migration, $this->migrations))
+ {
+ $this->migrations[] = $migration;
+ }
+ }
+
+ if ($check_fulfillable)
+ {
+ foreach ($this->migrations as $name)
+ {
+ $unfulfillable = $this->unfulfillable($name);
+ if ($unfulfillable !== false)
+ {
+ throw new phpbb_db_migration_exception('MIGRATION_NOT_FULFILLABLE', $name, $unfulfillable);
+ }
+ }
+ }
+
+ return $this->migrations;
+ }
}
diff --git a/phpBB/includes/extension/manager.php b/phpBB/includes/extension/manager.php
index 0d760681b9..44a30c6280 100644
--- a/phpBB/includes/extension/manager.php
+++ b/phpBB/includes/extension/manager.php
@@ -43,18 +43,20 @@ class phpbb_extension_manager
* @param ContainerInterface $container A container
* @param phpbb_db_driver $db A database connection
* @param phpbb_config $config phpbb_config
+ * @param phpbb_db_migrator $migrator
* @param string $extension_table The name of the table holding extensions
* @param string $phpbb_root_path Path to the phpbb includes directory.
* @param string $php_ext php file extension
* @param phpbb_cache_driver_interface $cache A cache instance or null
* @param string $cache_name The name of the cache variable, defaults to _ext
*/
- public function __construct(ContainerInterface $container, phpbb_db_driver $db, phpbb_config $config, $extension_table, $phpbb_root_path, $php_ext = '.php', phpbb_cache_driver_interface $cache = null, $cache_name = '_ext')
+ public function __construct(ContainerInterface $container, phpbb_db_driver $db, phpbb_config $config, phpbb_db_migrator $migrator, $extension_table, $phpbb_root_path, $php_ext = '.php', phpbb_cache_driver_interface $cache = null, $cache_name = '_ext')
{
$this->container = $container;
$this->phpbb_root_path = $phpbb_root_path;
$this->db = $db;
$this->config = $config;
+ $this->migrator = $migrator;
$this->cache = $cache;
$this->php_ext = $php_ext;
$this->extension_table = $extension_table;
@@ -69,14 +71,6 @@ class phpbb_extension_manager
}
/**
- * Set migrator (get around circular reference)
- */
- public function set_migrator(phpbb_db_migrator $migrator)
- {
- $this->migrator = $migrator;
- }
-
- /**
* Loads all extension information from the database
*
* @return null
@@ -528,13 +522,27 @@ class phpbb_extension_manager
*/
protected function handle_migrations($extension_name, $mode)
{
- $migrations_path = $this->phpbb_root_path . $this->get_extension_path($extension_name) . 'migrations/';
- if (!file_exists($migrations_path) || !is_dir($migrations_path))
+ $extensions = array(
+ $extension_name => $this->phpbb_root_path . $this->get_extension_path($extension_name),
+ );
+
+ $finder = $this->get_finder();
+ $migrations = array();
+ $file_list = $finder
+ ->extension_directory('/migrations')
+ ->find_from_paths($extensions);
+
+ if (empty($file_list))
{
return true;
}
- $migrations = $this->migrator->load_migrations($migrations_path);
+ foreach ($file_list as $file)
+ {
+ $migrations[$file['named_path']] = $file['ext_name'];
+ }
+ $migrations = $finder->get_classes_from_files($migrations);
+ $this->migrator->set_migrations($migrations);
// What is a safe limit of execution time? Half the max execution time should be safe.
$safe_time_limit = (ini_get('max_execution_time') / 2);
diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php
index 5701b8baca..98418ff9e7 100644
--- a/phpBB/includes/functions.php
+++ b/phpBB/includes/functions.php
@@ -3583,69 +3583,49 @@ function parse_cfg_file($filename, $lines = false)
}
/**
-* Add log event
+* Add log entry
+*
+* @param string $mode The mode defines which log_type is used and from which log the entry is retrieved
+* @param int $forum_id Mode 'mod' ONLY: forum id of the related item, NOT INCLUDED otherwise
+* @param int $topic_id Mode 'mod' ONLY: topic id of the related item, NOT INCLUDED otherwise
+* @param int $reportee_id Mode 'user' ONLY: user id of the reportee, NOT INCLUDED otherwise
+* @param string $log_operation Name of the operation
+* @param array $additional_data More arguments can be added, depending on the log_type
+*
+* @return int|bool Returns the log_id, if the entry was added to the database, false otherwise.
+*
+* @deprecated Use $phpbb_log->add() instead
*/
function add_log()
{
- global $db, $user;
-
- // In phpBB 3.1.x i want to have logging in a class to be able to control it
- // For now, we need a quite hakish approach to circumvent logging for some actions
- // @todo implement cleanly
- if (!empty($GLOBALS['skip_add_log']))
- {
- return false;
- }
+ global $phpbb_log, $user;
$args = func_get_args();
+ $mode = array_shift($args);
- $mode = array_shift($args);
- $reportee_id = ($mode == 'user') ? intval(array_shift($args)) : '';
- $forum_id = ($mode == 'mod') ? intval(array_shift($args)) : '';
- $topic_id = ($mode == 'mod') ? intval(array_shift($args)) : '';
- $action = array_shift($args);
- $data = (!sizeof($args)) ? '' : serialize($args);
-
- $sql_ary = array(
- 'user_id' => (empty($user->data)) ? ANONYMOUS : $user->data['user_id'],
- 'log_ip' => $user->ip,
- 'log_time' => time(),
- 'log_operation' => $action,
- 'log_data' => $data,
- );
-
+ // This looks kind of dirty, but add_log has some additional data before the log_operation
+ $additional_data = array();
switch ($mode)
{
case 'admin':
- $sql_ary['log_type'] = LOG_ADMIN;
+ case 'critical':
break;
-
case 'mod':
- $sql_ary += array(
- 'log_type' => LOG_MOD,
- 'forum_id' => $forum_id,
- 'topic_id' => $topic_id
- );
+ $additional_data['forum_id'] = array_shift($args);
+ $additional_data['topic_id'] = array_shift($args);
break;
-
case 'user':
- $sql_ary += array(
- 'log_type' => LOG_USERS,
- 'reportee_id' => $reportee_id
- );
- break;
-
- case 'critical':
- $sql_ary['log_type'] = LOG_CRITICAL;
+ $additional_data['reportee_id'] = array_shift($args);
break;
-
- default:
- return false;
}
- $db->sql_query('INSERT INTO ' . LOG_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary));
+ $log_operation = array_shift($args);
+ $additional_data = array_merge($additional_data, $args);
+
+ $user_id = (empty($user->data)) ? ANONYMOUS : $user->data['user_id'];
+ $user_ip = (empty($user->ip)) ? '' : $user->ip;
- return $db->sql_nextid();
+ return $phpbb_log->add($mode, $user_id, $user_ip, $log_operation, time(), $additional_data);
}
/**
diff --git a/phpBB/includes/functions_admin.php b/phpBB/includes/functions_admin.php
index b844bd1966..2103362651 100644
--- a/phpBB/includes/functions_admin.php
+++ b/phpBB/includes/functions_admin.php
@@ -2540,273 +2540,32 @@ function cache_moderators()
/**
* View log
-* If $log_count is set to false, we will skip counting all entries in the database.
+*
+* @param string $mode The mode defines which log_type is used and from which log the entry is retrieved
+* @param array &$log The result array with the logs
+* @param mixed &$log_count If $log_count is set to false, we will skip counting all entries in the database.
+* Otherwise an integer with the number of total matching entries is returned.
+* @param int $limit Limit the number of entries that are returned
+* @param int $offset Offset when fetching the log entries, f.e. when paginating
+* @param mixed $forum_id Restrict the log entries to the given forum_id (can also be an array of forum_ids)
+* @param int $topic_id Restrict the log entries to the given topic_id
+* @param int $user_id Restrict the log entries to the given user_id
+* @param int $log_time Only get log entries newer than the given timestamp
+* @param string $sort_by SQL order option, e.g. 'l.log_time DESC'
+* @param string $keywords Will only return log entries that have the keywords in log_operation or log_data
+*
+* @return int Returns the offset of the last valid page, if the specified offset was invalid (too high)
*/
function view_log($mode, &$log, &$log_count, $limit = 0, $offset = 0, $forum_id = 0, $topic_id = 0, $user_id = 0, $limit_days = 0, $sort_by = 'l.log_time DESC', $keywords = '')
{
- global $db, $user, $auth, $phpEx, $phpbb_root_path, $phpbb_admin_path;
-
- $topic_id_list = $reportee_id_list = $is_auth = $is_mod = array();
-
- $profile_url = (defined('IN_ADMIN')) ? append_sid("{$phpbb_admin_path}index.$phpEx", 'i=users&amp;mode=overview') : append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=viewprofile');
-
- switch ($mode)
- {
- case 'admin':
- $log_type = LOG_ADMIN;
- $sql_forum = '';
- break;
-
- case 'mod':
- $log_type = LOG_MOD;
- $sql_forum = '';
-
- if ($topic_id)
- {
- $sql_forum = 'AND l.topic_id = ' . (int) $topic_id;
- }
- else if (is_array($forum_id))
- {
- $sql_forum = 'AND ' . $db->sql_in_set('l.forum_id', array_map('intval', $forum_id));
- }
- else if ($forum_id)
- {
- $sql_forum = 'AND l.forum_id = ' . (int) $forum_id;
- }
- break;
-
- case 'user':
- $log_type = LOG_USERS;
- $sql_forum = 'AND l.reportee_id = ' . (int) $user_id;
- break;
-
- case 'users':
- $log_type = LOG_USERS;
- $sql_forum = '';
- break;
-
- case 'critical':
- $log_type = LOG_CRITICAL;
- $sql_forum = '';
- break;
-
- default:
- return;
- }
-
- // Use no preg_quote for $keywords because this would lead to sole backslashes being added
- // We also use an OR connection here for spaces and the | string. Currently, regex is not supported for searching (but may come later).
- $keywords = preg_split('#[\s|]+#u', utf8_strtolower($keywords), 0, PREG_SPLIT_NO_EMPTY);
- $sql_keywords = '';
-
- if (!empty($keywords))
- {
- $keywords_pattern = array();
-
- // Build pattern and keywords...
- for ($i = 0, $num_keywords = sizeof($keywords); $i < $num_keywords; $i++)
- {
- $keywords_pattern[] = preg_quote($keywords[$i], '#');
- $keywords[$i] = $db->sql_like_expression($db->any_char . $keywords[$i] . $db->any_char);
- }
+ global $phpbb_log;
- $keywords_pattern = '#' . implode('|', $keywords_pattern) . '#ui';
+ $count_logs = ($log_count !== false);
- $operations = array();
- foreach ($user->lang as $key => $value)
- {
- if (substr($key, 0, 4) == 'LOG_' && preg_match($keywords_pattern, $value))
- {
- $operations[] = $key;
- }
- }
-
- $sql_keywords = 'AND (';
- if (!empty($operations))
- {
- $sql_keywords .= $db->sql_in_set('l.log_operation', $operations) . ' OR ';
- }
- $sql_lower = $db->sql_lower_text('l.log_data');
- $sql_keywords .= "$sql_lower " . implode(" OR $sql_lower ", $keywords) . ')';
- }
-
- if ($log_count !== false)
- {
- $sql = 'SELECT COUNT(l.log_id) AS total_entries
- FROM ' . LOG_TABLE . ' l, ' . USERS_TABLE . " u
- WHERE l.log_type = $log_type
- AND l.user_id = u.user_id
- AND l.log_time >= $limit_days
- $sql_keywords
- $sql_forum";
- $result = $db->sql_query($sql);
- $log_count = (int) $db->sql_fetchfield('total_entries');
- $db->sql_freeresult($result);
- }
-
- // $log_count may be false here if false was passed in for it,
- // because in this case we did not run the COUNT() query above.
- // If we ran the COUNT() query and it returned zero rows, return;
- // otherwise query for logs below.
- if ($log_count === 0)
- {
- // Save the queries, because there are no logs to display
- return 0;
- }
-
- if ($offset >= $log_count)
- {
- $offset = ($offset - $limit < 0) ? 0 : $offset - $limit;
- }
-
- $sql = "SELECT l.*, u.username, u.username_clean, u.user_colour
- FROM " . LOG_TABLE . " l, " . USERS_TABLE . " u
- WHERE l.log_type = $log_type
- AND u.user_id = l.user_id
- " . (($limit_days) ? "AND l.log_time >= $limit_days" : '') . "
- $sql_keywords
- $sql_forum
- ORDER BY $sort_by";
- $result = $db->sql_query_limit($sql, $limit, $offset);
-
- $i = 0;
- $log = array();
- while ($row = $db->sql_fetchrow($result))
- {
- if ($row['topic_id'])
- {
- $topic_id_list[] = $row['topic_id'];
- }
-
- if ($row['reportee_id'])
- {
- $reportee_id_list[] = $row['reportee_id'];
- }
+ $log = $phpbb_log->get_logs($mode, $count_logs, $limit, $offset, $forum_id, $topic_id, $user_id, $limit_days, $sort_by, $keywords);
+ $log_count = $phpbb_log->get_log_count();
- $log[$i] = array(
- 'id' => $row['log_id'],
-
- 'reportee_id' => $row['reportee_id'],
- 'reportee_username' => '',
- 'reportee_username_full'=> '',
-
- 'user_id' => $row['user_id'],
- 'username' => $row['username'],
- 'username_full' => get_username_string('full', $row['user_id'], $row['username'], $row['user_colour'], false, $profile_url),
-
- 'ip' => $row['log_ip'],
- 'time' => $row['log_time'],
- 'forum_id' => $row['forum_id'],
- 'topic_id' => $row['topic_id'],
-
- 'viewforum' => ($row['forum_id'] && $auth->acl_get('f_read', $row['forum_id'])) ? append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $row['forum_id']) : false,
- 'action' => (isset($user->lang[$row['log_operation']])) ? $user->lang[$row['log_operation']] : '{' . ucfirst(str_replace('_', ' ', $row['log_operation'])) . '}',
- );
-
- if (!empty($row['log_data']))
- {
- $log_data_ary = @unserialize($row['log_data']);
- $log_data_ary = ($log_data_ary === false) ? array() : $log_data_ary;
-
- if (isset($user->lang[$row['log_operation']]))
- {
- // Check if there are more occurrences of % than arguments, if there are we fill out the arguments array
- // It doesn't matter if we add more arguments than placeholders
- if ((substr_count($log[$i]['action'], '%') - sizeof($log_data_ary)) > 0)
- {
- $log_data_ary = array_merge($log_data_ary, array_fill(0, substr_count($log[$i]['action'], '%') - sizeof($log_data_ary), ''));
- }
-
- $log[$i]['action'] = vsprintf($log[$i]['action'], $log_data_ary);
-
- // If within the admin panel we do not censor text out
- if (defined('IN_ADMIN'))
- {
- $log[$i]['action'] = bbcode_nl2br($log[$i]['action']);
- }
- else
- {
- $log[$i]['action'] = bbcode_nl2br(censor_text($log[$i]['action']));
- }
- }
- else if (!empty($log_data_ary))
- {
- $log[$i]['action'] .= '<br />' . implode('', $log_data_ary);
- }
-
- /* Apply make_clickable... has to be seen if it is for good. :/
- // Seems to be not for the moment, reconsider later...
- $log[$i]['action'] = make_clickable($log[$i]['action']);
- */
- }
-
- $i++;
- }
- $db->sql_freeresult($result);
-
- if (sizeof($topic_id_list))
- {
- $topic_id_list = array_unique($topic_id_list);
-
- // This query is not really needed if move_topics() updates the forum_id field,
- // although it's also used to determine if the topic still exists in the database
- $sql = 'SELECT topic_id, forum_id
- FROM ' . TOPICS_TABLE . '
- WHERE ' . $db->sql_in_set('topic_id', array_map('intval', $topic_id_list));
- $result = $db->sql_query($sql);
-
- $default_forum_id = 0;
-
- while ($row = $db->sql_fetchrow($result))
- {
- if ($auth->acl_get('f_read', $row['forum_id']))
- {
- $is_auth[$row['topic_id']] = $row['forum_id'];
- }
-
- if ($auth->acl_gets('a_', 'm_', $row['forum_id']))
- {
- $is_mod[$row['topic_id']] = $row['forum_id'];
- }
- }
- $db->sql_freeresult($result);
-
- foreach ($log as $key => $row)
- {
- $log[$key]['viewtopic'] = (isset($is_auth[$row['topic_id']])) ? append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'f=' . $is_auth[$row['topic_id']] . '&amp;t=' . $row['topic_id']) : false;
- $log[$key]['viewlogs'] = (isset($is_mod[$row['topic_id']])) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=logs&amp;mode=topic_logs&amp;t=' . $row['topic_id'], true, $user->session_id) : false;
- }
- }
-
- if (sizeof($reportee_id_list))
- {
- $reportee_id_list = array_unique($reportee_id_list);
- $reportee_names_list = array();
-
- $sql = 'SELECT user_id, username, user_colour
- FROM ' . USERS_TABLE . '
- WHERE ' . $db->sql_in_set('user_id', $reportee_id_list);
- $result = $db->sql_query($sql);
-
- while ($row = $db->sql_fetchrow($result))
- {
- $reportee_names_list[$row['user_id']] = $row;
- }
- $db->sql_freeresult($result);
-
- foreach ($log as $key => $row)
- {
- if (!isset($reportee_names_list[$row['reportee_id']]))
- {
- continue;
- }
-
- $log[$key]['reportee_username'] = $reportee_names_list[$row['reportee_id']]['username'];
- $log[$key]['reportee_username_full'] = get_username_string('full', $row['reportee_id'], $reportee_names_list[$row['reportee_id']]['username'], $reportee_names_list[$row['reportee_id']]['user_colour'], false, $profile_url);
- }
- }
-
- return $offset;
+ return $phpbb_log->get_valid_offset();
}
/**
diff --git a/phpBB/includes/functions_compatibility.php b/phpBB/includes/functions_compatibility.php
new file mode 100644
index 0000000000..2197815087
--- /dev/null
+++ b/phpBB/includes/functions_compatibility.php
@@ -0,0 +1,50 @@
+<?php
+/**
+*
+* @package phpBB3
+* @copyright (c) 2013 phpBB Group
+* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+*
+*/
+
+/**
+* @ignore
+*/
+if (!defined('IN_PHPBB'))
+{
+ exit;
+}
+
+/**
+* Get user avatar
+*
+* @deprecated 3.1.0-a1 (To be removed: 3.3.0)
+*
+* @param string $avatar Users assigned avatar name
+* @param int $avatar_type Type of avatar
+* @param string $avatar_width Width of users avatar
+* @param string $avatar_height Height of users avatar
+* @param string $alt Optional language string for alt tag within image, can be a language key or text
+* @param bool $ignore_config Ignores the config-setting, to be still able to view the avatar in the UCP
+*
+* @return string Avatar image
+*/
+function get_user_avatar($avatar, $avatar_type, $avatar_width, $avatar_height, $alt = 'USER_AVATAR', $ignore_config = false)
+{
+ // map arguments to new function phpbb_get_avatar()
+ $row = array(
+ 'avatar' => $avatar,
+ 'avatar_type' => $avatar_type,
+ 'avatar_width' => $avatar_width,
+ 'avatar_height' => $avatar_height,
+ );
+
+ if (!function_exists('phpbb_get_avatar'))
+ {
+ global $phpbb_root_path, $phpEx;
+
+ include($phpbb_root_path . 'includes/functions_display.' . $phpEx);
+ }
+
+ return phpbb_get_avatar($row, $alt, $ignore_config);
+}
diff --git a/phpBB/includes/functions_container.php b/phpBB/includes/functions_container.php
index a3ed21c35b..106b7d75cc 100644
--- a/phpBB/includes/functions_container.php
+++ b/phpBB/includes/functions_container.php
@@ -57,6 +57,7 @@ function phpbb_create_install_container($phpbb_root_path, $php_ext)
$container = phpbb_create_container(array($core), $phpbb_root_path, $php_ext);
$container->setParameter('core.root_path', $phpbb_root_path);
+ $container->setParameter('core.adm_relative_path', $phpbb_adm_relative_path);
$container->setParameter('core.php_ext', $php_ext);
$container->setParameter('core.table_prefix', '');
diff --git a/phpBB/includes/functions_display.php b/phpBB/includes/functions_display.php
index 42a9b45158..797ca718d8 100644
--- a/phpBB/includes/functions_display.php
+++ b/phpBB/includes/functions_display.php
@@ -1332,79 +1332,87 @@ function get_user_rank($user_rank, $user_posts, &$rank_title, &$rank_img, &$rank
/**
* Get user avatar
*
-* @param string $avatar Users assigned avatar name
-* @param int $avatar_type Type of avatar
-* @param string $avatar_width Width of users avatar
-* @param string $avatar_height Height of users avatar
+* @param array $user_row Row from the users table
* @param string $alt Optional language string for alt tag within image, can be a language key or text
* @param bool $ignore_config Ignores the config-setting, to be still able to view the avatar in the UCP
*
-* @return string Avatar image
+* @return string Avatar html
*/
-function get_user_avatar($avatar, $avatar_type, $avatar_width, $avatar_height, $alt = 'USER_AVATAR', $ignore_config = false)
+function phpbb_get_user_avatar($user_row, $alt = 'USER_AVATAR', $ignore_config = false)
{
- global $user, $config, $phpbb_root_path, $phpEx;
- global $phpbb_dispatcher;
-
- $overwrite_avatar = '';
+ $row = phpbb_avatar_manager::clean_row($user_row);
+ return phpbb_get_avatar($row, $alt, $ignore_config);
+}
- /**
- * Overwrite users avatar
- *
- * @event core.display_custom_bbcodes_modify_row
- * @var string avatar Users assigned avatar name
- * @var int avatar_type Type of avatar
- * @var string avatar_width Width of users avatar
- * @var string avatar_height Height of users avatar
- * @var string alt Language string for alt tag within image
- * Can be a language key or text
- * @var bool ignore_config Ignores config and force displaying avatar
- * @var string overwrite_avatar If set, this string will be the avatar
- * @since 3.1-A1
- */
- $vars = array('avatar', 'avatar_type', 'avatar_width', 'avatar_height', 'alt', 'ignore_config', 'overwrite_avatar');
- extract($phpbb_dispatcher->trigger_event('core.user_get_avatar', compact($vars)));
+/**
+* Get group avatar
+*
+* @param array $group_row Row from the groups table
+* @param string $alt Optional language string for alt tag within image, can be a language key or text
+* @param bool $ignore_config Ignores the config-setting, to be still able to view the avatar in the UCP
+*
+* @return string Avatar html
+*/
+function phpbb_get_group_avatar($user_row, $alt = 'GROUP_AVATAR', $ignore_config = false)
+{
+ $row = phpbb_avatar_manager::clean_row($user_row);
+ return phpbb_get_avatar($row, $alt, $ignore_config);
+}
- if ($overwrite_avatar)
- {
- return $overwrite_avatar;
- }
+/**
+* Get avatar
+*
+* @param array $row Row cleaned by phpbb_avatar_driver::clean_row
+* @param string $alt Optional language string for alt tag within image, can be a language key or text
+* @param bool $ignore_config Ignores the config-setting, to be still able to view the avatar in the UCP
+*
+* @return string Avatar html
+*/
+function phpbb_get_avatar($row, $alt, $ignore_config = false)
+{
+ global $user, $config, $cache, $phpbb_root_path, $phpEx;
+ global $request;
+ global $phpbb_container;
- if (empty($avatar) || !$avatar_type || (!$config['allow_avatar'] && !$ignore_config))
+ if (!$config['allow_avatar'] && !$ignore_config)
{
return '';
}
- $avatar_img = '';
+ $avatar_data = array(
+ 'src' => $row['avatar'],
+ 'width' => $row['avatar_width'],
+ 'height' => $row['avatar_height'],
+ );
+
+ $phpbb_avatar_manager = $phpbb_container->get('avatar.manager');
+ $driver = $phpbb_avatar_manager->get_driver($row['avatar_type'], $ignore_config);
+ $html = '';
- switch ($avatar_type)
+ if ($driver)
{
- case AVATAR_UPLOAD:
- if (!$config['allow_avatar_upload'] && !$ignore_config)
- {
- return '';
- }
- $avatar_img = $phpbb_root_path . "download/file.$phpEx?avatar=";
- break;
+ $html = $driver->get_custom_html($user, $row, $alt);
+ if (!empty($html))
+ {
+ return $html;
+ }
- case AVATAR_GALLERY:
- if (!$config['allow_avatar_local'] && !$ignore_config)
- {
- return '';
- }
- $avatar_img = $phpbb_root_path . $config['avatar_gallery_path'] . '/';
- break;
+ $avatar_data = $driver->get_data($row, $ignore_config);
+ }
+ else
+ {
+ $avatar_data['src'] = '';
+ }
- case AVATAR_REMOTE:
- if (!$config['allow_avatar_remote'] && !$ignore_config)
- {
- return '';
- }
- break;
+ if (!empty($avatar_data['src']))
+ {
+ $html = '<img src="' . $avatar_data['src'] . '" ' .
+ ($avatar_data['width'] ? ('width="' . $avatar_data['width'] . '" ') : '') .
+ ($avatar_data['height'] ? ('height="' . $avatar_data['height'] . '" ') : '') .
+ 'alt="' . ((!empty($user->lang[$alt])) ? $user->lang[$alt] : $alt) . '" />';
}
- $avatar_img .= $avatar;
- return '<img src="' . (str_replace(' ', '%20', $avatar_img)) . '" width="' . $avatar_width . '" height="' . $avatar_height . '" alt="' . ((!empty($user->lang[$alt])) ? $user->lang[$alt] : $alt) . '" />';
+ return $html;
}
/**
diff --git a/phpBB/includes/functions_user.php b/phpBB/includes/functions_user.php
index b7878ddfc7..bc636acabb 100644
--- a/phpBB/includes/functions_user.php
+++ b/phpBB/includes/functions_user.php
@@ -310,8 +310,10 @@ function user_add($user_row, $cp_data = false)
if ($add_group_id)
{
- // Because these actions only fill the log unneccessarily we skip the add_log() entry with a little hack. :/
- $GLOBALS['skip_add_log'] = true;
+ global $phpbb_log;
+
+ // Because these actions only fill the log unneccessarily we skip the add_log() entry.
+ $phpbb_log->disable('admin');
// Add user to "newly registered users" group and set to default group if admin specified so.
if ($config['new_member_group_default'])
@@ -324,7 +326,7 @@ function user_add($user_row, $cp_data = false)
group_user_add($add_group_id, $user_id);
}
- unset($GLOBALS['skip_add_log']);
+ $phpbb_log->enable('admin');
}
}
@@ -2048,6 +2050,7 @@ function avatar_delete($mode, $row, $clean_db = false)
avatar_remove_db($row[$mode . '_avatar']);
}
$filename = get_avatar_filename($row[$mode . '_avatar']);
+
if (file_exists($phpbb_root_path . $config['avatar_path'] . '/' . $filename))
{
@unlink($phpbb_root_path . $config['avatar_path'] . '/' . $filename);
@@ -2058,134 +2061,6 @@ function avatar_delete($mode, $row, $clean_db = false)
}
/**
-* Remote avatar linkage
-*/
-function avatar_remote($data, &$error)
-{
- global $config, $db, $user, $phpbb_root_path, $phpEx;
-
- if (!preg_match('#^(http|https|ftp)://#i', $data['remotelink']))
- {
- $data['remotelink'] = 'http://' . $data['remotelink'];
- }
- if (!preg_match('#^(http|https|ftp)://(?:(.*?\.)*?[a-z0-9\-]+?\.[a-z]{2,4}|(?:\d{1,3}\.){3,5}\d{1,3}):?([0-9]*?).*?\.(gif|jpg|jpeg|png)$#i', $data['remotelink']))
- {
- $error[] = $user->lang['AVATAR_URL_INVALID'];
- return false;
- }
-
- // Make sure getimagesize works...
- if (($image_data = @getimagesize($data['remotelink'])) === false && (empty($data['width']) || empty($data['height'])))
- {
- $error[] = $user->lang['UNABLE_GET_IMAGE_SIZE'];
- return false;
- }
-
- if (!empty($image_data) && ($image_data[0] < 2 || $image_data[1] < 2))
- {
- $error[] = $user->lang['AVATAR_NO_SIZE'];
- return false;
- }
-
- $width = ($data['width'] && $data['height']) ? $data['width'] : $image_data[0];
- $height = ($data['width'] && $data['height']) ? $data['height'] : $image_data[1];
-
- if ($width < 2 || $height < 2)
- {
- $error[] = $user->lang['AVATAR_NO_SIZE'];
- return false;
- }
-
- // Check image type
- include_once($phpbb_root_path . 'includes/functions_upload.' . $phpEx);
- $types = fileupload::image_types();
- $extension = strtolower(filespec::get_extension($data['remotelink']));
-
- if (!empty($image_data) && (!isset($types[$image_data[2]]) || !in_array($extension, $types[$image_data[2]])))
- {
- if (!isset($types[$image_data[2]]))
- {
- $error[] = $user->lang['UNABLE_GET_IMAGE_SIZE'];
- }
- else
- {
- $error[] = sprintf($user->lang['IMAGE_FILETYPE_MISMATCH'], $types[$image_data[2]][0], $extension);
- }
- return false;
- }
-
- if ($config['avatar_max_width'] || $config['avatar_max_height'])
- {
- if ($width > $config['avatar_max_width'] || $height > $config['avatar_max_height'])
- {
- $error[] = phpbb_avatar_error_wrong_size($width, $height);
- return false;
- }
- }
-
- if ($config['avatar_min_width'] || $config['avatar_min_height'])
- {
- if ($width < $config['avatar_min_width'] || $height < $config['avatar_min_height'])
- {
- $error[] = phpbb_avatar_error_wrong_size($width, $height);
- return false;
- }
- }
-
- return array(AVATAR_REMOTE, $data['remotelink'], $width, $height);
-}
-
-/**
-* Avatar upload using the upload class
-*/
-function avatar_upload($data, &$error)
-{
- global $phpbb_root_path, $config, $db, $user, $phpEx, $request;
-
- // Init upload class
- include_once($phpbb_root_path . 'includes/functions_upload.' . $phpEx);
- $upload = new fileupload('AVATAR_', array('jpg', 'jpeg', 'gif', 'png'), $config['avatar_filesize'], $config['avatar_min_width'], $config['avatar_min_height'], $config['avatar_max_width'], $config['avatar_max_height'], (isset($config['mime_triggers']) ? explode('|', $config['mime_triggers']) : false));
-
- $uploadfile = $request->file('uploadfile');
- if (!empty($uploadfile['name']))
- {
- $file = $upload->form_upload('uploadfile');
- }
- else
- {
- $file = $upload->remote_upload($data['uploadurl']);
- }
-
- $prefix = $config['avatar_salt'] . '_';
- $file->clean_filename('avatar', $prefix, $data['user_id']);
-
- $destination = $config['avatar_path'];
-
- // Adjust destination path (no trailing slash)
- if (substr($destination, -1, 1) == '/' || substr($destination, -1, 1) == '\\')
- {
- $destination = substr($destination, 0, -1);
- }
-
- $destination = str_replace(array('../', '..\\', './', '.\\'), '', $destination);
- if ($destination && ($destination[0] == '/' || $destination[0] == "\\"))
- {
- $destination = '';
- }
-
- // Move file and overwrite any existing image
- $file->move_file($destination, true);
-
- if (sizeof($file->error))
- {
- $file->remove();
- $error = array_merge($error, $file->error);
- }
-
- return array(AVATAR_UPLOAD, $data['user_id'] . '_' . time() . '.' . $file->get('extension'), $file->get('width'), $file->get('height'));
-}
-
-/**
* Generates avatar filename from the database entry
*/
function get_avatar_filename($avatar_entry)
@@ -2208,344 +2083,6 @@ function get_avatar_filename($avatar_entry)
}
/**
-* Avatar Gallery
-*/
-function avatar_gallery($category, $avatar_select, $items_per_column, $block_var = 'avatar_row')
-{
- global $user, $cache, $template;
- global $config, $phpbb_root_path;
-
- $avatar_list = array();
-
- $path = $phpbb_root_path . $config['avatar_gallery_path'];
-
- if (!file_exists($path) || !is_dir($path))
- {
- $avatar_list = array($user->lang['NO_AVATAR_CATEGORY'] => array());
- }
- else
- {
- // Collect images
- $dp = @opendir($path);
-
- if (!$dp)
- {
- return array($user->lang['NO_AVATAR_CATEGORY'] => array());
- }
-
- while (($file = readdir($dp)) !== false)
- {
- if ($file[0] != '.' && preg_match('#^[^&"\'<>]+$#i', $file) && is_dir("$path/$file"))
- {
- $avatar_row_count = $avatar_col_count = 0;
-
- if ($dp2 = @opendir("$path/$file"))
- {
- while (($sub_file = readdir($dp2)) !== false)
- {
- if (preg_match('#^[^&\'"<>]+\.(?:gif|png|jpe?g)$#i', $sub_file))
- {
- $avatar_list[$file][$avatar_row_count][$avatar_col_count] = array(
- 'file' => rawurlencode($file) . '/' . rawurlencode($sub_file),
- 'filename' => rawurlencode($sub_file),
- 'name' => ucfirst(str_replace('_', ' ', preg_replace('#^(.*)\..*$#', '\1', $sub_file))),
- );
- $avatar_col_count++;
- if ($avatar_col_count == $items_per_column)
- {
- $avatar_row_count++;
- $avatar_col_count = 0;
- }
- }
- }
- closedir($dp2);
- }
- }
- }
- closedir($dp);
- }
-
- if (!sizeof($avatar_list))
- {
- $avatar_list = array($user->lang['NO_AVATAR_CATEGORY'] => array());
- }
-
- @ksort($avatar_list);
-
- $category = (!$category) ? key($avatar_list) : $category;
- $avatar_categories = array_keys($avatar_list);
-
- $s_category_options = '';
- foreach ($avatar_categories as $cat)
- {
- $s_category_options .= '<option value="' . $cat . '"' . (($cat == $category) ? ' selected="selected"' : '') . '>' . $cat . '</option>';
- }
-
- $template->assign_vars(array(
- 'S_AVATARS_ENABLED' => true,
- 'S_IN_AVATAR_GALLERY' => true,
- 'S_CAT_OPTIONS' => $s_category_options)
- );
-
- $avatar_list = (isset($avatar_list[$category])) ? $avatar_list[$category] : array();
-
- foreach ($avatar_list as $avatar_row_ary)
- {
- $template->assign_block_vars($block_var, array());
-
- foreach ($avatar_row_ary as $avatar_col_ary)
- {
- $template->assign_block_vars($block_var . '.avatar_column', array(
- 'AVATAR_IMAGE' => $phpbb_root_path . $config['avatar_gallery_path'] . '/' . $avatar_col_ary['file'],
- 'AVATAR_NAME' => $avatar_col_ary['name'],
- 'AVATAR_FILE' => $avatar_col_ary['filename'])
- );
-
- $template->assign_block_vars($block_var . '.avatar_option_column', array(
- 'AVATAR_IMAGE' => $phpbb_root_path . $config['avatar_gallery_path'] . '/' . $avatar_col_ary['file'],
- 'S_OPTIONS_AVATAR' => $avatar_col_ary['filename'])
- );
- }
- }
-
- return $avatar_list;
-}
-
-
-/**
-* Tries to (re-)establish avatar dimensions
-*/
-function avatar_get_dimensions($avatar, $avatar_type, &$error, $current_x = 0, $current_y = 0)
-{
- global $config, $phpbb_root_path, $user;
-
- switch ($avatar_type)
- {
- case AVATAR_REMOTE :
- break;
-
- case AVATAR_UPLOAD :
- $avatar = $phpbb_root_path . $config['avatar_path'] . '/' . get_avatar_filename($avatar);
- break;
-
- case AVATAR_GALLERY :
- $avatar = $phpbb_root_path . $config['avatar_gallery_path'] . '/' . $avatar ;
- break;
- }
-
- // Make sure getimagesize works...
- if (($image_data = @getimagesize($avatar)) === false)
- {
- $error[] = $user->lang['UNABLE_GET_IMAGE_SIZE'];
- return false;
- }
-
- if ($image_data[0] < 2 || $image_data[1] < 2)
- {
- $error[] = $user->lang['AVATAR_NO_SIZE'];
- return false;
- }
-
- // try to maintain ratio
- if (!(empty($current_x) && empty($current_y)))
- {
- if ($current_x != 0)
- {
- $image_data[1] = (int) floor(($current_x / $image_data[0]) * $image_data[1]);
- $image_data[1] = min($config['avatar_max_height'], $image_data[1]);
- $image_data[1] = max($config['avatar_min_height'], $image_data[1]);
- }
- if ($current_y != 0)
- {
- $image_data[0] = (int) floor(($current_y / $image_data[1]) * $image_data[0]);
- $image_data[0] = min($config['avatar_max_width'], $image_data[1]);
- $image_data[0] = max($config['avatar_min_width'], $image_data[1]);
- }
- }
- return array($image_data[0], $image_data[1]);
-}
-
-/**
-* Uploading/Changing user avatar
-*/
-function avatar_process_user(&$error, $custom_userdata = false, $can_upload = null)
-{
- global $config, $phpbb_root_path, $auth, $user, $db, $request;
-
- $data = array(
- 'uploadurl' => request_var('uploadurl', ''),
- 'remotelink' => request_var('remotelink', ''),
- 'width' => request_var('width', 0),
- 'height' => request_var('height', 0),
- );
-
- $error = validate_data($data, array(
- 'uploadurl' => array('string', true, 5, 255),
- 'remotelink' => array('string', true, 5, 255),
- 'width' => array('string', true, 1, 3),
- 'height' => array('string', true, 1, 3),
- ));
-
- if (sizeof($error))
- {
- return false;
- }
-
- $sql_ary = array();
-
- if ($custom_userdata === false)
- {
- $userdata = &$user->data;
- }
- else
- {
- $userdata = &$custom_userdata;
- }
-
- $data['user_id'] = $userdata['user_id'];
- $change_avatar = ($custom_userdata === false) ? $auth->acl_get('u_chgavatar') : true;
- $avatar_select = basename(request_var('avatar_select', ''));
-
- // Can we upload?
- if (is_null($can_upload))
- {
- $can_upload = ($config['allow_avatar_upload'] && file_exists($phpbb_root_path . $config['avatar_path']) && phpbb_is_writable($phpbb_root_path . $config['avatar_path']) && $change_avatar && (@ini_get('file_uploads') || strtolower(@ini_get('file_uploads')) == 'on')) ? true : false;
- }
-
- $uploadfile = $request->file('uploadfile');
- if ((!empty($uploadfile['name']) || $data['uploadurl']) && $can_upload)
- {
- list($sql_ary['user_avatar_type'], $sql_ary['user_avatar'], $sql_ary['user_avatar_width'], $sql_ary['user_avatar_height']) = avatar_upload($data, $error);
- }
- else if ($data['remotelink'] && $change_avatar && $config['allow_avatar_remote'])
- {
- list($sql_ary['user_avatar_type'], $sql_ary['user_avatar'], $sql_ary['user_avatar_width'], $sql_ary['user_avatar_height']) = avatar_remote($data, $error);
- }
- else if ($avatar_select && $change_avatar && $config['allow_avatar_local'])
- {
- $category = basename(request_var('category', ''));
-
- $sql_ary['user_avatar_type'] = AVATAR_GALLERY;
- $sql_ary['user_avatar'] = $avatar_select;
-
- // check avatar gallery
- if (!is_dir($phpbb_root_path . $config['avatar_gallery_path'] . '/' . $category))
- {
- $sql_ary['user_avatar'] = '';
- $sql_ary['user_avatar_type'] = $sql_ary['user_avatar_width'] = $sql_ary['user_avatar_height'] = 0;
- }
- else
- {
- list($sql_ary['user_avatar_width'], $sql_ary['user_avatar_height']) = getimagesize($phpbb_root_path . $config['avatar_gallery_path'] . '/' . $category . '/' . urldecode($sql_ary['user_avatar']));
- $sql_ary['user_avatar'] = $category . '/' . $sql_ary['user_avatar'];
- }
- }
- else if (isset($_POST['delete']) && $change_avatar)
- {
- $sql_ary['user_avatar'] = '';
- $sql_ary['user_avatar_type'] = $sql_ary['user_avatar_width'] = $sql_ary['user_avatar_height'] = 0;
- }
- else if (!empty($userdata['user_avatar']))
- {
- // Only update the dimensions
-
- if (empty($data['width']) || empty($data['height']))
- {
- if ($dims = avatar_get_dimensions($userdata['user_avatar'], $userdata['user_avatar_type'], $error, $data['width'], $data['height']))
- {
- list($guessed_x, $guessed_y) = $dims;
- if (empty($data['width']))
- {
- $data['width'] = $guessed_x;
- }
- if (empty($data['height']))
- {
- $data['height'] = $guessed_y;
- }
- }
- }
- if (($config['avatar_max_width'] || $config['avatar_max_height']) &&
- (($data['width'] != $userdata['user_avatar_width']) || $data['height'] != $userdata['user_avatar_height']))
- {
- if ($data['width'] > $config['avatar_max_width'] || $data['height'] > $config['avatar_max_height'])
- {
- $error[] = phpbb_avatar_error_wrong_size($data['width'], $data['height']);
- }
- }
-
- if (!sizeof($error))
- {
- if ($config['avatar_min_width'] || $config['avatar_min_height'])
- {
- if ($data['width'] < $config['avatar_min_width'] || $data['height'] < $config['avatar_min_height'])
- {
- $error[] = phpbb_avatar_error_wrong_size($data['width'], $data['height']);
- }
- }
- }
-
- if (!sizeof($error))
- {
- $sql_ary['user_avatar_width'] = $data['width'];
- $sql_ary['user_avatar_height'] = $data['height'];
- }
- }
-
- if (!sizeof($error))
- {
- // Do we actually have any data to update?
- if (sizeof($sql_ary))
- {
- $ext_new = $ext_old = '';
- if (isset($sql_ary['user_avatar']))
- {
- $userdata = ($custom_userdata === false) ? $user->data : $custom_userdata;
- $ext_new = (empty($sql_ary['user_avatar'])) ? '' : substr(strrchr($sql_ary['user_avatar'], '.'), 1);
- $ext_old = (empty($userdata['user_avatar'])) ? '' : substr(strrchr($userdata['user_avatar'], '.'), 1);
-
- if ($userdata['user_avatar_type'] == AVATAR_UPLOAD)
- {
- // Delete old avatar if present
- if ((!empty($userdata['user_avatar']) && empty($sql_ary['user_avatar']))
- || ( !empty($userdata['user_avatar']) && !empty($sql_ary['user_avatar']) && $ext_new !== $ext_old))
- {
- avatar_delete('user', $userdata);
- }
- }
- }
-
- $sql = 'UPDATE ' . USERS_TABLE . '
- SET ' . $db->sql_build_array('UPDATE', $sql_ary) . '
- WHERE user_id = ' . (($custom_userdata === false) ? $user->data['user_id'] : $custom_userdata['user_id']);
- $db->sql_query($sql);
-
- }
- }
-
- return (sizeof($error)) ? false : true;
-}
-
-/**
-* Returns a language string with the avatar size of the new avatar and the allowed maximum and minimum
-*
-* @param $width int The width of the new uploaded/selected avatar
-* @param $height int The height of the new uploaded/selected avatar
-* @return string
-*/
-function phpbb_avatar_error_wrong_size($width, $height)
-{
- global $config, $user;
-
- return $user->lang('AVATAR_WRONG_SIZE',
- $user->lang('PIXELS', (int) $config['avatar_min_width']),
- $user->lang('PIXELS', (int) $config['avatar_min_height']),
- $user->lang('PIXELS', (int) $config['avatar_max_width']),
- $user->lang('PIXELS', (int) $config['avatar_max_height']),
- $user->lang('PIXELS', (int) $width),
- $user->lang('PIXELS', (int) $height));
-}
-
-/**
* Returns an explanation string with maximum avatar settings
*
* @return string
@@ -2570,7 +2107,7 @@ function phpbb_avatar_explanation_string()
*/
function group_create(&$group_id, $type, $name, $desc, $group_attributes, $allow_desc_bbcode = false, $allow_desc_urls = false, $allow_desc_smilies = false)
{
- global $phpbb_root_path, $config, $db, $user, $file_upload;
+ global $phpbb_root_path, $config, $db, $user, $file_upload, $phpbb_container;
$error = array();
@@ -2594,22 +2131,32 @@ function group_create(&$group_id, $type, $name, $desc, $group_attributes, $allow
$error[] = $user->lang['GROUP_ERR_TYPE'];
}
+ $group_teampage = !empty($group_attributes['group_teampage']);
+ unset($group_attributes['group_teampage']);
+
if (!sizeof($error))
{
- $current_legend = phpbb_group_positions::GROUP_DISABLED;
- $current_teampage = phpbb_group_positions::GROUP_DISABLED;
+ $current_legend = phpbb_groupposition_legend::GROUP_DISABLED;
+ $current_teampage = phpbb_groupposition_teampage::GROUP_DISABLED;
- $legend = new phpbb_group_positions($db, 'legend');
- $teampage = new phpbb_group_positions($db, 'teampage');
+ $legend = $phpbb_container->get('groupposition.legend');
+ $teampage = $phpbb_container->get('groupposition.teampage');
if ($group_id)
{
- $current_legend = $legend->get_group_value($group_id);
- $current_teampage = $teampage->get_group_value($group_id);
+ try
+ {
+ $current_legend = $legend->get_group_value($group_id);
+ $current_teampage = $teampage->get_group_value($group_id);
+ }
+ catch (phpbb_groupposition_exception $exception)
+ {
+ trigger_error($user->lang($exception->getMessage()));
+ }
}
if (!empty($group_attributes['group_legend']))
{
- if (($group_id && ($current_legend == phpbb_group_positions::GROUP_DISABLED)) || !$group_id)
+ if (($group_id && ($current_legend == phpbb_groupposition_legend::GROUP_DISABLED)) || !$group_id)
{
// Old group currently not in the legend or new group, add at the end.
$group_attributes['group_legend'] = 1 + $legend->get_group_count();
@@ -2620,44 +2167,26 @@ function group_create(&$group_id, $type, $name, $desc, $group_attributes, $allow
$group_attributes['group_legend'] = $current_legend;
}
}
- else if ($group_id && ($current_legend > phpbb_group_positions::GROUP_DISABLED))
+ else if ($group_id && ($current_legend != phpbb_groupposition_legend::GROUP_DISABLED))
{
// Group is removed from the legend
- $legend->delete_group($group_id, true);
- $group_attributes['group_legend'] = phpbb_group_positions::GROUP_DISABLED;
- }
- else
- {
- $group_attributes['group_legend'] = phpbb_group_positions::GROUP_DISABLED;
- }
-
- if (!empty($group_attributes['group_teampage']))
- {
- if (($group_id && ($current_teampage == phpbb_group_positions::GROUP_DISABLED)) || !$group_id)
+ try
{
- // Old group currently not on the teampage or new group, add at the end.
- $group_attributes['group_teampage'] = 1 + $teampage->get_group_count();
+ $legend->delete_group($group_id, true);
}
- else
+ catch (phpbb_groupposition_exception $exception)
{
- // Group stayes on the teampage
- $group_attributes['group_teampage'] = $current_teampage;
+ trigger_error($user->lang($exception->getMessage()));
}
- }
- else if ($group_id && ($current_teampage > phpbb_group_positions::GROUP_DISABLED))
- {
- // Group is removed from the teampage
- $teampage->delete_group($group_id, true);
- $group_attributes['group_teampage'] = phpbb_group_positions::GROUP_DISABLED;
+ $group_attributes['group_legend'] = phpbb_groupposition_legend::GROUP_DISABLED;
}
else
{
- $group_attributes['group_teampage'] = phpbb_group_positions::GROUP_DISABLED;
+ $group_attributes['group_legend'] = phpbb_groupposition_legend::GROUP_DISABLED;
}
// Unset the objects, we don't need them anymore.
unset($legend);
- unset($teampage);
$user_ary = array();
$sql_ary = array(
@@ -2751,6 +2280,20 @@ function group_create(&$group_id, $type, $name, $desc, $group_attributes, $allow
$db->sql_query($sql);
}
+ // Remove the group from the teampage, only if unselected and we are editing a group,
+ // which is currently displayed.
+ if (!$group_teampage && $group_id && $current_teampage != phpbb_groupposition_teampage::GROUP_DISABLED)
+ {
+ try
+ {
+ $teampage->delete_group($group_id);
+ }
+ catch (phpbb_groupposition_exception $exception)
+ {
+ trigger_error($user->lang($exception->getMessage()));
+ }
+ }
+
if (!$group_id)
{
$group_id = $db->sql_nextid();
@@ -2761,6 +2304,31 @@ function group_create(&$group_id, $type, $name, $desc, $group_attributes, $allow
}
}
+ try
+ {
+ if ($group_teampage && $current_teampage == phpbb_groupposition_teampage::GROUP_DISABLED)
+ {
+ $teampage->add_group($group_id);
+ }
+
+ if ($group_teampage)
+ {
+ if ($current_teampage == phpbb_groupposition_teampage::GROUP_DISABLED)
+ {
+ $teampage->add_group($group_id);
+ }
+ }
+ else if ($group_id && ($current_teampage != phpbb_groupposition_teampage::GROUP_DISABLED))
+ {
+ $teampage->delete_group($group_id);
+ }
+ }
+ catch (phpbb_groupposition_exception $exception)
+ {
+ trigger_error($user->lang($exception->getMessage()));
+ }
+ unset($teampage);
+
// Set user attributes
$sql_ary = array();
if (sizeof($group_attributes))
@@ -2842,7 +2410,7 @@ function avatar_remove_db($avatar_name)
*/
function group_delete($group_id, $group_name = false)
{
- global $db, $cache, $auth, $phpbb_root_path, $phpEx, $phpbb_dispatcher;
+ global $db, $cache, $auth, $user, $phpbb_root_path, $phpEx, $phpbb_dispatcher, $phpbb_container;
if (!$group_name)
{
@@ -2884,12 +2452,31 @@ function group_delete($group_id, $group_name = false)
while ($start);
// Delete group from legend and teampage
- $legend = new phpbb_group_positions($db, 'legend');
- $legend->delete_group($group_id);
- unset($legend);
- $teampage = new phpbb_group_positions($db, 'teampage');
- $teampage->delete_group($group_id);
- unset($teampage);
+ try
+ {
+ $legend = $phpbb_container->get('groupposition.legend');
+ $legend->delete_group($group_id);
+ unset($legend);
+ }
+ catch (phpbb_groupposition_exception $exception)
+ {
+ // The group we want to delete does not exist.
+ // No reason to worry, we just continue the deleting process.
+ //trigger_error($user->lang($exception->getMessage()));
+ }
+
+ try
+ {
+ $teampage = $phpbb_container->get('groupposition.teampage');
+ $teampage->delete_group($group_id);
+ unset($teampage);
+ }
+ catch (phpbb_groupposition_exception $exception)
+ {
+ // The group we want to delete does not exist.
+ // No reason to worry, we just continue the deleting process.
+ //trigger_error($user->lang($exception->getMessage()));
+ }
// Delete group
$sql = 'DELETE FROM ' . GROUPS_TABLE . "
diff --git a/phpBB/includes/groupposition/exception.php b/phpBB/includes/groupposition/exception.php
new file mode 100644
index 0000000000..e4ff09c703
--- /dev/null
+++ b/phpBB/includes/groupposition/exception.php
@@ -0,0 +1,23 @@
+<?php
+/**
+*
+* @package groupposition
+* @copyright (c) 2013 phpBB Group
+* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+*
+*/
+
+/**
+* @ignore
+*/
+if (!defined('IN_PHPBB'))
+{
+ exit;
+}
+
+/**
+* @package groupposition
+*/
+class phpbb_groupposition_exception extends \Exception
+{
+}
diff --git a/phpBB/includes/groupposition/interface.php b/phpBB/includes/groupposition/interface.php
new file mode 100644
index 0000000000..eacc04e1a4
--- /dev/null
+++ b/phpBB/includes/groupposition/interface.php
@@ -0,0 +1,84 @@
+<?php
+/**
+*
+* @package phpBB3
+* @copyright (c) 2012 phpBB Group
+* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+*
+*/
+
+/**
+* @ignore
+*/
+if (!defined('IN_PHPBB'))
+{
+ exit;
+}
+
+/**
+* Interface to manage group positions in various places of phpbb
+*
+* The interface provides simple methods to add, delete and move a group
+*
+* @package phpBB3
+*/
+interface phpbb_groupposition_interface
+{
+ /**
+ * Returns the value 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
+ */
+ public function get_group_value($group_id);
+
+ /**
+ * Get number of groups displayed
+ *
+ * @return int value of the last item displayed
+ */
+ public function get_group_count();
+
+ /**
+ * Addes a group by group_id
+ *
+ * @param int $group_id group_id of the group to be added
+ * @return bool True if the group was added successfully
+ */
+ public function add_group($group_id);
+
+ /**
+ * Deletes a group by group_id
+ *
+ * @param int $group_id group_id of the group to be deleted
+ * @param bool $skip_group Skip setting the value for this group, to save the query, when you need to update it anyway.
+ * @return bool True if the group was deleted successfully
+ */
+ public function delete_group($group_id, $skip_group = false);
+
+ /**
+ * Moves a group up by group_id
+ *
+ * @param int $group_id group_id of the group to be moved
+ * @return bool True if the group was moved successfully
+ */
+ public function move_up($group_id);
+
+ /**
+ * Moves a group down by group_id
+ *
+ * @param int $group_id group_id of the group to be moved
+ * @return bool True if the group was moved successfully
+ */
+ public function move_down($group_id);
+
+ /**
+ * 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 bool True if the group was moved successfully
+ */
+ public function move($group_id, $delta);
+}
diff --git a/phpBB/includes/group_positions.php b/phpBB/includes/groupposition/legend.php
index 60352ed97d..7fddadde99 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
@@ -30,81 +31,73 @@ class phpbb_group_positions
const GROUP_DISABLED = 0;
/**
- * phpbb-database object
- */
- public $db = null;
-
- /**
- * Name of the field we want to handle: either 'teampage' or 'legend'
+ * Database object
+ * @var phpbb_db_driver
*/
- private $field = '';
+ protected $db;
/**
- * URI for the adm_back_link when there was an error.
+ * User object
+ * @var phpbb_user
*/
- private $adm_back_link = '';
+ protected $user;
/**
* Constructor
+ *
+ * @param phpbb_db_driver $db Database object
+ * @param phpbb_user $user User object
*/
- public function __construct ($db, $field, $adm_back_link = '')
+ public function __construct(phpbb_db_driver $db, phpbb_user $user)
{
- $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)
{
// Group not found.
- $this->error('NO_GROUP');
+ throw new phpbb_groupposition_exception('NO_GROUP');
}
return (int) $current_value;
}
/**
- * 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 null
+ * {@inheritDoc}
*/
public function add_group($group_id)
{
@@ -116,19 +109,20 @@ 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);
+ return true;
}
+
+ return false;
}
/**
* 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 null
+ * {@inheritDoc}
*/
public function delete_group($group_id, $skip_group = false)
{
@@ -139,58 +133,57 @@ 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);
}
$this->db->sql_transaction('commit');
+
+ return true;
}
+
+ return false;
}
/**
* Moves a group up by group_id
*
- * @param int $group_id group_id of the group to be moved
- * @return null
+ * {@inheritDoc}
*/
public function move_up($group_id)
{
- $this->move($group_id, 1);
+ return $this->move($group_id, 1);
}
/**
* Moves a group down by group_id
*
- * @param int $group_id group_id of the group to be moved
- * @return null
+ * {@inheritDoc}
*/
public function move_down($group_id)
{
- $this->move($group_id, -1);
+ return $this->move($group_id, -1);
}
/**
* 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 null
+ * {@inheritDoc}
*/
public function move($group_id, $delta)
{
- if (!is_int($delta) || !$delta)
+ $delta = (int) $delta;
+ if (!$delta)
{
- return;
+ return false;
}
$move_up = ($delta > 0) ? true : false;
@@ -203,10 +196,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,20 +211,26 @@ 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);
+
+ $this->db->sql_transaction('commit');
+
+ return true;
}
$this->db->sql_transaction('commit');
}
+
+ return false;
}
/**
* 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..7c758199e7
--- /dev/null
+++ b/phpBB/includes/groupposition/teampage.php
@@ -0,0 +1,604 @@
+<?php
+/**
+*
+* @package phpBB3
+* @copyright (c) 2012 phpBB Group
+* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+*
+*/
+
+/**
+* @ignore
+*/
+if (!defined('IN_PHPBB'))
+{
+ exit;
+}
+
+/**
+* Teampage group position class
+*
+* Teampage position is an ascending list 1, 2, ..., n for items which are displayed. 1 is the first item, n the last.
+*
+* @package phpBB3
+*/
+class phpbb_groupposition_teampage implements phpbb_groupposition_interface
+{
+ /**
+ * Group is not displayed
+ */
+ const GROUP_DISABLED = 0;
+
+ /**
+ * No parent item
+ */
+ const NO_PARENT = 0;
+
+ /**
+ * Database object
+ * @var phpbb_db_driver
+ */
+ protected $db;
+
+ /**
+ * User object
+ * @var phpbb_user
+ */
+ protected $user;
+
+ /**
+ * Cache object
+ * @var phpbb_cache_driver_interface
+ */
+ protected $cache;
+
+ /**
+ * Constructor
+ *
+ * @param phpbb_db_driver $db Database object
+ * @param phpbb_user $user User object
+ * @param phpbb_cache_driver_interface $cache Cache object
+ */
+ public function __construct(phpbb_db_driver $db, phpbb_user $user, phpbb_cache_driver_interface $cache)
+ {
+ $this->db = $db;
+ $this->user = $user;
+ $this->cache = $cache;
+ }
+
+ /**
+ * Returns the teampage position for a given group, if the group exists.
+ *
+ * {@inheritDoc}
+ */
+ public function get_group_value($group_id)
+ {
+ // The join is required to ensure that the group itself exists
+ $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.
+ throw new phpbb_groupposition_exception('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)
+ {
+ // The join is required to ensure that the group itself exists
+ $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.
+ throw new phpbb_groupposition_exception('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.
+ throw new phpbb_groupposition_exception('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.
+ throw new phpbb_groupposition_exception('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)
+ {
+ return $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 bool True if the group was added successfully
+ */
+ 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)
+ {
+ // Check, whether the given parent is a category
+ $sql = 'SELECT teampage_id
+ FROM ' . TEAMPAGE_TABLE . '
+ WHERE group_id = 0
+ AND teampage_id = ' . (int) $parent_id;
+ $result = $this->db->sql_query_limit($sql, 1);
+ $parent_is_category = (bool) $this->db->sql_fetchfield('teampage_id');
+ $this->db->sql_freeresult($result);
+
+ if ($parent_is_category)
+ {
+ // 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);
+
+ $this->cache->destroy('sql', TEAMPAGE_TABLE);
+ return true;
+ }
+
+ $this->cache->destroy('sql', TEAMPAGE_TABLE);
+ return false;
+ }
+
+ /**
+ * Adds a new category
+ *
+ * @param string $category_name Name of the category to be added
+ * @return bool True if the category was added successfully
+ */
+ public function add_category_teampage($category_name)
+ {
+ if ($category_name === '')
+ {
+ return false;
+ }
+
+ $num_entries = $this->get_group_count();
+
+ $sql_ary = array(
+ 'group_id' => 0,
+ 'teampage_position' => $num_entries + 1,
+ 'teampage_parent' => 0,
+ 'teampage_name' => truncate_string($category_name, 255, 255),
+ );
+
+ $sql = 'INSERT INTO ' . TEAMPAGE_TABLE . ' ' . $this->db->sql_build_array('INSERT', $sql_ary);
+ $this->db->sql_query($sql);
+
+ $this->cache->destroy('sql', TEAMPAGE_TABLE);
+ return true;
+ }
+
+ /**
+ * 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);
+
+ $this->cache->destroy('sql', TEAMPAGE_TABLE);
+ return true;
+ }
+
+ $this->cache->destroy('sql', TEAMPAGE_TABLE);
+ return false;
+ }
+
+ /**
+ * 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 bool True if the item was deleted successfully
+ */
+ 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);
+
+ $this->cache->destroy('sql', TEAMPAGE_TABLE);
+ return true;
+ }
+
+ $this->cache->destroy('sql', TEAMPAGE_TABLE);
+ return false;
+ }
+
+ /**
+ * Moves a group up by group_id
+ *
+ * {@inheritDoc}
+ */
+ public function move_up($group_id)
+ {
+ return $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 bool True if the group was moved successfully
+ */
+ public function move_up_teampage($teampage_id)
+ {
+ return $this->move_teampage($teampage_id, 1);
+ }
+
+ /**
+ * Moves a group down by group_id
+ *
+ * {@inheritDoc}
+ */
+ public function move_down($group_id)
+ {
+ return $this->move($group_id, -1);
+ }
+
+ /**
+ * Movesan item down by teampage_id
+ *
+ * @param int $group_id group_id of the group to be moved
+ * @return bool True if the group was moved successfully
+ */
+ public function move_down_teampage($teampage_id)
+ {
+ return $this->move_teampage($teampage_id, -1);
+ }
+
+ /**
+ * Moves a group up/down
+ *
+ * {@inheritDoc}
+ */
+ public function move($group_id, $delta)
+ {
+ $delta = (int) $delta;
+ if (!$delta)
+ {
+ return false;
+ }
+
+ $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);
+
+ $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'];
+
+ if (!$move_up && $data['teampage_parent'] == self::NO_PARENT && $sibling_count == $sibling_limit)
+ {
+ // 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');
+ $this->cache->destroy('sql', TEAMPAGE_TABLE);
+
+ return true;
+ }
+
+ $this->db->sql_transaction('commit');
+ }
+
+ $this->cache->destroy('sql', TEAMPAGE_TABLE);
+ return false;
+ }
+
+ /**
+ * 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 bool True if the group was moved successfully
+ */
+ public function move_teampage($teampage_id, $delta)
+ {
+ $delta = (int) $delta;
+ if (!$delta)
+ {
+ return false;
+ }
+
+ $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');
+ $this->cache->destroy('sql', TEAMPAGE_TABLE);
+
+ return true;
+ }
+
+ $this->db->sql_transaction('commit');
+ }
+
+ $this->cache->destroy('sql', TEAMPAGE_TABLE);
+ return false;
+ }
+
+ /**
+ * 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';
+ }
+ }
+}
diff --git a/phpBB/includes/log/interface.php b/phpBB/includes/log/interface.php
new file mode 100644
index 0000000000..3b459c9bdf
--- /dev/null
+++ b/phpBB/includes/log/interface.php
@@ -0,0 +1,106 @@
+<?php
+/**
+*
+* @package phpbb_log
+* @copyright (c) 2012 phpBB Group
+* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+*
+*/
+
+/**
+* @ignore
+*/
+if (!defined('IN_PHPBB'))
+{
+ exit;
+}
+
+/**
+* The interface for the log-system.
+*
+* @package phpbb_log
+*/
+interface phpbb_log_interface
+{
+ /**
+ * This function returns the state of the log system.
+ *
+ * @param string $type The log type we want to check. Empty to get
+ * global log status.
+ *
+ * @return bool True if log for the type is enabled
+ */
+ public function is_enabled($type = '');
+
+ /**
+ * Disable log
+ *
+ * This function allows disabling the log system or parts of it, for this
+ * page call. When add_log is called and the type is disabled,
+ * the log will not be added to the database.
+ *
+ * @param mixed $type The log type we want to disable. Empty to
+ * disable all logs. Can also be an array of types.
+ *
+ * @return null
+ */
+ public function disable($type = '');
+
+ /**
+ * Enable log
+ *
+ * This function allows re-enabling the log system.
+ *
+ * @param mixed $type The log type we want to enable. Empty to
+ * enable all logs. Can also be an array of types.
+ *
+ * @return null
+ */
+ public function enable($type = '');
+
+ /**
+ * Adds a log entry to the database
+ *
+ * @param string $mode The mode defines which log_type is used and from which log the entry is retrieved
+ * @param int $user_id User ID of the user
+ * @param string $log_ip IP address of the user
+ * @param string $log_operation Name of the operation
+ * @param int $log_time Timestamp when the log entry was added, if empty time() will be used
+ * @param array $additional_data More arguments can be added, depending on the log_type
+ *
+ * @return int|bool Returns the log_id, if the entry was added to the database, false otherwise.
+ */
+ public function add($mode, $user_id, $log_ip, $log_operation, $log_time = false, $additional_data = array());
+
+ /**
+ * Grab the logs from the database
+ *
+ * @param string $mode The mode defines which log_type is used and ifrom which log the entry is retrieved
+ * @param bool $count_logs Shall we count all matching log entries?
+ * @param int $limit Limit the number of entries that are returned
+ * @param int $offset Offset when fetching the log entries, f.e. when paginating
+ * @param mixed $forum_id Restrict the log entries to the given forum_id (can also be an array of forum_ids)
+ * @param int $topic_id Restrict the log entries to the given topic_id
+ * @param int $user_id Restrict the log entries to the given user_id
+ * @param int $log_time Only get log entries newer than the given timestamp
+ * @param string $sort_by SQL order option, e.g. 'l.log_time DESC'
+ * @param string $keywords Will only return log entries that have the keywords in log_operation or log_data
+ *
+ * @return array The result array with the logs
+ */
+ public function get_logs($mode, $count_logs = true, $limit = 0, $offset = 0, $forum_id = 0, $topic_id = 0, $user_id = 0, $log_time = 0, $sort_by = 'l.log_time DESC', $keywords = '');
+
+ /**
+ * Get total log count
+ *
+ * @return int Returns the number of matching logs from the last call to get_logs()
+ */
+ public function get_log_count();
+
+ /**
+ * Get offset of the last valid page
+ *
+ * @return int Returns the offset of the last valid page from the last call to get_logs()
+ */
+ public function get_valid_offset();
+}
diff --git a/phpBB/includes/log/log.php b/phpBB/includes/log/log.php
new file mode 100644
index 0000000000..7a26858348
--- /dev/null
+++ b/phpBB/includes/log/log.php
@@ -0,0 +1,739 @@
+<?php
+/**
+*
+* @package phpbb_log
+* @copyright (c) 2012 phpBB Group
+* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+*
+*/
+
+/**
+* @ignore
+*/
+if (!defined('IN_PHPBB'))
+{
+ exit;
+}
+
+/**
+* This class is used to add entries into the log table.
+*
+* @package phpbb_log
+*/
+class phpbb_log implements phpbb_log_interface
+{
+ /**
+ * If set, administrative user profile links will be returned and messages
+ * will not be censored.
+ * @var bool
+ */
+ protected $is_in_admin;
+
+ /**
+ * An array with the disabled log types. Logs of such types will not be
+ * added when add_log() is called.
+ * @var array
+ */
+ protected $disabled_types;
+
+ /**
+ * Keeps the total log count of the last call to get_logs()
+ * @var int
+ */
+ protected $entry_count;
+
+ /**
+ * Keeps the offset of the last valid page of the last call to get_logs()
+ * @var int
+ */
+ protected $last_page_offset;
+
+ /**
+ * The table we use to store our logs.
+ * @var string
+ */
+ protected $log_table;
+
+ /**
+ * Database object
+ * @var phpbb_db_driver
+ */
+ protected $db;
+
+ /**
+ * User object
+ * @var phpbb_user
+ */
+ protected $user;
+
+ /**
+ * Auth object
+ * @var phpbb_auth
+ */
+ protected $auth;
+
+ /**
+ * Event dispatcher object
+ * @var phpbb_dispatcher
+ */
+ protected $dispatcher;
+
+ /**
+ * phpBB root path
+ * @var string
+ */
+ protected $phpbb_root_path;
+
+ /**
+ * Admin root path
+ * @var string
+ */
+ protected $phpbb_admin_path;
+
+ /**
+ * PHP Extension
+ * @var string
+ */
+ protected $php_ext;
+
+ /**
+ * Constructor
+ *
+ * @param phpbb_db_driver $db Database object
+ * @param phpbb_user $user User object
+ * @param phpbb_auth $auth Auth object
+ * @param phpbb_dispatcher $phpbb_dispatcher Event dispatcher
+ * @param string $phpbb_root_path Root path
+ * @param string $relative_admin_path Relative admin root path
+ * @param string $php_ext PHP Extension
+ * @param string $log_table Name of the table we use to store our logs
+ * @return null
+ */
+ public function __construct($db, $user, $auth, $phpbb_dispatcher, $phpbb_root_path, $relative_admin_path, $php_ext, $log_table)
+ {
+ $this->db = $db;
+ $this->user = $user;
+ $this->auth = $auth;
+ $this->dispatcher = $phpbb_dispatcher;
+ $this->phpbb_root_path = $phpbb_root_path;
+ $this->phpbb_admin_path = $this->phpbb_root_path . $relative_admin_path;
+ $this->php_ext = $php_ext;
+ $this->log_table = $log_table;
+
+ /*
+ * IN_ADMIN is set after the session is created,
+ * so we need to take ADMIN_START into account as well, otherwise
+ * it will not work for the phpbb_log object we create in common.php
+ */
+ $this->set_is_admin((defined('ADMIN_START') && ADMIN_START) || (defined('IN_ADMIN') && IN_ADMIN));
+ $this->enable();
+ }
+
+ /**
+ * Set is_in_admin in order to return administrative user profile links
+ * in get_logs()
+ *
+ * @param bool $is_in_admin Are we called from within the acp?
+ * @return null
+ */
+ public function set_is_admin($is_in_admin)
+ {
+ $this->is_in_admin = (bool) $is_in_admin;
+ }
+
+ /**
+ * Returns the is_in_admin option
+ *
+ * @return bool
+ */
+ public function get_is_admin()
+ {
+ return $this->is_in_admin;
+ }
+
+ /**
+ * Set table name
+ *
+ * @param string $log_table Can overwrite the table to use for the logs
+ * @return null
+ */
+ public function set_log_table($log_table)
+ {
+ $this->log_table = $log_table;
+ }
+
+ /**
+ * This function returns the state of the log system.
+ *
+ * {@inheritDoc}
+ */
+ public function is_enabled($type = '')
+ {
+ if ($type == '' || $type == 'all')
+ {
+ return !isset($this->disabled_types['all']);
+ }
+ return !isset($this->disabled_types[$type]) && !isset($this->disabled_types['all']);
+ }
+
+ /**
+ * Disable log
+ *
+ * This function allows disabling the log system or parts of it, for this
+ * page call. When add_log is called and the type is disabled,
+ * the log will not be added to the database.
+ *
+ * {@inheritDoc}
+ */
+ public function disable($type = '')
+ {
+ if (is_array($type))
+ {
+ foreach ($type as $disable_type)
+ {
+ $this->disable($disable_type);
+ }
+ return;
+ }
+
+ // Empty string is an equivalent for all types.
+ if ($type == '')
+ {
+ $type = 'all';
+ }
+ $this->disabled_types[$type] = true;
+ }
+
+ /**
+ * Enable log
+ *
+ * This function allows re-enabling the log system.
+ *
+ * {@inheritDoc}
+ */
+ public function enable($type = '')
+ {
+ if (is_array($type))
+ {
+ foreach ($type as $enable_type)
+ {
+ $this->enable($enable_type);
+ }
+ return;
+ }
+
+ if ($type == '' || $type == 'all')
+ {
+ $this->disabled_types = array();
+ return;
+ }
+ unset($this->disabled_types[$type]);
+ }
+
+ /**
+ * Adds a log to the database
+ *
+ * {@inheritDoc}
+ */
+ public function add($mode, $user_id, $log_ip, $log_operation, $log_time = false, $additional_data = array())
+ {
+ if (!$this->is_enabled($mode))
+ {
+ return false;
+ }
+
+ if ($log_time == false)
+ {
+ $log_time = time();
+ }
+
+ $sql_ary = array(
+ 'user_id' => $user_id,
+ 'log_ip' => $log_ip,
+ 'log_time' => $log_time,
+ 'log_operation' => $log_operation,
+ );
+
+ switch ($mode)
+ {
+ case 'admin':
+ $sql_ary += array(
+ 'log_type' => LOG_ADMIN,
+ 'log_data' => (!empty($additional_data)) ? serialize($additional_data) : '',
+ );
+ break;
+
+ case 'mod':
+ $forum_id = (int) $additional_data['forum_id'];
+ unset($additional_data['forum_id']);
+ $topic_id = (int) $additional_data['topic_id'];
+ unset($additional_data['topic_id']);
+ $sql_ary += array(
+ 'log_type' => LOG_MOD,
+ 'forum_id' => $forum_id,
+ 'topic_id' => $topic_id,
+ 'log_data' => (!empty($additional_data)) ? serialize($additional_data) : '',
+ );
+ break;
+
+ case 'user':
+ $reportee_id = (int) $additional_data['reportee_id'];
+ unset($additional_data['reportee_id']);
+
+ $sql_ary += array(
+ 'log_type' => LOG_USERS,
+ 'reportee_id' => $reportee_id,
+ 'log_data' => (!empty($additional_data)) ? serialize($additional_data) : '',
+ );
+ break;
+
+ case 'critical':
+ $sql_ary += array(
+ 'log_type' => LOG_CRITICAL,
+ 'log_data' => (!empty($additional_data)) ? serialize($additional_data) : '',
+ );
+ break;
+ }
+
+ /**
+ * Allows to modify log data before we add it to the database
+ *
+ * NOTE: if sql_ary does not contain a log_type value, the entry will
+ * not be stored in the database. So ensure to set it, if needed.
+ *
+ * @event core.add_log
+ * @var string mode Mode of the entry we log
+ * @var int user_id ID of the user who triggered the log
+ * @var string log_ip IP of the user who triggered the log
+ * @var string log_operation Language key of the log operation
+ * @var int log_time Timestamp, when the log was added
+ * @var array additional_data Array with additional log data
+ * @var array sql_ary Array with log data we insert into the
+ * database. If sql_ary[log_type] is not set,
+ * we won't add the entry to the database.
+ * @since 3.1-A1
+ */
+ $vars = array('mode', 'user_id', 'log_ip', 'log_operation', 'log_time', 'additional_data', 'sql_ary');
+ extract($this->dispatcher->trigger_event('core.add_log', $vars));
+
+ // We didn't find a log_type, so we don't save it in the database.
+ if (!isset($sql_ary['log_type']))
+ {
+ return false;
+ }
+
+ $this->db->sql_query('INSERT INTO ' . $this->log_table . ' ' . $this->db->sql_build_array('INSERT', $sql_ary));
+
+ return $this->db->sql_nextid();
+ }
+
+ /**
+ * Grab the logs from the database
+ *
+ * {@inheritDoc}
+ */
+ public function get_logs($mode, $count_logs = true, $limit = 0, $offset = 0, $forum_id = 0, $topic_id = 0, $user_id = 0, $log_time = 0, $sort_by = 'l.log_time DESC', $keywords = '')
+ {
+ $this->entry_count = 0;
+ $this->last_page_offset = $offset;
+
+ $topic_id_list = $reportee_id_list = array();
+
+ $profile_url = ($this->get_is_admin() && $this->phpbb_admin_path) ? append_sid("{$this->phpbb_admin_path}index.{$this->php_ext}", 'i=users&amp;mode=overview') : append_sid("{$this->phpbb_root_path}memberlist.{$this->php_ext}", 'mode=viewprofile');
+
+ switch ($mode)
+ {
+ case 'admin':
+ $log_type = LOG_ADMIN;
+ $sql_additional = '';
+ break;
+
+ case 'mod':
+ $log_type = LOG_MOD;
+ $sql_additional = '';
+
+ if ($topic_id)
+ {
+ $sql_additional = 'AND l.topic_id = ' . (int) $topic_id;
+ }
+ else if (is_array($forum_id))
+ {
+ $sql_additional = 'AND ' . $this->db->sql_in_set('l.forum_id', array_map('intval', $forum_id));
+ }
+ else if ($forum_id)
+ {
+ $sql_additional = 'AND l.forum_id = ' . (int) $forum_id;
+ }
+ break;
+
+ case 'user':
+ $log_type = LOG_USERS;
+ $sql_additional = 'AND l.reportee_id = ' . (int) $user_id;
+ break;
+
+ case 'users':
+ $log_type = LOG_USERS;
+ $sql_additional = '';
+ break;
+
+ case 'critical':
+ $log_type = LOG_CRITICAL;
+ $sql_additional = '';
+ break;
+
+ default:
+ $log_type = false;
+ $sql_additional = '';
+ }
+
+ /**
+ * Overwrite log type and limitations before we count and get the logs
+ *
+ * NOTE: if log_type is false, no entries will be returned.
+ *
+ * @event core.get_logs_modify_type
+ * @var string mode Mode of the entries we display
+ * @var bool count_logs Do we count all matching entries?
+ * @var int limit Limit the number of entries
+ * @var int offset Offset when fetching the entries
+ * @var mixed forum_id Limit entries to the forum_id,
+ * can also be an array of forum_ids
+ * @var int topic_id Limit entries to the topic_id
+ * @var int user_id Limit entries to the user_id
+ * @var int log_time Limit maximum age of log entries
+ * @var string sort_by SQL order option
+ * @var string keywords Will only return entries that have the
+ * keywords in log_operation or log_data
+ * @var string profile_url URL to the users profile
+ * @var int log_type Limit logs to a certain type. If log_type
+ * is false, no entries will be returned.
+ * @var string sql_additional Additional conditions for the entries,
+ * e.g.: 'AND l.forum_id = 1'
+ * @since 3.1-A1
+ */
+ $vars = array('mode', 'count_logs', 'limit', 'offset', 'forum_id', 'topic_id', 'user_id', 'log_time', 'sort_by', 'keywords', 'profile_url', 'log_type', 'sql_additional');
+ extract($this->dispatcher->trigger_event('core.get_logs_modify_type', $vars));
+
+ if ($log_type === false)
+ {
+ $this->last_page_offset = 0;
+ return array();
+ }
+
+ $sql_keywords = '';
+ if (!empty($keywords))
+ {
+ // Get the SQL condition for our keywords
+ $sql_keywords = $this->generate_sql_keyword($keywords);
+ }
+
+ if ($count_logs)
+ {
+ $sql = 'SELECT COUNT(l.log_id) AS total_entries
+ FROM ' . LOG_TABLE . ' l, ' . USERS_TABLE . ' u
+ WHERE l.log_type = ' . (int) $log_type . '
+ AND l.user_id = u.user_id
+ AND l.log_time >= ' . (int) $log_time . "
+ $sql_keywords
+ $sql_additional";
+ $result = $this->db->sql_query($sql);
+ $this->entry_count = (int) $this->db->sql_fetchfield('total_entries');
+ $this->db->sql_freeresult($result);
+
+ if ($this->entry_count == 0)
+ {
+ // Save the queries, because there are no logs to display
+ $this->last_page_offset = 0;
+ return array();
+ }
+
+ // Return the user to the last page that is valid
+ while ($this->last_page_offset >= $this->entry_count)
+ {
+ $this->last_page_offset = max(0, $this->last_page_offset - $limit);
+ }
+ }
+
+ $sql = 'SELECT l.*, u.username, u.username_clean, u.user_colour
+ FROM ' . LOG_TABLE . ' l, ' . USERS_TABLE . ' u
+ WHERE l.log_type = ' . (int) $log_type . '
+ AND u.user_id = l.user_id
+ ' . (($log_time) ? 'AND l.log_time >= ' . (int) $log_time : '') . "
+ $sql_keywords
+ $sql_additional
+ ORDER BY $sort_by";
+ $result = $this->db->sql_query_limit($sql, $limit, $this->last_page_offset);
+
+ $i = 0;
+ $log = array();
+ while ($row = $this->db->sql_fetchrow($result))
+ {
+ $row['forum_id'] = (int) $row['forum_id'];
+ if ($row['topic_id'])
+ {
+ $topic_id_list[] = (int) $row['topic_id'];
+ }
+
+ if ($row['reportee_id'])
+ {
+ $reportee_id_list[] = (int) $row['reportee_id'];
+ }
+
+ $log_entry_data = array(
+ 'id' => (int) $row['log_id'],
+
+ 'reportee_id' => (int) $row['reportee_id'],
+ 'reportee_username' => '',
+ 'reportee_username_full'=> '',
+
+ 'user_id' => (int) $row['user_id'],
+ 'username' => $row['username'],
+ 'username_full' => get_username_string('full', $row['user_id'], $row['username'], $row['user_colour'], false, $profile_url),
+
+ 'ip' => $row['log_ip'],
+ 'time' => (int) $row['log_time'],
+ 'forum_id' => (int) $row['forum_id'],
+ 'topic_id' => (int) $row['topic_id'],
+
+ 'viewforum' => ($row['forum_id'] && $this->auth->acl_get('f_read', $row['forum_id'])) ? append_sid("{$this->phpbb_root_path}viewforum.{$this->php_ext}", 'f=' . $row['forum_id']) : false,
+ 'action' => (isset($this->user->lang[$row['log_operation']])) ? $this->user->lang[$row['log_operation']] : '{' . ucfirst(str_replace('_', ' ', $row['log_operation'])) . '}',
+ );
+
+ /**
+ * Modify the entry's data before it is returned
+ *
+ * @event core.get_logs_modify_entry_data
+ * @var array row Entry data from the database
+ * @var array log_entry_data Entry's data which is returned
+ * @since 3.1-A1
+ */
+ $vars = array('row', 'log_entry_data');
+ extract($this->dispatcher->trigger_event('core.get_logs_modify_entry_data', $vars));
+
+ $log[$i] = $log_entry_data;
+
+ if (!empty($row['log_data']))
+ {
+ $log_data_ary = unserialize($row['log_data']);
+ $log_data_ary = ($log_data_ary !== false) ? $log_data_ary : array();
+
+ if (isset($this->user->lang[$row['log_operation']]))
+ {
+ // Check if there are more occurrences of % than
+ // arguments, if there are we fill out the arguments
+ // array. It doesn't matter if we add more arguments than
+ // placeholders.
+ if ((substr_count($log[$i]['action'], '%') - sizeof($log_data_ary)) > 0)
+ {
+ $log_data_ary = array_merge($log_data_ary, array_fill(0, substr_count($log[$i]['action'], '%') - sizeof($log_data_ary), ''));
+ }
+
+ $log[$i]['action'] = vsprintf($log[$i]['action'], $log_data_ary);
+
+ // If within the admin panel we do not censor text out
+ if ($this->get_is_admin())
+ {
+ $log[$i]['action'] = bbcode_nl2br($log[$i]['action']);
+ }
+ else
+ {
+ $log[$i]['action'] = bbcode_nl2br(censor_text($log[$i]['action']));
+ }
+ }
+ else if (!empty($log_data_ary))
+ {
+ $log[$i]['action'] .= '<br />' . implode('', $log_data_ary);
+ }
+
+ /* Apply make_clickable... has to be seen if it is for good. :/
+ // Seems to be not for the moment, reconsider later...
+ $log[$i]['action'] = make_clickable($log[$i]['action']);
+ */
+ }
+
+ $i++;
+ }
+ $this->db->sql_freeresult($result);
+
+ /**
+ * Get some additional data after we got all log entries
+ *
+ * @event core.get_logs_get_additional_data
+ * @var array log Array with all our log entries
+ * @var array topic_id_list Array of topic ids, for which we
+ * get the permission data
+ * @var array reportee_id_list Array of additional user IDs we
+ * get the username strings for
+ * @since 3.1-A1
+ */
+ $vars = array('log', 'topic_id_list', 'reportee_id_list');
+ extract($this->dispatcher->trigger_event('core.get_logs_get_additional_data', $vars));
+
+ if (sizeof($topic_id_list))
+ {
+ $topic_auth = $this->get_topic_auth($topic_id_list);
+
+ foreach ($log as $key => $row)
+ {
+ $log[$key]['viewtopic'] = (isset($topic_auth['f_read'][$row['topic_id']])) ? append_sid("{$this->phpbb_root_path}viewtopic.{$this->php_ext}", 'f=' . $topic_auth['f_read'][$row['topic_id']] . '&amp;t=' . $row['topic_id']) : false;
+ $log[$key]['viewlogs'] = (isset($topic_auth['m_'][$row['topic_id']])) ? append_sid("{$this->phpbb_root_path}mcp.{$this->php_ext}", 'i=logs&amp;mode=topic_logs&amp;t=' . $row['topic_id'], true, $this->user->session_id) : false;
+ }
+ }
+
+ if (sizeof($reportee_id_list))
+ {
+ $reportee_data_list = $this->get_reportee_data($reportee_id_list);
+
+ foreach ($log as $key => $row)
+ {
+ if (!isset($reportee_data_list[$row['reportee_id']]))
+ {
+ continue;
+ }
+
+ $log[$key]['reportee_username'] = $reportee_data_list[$row['reportee_id']]['username'];
+ $log[$key]['reportee_username_full'] = get_username_string('full', $row['reportee_id'], $reportee_data_list[$row['reportee_id']]['username'], $reportee_data_list[$row['reportee_id']]['user_colour'], false, $profile_url);
+ }
+ }
+
+ return $log;
+ }
+
+ /**
+ * Generates a sql condition for the specified keywords
+ *
+ * @param string $keywords The keywords the user specified to search for
+ *
+ * @return string Returns the SQL condition searching for the keywords
+ */
+ protected function generate_sql_keyword($keywords)
+ {
+ // Use no preg_quote for $keywords because this would lead to sole
+ // backslashes being added. We also use an OR connection here for
+ // spaces and the | string. Currently, regex is not supported for
+ // searching (but may come later).
+ $keywords = preg_split('#[\s|]+#u', utf8_strtolower($keywords), 0, PREG_SPLIT_NO_EMPTY);
+ $sql_keywords = '';
+
+ if (!empty($keywords))
+ {
+ $keywords_pattern = array();
+
+ // Build pattern and keywords...
+ for ($i = 0, $num_keywords = sizeof($keywords); $i < $num_keywords; $i++)
+ {
+ $keywords_pattern[] = preg_quote($keywords[$i], '#');
+ $keywords[$i] = $this->db->sql_like_expression($this->db->any_char . $keywords[$i] . $this->db->any_char);
+ }
+
+ $keywords_pattern = '#' . implode('|', $keywords_pattern) . '#ui';
+
+ $operations = array();
+ foreach ($this->user->lang as $key => $value)
+ {
+ if (substr($key, 0, 4) == 'LOG_' && preg_match($keywords_pattern, $value))
+ {
+ $operations[] = $key;
+ }
+ }
+
+ $sql_keywords = 'AND (';
+ if (!empty($operations))
+ {
+ $sql_keywords .= $this->db->sql_in_set('l.log_operation', $operations) . ' OR ';
+ }
+ $sql_lower = $this->db->sql_lower_text('l.log_data');
+ $sql_keywords .= " $sql_lower " . implode(" OR $sql_lower ", $keywords) . ')';
+ }
+
+ return $sql_keywords;
+ }
+
+ /**
+ * Determine whether the user is allowed to read and/or moderate the forum of the topic
+ *
+ * @param array $topic_ids Array with the topic ids
+ *
+ * @return array Returns an array with two keys 'm_' and 'read_f' which are also an array of topic_id => forum_id sets when the permissions are given. Sample:
+ * array(
+ * 'permission' => array(
+ * topic_id => forum_id
+ * ),
+ * ),
+ */
+ protected function get_topic_auth(array $topic_ids)
+ {
+ $forum_auth = array('f_read' => array(), 'm_' => array());
+ $topic_ids = array_unique($topic_ids);
+
+ $sql = 'SELECT topic_id, forum_id
+ FROM ' . TOPICS_TABLE . '
+ WHERE ' . $this->db->sql_in_set('topic_id', array_map('intval', $topic_ids));
+ $result = $this->db->sql_query($sql);
+
+ while ($row = $this->db->sql_fetchrow($result))
+ {
+ $row['topic_id'] = (int) $row['topic_id'];
+ $row['forum_id'] = (int) $row['forum_id'];
+
+ if ($this->auth->acl_get('f_read', $row['forum_id']))
+ {
+ $forum_auth['f_read'][$row['topic_id']] = $row['forum_id'];
+ }
+
+ if ($this->auth->acl_gets('a_', 'm_', $row['forum_id']))
+ {
+ $forum_auth['m_'][$row['topic_id']] = $row['forum_id'];
+ }
+ }
+ $this->db->sql_freeresult($result);
+
+ return $forum_auth;
+ }
+
+ /**
+ * Get the data for all reportee from the database
+ *
+ * @param array $reportee_ids Array with the user ids of the reportees
+ *
+ * @return array Returns an array with the reportee data
+ */
+ protected function get_reportee_data(array $reportee_ids)
+ {
+ $reportee_ids = array_unique($reportee_ids);
+ $reportee_data_list = array();
+
+ $sql = 'SELECT user_id, username, user_colour
+ FROM ' . USERS_TABLE . '
+ WHERE ' . $this->db->sql_in_set('user_id', $reportee_ids);
+ $result = $this->db->sql_query($sql);
+
+ while ($row = $this->db->sql_fetchrow($result))
+ {
+ $reportee_data_list[$row['user_id']] = $row;
+ }
+ $this->db->sql_freeresult($result);
+
+ return $reportee_data_list;
+ }
+
+ /**
+ * Get total log count
+ *
+ * {@inheritDoc}
+ */
+ public function get_log_count()
+ {
+ return ($this->entry_count) ? $this->entry_count : 0;
+ }
+
+ /**
+ * Get offset of the last valid log page
+ *
+ * {@inheritDoc}
+ */
+ public function get_valid_offset()
+ {
+ return ($this->last_page_offset) ? $this->last_page_offset : 0;
+ }
+}
diff --git a/phpBB/includes/mcp/mcp_notes.php b/phpBB/includes/mcp/mcp_notes.php
index 59cdf3c27e..12fcbfe91e 100644
--- a/phpBB/includes/mcp/mcp_notes.php
+++ b/phpBB/includes/mcp/mcp_notes.php
@@ -173,13 +173,13 @@ class mcp_notes
}
// Generate the appropriate user information for the user we are looking at
- if (!function_exists('get_user_avatar'))
+ if (!function_exists('phpbb_get_user_avatar'))
{
include($phpbb_root_path . 'includes/functions_display.' . $phpEx);
}
$rank_title = $rank_img = '';
- $avatar_img = get_user_avatar($userrow['user_avatar'], $userrow['user_avatar_type'], $userrow['user_avatar_width'], $userrow['user_avatar_height']);
+ $avatar_img = phpbb_get_user_avatar($userrow);
$limit_days = array(0 => $user->lang['ALL_ENTRIES'], 1 => $user->lang['1_DAY'], 7 => $user->lang['7_DAYS'], 14 => $user->lang['2_WEEKS'], 30 => $user->lang['1_MONTH'], 90 => $user->lang['3_MONTHS'], 180 => $user->lang['6_MONTHS'], 365 => $user->lang['1_YEAR']);
$sort_by_text = array('a' => $user->lang['SORT_USERNAME'], 'b' => $user->lang['SORT_DATE'], 'c' => $user->lang['SORT_IP'], 'd' => $user->lang['SORT_ACTION']);
diff --git a/phpBB/includes/mcp/mcp_warn.php b/phpBB/includes/mcp/mcp_warn.php
index 6a8fb4c5d5..4ef477775d 100644
--- a/phpBB/includes/mcp/mcp_warn.php
+++ b/phpBB/includes/mcp/mcp_warn.php
@@ -304,13 +304,13 @@ class mcp_warn
$message = smiley_text($message);
// Generate the appropriate user information for the user we are looking at
- if (!function_exists('get_user_avatar'))
+ if (!function_exists('phpbb_get_user_avatar'))
{
include($phpbb_root_path . 'includes/functions_display.' . $phpEx);
}
get_user_rank($user_row['user_rank'], $user_row['user_posts'], $rank_title, $rank_img, $rank_img_src);
- $avatar_img = get_user_avatar($user_row['user_avatar'], $user_row['user_avatar_type'], $user_row['user_avatar_width'], $user_row['user_avatar_height']);
+ $avatar_img = phpbb_get_user_avatar($user_row);
$template->assign_vars(array(
'U_POST_ACTION' => $this->u_action,
@@ -409,13 +409,13 @@ class mcp_warn
}
// Generate the appropriate user information for the user we are looking at
- if (!function_exists('get_user_avatar'))
+ if (!function_exists('phpbb_get_user_avatar'))
{
include($phpbb_root_path . 'includes/functions_display.' . $phpEx);
}
get_user_rank($user_row['user_rank'], $user_row['user_posts'], $rank_title, $rank_img, $rank_img_src);
- $avatar_img = get_user_avatar($user_row['user_avatar'], $user_row['user_avatar_type'], $user_row['user_avatar_width'], $user_row['user_avatar_height']);
+ $avatar_img = phpbb_get_user_avatar($user_row);
// OK, they didn't submit a warning so lets build the page for them to do so
$template->assign_vars(array(
diff --git a/phpBB/includes/ucp/info/ucp_profile.php b/phpBB/includes/ucp/info/ucp_profile.php
index 3581a7f533..e974cea713 100644
--- a/phpBB/includes/ucp/info/ucp_profile.php
+++ b/phpBB/includes/ucp/info/ucp_profile.php
@@ -21,7 +21,7 @@ class ucp_profile_info
'modes' => array(
'profile_info' => array('title' => 'UCP_PROFILE_PROFILE_INFO', 'auth' => 'acl_u_chgprofileinfo', 'cat' => array('UCP_PROFILE')),
'signature' => array('title' => 'UCP_PROFILE_SIGNATURE', 'auth' => 'acl_u_sig', 'cat' => array('UCP_PROFILE')),
- 'avatar' => array('title' => 'UCP_PROFILE_AVATAR', 'auth' => 'cfg_allow_avatar && (cfg_allow_avatar_local || cfg_allow_avatar_remote || cfg_allow_avatar_upload || cfg_allow_avatar_remote_upload)', 'cat' => array('UCP_PROFILE')),
+ 'avatar' => array('title' => 'UCP_PROFILE_AVATAR', 'auth' => 'cfg_allow_avatar', 'cat' => array('UCP_PROFILE')),
'reg_details' => array('title' => 'UCP_PROFILE_REG_DETAILS', 'auth' => '', 'cat' => array('UCP_PROFILE')),
'autologin_keys'=> array('title' => 'UCP_PROFILE_AUTOLOGIN_KEYS', 'auth' => '', 'cat' => array('UCP_PROFILE')),
),
diff --git a/phpBB/includes/ucp/ucp_groups.php b/phpBB/includes/ucp/ucp_groups.php
index b9a06bc3b4..8516682633 100644
--- a/phpBB/includes/ucp/ucp_groups.php
+++ b/phpBB/includes/ucp/ucp_groups.php
@@ -27,7 +27,7 @@ class ucp_groups
{
global $config, $phpbb_root_path, $phpEx, $phpbb_admin_path;
global $db, $user, $auth, $cache, $template;
- global $request;
+ global $request, $phpbb_container;
$user->add_lang('groups');
@@ -438,7 +438,7 @@ class ucp_groups
$group_name = $group_row['group_name'];
$group_type = $group_row['group_type'];
- $avatar_img = (!empty($group_row['group_avatar'])) ? get_user_avatar($group_row['group_avatar'], $group_row['group_avatar_type'], $group_row['group_avatar_width'], $group_row['group_avatar_height'], 'GROUP_AVATAR') : '<img src="' . $phpbb_admin_path . 'images/no_avatar.gif" alt="" />';
+ $avatar = phpbb_get_group_avatar($group_row, 'GROUP_AVATAR', true);
$template->assign_vars(array(
'GROUP_NAME' => ($group_type == GROUP_SPECIAL) ? $user->lang['G_' . $group_name] : $group_name,
@@ -447,8 +447,8 @@ class ucp_groups
'GROUP_DESC_DISP' => generate_text_for_display($group_row['group_desc'], $group_row['group_desc_uid'], $group_row['group_desc_bitfield'], $group_row['group_desc_options']),
'GROUP_TYPE' => $group_row['group_type'],
- 'AVATAR' => $avatar_img,
- 'AVATAR_IMAGE' => $avatar_img,
+ 'AVATAR' => (empty($avatar) ? '<img src="' . $phpbb_admin_path . 'images/no_avatar.gif" alt="" />' : $avatar),
+ 'AVATAR_IMAGE' => (empty($avatar) ? '<img src="' . $phpbb_admin_path . 'images/no_avatar.gif" alt="" />' : $avatar),
'AVATAR_WIDTH' => (isset($group_row['group_avatar_width'])) ? $group_row['group_avatar_width'] : '',
'AVATAR_HEIGHT' => (isset($group_row['group_avatar_height'])) ? $group_row['group_avatar_height'] : '',
));
@@ -483,10 +483,20 @@ class ucp_groups
$error = array();
- $avatar_select = basename(request_var('avatar_select', ''));
- $category = basename(request_var('category', ''));
+ // Setup avatar data for later
+ $avatars_enabled = false;
+ $avatar_drivers = null;
+ $avatar_data = null;
+ $avatar_error = array();
- $can_upload = (file_exists($phpbb_root_path . $config['avatar_path']) && phpbb_is_writable($phpbb_root_path . $config['avatar_path']) && $file_uploads) ? true : false;
+ if ($config['allow_avatar'])
+ {
+ $phpbb_avatar_manager = $phpbb_container->get('avatar.manager');
+ $avatar_drivers = $phpbb_avatar_manager->get_enabled_drivers();
+
+ // This is normalised data, without the group_ prefix
+ $avatar_data = phpbb_avatar_manager::clean_row($group_row);
+ }
// Did we submit?
if ($update)
@@ -507,87 +517,36 @@ class ucp_groups
'max_recipients'=> request_var('group_max_recipients', 0),
);
- $data['uploadurl'] = request_var('uploadurl', '');
- $data['remotelink'] = request_var('remotelink', '');
- $data['width'] = request_var('width', '');
- $data['height'] = request_var('height', '');
- $delete = request_var('delete', '');
-
- $uploadfile = $request->file('uploadfile');
- if (!empty($uploadfile['tmp_name']) || $data['uploadurl'] || $data['remotelink'])
+ if ($config['allow_avatar'])
{
- // Avatar stuff
- $var_ary = array(
- 'uploadurl' => array('string', true, 5, 255),
- 'remotelink' => array('string', true, 5, 255),
- 'width' => array('string', true, 1, 3),
- 'height' => array('string', true, 1, 3),
- );
+ // Handle avatar
+ $driver_name = $phpbb_avatar_manager->clean_driver_name($request->variable('avatar_driver', ''));
+ $config_name = preg_replace('#^avatar\.driver.#', '', $driver_name);
- if (!($error = validate_data($data, $var_ary)))
+ if (in_array($driver_name, $avatar_drivers) && !$request->is_set_post('avatar_delete'))
{
- $data['user_id'] = "g$group_id";
+ $driver = $phpbb_avatar_manager->get_driver($driver_name);
+ $result = $driver->process_form($request, $template, $user, $avatar_data, $avatar_error);
- if ((!empty($uploadfile['tmp_name']) || $data['uploadurl']) && $can_upload)
+ if ($result && empty($avatar_error))
{
- list($submit_ary['avatar_type'], $submit_ary['avatar'], $submit_ary['avatar_width'], $submit_ary['avatar_height']) = avatar_upload($data, $error);
- }
- else if ($data['remotelink'])
- {
- list($submit_ary['avatar_type'], $submit_ary['avatar'], $submit_ary['avatar_width'], $submit_ary['avatar_height']) = avatar_remote($data, $error);
- }
- }
- }
- else if ($avatar_select && $config['allow_avatar_local'])
- {
- // check avatar gallery
- if (is_dir($phpbb_root_path . $config['avatar_gallery_path'] . '/' . $category))
- {
- $submit_ary['avatar_type'] = AVATAR_GALLERY;
+ $result['avatar_type'] = $driver_name;
- list($submit_ary['avatar_width'], $submit_ary['avatar_height']) = getimagesize($phpbb_root_path . $config['avatar_gallery_path'] . '/' . $category . '/' . $avatar_select);
- $submit_ary['avatar'] = $category . '/' . $avatar_select;
- }
- }
- else if ($delete)
- {
- $submit_ary['avatar'] = '';
- $submit_ary['avatar_type'] = $submit_ary['avatar_width'] = $submit_ary['avatar_height'] = 0;
- }
- else if ($data['width'] && $data['height'])
- {
- // Only update the dimensions?
- if ($config['avatar_max_width'] || $config['avatar_max_height'])
- {
- if ($data['width'] > $config['avatar_max_width'] || $data['height'] > $config['avatar_max_height'])
- {
- $error[] = phpbb_avatar_error_wrong_size($data['width'], $data['height']);
+ $submit_ary = array_merge($submit_ary, $result);
}
}
-
- if (!sizeof($error))
+ else
{
- if ($config['avatar_min_width'] || $config['avatar_min_height'])
+ if ($driver = $phpbb_avatar_manager->get_driver($user->data['user_avatar_type']))
{
- if ($data['width'] < $config['avatar_min_width'] || $data['height'] < $config['avatar_min_height'])
- {
- $error[] = phpbb_avatar_error_wrong_size($data['width'], $data['height']);
- }
+ $driver->delete($avatar_data);
}
- }
-
- if (!sizeof($error))
- {
- $submit_ary['avatar_width'] = $data['width'];
- $submit_ary['avatar_height'] = $data['height'];
- }
- }
- if ((isset($submit_ary['avatar']) && $submit_ary['avatar'] && (!isset($group_row['group_avatar']))) || $delete)
- {
- if (isset($group_row['group_avatar']) && $group_row['group_avatar'])
- {
- avatar_delete('group', $group_row, true);
+ // Removing the avatar
+ $submit_ary['avatar_type'] = '';
+ $submit_ary['avatar'] = '';
+ $submit_ary['avatar_width'] = 0;
+ $submit_ary['avatar_height'] = 0;
}
}
@@ -607,7 +566,7 @@ class ucp_groups
'rank' => 'int',
'colour' => 'string',
'avatar' => 'string',
- 'avatar_type' => 'int',
+ 'avatar_type' => 'string',
'avatar_width' => 'int',
'avatar_height' => 'int',
'receive_pm' => 'int',
@@ -683,28 +642,48 @@ class ucp_groups
$type_closed = ($group_type == GROUP_CLOSED) ? ' checked="checked"' : '';
$type_hidden = ($group_type == GROUP_HIDDEN) ? ' checked="checked"' : '';
- $display_gallery = (isset($_POST['display_gallery'])) ? true : false;
-
- if ($config['allow_avatar'] && $config['allow_avatar_local'] && $display_gallery)
+ // Load up stuff for avatars
+ if ($config['allow_avatar'])
{
- avatar_gallery($category, $avatar_select, 4);
+ $avatars_enabled = false;
+ $selected_driver = $phpbb_avatar_manager->clean_driver_name($request->variable('avatar_driver', $avatar_data['avatar_type']));
+
+ foreach ($avatar_drivers as $current_driver)
+ {
+ $driver = $phpbb_avatar_manager->get_driver($current_driver);
+
+ $avatars_enabled = true;
+ $template->set_filenames(array(
+ 'avatar' => $driver->get_template_name(),
+ ));
+
+ if ($driver->prepare_form($request, $template, $user, $avatar_data, $avatar_error))
+ {
+ $driver_name = $phpbb_avatar_manager->prepare_driver_name($current_driver);
+ $driver_upper = strtoupper($driver_name);
+ $template->assign_block_vars('avatar_drivers', array(
+ 'L_TITLE' => $user->lang($driver_upper . '_TITLE'),
+ 'L_EXPLAIN' => $user->lang($driver_upper . '_EXPLAIN'),
+
+ 'DRIVER' => $driver_name,
+ 'SELECTED' => $current_driver == $selected_driver,
+ 'OUTPUT' => $template->assign_display('avatar'),
+ ));
+ }
+ }
}
- $avatars_enabled = ($config['allow_avatar'] && (($can_upload && ($config['allow_avatar_upload'] || $config['allow_avatar_remote_upload'])) || ($config['allow_avatar_local'] || $config['allow_avatar_remote']))) ? true : false;
+ // Merge any avatars errors into the primary error array
+ $error = array_merge($error, $phpbb_avatar_manager->localize_errors($user, $avatar_error));
$template->assign_vars(array(
'S_EDIT' => true,
'S_INCLUDE_SWATCH' => true,
- 'S_FORM_ENCTYPE' => ($config['allow_avatar'] && $can_upload && ($config['allow_avatar_upload'] || $config['allow_avatar_remote_upload'])) ? ' enctype="multipart/form-data"' : '',
+ 'S_FORM_ENCTYPE' => ' enctype="multipart/form-data"',
'S_ERROR' => (sizeof($error)) ? true : false,
'S_SPECIAL_GROUP' => ($group_type == GROUP_SPECIAL) ? true : false,
- 'S_AVATARS_ENABLED' => $avatars_enabled,
- 'S_DISPLAY_GALLERY' => ($config['allow_avatar'] && $config['allow_avatar_local'] && !$display_gallery) ? true : false,
- 'S_IN_GALLERY' => ($config['allow_avatar_local'] && $display_gallery) ? true : false,
-
- 'S_UPLOAD_AVATAR_FILE' => ($config['allow_avatar'] && $config['allow_avatar_upload'] && $can_upload) ? true : false,
- 'S_UPLOAD_AVATAR_URL' => ($config['allow_avatar'] && $config['allow_avatar_remote_upload'] && $can_upload) ? true : false,
- 'S_LINK_AVATAR' => ($config['allow_avatar'] && $config['allow_avatar_remote']) ? true : false,
+ 'S_AVATARS_ENABLED' => ($config['allow_avatar'] && $avatars_enabled),
+ 'S_GROUP_MANAGE' => true,
'ERROR_MSG' => (sizeof($error)) ? implode('<br />', $error) : '',
'GROUP_RECEIVE_PM' => (isset($group_row['group_receive_pm']) && $group_row['group_receive_pm']) ? ' checked="checked"' : '',
@@ -717,7 +696,6 @@ class ucp_groups
'S_DESC_SMILIES_CHECKED'=> $group_desc_data['allow_smilies'],
'S_RANK_OPTIONS' => $rank_options,
- 'AVATAR_MAX_FILESIZE' => $config['avatar_filesize'],
'GROUP_TYPE_FREE' => GROUP_FREE,
'GROUP_TYPE_OPEN' => GROUP_OPEN,
diff --git a/phpBB/includes/ucp/ucp_pm_viewmessage.php b/phpBB/includes/ucp/ucp_pm_viewmessage.php
index c85b05f144..712032463f 100644
--- a/phpBB/includes/ucp/ucp_pm_viewmessage.php
+++ b/phpBB/includes/ucp/ucp_pm_viewmessage.php
@@ -371,12 +371,12 @@ function get_user_information($user_id, $user_row)
}
}
- if (!function_exists('get_user_avatar'))
+ if (!function_exists('phpbb_get_user_avatar'))
{
include($phpbb_root_path . 'includes/functions_display.' . $phpEx);
}
- $user_row['avatar'] = ($user->optionget('viewavatars')) ? get_user_avatar($user_row['user_avatar'], $user_row['user_avatar_type'], $user_row['user_avatar_width'], $user_row['user_avatar_height']) : '';
+ $user_row['avatar'] = ($user->optionget('viewavatars')) ? phpbb_get_user_avatar($user_row) : '';
get_user_rank($user_row['user_rank'], $user_row['user_posts'], $user_row['rank_title'], $user_row['rank_image'], $user_row['rank_image_src']);
diff --git a/phpBB/includes/ucp/ucp_profile.php b/phpBB/includes/ucp/ucp_profile.php
index e7cea06a45..d2507e5dbd 100644
--- a/phpBB/includes/ucp/ucp_profile.php
+++ b/phpBB/includes/ucp/ucp_profile.php
@@ -28,8 +28,9 @@ class ucp_profile
function main($id, $mode)
{
- global $config, $db, $user, $auth, $template, $phpbb_root_path, $phpEx;
+ global $cache, $config, $db, $user, $auth, $template, $phpbb_root_path, $phpEx;
global $request;
+ global $phpbb_container;
$user->add_lang('posting');
@@ -549,78 +550,129 @@ class ucp_profile
break;
case 'avatar':
+ if (!function_exists('phpbb_get_user_avatar'))
+ {
+ include($phpbb_root_path . 'includes/functions_display.' . $phpEx);
+ }
- include($phpbb_root_path . 'includes/functions_display.' . $phpEx);
+ add_form_key('ucp_avatar');
- $display_gallery = request_var('display_gallery', '0');
- $avatar_select = basename(request_var('avatar_select', ''));
- $category = basename(request_var('category', ''));
+ $avatars_enabled = false;
- $can_upload = (file_exists($phpbb_root_path . $config['avatar_path']) && phpbb_is_writable($phpbb_root_path . $config['avatar_path']) && $auth->acl_get('u_chgavatar') && (@ini_get('file_uploads') || strtolower(@ini_get('file_uploads')) == 'on')) ? true : false;
+ if ($config['allow_avatar'] && $auth->acl_get('u_chgavatar'))
+ {
+ $phpbb_avatar_manager = $phpbb_container->get('avatar.manager');
+ $avatar_drivers = $phpbb_avatar_manager->get_enabled_drivers();
- add_form_key('ucp_avatar');
+ // This is normalised data, without the user_ prefix
+ $avatar_data = phpbb_avatar_manager::clean_row($user->data);
- if ($submit)
- {
- if (check_form_key('ucp_avatar'))
+ if ($submit)
{
- if (avatar_process_user($error, false, $can_upload))
+ if (check_form_key('ucp_avatar'))
{
- meta_refresh(3, $this->u_action);
- $message = $user->lang['PROFILE_UPDATED'] . '<br /><br />' . sprintf($user->lang['RETURN_UCP'], '<a href="' . $this->u_action . '">', '</a>');
- trigger_error($message);
+ $driver_name = $phpbb_avatar_manager->clean_driver_name($request->variable('avatar_driver', ''));
+
+ if (in_array($driver_name, $avatar_drivers) && !$request->is_set_post('avatar_delete'))
+ {
+ $driver = $phpbb_avatar_manager->get_driver($driver_name);
+ $result = $driver->process_form($request, $template, $user, $avatar_data, $error);
+
+ if ($result && empty($error))
+ {
+ // Success! Lets save the result in the database
+ $result = array(
+ 'user_avatar_type' => $driver_name,
+ 'user_avatar' => $result['avatar'],
+ 'user_avatar_width' => $result['avatar_width'],
+ 'user_avatar_height' => $result['avatar_height'],
+ );
+
+ $sql = 'UPDATE ' . USERS_TABLE . '
+ SET ' . $db->sql_build_array('UPDATE', $result) . '
+ WHERE user_id = ' . (int) $user->data['user_id'];
+
+ $db->sql_query($sql);
+
+ meta_refresh(3, $this->u_action);
+ $message = $user->lang['PROFILE_UPDATED'] . '<br /><br />' . sprintf($user->lang['RETURN_UCP'], '<a href="' . $this->u_action . '">', '</a>');
+ trigger_error($message);
+ }
+ }
+ else
+ {
+ if ($driver = $phpbb_avatar_manager->get_driver($user->data['user_avatar_type']))
+ {
+ $driver->delete($avatar_data);
+ }
+
+ $result = array(
+ 'user_avatar' => '',
+ 'user_avatar_type' => '',
+ 'user_avatar_width' => 0,
+ 'user_avatar_height' => 0,
+ );
+
+ $sql = 'UPDATE ' . USERS_TABLE . '
+ SET ' . $db->sql_build_array('UPDATE', $result) . '
+ WHERE user_id = ' . (int) $user->data['user_id'];
+
+ $db->sql_query($sql);
+
+ meta_refresh(3, $this->u_action);
+ $message = $user->lang['PROFILE_UPDATED'] . '<br /><br />' . sprintf($user->lang['RETURN_UCP'], '<a href="' . $this->u_action . '">', '</a>');
+ trigger_error($message);
+ }
+ }
+ else
+ {
+ $error[] = 'FORM_INVALID';
}
}
- else
+
+ $selected_driver = $phpbb_avatar_manager->clean_driver_name($request->variable('avatar_driver', $user->data['user_avatar_type']));
+
+ foreach ($avatar_drivers as $current_driver)
{
- $error[] = 'FORM_INVALID';
+ $driver = $phpbb_avatar_manager->get_driver($current_driver);
+
+ $avatars_enabled = true;
+ $template->set_filenames(array(
+ 'avatar' => $driver->get_template_name(),
+ ));
+
+ if ($driver->prepare_form($request, $template, $user, $avatar_data, $error))
+ {
+ $driver_name = $phpbb_avatar_manager->prepare_driver_name($current_driver);
+ $driver_upper = strtoupper($driver_name);
+
+ $template->assign_block_vars('avatar_drivers', array(
+ 'L_TITLE' => $user->lang($driver_upper . '_TITLE'),
+ 'L_EXPLAIN' => $user->lang($driver_upper . '_EXPLAIN'),
+
+ 'DRIVER' => $driver_name,
+ 'SELECTED' => $current_driver == $selected_driver,
+ 'OUTPUT' => $template->assign_display('avatar'),
+ ));
+ }
}
- // Replace "error" strings with their real, localised form
- $error = array_map(array($user, 'lang'), $error);
}
- if (!$config['allow_avatar'] && $user->data['user_avatar_type'])
- {
- $error[] = $user->lang['AVATAR_NOT_ALLOWED'];
- }
- else if ((($user->data['user_avatar_type'] == AVATAR_UPLOAD) && !$config['allow_avatar_upload']) ||
- (($user->data['user_avatar_type'] == AVATAR_REMOTE) && !$config['allow_avatar_remote']) ||
- (($user->data['user_avatar_type'] == AVATAR_GALLERY) && !$config['allow_avatar_local']))
- {
- $error[] = $user->lang['AVATAR_TYPE_NOT_ALLOWED'];
- }
+ // Replace "error" strings with their real, localised form
+ $error = $phpbb_avatar_manager->localize_errors($user, $error);
+
+ $avatar = phpbb_get_user_avatar($user->data, 'USER_AVATAR', true);
$template->assign_vars(array(
'ERROR' => (sizeof($error)) ? implode('<br />', $error) : '',
- 'AVATAR' => get_user_avatar($user->data['user_avatar'], $user->data['user_avatar_type'], $user->data['user_avatar_width'], $user->data['user_avatar_height'], 'USER_AVATAR', true),
- 'AVATAR_SIZE' => $config['avatar_filesize'],
-
- 'U_GALLERY' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=profile&amp;mode=avatar&amp;display_gallery=1'),
+ 'AVATAR' => $avatar,
- 'S_FORM_ENCTYPE' => ($can_upload && ($config['allow_avatar_upload'] || $config['allow_avatar_remote_upload'])) ? ' enctype="multipart/form-data"' : '',
+ 'S_FORM_ENCTYPE' => ' enctype="multipart/form-data"',
'L_AVATAR_EXPLAIN' => phpbb_avatar_explanation_string(),
- ));
- if ($config['allow_avatar'] && $display_gallery && $auth->acl_get('u_chgavatar') && $config['allow_avatar_local'])
- {
- avatar_gallery($category, $avatar_select, 4);
- }
- else if ($config['allow_avatar'])
- {
- $avatars_enabled = (($can_upload && ($config['allow_avatar_upload'] || $config['allow_avatar_remote_upload'])) || ($auth->acl_get('u_chgavatar') && ($config['allow_avatar_local'] || $config['allow_avatar_remote']))) ? true : false;
-
- $template->assign_vars(array(
- 'AVATAR_WIDTH' => request_var('width', $user->data['user_avatar_width']),
- 'AVATAR_HEIGHT' => request_var('height', $user->data['user_avatar_height']),
-
- 'S_AVATARS_ENABLED' => $avatars_enabled,
- 'S_UPLOAD_AVATAR_FILE' => ($can_upload && $config['allow_avatar_upload']) ? true : false,
- 'S_UPLOAD_AVATAR_URL' => ($can_upload && $config['allow_avatar_remote_upload']) ? true : false,
- 'S_LINK_AVATAR' => ($auth->acl_get('u_chgavatar') && $config['allow_avatar_remote']) ? true : false,
- 'S_DISPLAY_GALLERY' => ($auth->acl_get('u_chgavatar') && $config['allow_avatar_local']) ? true : false)
- );
- }
+ 'S_AVATARS_ENABLED' => ($config['allow_avatar'] && $avatars_enabled),
+ ));
break;