예제 #1
0
    /**
     * Delete those messages from the database which corresponds to the given condition or to the given ids array
     * Note: the delete cascade arrays are handled!
     *
     * @param string the name of this class
     *   Note: This is required until min phpversion will be 5.3. Since PHP 5.3 we can use static::function_name to achieve late static bindings
     * @param string where condition
     * @param array object ids
     * @return mixed # of rows affected or false if error
     */
    static function db_delete_where($class_name, $sql_where, $object_ids = NULL, $params = NULL)
    {
        global $DB;
        $DB->begin();
        if (!empty($sql_where)) {
            $messages_to_delete = $DB->get_assoc('SELECT msg_ID, msg_thread_ID FROM T_messaging__message WHERE ' . $sql_where);
            $object_ids = array_keys($messages_to_delete);
            $thread_ids_to_delete = array_unique($messages_to_delete);
        }
        if (!$object_ids) {
            // There is no comment to delete
            $DB->commit();
            return;
        }
        $message_ids_to_delete = implode(', ', $object_ids);
        if (empty($thread_ids_to_delete)) {
            // Make sure thread ids of the messages are collected
            $thread_ids_to_delete = $DB->get_col('SELECT msg_thread_ID FROM T_messaging__message WHERE msg_ID IN ( ' . $message_ids_to_delete . ' )');
        }
        // Update thread statuses first unread message IDs
        $result = $DB->query('UPDATE T_messaging__threadstatus
				SET tsta_first_unread_msg_ID =
				( SELECT message1.msg_ID
					FROM T_messaging__message as message1
					WHERE message1.msg_thread_ID = tsta_thread_ID
						AND message1.msg_datetime > ( SELECT MAX( message2.msg_datetime)
							FROM T_messaging__message as message2
							WHERE message2.msg_ID IN ( ' . $message_ids_to_delete . ' )
								AND message2.msg_thread_ID = tsta_thread_ID
						)
					ORDER BY message1.msg_datetime ASC
					LIMIT 1
				)
				WHERE tsta_first_unread_msg_ID IN ( ' . $message_ids_to_delete . ')') !== false;
        if ($result) {
            // Remove messages with all of its delete cascade relations
            $result = parent::db_delete_where($class_name, $sql_where, $object_ids);
        }
        if ($result !== false) {
            // Delete those threads where all of the messages were deleted
            load_class('messaging/model/_thread.class.php', 'Thread');
            $orphan_thread_ids = $DB->get_col('
				SELECT msg_thread_ID FROM T_messaging__message
				WHERE msg_thread_ID IN ( ' . implode(', ', $thread_ids_to_delete) . ' )
				GROUP BY msg_thread_ID
					HAVING COUNT(*) < 1');
            // Delete orphan threads if there are any
            if (!empty($orphan_thread_ids) && Thread::db_delete_where('Thread', NULL, $orphan_thread_ids) === false) {
                // Deleting threads was unsuccessful
                $result = false;
            }
        }
        // Commit or rollback the transaction
        $result !== false ? $DB->commit() : $DB->rollback();
        return $result;
    }
예제 #2
0
/**
 * Delete orphan threads
 *
 * @param integer or array of integers - one or multiple user ids - to delete those orphan threads where only the given user(s) was/were involved, leave it to NULL to delete all orphan threads
 * @return boolean true on success
 */
function delete_orphan_threads($user_ids = NULL)
{
    global $DB;
    $DB->begin();
    if (is_array($user_ids)) {
        $users = implode(', ', $user_ids);
        $in_users_condition = ' OR user_ID IN ( ' . $users . ' )';
        $not_in_users_condition = ' AND user_ID NOT IN ( ' . $users . ' )';
    } else {
        $in_users_condition = is_number($user_ids) ? ' OR user_ID = ' . $user_ids : '';
        $not_in_users_condition = is_number($user_ids) ? ' AND user_ID != ' . $user_ids : '';
    }
    // Get those thread ids which have already deleted participants or which participants will be deleted now
    $affected_threads_ids = $DB->get_col('SELECT DISTINCT tsta_thread_ID
		FROM T_messaging__threadstatus
		LEFT JOIN T_users ON tsta_user_ID = user_ID
		WHERE user_ID IS NULL' . $in_users_condition);
    if (empty($affected_threads_ids)) {
        // There are no affected thread ids, nothing to delete
        $DB->commit();
        return true;
    }
    // Filter previously collected thread ids to get those which have existing users outside of the deleted ones
    $not_orphan_threads = $DB->get_col('SELECT DISTINCT tsta_thread_ID
		FROM T_messaging__threadstatus
		LEFT JOIN T_users ON tsta_user_ID = user_ID
		WHERE tsta_thread_ID IN ( ' . implode(', ', $affected_threads_ids) . ' )
			AND user_ID IS NOT NULL' . $not_in_users_condition);
    // Orphan thread ids are the affected threads minus the ones with existing users
    $orphan_thread_ids = array_diff($affected_threads_ids, $not_orphan_threads);
    if (!empty($orphan_thread_ids)) {
        // There are orphan threads ( or orphan thread targets )
        load_class('messaging/model/_thread.class.php', 'Thread');
        // Delete all orphan threads with all cascade relations
        if (Thread::db_delete_where('Thread', NULL, $orphan_thread_ids, array('use_transaction' => false)) === false) {
            // Deleting orphan threads failed
            $DB->rollback();
            return false;
        }
    }
    $DB->commit();
    return true;
}