Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CUSTDB-804] Better handling of user delete #319

Draft
wants to merge 2 commits into
base: 3.2.x
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions config/services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ services:
- '@dbal.conn'
- '@user'
- '@template'
- '@language'
- '@phpbb.titania.controller.helper'
- '@phpbb.titania.access'
- '@phpbb.titania.contribution.type.collection'
Expand Down
151 changes: 150 additions & 1 deletion event/main_listener.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use phpbb\db\driver\driver_interface as db_driver_interface;
use phpbb\event\data;
use phpbb\auth\auth;
use phpbb\language\language;
use phpbb\template\template;
use phpbb\titania\controller\helper;
use phpbb\titania\ext;
Expand Down Expand Up @@ -44,6 +45,9 @@ class main_listener implements EventSubscriberInterface
/** @var \phpbb\template\template */
protected $template;

/** @var \phpbb\language\language */
protected $language;

/** @var \phpbb\titania\controller\helper */
protected $controller_helper;

Expand Down Expand Up @@ -79,12 +83,13 @@ class main_listener implements EventSubscriberInterface
* @param string $ext_root_path Titania root path
* @param string $php_ext PHP file extension
*/
public function __construct(request $request, db_driver_interface $db, user $user, template $template, helper $controller_helper, access $access, type_collection $types, $phpbb_root_path, $ext_root_path, $php_ext)
public function __construct(request $request, db_driver_interface $db, user $user, template $template, language $language, helper $controller_helper, access $access, type_collection $types, $phpbb_root_path, $ext_root_path, $php_ext)
{
$this->request = $request;
$this->db = $db;
$this->user = $user;
$this->template = $template;
$this->language = $language;
$this->controller_helper = $controller_helper;
$this->access = $access;
$this->types = $types;
Expand All @@ -105,6 +110,10 @@ static public function getSubscribedEvents()
// Check whether a user is removed from a team
'core.group_delete_user_after' => 'remove_users_from_subscription',

// Check whether a user is deleted
'core.acp_users_overview_before' => 'user_delete',
'core.delete_user_before' => 'remove_contributions',

// Include quoted text when private messaging
'core.ucp_pm_compose_predefined_message' => 'quote_text_upon_pm',
);
Expand Down Expand Up @@ -406,4 +415,144 @@ public function quote_text_upon_pm($event)
}
}
}

/**
* Append our message to inform the admin that deleting the user will also delete things in Titania
* @param $event
*/
public function user_delete($event)
{
// Add our message to the end of the existing one
$this->language->add_lang('info_acp_titania', 'phpbb/titania');
$stored_lang = $this->user->lang;
$stored_lang['CONFIRM_OPERATION'] .= ' ' . $stored_lang['CONFIRM_DELETE_USER_OPERATION'];
$this->user->lang = $stored_lang;
}

/**
* Automatically remove topics, posts and contributions when user is deleted
* @param $event
*/
public function remove_contributions($event)
{
if (!defined('TITANIA_CONTRIBS_TABLE'))
{
// Include Titania so we can access the constants
require($this->ext_root_path . 'common.' . $this->php_ext);
}

$event_data = $event->get_data();

// Get rid of the contribs that only have unapproved revisions.
// We'll keep anything that has an approved revision
$this->delete_user_contribs_with_unapproved_revisions($event_data);

// Delete Titania topics and posts by the user(s)
if ($event_data['mode'] === 'remove' || $event_data['mode'] == 'retain')
{
// Handle the topics
$this->delete_user_titania_topics($event_data);

// Handle the posts
$this->delete_user_titania_posts($event_data);
}
}

/**
* Delete contributions by the selected users that only contain unapproved revisions
* @param $event_data
*/
private function delete_user_contribs_with_unapproved_revisions($event_data)
{
// Delete contributions without any approved revisions
$sql_array = array(
'SELECT' => 'c.contrib_id, COUNT(r.revision_id) AS approved_revisions',
'FROM' => array(
TITANIA_CONTRIBS_TABLE => 'c',
),

'LEFT_JOIN' => array(
array(
'FROM' => array(TITANIA_REVISIONS_TABLE => 'r'),
'ON' => 'c.contrib_id = r.contrib_id AND revision_status = ' . ext::TITANIA_REVISION_APPROVED,
),
),

'WHERE' => $this->db->sql_in_set('c.contrib_user_id', $event_data['user_ids']),

'GROUP_BY' => 'c.contrib_id',
);

$sql = $this->db->sql_build_query('SELECT', $sql_array);
$result = $this->db->sql_query($sql);

while ($row = $this->db->sql_fetchrow($result))
{
$contrib_id = (int) $row['contrib_id'];
$approved_revisions = (int) $row['approved_revisions'];

// If there are no approved revisions, then delete the contribution
if ($approved_revisions === 0)
{
$contrib = new \titania_contribution;

if ($contrib->load($contrib_id))
{
// Delete now
$contrib->delete();
}
}
}

$this->db->sql_freeresult($result);
}

/**
* Delete Titania topics by the selected users
* @param $event_data
*/
private function delete_user_titania_topics($event_data)
{
// Delete topics by the user in Titania
$topic = new \titania_topic();

$sql = 'SELECT * FROM ' . TITANIA_TOPICS_TABLE . '
WHERE ' . $this->db->sql_in_set('topic_first_post_user_id', $event_data['user_ids']) . '
AND topic_type = ' . ext::TITANIA_SUPPORT;

$result = $this->db->sql_query($sql);

while ($row = $this->db->sql_fetchrow($result))
{
// Delete each topic created by the to-be deleted user
$topic->__set_array($row);
$topic->delete();
}

$this->db->sql_freeresult($result);
}

/**
* Delete Titania posts by the selected users
* @param $event_data
*/
private function delete_user_titania_posts($event_data)
{
// Delete posts by the user in Titania
$post = new \titania_post();

$sql = 'SELECT * FROM ' . TITANIA_POSTS_TABLE . '
WHERE ' . $this->db->sql_in_set('post_user_id', $event_data['user_ids']) . '
AND post_type = ' . ext::TITANIA_SUPPORT;

$result = $this->db->sql_query($sql);

while ($row = $this->db->sql_fetchrow($result))
{
$post->__set_array($row);
$post->delete();
}

$this->db->sql_freeresult($result);
}
}
2 changes: 2 additions & 0 deletions language/en/info_acp_titania.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@

// Merge the following language entries into the lang array
$lang = array_merge($lang, array(
'CONFIRM_DELETE_USER_OPERATION' => 'This will also remove all Customisation Database posts, topics and unapproved contributions submitted by this user.',

'ROLE_TITANIA_MODIFICATION_TEAM' => 'Titania Modifications Team Role',
'ROLE_TITANIA_STYLE_TEAM' => 'Titania Style Team Role',
'ROLE_TITANIA_MODERATOR_TEAM' => 'Titania Moderation Team Role',
Expand Down