1
0
mirror of https://github.com/phpbb/phpbb.git synced 2025-01-19 07:08:09 +01:00

[ticket/13867] Enable/disable mechanism for new profile field types

Adds methods to enable, disable and purge profile field types to the
profilefields\manager class.  These methods are to be called from
extensions that add new profile field types on the enable, disable
and purge methods of the ext class.  If not done, any profile field
of a new type that is left after extension is disabled or removed will
break the forum in several places.

PHPBB3-13867
This commit is contained in:
javiexin 2015-05-28 22:25:06 +02:00 committed by mrgoldy
parent 3539f9372d
commit 78ea308608
2 changed files with 176 additions and 1 deletions

View File

@ -2,6 +2,7 @@ services:
profilefields.manager:
class: phpbb\profilefields\manager
arguments:
- '@service_container'
- '@auth'
- '@dbal.conn'
- '@dispatcher'

View File

@ -13,11 +13,19 @@
namespace phpbb\profilefields;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Custom Profile Fields
*/
class manager
{
/**
* Container interface
* @var ContainerInterface
*/
protected $container;
/**
* Auth object
* @var \phpbb\auth\auth
@ -68,9 +76,14 @@ class manager
protected $profile_cache = array();
protected $config_text;
protected $db_tools;
/**
* Construct
*
* @param ContainerInterface $container A container
* @param \phpbb\auth\auth $auth Auth object
* @param \phpbb\db\driver\driver_interface $db Database object
* @param \phpbb\event\dispatcher_interface $dispatcher Event dispatcher object
@ -82,8 +95,9 @@ class manager
* @param string $fields_language_table
* @param string $fields_data_table
*/
public function __construct(\phpbb\auth\auth $auth, \phpbb\db\driver\driver_interface $db, \phpbb\event\dispatcher_interface $dispatcher, \phpbb\request\request $request, \phpbb\template\template $template, \phpbb\di\service_collection $type_collection, \phpbb\user $user, $fields_table, $fields_language_table, $fields_data_table)
public function __construct(ContainerInterface $container, \phpbb\auth\auth $auth, \phpbb\db\driver\driver_interface $db, \phpbb\event\dispatcher_interface $dispatcher, \phpbb\request\request $request, \phpbb\template\template $template, \phpbb\di\service_collection $type_collection, \phpbb\user $user, $fields_table, $fields_language_table, $fields_data_table)
{
$this->container = $container;
$this->auth = $auth;
$this->db = $db;
$this->dispatcher = $dispatcher;
@ -95,6 +109,9 @@ class manager
$this->fields_table = $fields_table;
$this->fields_language_table = $fields_language_table;
$this->fields_data_table = $fields_data_table;
$this->config_text = $this->container->get('config_text');
$this->db_tools = $this->container->get('dbal.tools');
}
/**
@ -499,4 +516,161 @@ class manager
return $cp_data;
}
/**
* Disable all profile fields of a certain type
*
* This should be called when an extension which has profile field types
* is disabled so that all those profile fields are hidden and do not
* cause errors
*
* @param string $profilefield_type_name Type identifier of the profile fields
*/
public function disable_profilefields($profilefield_type_name)
{
// Get list of profile fields affected by this operation, if any
$pfs = array();
$sql = 'SELECT field_id, field_ident
FROM ' . PROFILE_FIELDS_TABLE . "
WHERE field_active = 1
AND field_type = '" . $this->db->sql_escape($profilefield_type_name) . "'";
$result = $this->db->sql_query($sql);
while ($row = $this->db->sql_fetchrow($result))
{
$pfs[(int) $row['field_id']] = $row['field_ident'];
}
$this->db->sql_freeresult($result);
// If no profile fields affected, then nothing to do
if (!sizeof($pfs))
{
return;
}
// Update the affected profile fields to "inactive"
$sql = 'UPDATE ' . PROFILE_FIELDS_TABLE . "
SET field_active = 0
WHERE field_active = 1
AND field_type = '" . $this->db->sql_escape($profilefield_type_name) . "'";
$this->db->sql_query($sql);
// Save modified information into a config_text field to recover on enable
$this->config_text->set($profilefield_type_name . '.saved', base64_encode(serialize($pfs)));
// Log activity
foreach ($pfs as $field_ident)
{
add_log('admin', 'LOG_PROFILE_FIELD_DEACTIVATE', $field_ident);
}
}
/**
* Purge all profile fields of a certain type
*
* This should be called when an extension which has profile field types
* is purged so that all those profile fields are removed
*
* @param string $profilefield_type_name Type identifier of the profile fields
*/
public function purge_profilefields($profilefield_type_name)
{
// Remove the information saved on disable in a config_text field, not needed any longer
$this->config_text->delete($profilefield_type_name . '.saved');
// Get list of profile fields affected by this operation, if any
$pfs = array();
$sql = 'SELECT field_id, field_ident
FROM ' . PROFILE_FIELDS_TABLE . "
WHERE field_type = '" . $this->db->sql_escape($profilefield_type_name) . "'";
$result = $this->db->sql_query($sql);
while ($row = $this->db->sql_fetchrow($result))
{
$pfs[(int) $row['field_id']] = $row['field_ident'];
}
$this->db->sql_freeresult($result);
// If no profile fields exist, then nothing to do
if (!sizeof($pfs))
{
return;
}
$this->db->sql_transaction('begin');
// Delete entries from all profile field definition tables
$where = $this->db->sql_in_set('field_id', array_keys($pfs));
$this->db->sql_query('DELETE FROM ' . PROFILE_FIELDS_TABLE . ' WHERE ' . $where);
$this->db->sql_query('DELETE FROM ' . PROFILE_FIELDS_LANG_TABLE . ' WHERE ' . $where);
$this->db->sql_query('DELETE FROM ' . PROFILE_LANG_TABLE . ' WHERE ' . $where);
// Drop columns from the Profile Fields data table
foreach ($pfs as $field_ident)
{
$this->db_tools->sql_column_remove(PROFILE_FIELDS_DATA_TABLE, 'pf_' . $field_ident);
}
// Reset the order of the remaining fields
$order = 0;
$sql = 'SELECT *
FROM ' . PROFILE_FIELDS_TABLE . '
ORDER BY field_order';
$result = $this->db->sql_query($sql);
while ($row = $this->db->sql_fetchrow($result))
{
$order++;
if ($row['field_order'] != $order)
{
$sql = 'UPDATE ' . PROFILE_FIELDS_TABLE . "
SET field_order = $order
WHERE field_id = {$row['field_id']}";
$this->db->sql_query($sql);
}
}
$this->db->sql_freeresult($result);
$this->db->sql_transaction('commit');
// Log activity
foreach ($pfs as $field_ident)
{
add_log('admin', 'LOG_PROFILE_FIELD_REMOVED', $field_ident);
}
}
/**
* Enable the profile fields of a certain type
*
* This should be called when an extension which has profile field types
* that was disabled is re-enabled so that all those profile fields that
* were disabled are enabled again
*
* @param string $profilefield_type_name Type identifier of the profile fields
*/
public function enable_profilefields($profilefield_type_name)
{
// Read the modified information saved on disable from a config_text field to recover values, then remove it
$pfs = $this->config_text->get($profilefield_type_name . '.saved');
$this->config_text->delete($profilefield_type_name . '.saved');
// If nothing saved, then nothing to do
if ($pfs == '')
{
return;
}
$pfs = unserialize(base64_decode($pfs));
// Restore the affected profile fields to "active"
$sql = 'UPDATE ' . PROFILE_FIELDS_TABLE . "
SET field_active = 1
WHERE field_active = 0
AND " . $this->db->sql_in_set('field_id', array_keys($pfs));
$this->db->sql_query($sql);
foreach ($pfs as $field_ident)
{
add_log('admin', 'LOG_PROFILE_FIELD_ACTIVATE', $field_ident);
}
}
}