Esempio n. 1
0
 /**
  * Get the diff for the sum of a question for all choices of a specific text
  * $sign is either 1 or -1
  *
  * @param int $question_id
  * @param string $sign
  * @param string $value
  * @param array $cdiff
  */
 protected function get_choice_sum_diff_for_answer($question_id, $value, $sign, &$cdiff)
 {
     $exploded_answers = '';
     if ($this->questions[$question_id]['type'] == self::$QUESTION_TYPES['MULTIPLE_CHOICE']) {
         $exploded_answers = explode(",", utf8_case_fold_nfc($value));
     }
     foreach ($this->questions[$question_id]['choices'] as $choice_id => $choice) {
         if ($this->questions[$question_id]['type'] == self::$QUESTION_TYPES['MULTIPLE_CHOICE']) {
             $cdiff[$choice_id] += in_array(utf8_case_fold_nfc($choice['text']), $exploded_answers) ? $sign : 0;
         } else {
             $cdiff[$choice_id] += utf8_case_fold_nfc($choice['text']) == utf8_case_fold_nfc($value) ? $sign : 0;
         }
     }
 }
Esempio n. 2
0
    function main($id, $mode)
    {
        global $db, $user, $auth, $template, $config, $phpbb_root_path, $phpEx, $phpbb_log, $phpbb_container, $table_prefix, $request;
        $user->add_lang_ext('phpbbservices/digests', array('info_acp_common'));
        $submit = isset($_POST['submit']) ? true : false;
        $form_key = 'phpbbservices/digests';
        add_form_key($form_key);
        /**
         *	Validation types are:
         *		string, int, bool,
         *		script_path (absolute path in url - beginning with / and no trailing slash),
         *		rpath (relative), rwpath (realtive, writable), path (relative path, but able to escape the root), wpath (writable)
         */
        switch ($mode) {
            case 'digests_general':
                $display_vars = array('title' => 'ACP_DIGESTS_GENERAL_SETTINGS', 'vars' => array('legend1' => '', 'phpbbservices_digests_enable_log' => array('lang' => 'DIGESTS_ENABLE_LOG', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'phpbbservices_digests_show_email' => array('lang' => 'DIGESTS_SHOW_EMAIL', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'phpbbservices_digests_enable_auto_subscriptions' => array('lang' => 'DIGESTS_ENABLE_AUTO_SUBSCRIPTIONS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'phpbbservices_digests_registration_field' => array('lang' => 'DIGESTS_REGISTRATION_FIELD', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'phpbbservices_digests_block_images' => array('lang' => 'DIGESTS_BLOCK_IMAGES', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'phpbbservices_digests_notify_on_admin_changes' => array('lang' => 'DIGESTS_NOTIFY_ON_ADMIN_CHANGES', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'phpbbservices_digests_weekly_digest_day' => array('lang' => 'DIGESTS_WEEKLY_DIGESTS_DAY', 'validate' => 'int:0:6', 'type' => 'select', 'method' => 'dow_select', 'explain' => false), 'phpbbservices_digests_max_items' => array('lang' => 'DIGESTS_MAX_ITEMS', 'validate' => 'int:0', 'type' => 'text:5:5', 'explain' => true), 'phpbbservices_digests_enable_custom_stylesheets' => array('lang' => 'DIGESTS_ENABLE_CUSTOM_STYLESHEET', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'phpbbservices_digests_custom_stylesheet_path' => array('lang' => 'DIGESTS_CUSTOM_STYLESHEET_PATH', 'validate' => 'string', 'type' => 'text:40:255', 'explain' => true), 'phpbbservices_digests_from_email_address' => array('lang' => 'DIGESTS_FROM_EMAIL_ADDRESS', 'validate' => 'string', 'type' => 'text:40:255', 'explain' => true), 'phpbbservices_digests_from_email_name' => array('lang' => 'DIGESTS_FROM_EMAIL_NAME', 'validate' => 'string', 'type' => 'text:40:255', 'explain' => true), 'phpbbservices_digests_reply_to_email_address' => array('lang' => 'DIGESTS_REPLY_TO_EMAIL_ADDRESS', 'validate' => 'string', 'type' => 'text:40:255', 'explain' => true), 'phpbbservices_digests_users_per_page' => array('lang' => 'DIGESTS_USERS_PER_PAGE', 'validate' => 'int:0', 'type' => 'text:4:4', 'explain' => true), 'phpbbservices_digests_include_forums' => array('lang' => 'DIGESTS_INCLUDE_FORUMS', 'validate' => 'string', 'type' => 'text:15:255', 'explain' => true), 'phpbbservices_digests_exclude_forums' => array('lang' => 'DIGESTS_EXCLUDE_FORUMS', 'validate' => 'string', 'type' => 'text:15:255', 'explain' => true), 'phpbbservices_digests_time_zone' => array('lang' => 'DIGESTS_TIME_ZONE', 'validate' => 'int:-12:12', 'type' => 'text:5:5', 'explain' => true)));
                break;
            case 'digests_user_defaults':
                $display_vars = array('title' => 'ACP_DIGESTS_USER_DEFAULT_SETTINGS', 'vars' => array('legend1' => '', 'phpbbservices_digests_user_digest_registration' => array('lang' => 'DIGESTS_USER_DIGESTS_REGISTRATION', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'phpbbservices_digests_user_digest_type' => array('lang' => 'DIGESTS_USER_DIGESTS_TYPE', 'validate' => 'string', 'type' => 'select', 'method' => 'digest_type_select', 'explain' => false), 'phpbbservices_digests_user_digest_format' => array('lang' => 'DIGESTS_USER_DIGESTS_STYLE', 'validate' => 'string', 'type' => 'select', 'method' => 'digest_style_select', 'explain' => false), 'phpbbservices_digests_user_digest_send_hour_gmt' => array('lang' => 'DIGESTS_USER_DIGESTS_SEND_HOUR_GMT', 'validate' => 'int:-1:23', 'type' => 'select', 'method' => 'digest_send_hour_gmt', 'explain' => false), 'phpbbservices_digests_user_digest_filter_type' => array('lang' => 'DIGESTS_USER_DIGESTS_FILTER_TYPE', 'validate' => 'string', 'type' => 'select', 'method' => 'digest_filter_type', 'explain' => false), 'phpbbservices_digests_user_check_all_forums' => array('lang' => 'DIGESTS_USER_DIGESTS_CHECK_ALL_FORUMS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'phpbbservices_digests_user_digest_max_posts' => array('lang' => 'DIGESTS_USER_DIGESTS_MAX_POSTS', 'validate' => 'int:0', 'type' => 'text:5:5', 'explain' => true), 'phpbbservices_digests_user_digest_min_words' => array('lang' => 'DIGESTS_USER_DIGESTS_MIN_POSTS', 'validate' => 'int:0', 'type' => 'text:5:5', 'explain' => true), 'phpbbservices_digests_user_digest_new_posts_only' => array('lang' => 'DIGESTS_USER_DIGESTS_NEW_POSTS_ONLY', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'phpbbservices_digests_user_digest_show_mine' => array('lang' => 'DIGESTS_USER_DIGESTS_SHOW_MINE', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'phpbbservices_digests_user_digest_remove_foes' => array('lang' => 'DIGESTS_USER_DIGESTS_SHOW_FOES', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'phpbbservices_digests_user_digest_show_pms' => array('lang' => 'DIGESTS_USER_DIGESTS_SHOW_PMS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'phpbbservices_digests_user_digest_pm_mark_read' => array('lang' => 'DIGESTS_USER_DIGESTS_PM_MARK_READ', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'phpbbservices_digests_user_digest_sortby' => array('lang' => 'DIGESTS_USER_DIGESTS_SORT_ORDER', 'validate' => 'string', 'type' => 'select', 'method' => 'digest_post_sort_order', 'explain' => false), 'phpbbservices_digests_user_digest_max_display_words' => array('lang' => 'DIGESTS_USER_DIGESTS_MAX_DISPLAY_WORDS', 'validate' => 'int:-1', 'type' => 'text:5:5', 'explain' => true), 'phpbbservices_digests_user_digest_send_on_no_posts' => array('lang' => 'DIGESTS_USER_DIGESTS_SEND_ON_NO_POSTS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'phpbbservices_digests_user_digest_reset_lastvisit' => array('lang' => 'DIGESTS_USER_DIGESTS_RESET_LASTVISIT', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'phpbbservices_digests_user_digest_attachments' => array('lang' => 'DIGESTS_USER_DIGESTS_ATTACHMENTS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'phpbbservices_digests_user_digest_block_images' => array('lang' => 'DIGESTS_USER_DIGESTS_BLOCK_IMAGES', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'phpbbservices_digests_user_digest_toc' => array('lang' => 'DIGESTS_USER_DIGESTS_TOC', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false)));
                break;
            case 'digests_edit_subscribers':
                $display_vars = array('title' => 'ACP_DIGESTS_EDIT_SUBSCRIBERS', 'vars' => array('legend1' => ''));
                // Grab some URL parameters
                $member = $request->variable('member', '', true);
                $start = $request->variable('start', 0);
                $subscribe = $request->variable('subscribe', 'a', true);
                $sortby = $request->variable('sortby', 'u', true);
                $sortorder = $request->variable('sortorder', 'a', true);
                // Translate time zone information
                $template->assign_vars(array('L_DIGESTS_HOUR_SENT' => $user->lang('DIGESTS_HOUR_SENT', $config['phpbbservices_digests_time_zone']), 'L_DIGESTS_BASED_ON' => $user->lang('DIGESTS_BASED_ON', $config['phpbbservices_digests_time_zone']), 'S_EDIT_SUBSCRIBERS' => true));
                // Set up subscription filter
                $all_selected = $stopped_subscribing = $subscribe_selected = $unsubscribe_selected = '';
                switch ($subscribe) {
                    case 'u':
                        $subscribe_sql = "user_digest_type = 'NONE' AND user_digest_has_unsubscribed = 0 AND ";
                        $unsubscribe_selected = ' selected="selected"';
                        $context = $user->lang('DIGESTS_UNSUBSCRIBED');
                        break;
                    case 't':
                        $subscribe_sql = "user_digest_type = 'NONE' AND user_digest_has_unsubscribed = 1 AND";
                        $stopped_subscribing = ' selected="selected"';
                        $context = $user->lang('DIGESTS_STOPPED_SUBSCRIBING');
                        break;
                    case 's':
                        $subscribe_sql = "user_digest_type <> 'NONE' AND user_digest_send_hour_gmt >= 0 AND user_digest_send_hour_gmt < 24 AND user_digest_has_unsubscribed = 0 AND";
                        $subscribe_selected = ' selected="selected"';
                        $context = $user->lang('DIGESTS_SUBSCRIBED');
                        break;
                    case 'a':
                    default:
                        $subscribe_sql = '';
                        $all_selected = ' selected="selected"';
                        $context = $user->lang('DIGESTS_ALL');
                        break;
                }
                // Set up sort by column
                $last_sent_selected = $has_unsubscribed_selected = $username_selected = $frequency_selected = $format_selected = $hour_selected = $lastvisit_selected = $email_selected = '';
                switch ($sortby) {
                    case 'f':
                        $sort_by_sql = 'user_digest_type %s, lower(username) %s';
                        $frequency_selected = ' selected="selected"';
                        break;
                    case 'e':
                        $sort_by_sql = 'user_email %s, lower(username) %s';
                        $email_selected = ' selected="selected"';
                        break;
                    case 's':
                        $sort_by_sql = 'user_digest_format %s, lower(username) %s';
                        $format_selected = ' selected="selected"';
                        break;
                    case 'h':
                        $sort_by_sql = 'send_hour_board %s, lower(username) %s';
                        $hour_selected = ' selected="selected"';
                        break;
                    case 'l':
                        $sort_by_sql = 'user_lastvisit %s, lower(username) %s';
                        $lastvisit_selected = ' selected="selected"';
                        break;
                    case 'b':
                        $sort_by_sql = 'user_digest_has_unsubscribed %s, lower(username) %s';
                        $has_unsubscribed_selected = ' selected="selected"';
                        break;
                    case 't':
                        $sort_by_sql = 'user_digest_last_sent %s, lower(username) %s';
                        $last_sent_selected = ' selected="selected"';
                        break;
                    case 'u':
                    default:
                        $sort_by_sql = 'lower(username) %s';
                        $username_selected = ' selected="selected"';
                        break;
                }
                // Set up sort order
                $ascending_selected = $descending_selected = '';
                switch ($sortorder) {
                    case 'd':
                        $order_by_sql = 'DESC';
                        $descending_selected = ' selected="selected"';
                        break;
                    case 'a':
                    default:
                        $order_by_sql = 'ASC';
                        $ascending_selected = ' selected="selected"';
                        break;
                }
                // Set up member search SQL
                $match_any_chars = $db->get_any_char();
                $member_sql = $member != '' ? " username_clean " . $db->sql_like_expression($match_any_chars . utf8_case_fold_nfc($member) . $match_any_chars) . " AND " : '';
                // Get the total rows for pagination purposes
                $sql_array = array('SELECT' => 'count(*) AS total_users', 'FROM' => array(USERS_TABLE => 'u'), 'WHERE' => "{$subscribe_sql} {$member_sql} user_type <> " . USER_IGNORE);
                $sql = $db->sql_build_query('SELECT', $sql_array);
                $result = $db->sql_query($sql);
                // Get the total users, this is a single row, single field.
                $total_users = $db->sql_fetchfield('total_users');
                // Free the result
                $db->sql_freeresult($result);
                // Create pagination logic
                $pagination = $phpbb_container->get('pagination');
                $base_url = "index.php?i=-phpbbservices-digests-acp-main_module&amp;mode=digests_edit_subscribers&amp;sortby={$sortby}";
                $base_url = append_sid($base_url);
                $pagination->generate_template_pagination($base_url, 'pagination', 'start', $total_users, $config['phpbbservices_digests_users_per_page'], $start);
                // Stealing some code from my Smartfeed extension so I can get a list of forums that a particular user can access
                // We need to know which auth_option_id corresponds to the forum read privilege (f_read) and forum list (f_list) privilege.
                $auth_options = array('f_read', 'f_list');
                $sql_array = array('SELECT' => 'auth_option, auth_option_id', 'FROM' => array(ACL_OPTIONS_TABLE => 'o'), 'WHERE' => $db->sql_in_set('auth_option', $auth_options));
                $sql = $db->sql_build_query('SELECT', $sql_array);
                $result = $db->sql_query($sql);
                $read_id = '';
                while ($row = $db->sql_fetchrow($result)) {
                    if ($row['auth_option'] == 'f_read') {
                        $read_id = $row['auth_option_id'];
                    }
                }
                $db->sql_freeresult($result);
                // Query be gone!
                // Fill in some non-block template variables
                $template->assign_vars(array('ALL_SELECTED' => $all_selected, 'ASCENDING_SELECTED' => $ascending_selected, 'DESCENDING_SELECTED' => $descending_selected, 'DIGESTS_HTML_VALUE' => constants::DIGESTS_HTML_VALUE, 'DIGESTS_HTML_CLASSIC_VALUE' => constants::DIGESTS_HTML_CLASSIC_VALUE, 'DIGESTS_PLAIN_VALUE' => constants::DIGESTS_PLAIN_VALUE, 'DIGESTS_PLAIN_CLASSIC_VALUE' => constants::DIGESTS_PLAIN_CLASSIC_VALUE, 'DIGESTS_FORMAT_TEXT_VALUE' => constants::DIGESTS_TEXT_VALUE, 'EMAIL_SELECTED' => $email_selected, 'FORMAT_SELECTED' => $format_selected, 'FREQUENCY_SELECTED' => $frequency_selected, 'HAS_UNSUBSCRIBED_SELECTED' => $has_unsubscribed_selected, 'HOUR_SELECTED' => $hour_selected, 'IMAGE_PATH' => $phpbb_root_path . 'ext/phpbbservices/digests/adm/images/', 'LAST_SENT_SELECTED' => $last_sent_selected, 'LASTVISIT_SELECTED' => $lastvisit_selected, 'L_CONTEXT' => $context, 'MEMBER' => $member, 'STOPPED_SUBSCRIBING_SELECTED' => $stopped_subscribing, 'SUBSCRIBE_SELECTED' => $subscribe_selected, 'TOTAL_USERS' => $user->lang('DIGESTS_LIST_USERS', (int) $total_users), 'UNSUBSCRIBE_SELECTED' => $unsubscribe_selected, 'USERNAME_SELECTED' => $username_selected));
                $board_offset_hours = (int) $config['phpbbservices_digests_time_zone'];
                $sql_array = array('SELECT' => '*, CASE
										WHEN user_digest_send_hour_gmt + ' . $board_offset_hours . ' >= 24 THEN
						 					user_digest_send_hour_gmt + ' . $board_offset_hours . ' - 24  
										WHEN user_digest_send_hour_gmt + ' . $board_offset_hours . ' < 0 THEN
						 					user_digest_send_hour_gmt + ' . $board_offset_hours . ' + 24 
										ELSE user_digest_send_hour_gmt + ' . $board_offset_hours . '
										END AS send_hour_board', 'FROM' => array(USERS_TABLE => 'u'), 'WHERE' => "{$subscribe_sql} {$member_sql} user_type <> " . USER_IGNORE, 'ORDER_BY' => sprintf($sort_by_sql, $order_by_sql, $order_by_sql));
                $sql = $db->sql_build_query('SELECT', $sql_array);
                $result = $db->sql_query_limit($sql, $config['phpbbservices_digests_users_per_page'], $start);
                while ($row = $db->sql_fetchrow($result)) {
                    // Make some translations into something more readable
                    switch ($row['user_digest_type']) {
                        case 'DAY':
                            $digest_type = $user->lang('DIGESTS_DAILY');
                            break;
                        case 'WEEK':
                            $digest_type = $user->lang('DIGESTS_WEEKLY');
                            break;
                        case 'MNTH':
                            $digest_type = $user->lang('DIGESTS_MONTHLY');
                            break;
                        default:
                            $digest_type = $user->lang('DIGESTS_UNKNOWN');
                            break;
                    }
                    switch ($row['user_digest_format']) {
                        case constants::DIGESTS_HTML_VALUE:
                            $digest_format = $user->lang('DIGESTS_FORMAT_HTML');
                            break;
                        case constants::DIGESTS_HTML_CLASSIC_VALUE:
                            $digest_format = $user->lang('DIGESTS_FORMAT_HTML_CLASSIC');
                            break;
                        case constants::DIGESTS_PLAIN_VALUE:
                            $digest_format = $user->lang('DIGESTS_FORMAT_PLAIN');
                            break;
                        case constants::DIGESTS_PLAIN_CLASSIC_VALUE:
                            $digest_format = $user->lang('DIGESTS_FORMAT_PLAIN_CLASSIC');
                            break;
                        case constants::DIGESTS_TEXT_VALUE:
                            $digest_format = $user->lang('DIGESTS_FORMAT_TEXT');
                            break;
                        default:
                            $digest_format = $user->lang('DIGESTS_UNKNOWN');
                            break;
                    }
                    // Calculate a digest send hour in board time
                    $send_hour_board = str_replace('.', ':', floor($row['user_digest_send_hour_gmt']) + $board_offset_hours);
                    if ($send_hour_board >= 24) {
                        $send_hour_board = $send_hour_board - 24;
                    } else {
                        if ($send_hour_board < 0) {
                            $send_hour_board = $send_hour_board + 24;
                        }
                    }
                    // Create an array of GMT offsets from board time zone
                    $board_offset = array();
                    for ($i = 0; $i < 24; $i++) {
                        if ($i - $board_offset_hours < 0) {
                            $board_offset[$i] = $i - $board_offset_hours + 24;
                        } else {
                            if ($i - $board_offset_hours > 23) {
                                $board_offset[$i] = $i - $board_offset_hours - 24;
                            } else {
                                $board_offset[$i] = $i - $board_offset_hours;
                            }
                        }
                    }
                    $sql_array = array('SELECT' => 'forum_id ', 'FROM' => array($table_prefix . constants::DIGESTS_SUBSCRIBED_FORUMS_TABLE => 'sf'), 'WHERE' => 'user_id = ' . (int) $row['user_id']);
                    $sql2 = $db->sql_build_query('SELECT', $sql_array);
                    $result2 = $db->sql_query($sql2);
                    $subscribed_forums = $db->sql_fetchrowset($result2);
                    $db->sql_freeresult();
                    $all_by_default = sizeof($subscribed_forums) == 0 ? true : false;
                    $template->assign_block_vars('digests_edit_subscribers', array('1ST' => $row['user_digest_filter_type'] == constants::DIGESTS_FIRST, 'ALL' => $row['user_digest_filter_type'] == constants::DIGESTS_ALL, 'BM' => $row['user_digest_filter_type'] == constants::DIGESTS_BOOKMARKS, 'BOARD_OFFSET_0' => $board_offset[0], 'BOARD_OFFSET_1' => $board_offset[1], 'BOARD_OFFSET_2' => $board_offset[2], 'BOARD_OFFSET_3' => $board_offset[3], 'BOARD_OFFSET_4' => $board_offset[4], 'BOARD_OFFSET_5' => $board_offset[5], 'BOARD_OFFSET_6' => $board_offset[6], 'BOARD_OFFSET_7' => $board_offset[7], 'BOARD_OFFSET_8' => $board_offset[8], 'BOARD_OFFSET_9' => $board_offset[9], 'BOARD_OFFSET_10' => $board_offset[10], 'BOARD_OFFSET_11' => $board_offset[11], 'BOARD_OFFSET_12' => $board_offset[12], 'BOARD_OFFSET_13' => $board_offset[13], 'BOARD_OFFSET_14' => $board_offset[14], 'BOARD_OFFSET_15' => $board_offset[15], 'BOARD_OFFSET_16' => $board_offset[16], 'BOARD_OFFSET_17' => $board_offset[17], 'BOARD_OFFSET_18' => $board_offset[18], 'BOARD_OFFSET_19' => $board_offset[19], 'BOARD_OFFSET_20' => $board_offset[20], 'BOARD_OFFSET_21' => $board_offset[21], 'BOARD_OFFSET_22' => $board_offset[22], 'BOARD_OFFSET_23' => $board_offset[23], 'DIGEST_MAX_SIZE' => $row['user_digest_max_display_words'], 'L_DIGEST_CHANGE_SUBSCRIPTION' => $row['user_digest_type'] != 'NONE' ? $user->lang('DIGESTS_UNSUBSCRIBE') : $user->lang('DIGESTS_SUBSCRIBE_LITERAL'), 'S_ALL_BY_DEFAULT' => $all_by_default, 'S_ATTACHMENTS_NO_CHECKED' => $row['user_digest_attachments'] == 0, 'S_ATTACHMENTS_YES_CHECKED' => $row['user_digest_attachments'] == 1, 'S_BLOCK_IMAGES_NO_CHECKED' => $row['user_digest_block_images'] == 0, 'S_BLOCK_IMAGES_YES_CHECKED' => $row['user_digest_block_images'] == 1, 'S_BOARD_SELECTED' => $row['user_digest_sortby'] == constants::DIGESTS_SORTBY_BOARD, 'S_DIGEST_FILTER_FOES_CHECKED_NO' => $row['user_digest_remove_foes'] == 0, 'S_DIGEST_FILTER_FOES_CHECKED_YES' => $row['user_digest_remove_foes'] == 1, 'S_DIGEST_DAY_CHECKED' => $row['user_digest_type'] == constants::DIGESTS_DAILY_VALUE, 'S_DIGEST_HTML_CHECKED' => $row['user_digest_format'] == constants::DIGESTS_HTML_VALUE, 'S_DIGEST_HTML_CLASSIC_CHECKED' => $row['user_digest_format'] == constants::DIGESTS_HTML_CLASSIC_VALUE, 'S_DIGEST_MONTH_CHECKED' => $row['user_digest_type'] == constants::DIGESTS_MONTHLY_VALUE, 'S_DIGEST_NEW_POSTS_ONLY_CHECKED_NO' => $row['user_digest_new_posts_only'] == 0, 'S_DIGEST_NEW_POSTS_ONLY_CHECKED_YES' => $row['user_digest_new_posts_only'] == 1, 'S_DIGEST_NONE_CHECKED' => $row['user_digest_type'] == constants::DIGESTS_NONE_VALUE, 'S_DIGEST_NO_POST_TEXT_CHECKED_NO' => $row['user_digest_no_post_text'] == 0, 'S_DIGEST_NO_POST_TEXT_CHECKED_YES' => $row['user_digest_no_post_text'] == 1, 'S_DIGEST_PLAIN_CHECKED' => $row['user_digest_format'] == constants::DIGESTS_PLAIN_VALUE, 'S_DIGEST_PLAIN_CLASSIC_CHECKED' => $row['user_digest_format'] == constants::DIGESTS_PLAIN_CLASSIC_VALUE, 'S_DIGEST_PM_MARK_READ_CHECKED_NO' => $row['user_digest_pm_mark_read'] == 0, 'S_DIGEST_PM_MARK_READ_CHECKED_YES' => $row['user_digest_pm_mark_read'] == 1, 'S_DIGEST_POST_ANY' => $row['user_digest_filter_type'] == constants::DIGESTS_ALL, 'S_DIGEST_POST_BM' => $row['user_digest_filter_type'] == constants::DIGESTS_BOOKMARKS, 'S_DIGEST_POST_FIRST' => $row['user_digest_filter_type'] == constants::DIGESTS_FIRST, 'S_DIGEST_PRIVATE_MESSAGES_IN_DIGEST_NO' => $row['user_digest_show_pms'] == 0, 'S_DIGEST_PRIVATE_MESSAGES_IN_DIGEST_YES' => $row['user_digest_show_pms'] == 1, 'S_DIGEST_SEND_HOUR_0_CHECKED' => $send_hour_board == 0, 'S_DIGEST_SEND_HOUR_1_CHECKED' => $send_hour_board == 1, 'S_DIGEST_SEND_HOUR_2_CHECKED' => $send_hour_board == 2, 'S_DIGEST_SEND_HOUR_3_CHECKED' => $send_hour_board == 3, 'S_DIGEST_SEND_HOUR_4_CHECKED' => $send_hour_board == 4, 'S_DIGEST_SEND_HOUR_5_CHECKED' => $send_hour_board == 5, 'S_DIGEST_SEND_HOUR_6_CHECKED' => $send_hour_board == 6, 'S_DIGEST_SEND_HOUR_7_CHECKED' => $send_hour_board == 7, 'S_DIGEST_SEND_HOUR_8_CHECKED' => $send_hour_board == 8, 'S_DIGEST_SEND_HOUR_9_CHECKED' => $send_hour_board == 9, 'S_DIGEST_SEND_HOUR_10_CHECKED' => $send_hour_board == 10, 'S_DIGEST_SEND_HOUR_11_CHECKED' => $send_hour_board == 11, 'S_DIGEST_SEND_HOUR_12_CHECKED' => $send_hour_board == 12, 'S_DIGEST_SEND_HOUR_13_CHECKED' => $send_hour_board == 13, 'S_DIGEST_SEND_HOUR_14_CHECKED' => $send_hour_board == 14, 'S_DIGEST_SEND_HOUR_15_CHECKED' => $send_hour_board == 15, 'S_DIGEST_SEND_HOUR_16_CHECKED' => $send_hour_board == 16, 'S_DIGEST_SEND_HOUR_17_CHECKED' => $send_hour_board == 17, 'S_DIGEST_SEND_HOUR_18_CHECKED' => $send_hour_board == 18, 'S_DIGEST_SEND_HOUR_19_CHECKED' => $send_hour_board == 19, 'S_DIGEST_SEND_HOUR_20_CHECKED' => $send_hour_board == 20, 'S_DIGEST_SEND_HOUR_21_CHECKED' => $send_hour_board == 21, 'S_DIGEST_SEND_HOUR_22_CHECKED' => $send_hour_board == 22, 'S_DIGEST_SEND_HOUR_23_CHECKED' => $send_hour_board == 23, 'S_DIGEST_SEND_ON_NO_POSTS_NO_CHECKED' => $row['user_digest_send_on_no_posts'] == 0, 'S_DIGEST_SEND_ON_NO_POSTS_YES_CHECKED' => $row['user_digest_send_on_no_posts'] == 1, 'S_DIGEST_SHOW_MINE_CHECKED_YES' => $row['user_digest_show_mine'] == 1, 'S_DIGEST_SHOW_MINE_CHECKED_NO' => $row['user_digest_show_mine'] == 0, 'S_DIGEST_TEXT_CHECKED' => $row['user_digest_format'] == constants::DIGESTS_TEXT_VALUE, 'S_DIGEST_WEEK_CHECKED' => $row['user_digest_type'] == constants::DIGESTS_WEEKLY_VALUE, 'S_LASTVISIT_NO_CHECKED' => $row['user_digest_reset_lastvisit'] == 0, 'S_LASTVISIT_YES_CHECKED' => $row['user_digest_reset_lastvisit'] == 1, 'S_POSTDATE_DESC_SELECTED' => $row['user_digest_sortby'] == constants::DIGESTS_SORTBY_POSTDATE_DESC, 'S_POSTDATE_SELECTED' => $row['user_digest_sortby'] == constants::DIGESTS_SORTBY_POSTDATE, 'S_STANDARD_DESC_SELECTED' => $row['user_digest_sortby'] == constants::DIGESTS_SORTBY_STANDARD_DESC, 'S_STANDARD_SELECTED' => $row['user_digest_sortby'] == constants::DIGESTS_SORTBY_STANDARD, 'S_TOC_NO_CHECKED' => $row['user_digest_toc'] == 0, 'S_TOC_YES_CHECKED' => $row['user_digest_toc'] == 1, 'USERNAME' => $row['username'], 'USER_DIGEST_FORMAT' => $digest_format, 'USER_DIGEST_HAS_UNSUBSCRIBED' => $row['user_digest_has_unsubscribed'] ? 'x' : '-', 'USER_DIGEST_LAST_SENT' => $row['user_digest_last_sent'] == 0 ? $user->lang('DIGESTS_NO_DIGESTS_SENT') : date($config['default_dateformat'], $row['user_digest_last_sent'] + 60 * 60 * ($config['phpbbservices_digests_time_zone'] - date('O') / 100)), 'USER_DIGEST_MAX_DISPLAY_WORDS' => $row['user_digest_max_display_words'], 'USER_DIGEST_MAX_POSTS' => $row['user_digest_max_posts'], 'USER_DIGEST_MIN_WORDS' => $row['user_digest_min_words'], 'USER_DIGEST_TYPE' => $digest_type, 'USER_EMAIL' => $row['user_email'], 'USER_ID' => $row['user_id'], 'USER_LAST_VISIT' => $row['user_lastvisit'] == 0 ? $user->lang('DIGESTS_NEVER_VISITED') : date($config['default_dateformat'], $row['user_lastvisit'] + 60 * 60 * ($config['phpbbservices_digests_time_zone'] - date('O') / 100)), 'USER_SUBSCRIBE_UNSUBSCRIBE_FLAG' => $row['user_digest_type'] != 'NONE' ? 'u' : 's'));
                    // Now let's get this user's forum permissions. Note that non-registered, robots etc. get a list of public forums
                    // with read permissions.
                    unset($allowed_forums, $forum_array, $parent_stack);
                    $forum_array = $auth->acl_raw_data_single_user($row['user_id']);
                    foreach ($forum_array as $key => $value) {
                        foreach ($value as $auth_option_id => $auth_setting) {
                            if ($auth_option_id == $read_id) {
                                if ($auth_setting == 1) {
                                    $allowed_forums[] = $key;
                                }
                            }
                        }
                    }
                    // Now we will display the forums that this user can read, as well as any parent forums, checking those if any that
                    // the user has subscribed to.
                    if (isset($allowed_forums)) {
                        $sql_array = array('SELECT' => 'forum_name, forum_id, parent_id, forum_type', 'FROM' => array(FORUMS_TABLE => 'f'), 'WHERE' => $db->sql_in_set('forum_id', $allowed_forums) . ' AND forum_type <> ' . FORUM_LINK . "\n\t\t\t\t\t\t\t\t\tAND forum_password = ''", 'ORDER_BY' => 'left_id ASC');
                        $sql2 = $db->sql_build_query('SELECT', $sql_array);
                        $result2 = $db->sql_query($sql2);
                        $current_level = 0;
                        // How deeply nested are we at the moment
                        $parent_stack = array();
                        // Holds a stack showing the current parent_id of the forum
                        $parent_stack[] = 0;
                        // 0, the first value in the stack, represents the <div_0> element, a container holding all the categories and forums in the template
                        while ($row2 = $db->sql_fetchrow($result2)) {
                            if ((int) $row2['parent_id'] != (int) end($parent_stack) || end($parent_stack) == 0) {
                                if (in_array($row2['parent_id'], $parent_stack)) {
                                    // If parent is in the stack, then pop the stack until the parent is found, otherwise push stack adding the current parent. This creates a </div>
                                    while ((int) $row2['parent_id'] != (int) end($parent_stack)) {
                                        array_pop($parent_stack);
                                        $current_level--;
                                        // Need to close a category level here
                                        $template->assign_block_vars('digests_edit_subscribers.forums', array('S_DIV_CLOSE' => true, 'S_DIV_OPEN' => false, 'S_PRINT' => false));
                                    }
                                } else {
                                    // If the parent is not in the stack, then push the parent_id on the stack. This is also a trigger to indent the block. This creates a <div>
                                    array_push($parent_stack, (int) $row2['parent_id']);
                                    $current_level++;
                                    // Need to add a category level here
                                    $template->assign_block_vars('digests_edit_subscribers.forums', array('CAT_ID' => 'div_' . $row2['parent_id'], 'S_DIV_CLOSE' => false, 'S_DIV_OPEN' => true, 'S_PRINT' => false));
                                }
                            }
                            // This code prints the forum or category, which will exist inside the previously created <div> block
                            // Check this forum's checkbox? Only if they have forum subscriptions
                            if (!$all_by_default) {
                                $check = false;
                                foreach ($subscribed_forums as $this_row) {
                                    if ($this_row['forum_id'] == $row2['forum_id']) {
                                        $check = true;
                                        break;
                                    }
                                }
                            } else {
                                $check = true;
                            }
                            $template->assign_block_vars('digests_edit_subscribers.forums', array('FORUM_LABEL' => $row2['forum_name'], 'FORUM_NAME' => 'elt_' . (int) $row2['forum_id'] . '_' . (int) $row2['parent_id'], 'S_FORUM_SUBSCRIBED' => $check, 'S_IS_FORUM' => !($row2['forum_type'] == FORUM_CAT), 'S_PRINT' => true));
                        }
                        $db->sql_freeresult($result2);
                        // Now out of the loop, it is important to remember to close any open <div> tags. Typically there is at least one.
                        while ((int) $row2['parent_id'] != (int) end($parent_stack)) {
                            array_pop($parent_stack);
                            $current_level--;
                            // Need to close the <div> tag
                            $template->assign_block_vars('digests_edit_subscribers.forums', array('S_DIV_CLOSE' => true, 'S_DIV_OPEN' => false, 'S_PRINT' => false));
                        }
                    }
                }
                $db->sql_freeresult($result);
                // Query be gone!
                break;
            case 'digests_balance_load':
                $display_vars = array('title' => 'ACP_DIGESTS_BALANCE_LOAD', 'vars' => array('legend1' => ''));
                // Translate time zone information
                $template->assign_vars(array('L_DIGESTS_HOUR_SENT' => $user->lang('DIGESTS_HOUR_SENT', $config['phpbbservices_digests_time_zone']), 'S_BALANCE_LOAD' => true));
                $sql_array = array('SELECT' => 'user_digest_send_hour_gmt AS hour, count(*) AS hour_count', 'FROM' => array(USERS_TABLE => 'u'), 'WHERE' => "user_digest_type <> '" . constants::DIGESTS_NONE_VALUE . "' AND user_type <> " . USER_IGNORE, 'GROUP_BY' => 'user_digest_send_hour_gmt', 'ORDER_BY' => '1');
                $sql = $db->sql_build_query('SELECT', $sql_array);
                $result = $db->sql_query($sql);
                $rowset = $db->sql_fetchrowset($result);
                for ($i = 0; $i < 24; $i++) {
                    // Convert digest hour to GMT
                    $hour_gmt = floor($i - $config['phpbbservices_digests_time_zone']);
                    if ($hour_gmt < 0) {
                        $hour_gmt = $hour_gmt + 24;
                    } else {
                        if ($hour_gmt > 23) {
                            $hour_gmt = $hour_gmt - 24;
                        }
                    }
                    // If there are digest counts for this GMT hour, show it, otherwise show zero (no digests for this GMT hour)
                    $hour_count = 0;
                    if (isset($rowset)) {
                        foreach ($rowset as $row) {
                            if (floor($row['hour']) == $hour_gmt) {
                                $hour_count = $row['hour_count'];
                                break;
                            }
                        }
                    }
                    $template->assign_block_vars('digests_balance_load', array('HOUR' => $i, 'HOUR_COUNT' => $hour_count));
                }
                $db->sql_freeresult($result);
                // Query be gone!
                break;
            case 'digests_mass_subscribe_unsubscribe':
                $display_vars = array('title' => 'ACP_DIGESTS_MASS_SUBSCRIBE_UNSUBSCRIBE', 'vars' => array('legend1' => '', 'phpbbservices_digests_enable_subscribe_unsubscribe' => array('lang' => 'DIGESTS_ENABLE_SUBSCRIBE_UNSUBSCRIBE', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'phpbbservices_digests_subscribe_all' => array('lang' => 'DIGESTS_SUBSCRIBE_ALL', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'phpbbservices_digests_include_admins' => array('lang' => 'DIGESTS_INCLUDE_ADMINS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true)));
                break;
            case 'digests_reset_cron_run_time':
                $display_vars = array('title' => 'ACP_DIGESTS_RESET_CRON_RUN_TIME', 'vars' => array('legend1' => '', 'phpbbservices_digests_enable_subscribe_unsubscribe' => array('lang' => 'DIGESTS_RESET_CRON_RUN_TIME', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true)));
                break;
            case 'digests_test':
                $display_vars = array('title' => 'ACP_DIGESTS_TEST', 'vars' => array('legend1' => 'GENERAL_OPTIONS', 'phpbbservices_digests_test' => array('lang' => 'DIGESTS_RUN_TEST', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'phpbbservices_digests_test_spool' => array('lang' => 'DIGESTS_RUN_TEST_SPOOL', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'phpbbservices_digests_test_clear_spool' => array('lang' => 'DIGESTS_RUN_TEST_CLEAR_SPOOL', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'phpbbservices_digests_test_send_to_admin' => array('lang' => 'DIGESTS_RUN_TEST_SEND_TO_ADMIN', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'phpbbservices_digests_test_email_address' => array('lang' => 'DIGESTS_RUN_TEST_EMAIL_ADDRESS', 'validate' => 'string', 'type' => 'email:25:100', 'explain' => true), 'legend2' => 'DIGESTS_RUN_TEST_OPTIONS', 'phpbbservices_digests_test_time_use' => array('lang' => 'DIGESTS_RUN_TEST_TIME_USE', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'phpbbservices_digests_test_year' => array('lang' => 'DIGESTS_RUN_TEST_YEAR', 'validate' => 'int:2000:2030', 'type' => 'text:4:4', 'explain' => true), 'phpbbservices_digests_test_month' => array('lang' => 'DIGESTS_RUN_TEST_MONTH', 'validate' => 'int:1:12', 'type' => 'text:2:2', 'explain' => true), 'phpbbservices_digests_test_day' => array('lang' => 'DIGESTS_RUN_TEST_DAY', 'validate' => 'int:1:31', 'type' => 'text:2:2', 'explain' => true), 'phpbbservices_digests_test_hour' => array('lang' => 'DIGESTS_RUN_TEST_HOUR', 'validate' => 'int:0:23', 'type' => 'text:2:2', 'explain' => true)));
                break;
            default:
                trigger_error('NO_MODE', E_USER_ERROR);
                break;
        }
        $this->new_config = $config;
        $cfg_array = isset($_REQUEST['config']) ? $request->variable('config', array('' => ''), true) : $this->new_config;
        $error = array();
        // We validate the complete config if wished
        validate_config_vars($display_vars['vars'], $cfg_array, $error);
        if ($submit && !check_form_key($form_key)) {
            $error[] = $user->lang('FORM_INVALID');
        }
        // Do not write values if there is an error
        if (sizeof($error)) {
            $submit = false;
        }
        // We go through the display_vars to make sure no one is trying to set variables he/she is not allowed to...
        foreach ($display_vars['vars'] as $config_name => $data) {
            if (!isset($cfg_array[$config_name]) || strpos($config_name, 'legend') !== false) {
                continue;
            }
            $this->new_config[$config_name] = $config_value = $cfg_array[$config_name];
            if ($submit) {
                $config->set($config_name, $config_value);
            }
        }
        if ($submit && $mode == 'digests_edit_subscribers') {
            // The "selected" input control indicates whether to do mass actions or not. With mass actions only the select control and
            // the mark checkboxes matter. Other controls are ignored.
            $selected = $request->variable('selected', 'IGNORE', true);
            $mass_action = $selected == 'IGNORE' ? false : true;
            $use_defaults = false;
            $use_defaults_pass = false;
            unset($sql_ary, $sql_ary2);
            // Get the entire request variables as an array for parsing
            unset($requests_vars);
            $request_vars = $request->get_super_global(\phpbb\request\request_interface::POST);
            // If a mass action, we want to remove all post variables with the user-99-col_name pattern. It makes the logic easier by effectively ignoring them.
            if ($mass_action) {
                foreach ($request_vars as $key => $value) {
                    if (substr($key, 0, 5) == 'user-' && strpos($key, '-', 5) > 5) {
                        unset($request_vars[$key]);
                    }
                }
            }
            // Now let's sort the request variables so we process one can user at a time
            ksort($request_vars);
            // Set some flags
            $current_user_id = NULL;
            foreach ($request_vars as $name => $value) {
                // We only care if the request variable starts with "user-".
                if (substr($name, 0, 5) == 'user-') {
                    // Parse for the user_id, which is embedded in the form field name. Format is user-99-column_name where 99
                    // is the user id. The mark switch is in the form user-99.
                    $delimiter_pos = strpos($name, '-', 5);
                    if ($delimiter_pos === false) {
                        // This is the mark all checkbox for a given user
                        $delimiter_pos = strlen($name);
                    }
                    $user_id = substr($name, 5, $delimiter_pos - 5);
                    $var_part = substr($name, $delimiter_pos + 1);
                    if ($current_user_id === NULL) {
                        $current_user_id = $user_id;
                    } else {
                        if ($current_user_id !== $user_id) {
                            // Save this subscriber's digest settings
                            if (isset($sql_ary) && sizeof($sql_ary) > 0) {
                                $sql = 'UPDATE ' . USERS_TABLE . ' 
								SET ' . $db->sql_build_array('UPDATE', $sql_ary) . '
								WHERE user_id = ' . (int) $current_user_id;
                                $db->sql_query($sql);
                            }
                            // If there are any individual forum subscriptions for this user, remove the old ones.
                            $sql = 'DELETE FROM ' . $table_prefix . constants::DIGESTS_SUBSCRIBED_FORUMS_TABLE . ' 
								WHERE user_id = ' . (int) $current_user_id;
                            $db->sql_query($sql);
                            // Now save the individual forum subscriptions, if any
                            if (!$mass_action && isset($sql_ary2) && sizeof($sql_ary2) > 0) {
                                $db->sql_multi_insert($table_prefix . constants::DIGESTS_SUBSCRIBED_FORUMS_TABLE, $sql_ary2);
                            }
                            // Also want to save some information to an array to be used for sending emails to affected users.
                            $digest_notify_list[] = $current_user_id;
                            // We need to set these variables so we can detect if individual forum subscriptions will need to be processed.
                            $current_user_id = $user_id;
                            $use_defaults = false;
                            $use_defaults_pass = false;
                            unset($sql_ary, $sql_ary2);
                        }
                    }
                    if ($mass_action) {
                        // We need to save the digest settings for this mass user. There should only be one request variable for the user.
                        // Do a mass action only if the mark variable for the user_id is checked
                        if ($value == 'on') {
                            switch ($selected) {
                                case constants::DIGESTS_DEFAULT_VALUE:
                                    // Use the default digest type
                                    $sql_ary['user_digest_type'] = $config['phpbbservices_digests_user_digest_type'];
                                    break;
                                case constants::DIGESTS_NONE_VALUE:
                                    // Remove user's subscription (mass action)
                                    $sql_ary['user_digest_type'] = constants::DIGESTS_NONE_VALUE;
                                    break;
                                default:
                                    break;
                            }
                            // Create a digest subscription using board defaults
                            $sql_ary['user_digest_format'] = $config['phpbbservices_digests_user_digest_format'];
                            $sql_ary['user_digest_show_mine'] = $config['phpbbservices_digests_user_digest_show_mine'] == 1 ? 0 : 1;
                            $sql_ary['user_digest_send_on_no_posts'] = $config['phpbbservices_digests_user_digest_send_on_no_posts'];
                            $sql_ary['user_digest_send_hour_gmt'] = $config['phpbbservices_digests_user_digest_send_hour_gmt'] == -1 ? rand(0, 23) : $config['phpbbservices_digests_user_digest_send_hour_gmt'];
                            $sql_ary['user_digest_show_pms'] = $config['phpbbservices_digests_user_digest_show_pms'];
                            $sql_ary['user_digest_max_posts'] = $config['phpbbservices_digests_user_digest_max_posts'];
                            $sql_ary['user_digest_min_words'] = $config['phpbbservices_digests_user_digest_min_words'];
                            $sql_ary['user_digest_remove_foes'] = $config['phpbbservices_digests_user_digest_remove_foes'];
                            $sql_ary['user_digest_sortby'] = $config['phpbbservices_digests_user_digest_sortby'];
                            $sql_ary['user_digest_max_display_words'] = $config['phpbbservices_digests_user_digest_max_display_words'] == -1 ? 0 : $config['phpbbservices_digests_user_digest_max_display_words'];
                            $sql_ary['user_digest_reset_lastvisit'] = $config['phpbbservices_digests_user_digest_reset_lastvisit'];
                            $sql_ary['user_digest_filter_type'] = $config['phpbbservices_digests_user_digest_filter_type'];
                            $sql_ary['user_digest_pm_mark_read'] = $config['phpbbservices_digests_user_digest_pm_mark_read'];
                            $sql_ary['user_digest_new_posts_only'] = $config['phpbbservices_digests_user_digest_new_posts_only'];
                            $sql_ary['user_digest_no_post_text'] = $config['phpbbservices_digests_user_digest_max_display_words'] == 0 ? 1 : 0;
                            $sql_ary['user_digest_attachments'] = $config['phpbbservices_digests_user_digest_attachments'];
                            $sql_ary['user_digest_block_images'] = $config['phpbbservices_digests_user_digest_block_images'];
                            $sql_ary['user_digest_toc'] = $config['phpbbservices_digests_user_digest_toc'];
                        }
                    } else {
                        // We need to get these variables so we can detect if individual forum subscriptions will need to be processed.
                        $var = 'user-' . $current_user_id . '-all_forums';
                        $all_forums = $request->variable($var, '', true);
                        $var = 'user-' . $current_user_id . '-filter_type';
                        $filter_type = $request->variable($var, '', true);
                        // No mass action, so associate the database columns with its requested value
                        if (!$use_defaults && $var_part == 'digest_type' && $value == constants::DIGESTS_DEFAULT_VALUE) {
                            $use_defaults = true;
                            unset($sql_ary);
                        }
                        if ($use_defaults) {
                            if (!$use_defaults_pass) {
                                // Create a digest subscription using board defaults. but do it only once for the user_id
                                $sql_ary['user_digest_type'] = $config['phpbbservices_digests_user_digest_type'];
                                $sql_ary['user_digest_format'] = $config['phpbbservices_digests_user_digest_format'];
                                $sql_ary['user_digest_show_mine'] = $config['phpbbservices_digests_user_digest_show_mine'] == 1 ? 0 : 1;
                                $sql_ary['user_digest_send_on_no_posts'] = $config['phpbbservices_digests_user_digest_send_on_no_posts'];
                                $sql_ary['user_digest_send_hour_gmt'] = $config['phpbbservices_digests_user_digest_send_hour_gmt'] == -1 ? rand(0, 23) : $config['phpbbservices_digests_user_digest_send_hour_gmt'];
                                $sql_ary['user_digest_show_pms'] = $config['phpbbservices_digests_user_digest_show_pms'];
                                $sql_ary['user_digest_max_posts'] = $config['phpbbservices_digests_user_digest_max_posts'];
                                $sql_ary['user_digest_min_words'] = $config['phpbbservices_digests_user_digest_min_words'];
                                $sql_ary['user_digest_remove_foes'] = $config['phpbbservices_digests_user_digest_remove_foes'];
                                $sql_ary['user_digest_sortby'] = $config['phpbbservices_digests_user_digest_sortby'];
                                $sql_ary['user_digest_max_display_words'] = $config['phpbbservices_digests_user_digest_max_display_words'] == -1 ? 0 : $config['phpbbservices_digests_user_digest_max_display_words'];
                                $sql_ary['user_digest_reset_lastvisit'] = $config['phpbbservices_digests_user_digest_reset_lastvisit'];
                                $sql_ary['user_digest_filter_type'] = $config['phpbbservices_digests_user_digest_filter_type'];
                                $sql_ary['user_digest_pm_mark_read'] = $config['phpbbservices_digests_user_digest_pm_mark_read'];
                                $sql_ary['user_digest_new_posts_only'] = $config['phpbbservices_digests_user_digest_new_posts_only'];
                                $sql_ary['user_digest_no_post_text'] = $config['phpbbservices_digests_user_digest_max_display_words'] == 0 ? 1 : 0;
                                $sql_ary['user_digest_attachments'] = $config['phpbbservices_digests_user_digest_attachments'];
                                $sql_ary['user_digest_block_images'] = $config['phpbbservices_digests_user_digest_block_images'];
                                $sql_ary['user_digest_toc'] = $config['phpbbservices_digests_user_digest_toc'];
                                $use_defaults_pass = true;
                            }
                        } else {
                            switch ($var_part) {
                                case 'digest_type':
                                    $sql_ary['user_digest_type'] = $value;
                                    break;
                                case 'style':
                                    $sql_ary['user_digest_format'] = $value;
                                    break;
                                case 'send_hour':
                                    $sql_ary['user_digest_send_hour_gmt'] = $value;
                                    break;
                                case 'filter_type':
                                    $sql_ary['user_digest_filter_type'] = $value;
                                    break;
                                case 'max_posts':
                                    $sql_ary['user_digest_max_posts'] = $value;
                                    break;
                                case 'min_words':
                                    $sql_ary['user_digest_min_words'] = $value;
                                    break;
                                case 'new_posts_only':
                                    $sql_ary['user_digest_new_posts_only'] = $value;
                                    break;
                                case 'show_mine':
                                    $sql_ary['user_digest_show_mine'] = $value == '0' ? '1' : '0';
                                    break;
                                case 'filter_foes':
                                    $sql_ary['user_digest_remove_foes'] = $value;
                                    break;
                                case 'pms':
                                    $sql_ary['user_digest_show_pms'] = $value;
                                    break;
                                case 'mark_read':
                                    $sql_ary['user_digest_pm_mark_read'] = $value;
                                    break;
                                case 'sortby':
                                    $sql_ary['user_digest_sortby'] = $value;
                                    break;
                                case 'max_display_words':
                                    $sql_ary['user_digest_max_display_words'] = $value;
                                    break;
                                case 'no_post_text':
                                    $sql_ary['user_digest_no_post_text'] = $value;
                                    break;
                                case 'send_on_no_posts':
                                    $sql_ary['user_digest_send_on_no_posts'] = $value;
                                    break;
                                case 'lastvisit':
                                    $sql_ary['user_digest_reset_lastvisit'] = $value;
                                    break;
                                case 'attachments':
                                    $sql_ary['user_digest_attachments'] = $value;
                                    break;
                                case 'blockimages':
                                    $sql_ary['user_digest_block_images'] = $value;
                                    break;
                                case 'toc':
                                    $sql_ary['user_digest_toc'] = $value;
                                    break;
                                default:
                                    break;
                            }
                        }
                        // Note that if "all_forums" is unchecked and bookmarks is unchecked, there are individual forum subscriptions, so they must be saved.
                        if (substr($var_part, 0, 4) == 'elt_') {
                            // We should save this forum as an individual forum subscription, but only if the all forums checkbox
                            // is not set AND the user should not get posts for bookmarked topics only.
                            // This request variable is a checkbox for a forum for this user. It should be checked or it would
                            // not be in the $request_vars array.
                            $delimiter_pos = strpos($var_part, '_', 4);
                            $forum_id = substr($var_part, 4, $delimiter_pos - 4);
                            if ($all_forums !== 'on' && trim($filter_type) !== constants::DIGESTS_BOOKMARKS) {
                                $sql_ary2[] = array('user_id' => (int) $current_user_id, 'forum_id' => (int) $forum_id);
                            }
                        }
                    }
                }
                // $request_vars variable is named user-*
            }
            // foreach
            // Process last user
            // Save this subscriber's digest settings
            if (isset($sql_ary) && sizeof($sql_ary) > 0) {
                $sql = 'UPDATE ' . USERS_TABLE . ' 
					SET ' . $db->sql_build_array('UPDATE', $sql_ary) . '
					WHERE user_id = ' . (int) $current_user_id;
                $db->sql_query($sql);
            }
            // If there are any individual forum subscriptions for this user, remove the old ones.
            if (!is_null($current_user_id)) {
                $sql = 'DELETE FROM ' . $table_prefix . constants::DIGESTS_SUBSCRIBED_FORUMS_TABLE . ' 
						WHERE user_id = ' . (int) $current_user_id;
                $db->sql_query($sql);
            }
            // Now save the individual forum subscriptions, if any
            if (!$mass_action && isset($sql_ary2) && sizeof($sql_ary2) > 0) {
                $db->sql_multi_insert($table_prefix . constants::DIGESTS_SUBSCRIBED_FORUMS_TABLE, $sql_ary2);
            }
            // Also want to save some information to an array to be used for sending emails to affected users.
            $digest_notify_list[] = $current_user_id;
            // Notify users whose subscriptions were changed
            if ($config['phpbbservices_digests_notify_on_admin_changes']) {
                $this->notify_subscribers($digest_notify_list, 'digests_subscription_edited');
            }
            $message = $user->lang('CONFIG_UPDATED');
        }
        if ($submit && $mode == 'digests_balance_load') {
            $sql_array = array('SELECT' => 'count(*) AS digests_count', 'FROM' => array(USERS_TABLE => 'u'), 'WHERE' => "user_digest_type <> '" . constants::DIGESTS_NONE_VALUE . "' \n\t\t\t\t\tAND user_type <> " . USER_IGNORE);
            $sql = $db->sql_build_query('SELECT', $sql_array);
            $result = $db->sql_query($sql);
            $row = $db->sql_fetchrow($result);
            // Determine the average number of subscribers per hour. We need to assume at least one subscriber per hour to avoid
            // resetting user's preferred digest time unnecessarily. If the average is 3 per hour, the first 3 already subscribed
            // will not have their digest arrival time changed.
            $avg_subscribers_per_hour = max(floor($row['digests_count'] / 24), 1);
            $db->sql_freeresult($result);
            // Get oversubscribed hours, place in an array
            $sql_array = array('SELECT' => 'user_digest_send_hour_gmt AS hour, count(*) AS hour_count', 'FROM' => array(USERS_TABLE => 'u'), 'WHERE' => "user_digest_type <> 'NONE' AND user_type <> " . USER_IGNORE, 'GROUP_BY' => 'user_digest_send_hour_gmt', 'HAVING' => 'count(user_digest_send_hour_gmt) > ' . (int) $avg_subscribers_per_hour, 'ORDER_BY' => '1');
            $sql = $db->sql_build_query('SELECT', $sql_array);
            $result = $db->sql_query($sql);
            $rowset = $db->sql_fetchrowset($result);
            $oversubscribed_hours = array();
            foreach ($rowset as $row) {
                $oversubscribed_hours[] = $row['hour'];
            }
            $db->sql_freeresult($result);
            // Get a list of subscribers whose hour to get digest should be changed because they exceed the average number of subscribers
            // allowed in that hour. We will ignore the first $oversubscribed_hours subscribers.
            $rebalanced = 0;
            $digest_notify_list = array();
            if (sizeof($oversubscribed_hours) > 0) {
                $sql_array = array('SELECT' => 'user_digest_send_hour_gmt, user_id, username, user_email, user_lang', 'FROM' => array(USERS_TABLE => 'u'), 'WHERE' => "user_digest_type <> '" . constants::DIGESTS_NONE_VALUE . "' AND user_type <> " . USER_IGNORE . '
						AND ' . $db->sql_in_set('user_digest_send_hour_gmt', $oversubscribed_hours), 'ORDER_BY' => '1, 2');
                $sql = $db->sql_build_query('SELECT', $sql_array);
                $result = $db->sql_query_limit($sql, 100000, $avg_subscribers_per_hour - 1);
                // Result sets start with array indexed at zero
                $rowset = $db->sql_fetchrowset($result);
                $current_hour = -1;
                $counted_for_this_hour = 0;
                // Finally, change the digest send hour for these subscribers to a random hour between 0 and 24.
                foreach ($rowset as $row) {
                    $digest_notify_list[] = $row['user_id'];
                    if ($current_hour != $row['user_digest_send_hour_gmt']) {
                        $current_hour = $row['user_digest_send_hour_gmt'];
                        $counted_for_this_hour = 0;
                    }
                    $counted_for_this_hour++;
                    if ($counted_for_this_hour > $avg_subscribers_per_hour) {
                        $sql_ary = array('user_digest_send_hour_gmt' => rand(0, 23));
                        $sql2 = 'UPDATE ' . USERS_TABLE . '
							SET ' . $db->sql_build_array('UPDATE', $sql_ary) . '
							WHERE user_id = ' . (int) $row['user_id'];
                        $db->sql_query($sql2);
                        $rebalanced++;
                    }
                }
                $db->sql_freeresult($result);
                // Notify users whose subscriptions were changed
                if ($config['phpbbservices_digests_notify_on_admin_changes']) {
                    $this->notify_subscribers($digest_notify_list, 'digests_subscription_edited');
                }
            }
            $message = $user->lang('DIGESTS_REBALANCED', $rebalanced);
        }
        if ($submit && $mode == 'digests_mass_subscribe_unsubscribe') {
            // Did the admin explicitly request a mass subscription or unsubscription action?
            if ($config['phpbbservices_digests_enable_subscribe_unsubscribe']) {
                // Determine which user types are to be updated
                $user_types = array(USER_NORMAL);
                if ($config['phpbbservices_digests_include_admins']) {
                    $user_types[] = USER_FOUNDER;
                }
                // If doing a mass subscription, we don't want to mess up digest subscriptions already in place, so we need to create a snippet of SQL.
                // If doing a mass unsubscribe, all qualified subscriptions are removed. Note however that except for the digest type, all other settings
                // are retained.
                $sql_qualifier = $config['phpbbservices_digests_subscribe_all'] ? " AND user_digest_type = '" . constants::DIGESTS_NONE_VALUE . "'" : " AND user_digest_type != '" . constants::DIGESTS_NONE_VALUE . "'";
                $digest_notify_list = array();
                if ($config['phpbbservices_digests_notify_on_admin_changes']) {
                    $sql_array = array('SELECT' => 'user_id', 'FROM' => array(USERS_TABLE => 'u'), 'WHERE' => $db->sql_in_set('user_type', $user_types) . $sql_qualifier);
                    $sql = $db->sql_build_query('SELECT', $sql_array);
                    $result = $db->sql_query($sql);
                    $rowset = $db->sql_fetchrowset($result);
                    foreach ($rowset as $row) {
                        $digest_notify_list[] = $row['user_id'];
                    }
                    $db->sql_freeresult($result);
                    // Query be gone!
                }
                // Set columns in user table to be updated
                $sql_ary = array('user_digest_type' => $config['phpbbservices_digests_subscribe_all'] ? $config['phpbbservices_digests_user_digest_type'] : constants::DIGESTS_NONE_VALUE, 'user_digest_format' => $config['phpbbservices_digests_user_digest_format'], 'user_digest_show_mine' => $config['phpbbservices_digests_user_digest_show_mine'] == 1 ? 0 : 1, 'user_digest_send_on_no_posts' => $config['phpbbservices_digests_user_digest_send_on_no_posts'], 'user_digest_send_hour_gmt' => $config['phpbbservices_digests_user_digest_send_hour_gmt'] == -1 ? rand(0, 23) : $config['phpbbservices_digests_user_digest_send_hour_gmt'], 'user_digest_show_pms' => $config['phpbbservices_digests_user_digest_show_pms'], 'user_digest_max_posts' => $config['phpbbservices_digests_user_digest_max_posts'], 'user_digest_min_words' => $config['phpbbservices_digests_user_digest_min_words'], 'user_digest_remove_foes' => $config['phpbbservices_digests_user_digest_remove_foes'], 'user_digest_sortby' => $config['phpbbservices_digests_user_digest_sortby'], 'user_digest_max_display_words' => $config['phpbbservices_digests_user_digest_max_display_words'] == -1 ? 0 : $config['phpbbservices_digests_user_digest_max_display_words'], 'user_digest_reset_lastvisit' => $config['phpbbservices_digests_user_digest_reset_lastvisit'], 'user_digest_filter_type' => $config['phpbbservices_digests_user_digest_filter_type'], 'user_digest_pm_mark_read' => $config['phpbbservices_digests_user_digest_pm_mark_read'], 'user_digest_new_posts_only' => $config['phpbbservices_digests_user_digest_new_posts_only'], 'user_digest_no_post_text' => $config['phpbbservices_digests_user_digest_max_display_words'] == 0 ? 1 : 0, 'user_digest_attachments' => $config['phpbbservices_digests_user_digest_attachments'], 'user_digest_block_images' => $config['phpbbservices_digests_user_digest_block_images'], 'user_digest_toc' => $config['phpbbservices_digests_user_digest_toc']);
                $sql = 'UPDATE ' . USERS_TABLE . ' 
						SET ' . $db->sql_build_array('UPDATE', $sql_ary) . '
						WHERE ' . $db->sql_in_set('user_type', $user_types) . $sql_qualifier;
                $result = $db->sql_query($sql);
                $db->sql_freeresult($result);
                // Query be gone!
                // Notify users or subscription or unsubscription if directed
                if ($config['phpbbservices_digests_notify_on_admin_changes']) {
                    $this->notify_subscribers($digest_notify_list);
                }
                if ($config['phpbbservices_digests_subscribe_all']) {
                    $message = $user->lang('DIGESTS_ALL_SUBSCRIBED', sizeof($digest_notify_list));
                } else {
                    $message = $user->lang('DIGESTS_ALL_UNSUBSCRIBED', sizeof($digest_notify_list));
                }
            } else {
                // show no update message
                $message = $user->lang('DIGESTS_NO_MASS_ACTION');
            }
        }
        if ($submit && $mode == 'digests_reset_cron_run_time') {
            $config->set('phpbbservices_digests_cron_task_last_gc', 0);
        }
        if ($submit && $mode == 'digests_test') {
            define('IN_DIGESTS_TEST', true);
            $continue = true;
            if (!$config['phpbbservices_digests_test'] && !$config['phpbbservices_digests_test_clear_spool']) {
                $message = $user->lang('DIGESTS_MAILER_NOT_RUN');
                $continue = false;
            }
            if ($continue && $config['phpbbservices_digests_test_clear_spool']) {
                // Clear the digests cache folder of .txt and .html files, if so instructed
                $all_cleared = true;
                $directory_found = true;
                $path = $phpbb_root_path . 'store/ext/phpbbservices/digests';
                if (is_dir($path)) {
                    foreach (new \DirectoryIterator($path) as $file_info) {
                        $file_name = $file_info->getFilename();
                        // Exclude dot files, hidden files and non "real" files, and real files if they don't have the .html or .txt suffix
                        if (substr($file_name, 0, 1) !== '.' && $file_info->isFile() && ($file_info->getExtension() == 'html' || $file_info->getExtension() == 'txt')) {
                            $deleted = unlink($path . '/' . $file_name);
                            // delete file
                            if (!$deleted) {
                                $all_cleared = false;
                            }
                        }
                    }
                } else {
                    $directory_found = false;
                }
                if ($config['phpbbservices_digests_enable_log'] && $directory_found) {
                    if ($all_cleared) {
                        $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_CONFIG_DIGESTS_CACHE_CLEARED');
                    } else {
                        $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_CONFIG_DIGESTS_CLEAR_SPOOL_ERROR');
                    }
                }
                if (!$all_cleared) {
                    $message_type = E_USER_WARNING;
                    $message = strip_tags($user->lang('LOG_CONFIG_DIGESTS_CLEAR_SPOOL_ERROR'));
                    $continue = false;
                }
            }
            if ($continue && $config['phpbbservices_digests_test_time_use']) {
                // Make sure run date is valid, if a run date was requested.
                $good_date = checkdate($config['phpbbservices_digests_test_month'], $config['phpbbservices_digests_test_day'], $config['phpbbservices_digests_test_year']);
                if (!$good_date) {
                    $message_type = E_USER_WARNING;
                    $message = $user->lang('DIGESTS_ILLOGICAL_DATE');
                    $continue = false;
                }
            }
            // Get ready to manually mail digests
            if ($continue) {
                // Must save the current state or the sidebar will disappear after the mailer call
                $save_template = serialize($template);
                // Get the common include files, to pass the reference to mailer
                $helper = $phpbb_container->get('phpbbservices.digests.common');
                // Create a mailer object and call its run method. The logic for sending a digest is embedded in this method, which is normally run as a cron task.
                $mailer = new \phpbbservices\digests\cron\task\digests($config, $request, $user, $db, $phpEx, $phpbb_root_path, $template, $auth, $table_prefix, $phpbb_log, $helper);
                $success = $mailer->run();
                if (!$success) {
                    $message_type = E_USER_WARNING;
                    $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_CONFIG_DIGESTS_MAILER_RAN_WITH_ERROR');
                    $message = strip_tags($user->lang('LOG_CONFIG_DIGESTS_MAILER_RAN_WITH_ERROR'));
                } else {
                    if ($config['phpbbservices_digests_test_spool']) {
                        $message = $user->lang('DIGESTS_MAILER_SPOOLED');
                    } else {
                        $message = $user->lang('DIGESTS_MAILER_RAN_SUCCESSFULLY');
                    }
                }
                // Restore the sidebar content
                $template = unserialize($save_template);
            }
        }
        if ($submit) {
            if (!isset($message_type)) {
                $message_type = E_USER_NOTICE;
            }
            if (!isset($message)) {
                $message = $user->lang('CONFIG_UPDATED');
            }
            if ($mode !== 'digests_test') {
                $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_CONFIG_' . strtoupper($mode));
            }
            trigger_error($message . adm_back_link($this->u_action), $message_type);
        }
        $this->tpl_name = 'acp_digests';
        $this->page_title = $display_vars['title'];
        $template->assign_vars(array('ERROR_MSG' => is_array($error) ? implode('<br />', $error) : $error, 'L_MESSAGE' => $error, 'L_TITLE' => $user->lang($display_vars['title']), 'L_TITLE_EXPLAIN' => $user->lang($display_vars['title'] . '_EXPLAIN'), 'S_ERROR' => sizeof($error) ? true : false, 'U_ACTION' => $this->u_action));
        // Output relevant page
        foreach ($display_vars['vars'] as $config_key => $vars) {
            if (!is_array($vars) && strpos($config_key, 'legend') === false) {
                continue;
            }
            if (strpos($config_key, 'legend') !== false) {
                $template->assign_block_vars('options', array('LEGEND' => sizeof($user->lang[$vars]) > 0 ? $user->lang($vars) : $vars, 'S_LEGEND' => true));
                continue;
            }
            $type = explode(':', $vars['type']);
            $l_explain = '';
            if ($vars['explain'] && isset($vars['lang_explain'])) {
                $l_explain = isset($user->lang[$vars['lang_explain']]) ? $user->lang($vars['lang_explain']) : $vars['lang_explain'];
            } else {
                if ($vars['explain']) {
                    $l_explain = isset($user->lang[$vars['lang'] . '_EXPLAIN']) ? $user->lang($vars['lang'] . '_EXPLAIN') : '';
                }
            }
            $content = build_cfg_template($type, $config_key, $this->new_config, $config_key, $vars);
            if (empty($content)) {
                continue;
            }
            $template->assign_block_vars('options', array('CONTENT' => $content, 'KEY' => $config_key, 'TITLE' => isset($user->lang[$vars['lang']]) ? $user->lang($vars['lang']) : $vars['lang'], 'S_EXPLAIN' => $vars['explain'], 'TITLE_EXPLAIN' => $l_explain));
            unset($display_vars['vars'][$config_key]);
        }
    }