<?php
/**
 * SeekQuarry/Yioop --
 * Open Source Pure PHP Search Engine, Crawler, and Indexer
 *
 * Copyright (C) 2009 - 2026  Chris Pollett chris@pollett.org
 *
 * LICENSE:
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 *
 * END LICENSE
 *
 * @author Mallika Perepa (Creator), Chris Pollett (rewrote)
 * @license https://www.gnu.org/licenses/ GPL3
 * @link https://www.seekquarry.com/
 * @copyright 2009 - 2026
 * @filesource
 */
namespace seekquarry\yioop\views\elements;

use seekquarry\yioop as B;
use seekquarry\yioop\configs as C;
use seekquarry\yioop\library as L;

/**
 * Used to draw the admin screen on which users can create groups, delete
 * groups and add and delete users and roles to a group
 *
 * @author Mallika Perepa (started) Chris Pollett (rewrite)
 */
class ManagegroupsElement extends Element
{
    /**
     * Renders the screen in which groups can be created, deleted, and added or
     * deleted
     *
     * @param array $data  contains antiCSRF token, as well as data on
     *     available groups or which user is in what group
     */
    public function render($data)
    {
        $data['ACTIVITY'] = 'manageGroups';
        $data['VIEW'] = $this->view;
        $data['NO_FLOAT_TABLE'] = false;
        $data['NO_ADD_TOGGLE'] = true;
        $is_browse = !empty($data['browse']) && $data['browse'] == 'true';
        ?>
        <div class="current-activity" >
        <?php
        if (!$is_browse &&
            !empty($data['FORM_TYPE']) && !in_array($data['FORM_TYPE'],
            ["inviteusers"])) {
            $token = C\p('CSRF_TOKEN') . "=" . $data[C\p('CSRF_TOKEN')];
            switch ($data['CONTEXT']) {
                case "account":
                    $close_url = htmlentities(B\controllerUrl("admin", true)) .
                        "$token&amp;a=manageAccounts";
                    break;
                case "groups":
                    $close_url =  htmlentities(B\feedsUrl("", "",
                        true, "group")). $token;
                    break;
                case "join_groups":
                    $close_url = htmlentities(B\controllerUrl("admin", true)) .
                        "$token&amp;a=manageGroups&amp;browse=true";
                    break;
            }
            $this->view->helper("close")->render($close_url);
        }
        switch ($data['FORM_TYPE']) {
            case "addgroup":
            case "groupsettings":
                $this->renderGroupsForm($data);
                break;
            case "infogroup":
                $this->renderInfoGroup($data);
                break;
            case "graphstats":
                if (!C\p('GROUP_ANALYTICS_MODE') ||
                    C\p('GROUP_ANALYTICS_MODE') == "0") {
                    break;
                }
                $this->renderGraphStats($data);
                ?>
                    <div class="clear show-narrow">&nbsp;</div><?php
                break;
            case "inviteusers":
                $this->renderInviteUsersForm($data);
                break;
            case "statistics":
                if (!C\p('GROUP_ANALYTICS_MODE') ||
                    C\p('GROUP_ANALYTICS_MODE') == "0") {
                    break;
                }
                $this->renderGroupStatistics($data);
                ?>
                    <div class="clear show-narrow">&nbsp;</div><?php
                break;
        }
        if ($is_browse) {
            $this->renderJoinTable($data);
        } ?>
        </div><?php
    }
    /**
     * Render the table of groups that a user could join.
     *
     * @param array $data data from the controller used to draw this table
     */
    public function renderJoinTable($data)
    {
        if (empty($data['ADMIN'])) {
            return;
        }
        $token = C\p('CSRF_TOKEN') . "=" . $data[C\p('CSRF_TOKEN')];
        $admin_url = htmlentities(B\controllerUrl('admin', true));
        $group_url = "{$admin_url}a=manageGroups&amp;$token".
            "&amp;context=join_groups";
        ?>
        <div class="float-opposite">
        <form>
        <?php
        $paging_query = $group_url . "&amp;browse=true";
        $filter_paging_query = $paging_query;
        $icon_helper = $this->view->helper('iconlink');
        if (!empty($data["GROUP_FILTER"])) {
            $paging_query .= "&amp;group_filter=" . $data["GROUP_FILTER"];
            $filter_paging_query = $paging_query;
        }
        if (!empty($data["GROUP_SORT"])) {
            $paging_query .= "&amp;group_sort=" . $data["GROUP_SORT"];
        }
        $this->view->helper("options")->renderLinkDropDown(
            "group-sort", $data['group_sorts'],
            $data["GROUP_SORT"], "$filter_paging_query&amp;group_sort=",
            false, "",
            "<span class='hover-lightgray' role='img' aria-label='" .
            tl('groupfeed_element_sort_order') . "'>&#8645;</span>");
        ?>
        <input type="hidden" name="<?= C\p('CSRF_TOKEN') ?>"
            value="<?= $data[C\p('CSRF_TOKEN')] ?>" >
        <input type="hidden" name="a" value="manageGroups" >
        <input type="hidden" name="context" value="join_groups" >
        <input type="hidden" name="browse" value="true" >
        <input type="hidden" name="group_sort"
            value="<?= $data["GROUP_SORT"] ?>" >
        <div class="filter-container">
        <input type="search" class="narrow-field" name='group_filter'
            placeholder="<?=tl('groupfeed_element_group_filter') ?>"
            id='group-filter' value="<?=$data['GROUP_FILTER']?>" >
        </div>
        <button type="submit" class="button-box" ><?=
            tl('groupfeed_element_go')?></button>
        </form>
        </div><?=$this->view->element("socialcontrols")->render($data) ?><?php
        $is_exact_group_query = ($data['GROUP_FILTER'][0] ?? "") == "=";
        $this->view->helper("grouplist")->render($data['GROUPS'], $token,
            $icon_helper, "admin", "join_groups", $is_exact_group_query,
            modifiers: $data['GROUP_MODIFIERS']);
        $data['TOTAL_ROWS'] = $data['NUM_TOTAL'];
        if ($data['NUM_TOTAL'] > $data['RESULTS_PER_PAGE']) {
            $this->view->helper("pagination")->render(
                $paging_query, $data['LIMIT'], $data['RESULTS_PER_PAGE'],
                $data['TOTAL_ROWS']);
        }
    }
    /**
     * Draws the add groups and edit groups forms
     *
     * @param array $data consists of values of groups fields set
     *     so far as well as values of the drops downs on the form
     */
    public function renderGroupsForm($data)
    {
        $admin_url = htmlentities(B\controllerUrl('admin', true));
        $base_url = $admin_url . C\p('CSRF_TOKEN') . "=" .
            $data[C\p('CSRF_TOKEN')].
            "&amp;a=manageGroups&amp;visible_users=" . $data['visible_users'];
        $browse_url = $base_url . '&amp;arg=search&amp;browse=true';
        $group_settings = ($data['FORM_TYPE'] == "groupsettings") ? true :
            false;
        $creategroup = ($data['FORM_TYPE'] == "addgroup") ? true : false;
        $form_type = ($creategroup) ? "creategroup" : "groupsettings";
        ?>
        <form id="admin-form" method="post" enctype="multipart/form-data"><?php
        /* Each part of this form carries its own help, so the one button
           that stood for the whole of it is gone: a page covering every
           setting at once was too long to be read at the moment a writer
           wanted one of them. */
        if ($group_settings) {
            e("<h2>" . tl('managegroups_element_group_settings') . "</h2>");
        } else {
            e("<h2>" . tl('managegroups_element_create_group') . "</h2>");
        }
        ?>
        <input type="hidden" name="c" value="admin" >
        <input type="hidden" name="<?= C\p('CSRF_TOKEN') ?>" value="<?=
            $data[C\p('CSRF_TOKEN')] ?>" >
        <input type="hidden" name="a" value="manageGroups" >
        <input type="hidden" name="add_refer" value="0" >
        <input type="hidden" name="arg" value="<?=$form_type ?>" >
        <input type="hidden" name="context" value="<?=$data['CONTEXT'] ?>" >
        <input type="hidden" id="visible-users" name="visible_users"
            value="<?= $data['visible_users'] ?>" >
        <input type="hidden" name="group_id" value="<?=
            $data['CURRENT_GROUP']['id'] ?>" >
        <?php $this->renderOrganization($data, $base_url); ?>
        <?php $this->renderMembership($data, $base_url); ?>
        <?php $this->renderAppearance($data, $base_url); ?>
        <?php $this->renderFeeds($data, $base_url); ?>
        <?php $this->renderWikiSettings($data, $base_url); ?>
        <table class="name-table save-row">
        <tr><td colspan="2" class="center"><button class="button-box"
            id="focus-button"
            type="submit"><?= tl('managegroups_element_save')
            ?></button></td>
        </tr>
        </table>
        </form>
        <script>
        var user_ids = [];
        function arrayIntoFormVariable(arr, base_url, form_var)
        {
            arr_string = arr.join("*");
            return base_url + form_var + '='  + arr_string;
        }
        function updateCheckedUserIds(event)
        {
            var form = this.form;
            if (this.checked) {
              user_ids[user_ids.length] = this.value;
            } else {
                var index = user_ids.indexOf(this.value);
                if (index > -1) {
                     user_ids.splice(index, 1);
                }
            }
        }
        /*
         * Rebuilds the one line with commas between that the hidden
         * page_categories field carries, from the rows now standing in
         * the list. The form sends that field, so a row added or
         * dropped only counts once this has run.
         */
        function syncGroupCategories()
        {
            var hidden = elt('group-categories');
            if (!hidden) {
                return;
            }
            var texts = sel('#group-category-list .tag-text');
            var names = [];
            for (var i = 0; i < texts.length; i++) {
                names.push(texts[i].textContent);
            }
            hidden.value = names.join(',');
        }
        /*
         * Makes a row for one category name, holding the name and the
         * button that drops it, so a row added in the browser matches
         * one the page arrived with.
         */
        function groupCategoryRow(name, remove_label)
        {
            var row = ce('li');
            row.className = 'tag-item';
            var text = ce('span');
            text.className = 'tag-text';
            text.textContent = name;
            var remove = ce('button');
            remove.type = 'button';
            remove.className = 'tag-remove group-category-remove';
            remove.title = remove_label;
            remove.innerHTML = '&times;';
            row.appendChild(text);
            row.appendChild(remove);
            return row;
        }
        /*
         * Wires the category list's add and remove buttons. Adding
         * takes what is in the field, passes over a name already
         * standing or holding a comma, and puts a row in; removing
         * takes a row out. Either way the hidden field is rebuilt.
         * Removal is listened for on the list rather than on each
         * button, so a row added after the page loaded works too.
         */
        function initGroupCategoryList()
        {
            var add_button = elt('group-category-add-button');
            var add_input = elt('group-category-add');
            var list = elt('group-category-list');
            if (!add_button || !add_input || !list) {
                return;
            }
            var remove_label =
                add_button.getAttribute('data-remove-label') || '';
            listen(add_button, 'click', function () {
                var name = add_input.value.trim();
                if (name === '' || name.indexOf(',') > -1) {
                    return;
                }
                var texts = list.querySelectorAll('.tag-text');
                for (var i = 0; i < texts.length; i++) {
                    if (texts[i].textContent === name) {
                        add_input.value = '';
                        return;
                    }
                }
                list.appendChild(groupCategoryRow(name, remove_label));
                add_input.value = '';
                syncGroupCategories();
            });
            listen(list, 'click', function (event) {
                var pressed = event.target;
                if (!pressed ||
                    !pressed.classList.contains('group-category-remove')) {
                    return;
                }
                var row = pressed.parentNode;
                if (row && row.parentNode) {
                    row.parentNode.removeChild(row);
                    syncGroupCategories();
                }
            });
        }
        </script>
        <?php
    }
    /**
     * Draws the infomartion about a particular groups attributes
     *
     * @param array $data consists of values of groups fields
     */
    public function renderInfoGroup($data)
    {
        $group = $data['CURRENT_GROUP'];
        $token = C\p('CSRF_TOKEN') . "=" . $data[C\p('CSRF_TOKEN')];
        $user_feed = B\feedsUrl("user", $group['owner_id'],
                true, "group");
        ?>
        <h2><?= tl('managegroups_element_info_group') ?></h2>
        <table class="name-table">
        <tr><th class="table-label"><?=
            tl('managegroups_element_groupname') ?>:</th>
            <td><?= $group['name'] ?></td></tr>
        <tr><th class="table-label"><?=
            tl('managegroups_element_owner') ?>:</th>
            <td><a href="<?=$user_feed
                ?>"><img class="home-icon" src="<?=
                $group['user_icon']?>" alt="<?=
                tl('groupfeed_element_usericon') ?>" ><br>
                <?=$group['owner'] ?></a></td></tr>
        <tr><th class="table-label"><?=
            tl('managegroups_element_register')?>:</th>
            <td><?=$data["REGISTER_CODES"][$group['register']]
            ?></td></tr>
        <tr><th class="table-label"><?=
            tl('managegroups_element_memberaccess')?>:</th>
            <td><?=$data["ACCESS_CODES"][$group['member_access']]
            ?></td></tr>
        <tr><th class="table-label"><?=
            tl('managegroups_element_voting')?>:</th>
            <td><?= $data["VOTING_CODES"][$group['vote_access']]
            ?></td></tr>
        <tr><th class="table-label"><?=
            tl('managegroups_element_post_lifetime')?>:</th>
            <td><?=$data["POST_LIFETIMES"][$group['post_lifetime']] ?></td></tr>
        <tr><th class="table-label"><?=
            tl('managegroups_element_wikieditors') ?>:</th>
            <td><?= $group['name'] ?></td></tr>
        <tr><th class="table-label"><label for="encryption"><?=
            tl('managegroups_element_encryption')?>:</th>
            <td><?= ($group['encryption'] == 1) ?
                "Enabled" : "Disabled" ?></td></tr>
        <tr><th class="table-label"><?=
            tl('managegroups_element_group_users') ?>:</th>
            <td><?=$data['NUM_USERS_GROUP']?></td></tr>
        <?php if (!empty($data['SHOW_MAIL_PREF'])) { ?>
        <tr><th class="table-label"><label for="receive-group-mail"><?=
            tl('managegroups_element_receive_group_mail')?></label>:</th>
            <td><input type="checkbox" id="receive-group-mail"
            name="receive_group_mail" value="1"<?=
            empty($data['RECEIVE_GROUP_MAIL']) ? '' : ' checked'
            ?> form="group-mail-pref-form"></td></tr>
        <tr><th class="table-label"></th><td><button class="button-box"
            form="group-mail-pref-form" type="submit"><?=
            tl('managegroups_element_save')?></button></td></tr>
        <?php } ?>
        </table>
        <?php if (!empty($data['SHOW_MAIL_PREF'])) { ?>
        <form id="group-mail-pref-form" method="post">
        <input type="hidden" name="c" value="admin">
        <input type="hidden" name="<?=C\p('CSRF_TOKEN')?>" value="<?=
            $data[C\p('CSRF_TOKEN')]?>">
        <input type="hidden" name="a" value="manageGroups">
        <input type="hidden" name="arg" value="changemailpref">
        <input type="hidden" name="group_id" value="<?=
            $data['CURRENT_GROUP']['id']?>">
        <input type="hidden" name="return" value="<?=$data['FORM_TYPE']?>">
        </form>
        <?php } ?>
        <?php
    }
    /**
     * Draws form used to invite users to the current group
     * @param array $data from the admin controller with a
     *     'CURRENT_GROUP' field providing information about the
     *     current group as well as info about the current CSRF_TOKEN
     */
    public function renderInviteUsersForm($data)
    {
        $context = "";
        if (!empty($data['context'])) {
            $context = '&amp;context=search';
        }
        $admin_url = htmlentities(B\controllerUrl('admin', true));
        $base_url = $admin_url . C\p('CSRF_TOKEN') . "=" .
            $data[C\p('CSRF_TOKEN')].
            "&amp;a=manageGroups&amp;visible_users=true$context".
            "&amp;arg=groupsettings&amp;".
            "group_id=" . $data['CURRENT_GROUP']['id'];
        $this->view->helper("close")->render($base_url);
        ?>
        <h2><?= tl('managegroups_element_invite_users_group') ?></h2>
        <form id="admin-form" method="post">
        <input type="hidden" name="c" value="admin" >
        <input type="hidden" name="<?= C\p('CSRF_TOKEN') ?>" value="<?=
            $data[C\p('CSRF_TOKEN')] ?>" >
        <input type="hidden" name="a" value="manageGroups" >
        <input type="hidden" name="arg" value="<?=
            $data['FORM_TYPE']?>" >
        <?php
            if (!empty($data['context'])) {
                ?>
                <input type="hidden" name="context" value="search" >
                <?php
            }
        ?>
        <input type="hidden" name="group_id" value="<?=
            $data['CURRENT_GROUP']['id'] ?>" >
        <div>
        <b><label for="group-name"><?=
            tl('managegroups_element_groupname') ?></label>:</b>
            <input type="text" id="group-name"
                name="name"  maxlength="<?= C\SHORT_TITLE_LEN ?>"
                value="<?= $data['CURRENT_GROUP']['name'] ?>"
                class="narrow-field" disabled="disabled" >
        </div>
        <div>
        <b><label for="users-names"><?=
            tl('managegroups_element_usernames') ?></label></b>
        </div>
        <?php $center = 'class="center-wide"'; ?>
        <div <?= $center ?>>
        <textarea class="short-text-area" id='users-names'
            name='users_names'></textarea>
        <button class="button-box"
            type="submit"><?=tl('managegroups_element_invite')
            ?></button>
        </div>
        </form>
        <?php
    }
    /**
     * Draws group statistics related to number of users, popular threads
     * and wiki pages.
     *
     * @param array $data from the admin controller with a
     *     'CURRENT_GROUP' field providing information about the
     *     current group as well as info about the current CSRF_TOKEN
     */
    public function renderGroupStatistics($data)
    {
        $admin_url = htmlentities(B\controllerUrl('admin', true));
        $base_url = $admin_url . C\p('CSRF_TOKEN')."=" .
            $data[C\p('CSRF_TOKEN')].
            "&amp;a=manageGroups";
        $graph_stats_url = $base_url . "&amp;arg=graphstats&amp;group_id=".
            $data['CURRENT_GROUP']['id'];
        if (!empty($_REQUEST['browse']) && $_REQUEST['browse'] == 'true') {
            $graph_stats_url .= '&amp;browse=true';
        }
        ?>
        <h2><?= tl('managegroups_element_group_statistics',
        $data['CURRENT_GROUP']['name']) ?></h2>
        <form>
        <div>
        <b><label for='title-filter'><?=
        tl('managegroups_element_filter')?></label></b>
        <input type="text" class="narrow-field" name='filter'
            id='title-filter' value="<?=$data['FILTER']?>" >
        <input type="hidden" name='<?=C\p('CSRF_TOKEN')?>'
            value='<?=$data[C\p('CSRF_TOKEN')]?>' >
        <input type="hidden" name='arg' value='statistics' >
        <input type="hidden" name='group_id' value='<?=
            $data['CURRENT_GROUP']['id'] ?>' >
        <input type="hidden" name='a' value='manageGroups' >
        <input type="hidden" name='c' value='admin' >
        <button type='submit' name='filter_go' id='focus-button'
            class="button-box"><?=tl('managegroups_element_go') ?></button>
        </div></form>
        <?php
        $stat_types = [
            C\GROUP_IMPRESSION => tl('managegroups_element_group_views'),
            C\THREAD_IMPRESSION => tl('managegroups_element_thread_views'),
            C\WIKI_IMPRESSION => tl('managegroups_element_wiki_views'),
            ];
        $time_periods = [
           C\ONE_HOUR => tl('managegroups_element_last_hour'),
           C\ONE_DAY => tl('managegroups_element_last_day'),
           C\ONE_MONTH => tl('managegroups_element_last_month'),
           C\ONE_YEAR => tl('managegroups_element_last_year'),
           C\FOREVER => tl('managegroups_element_all_time'),
        ];
        foreach ($stat_types as $field => $heading) {?>
            <h3><?=$heading ?></h3>
            <div class="trending-container">
            <?php
            if ($field == C\GROUP_IMPRESSION) {?>
                <div class="trending-float">
                <table class="trending-table">
                <?php
            }
            foreach ($time_periods as  $time_period => $period_heading) {
                if ($field == C\GROUP_IMPRESSION) { ?>
                    <tr><th><?=$period_heading?></th><?php
                    if (empty($data['STATISTICS'][$field][
                        $time_period][0]['NUM_VIEWS'])) {?>
                        <td><?=
                            tl('managegroups_element_no_activity')
                        ?></td><?php
                    } else {
                        if ($time_period == C\ONE_HOUR ||
                            $time_period == C\FOREVER ||
                            C\p('DIFFERENTIAL_PRIVACY')) { ?>
                            <td><?=
                            $data['STATISTICS'][$field]
                            [$time_period][0]['NUM_VIEWS']?>
                            </td><?php
                        } else {?>
                            <td><a href='<?=$graph_stats_url .
                            "&amp;impression=" . $field .
                            "&amp;time=" . $time_period .
                            "&amp;item=" . $data['STATISTICS'][$field]
                            [$time_period][0]['ID']?>'><?=
                            $data['STATISTICS'][$field]
                            [$time_period][0]['NUM_VIEWS']?>
                            </a></td><?php
                        }
                    }?>
                    </tr><?php
                } else {?>
                    <div class="trending-float">
                    <table class="trending-table">
                    <tr class="trending-tr">
                    <th class="trending-th" ><?=$period_heading ?></th>
                    <th class="trend-score trending-th"><?=
                        tl('managegroups_element_views');
                    ?></th></tr><?php
                    if (!empty($data['STATISTICS'][$field][
                        $time_period])) {
                        $background = "";
                        foreach ($data['STATISTICS'][$field][
                            $time_period] as $item_name => $item_data) {
                            $background = empty($background) ?
                                " class='back-gray' " : "";?>
                            <tr <?=$background ?>>
                            <td class="trending-td"><?=$item_name
                            ?></td><td class="trend-score trending-td"><?php
                            if ($time_period == C\ONE_HOUR ||
                                $time_period == C\FOREVER ||
                                C\p('DIFFERENTIAL_PRIVACY')) {
                                e($item_data[0]['NUM_VIEWS']);
                            } else {?>
                                <a href='<?=$graph_stats_url.
                                    "&amp;impression=".$field.
                                    "&amp;time=".$time_period.
                                    "&amp;item=".$item_data[0]['ID']?>'><?=
                                    $item_data[0]['NUM_VIEWS'] ?>
                                    </a><?php
                            }?></td></tr><?php
                        }
                    } else {?>
                        <tr class='back-gray'><td colspan="2"><?=
                            tl('managegroups_element_no_activity') ?>
                        </td>
                        </tr><?php
                    }?>
                    </table>
                    </div><?php
                }
            }
            if ($field == C\GROUP_IMPRESSION) {?>
                </table>
                </div><?php
            }?>
            </div><?php
        }
    }
    /**
     * Draws the search for groups forms
     *
     * @param array $data consists of values of role fields set
     *     so far as well as values of the drops downs on the form
     */
    public function renderSearchForm($data)
    {
        $controller = "admin";
        $activity = "manageGroups";
        $view = $this->view;
        if (isset($data['browse'])) {
            $title = tl('managegroups_element_search_joinable');
            $title .= "&nbsp;" . $view->helper("helpbutton")->render(
            "Discover Groups", $data[C\p('CSRF_TOKEN')]);
        } else {
            $title = tl('managegroups_element_search_subscribed');
        }
        $fields = [
            tl('managegroups_element_groupname') => "name",
            tl('managegroups_element_groupowner') => "owner",
            tl('managegroups_element_registertype') =>
                ["register", $data['EQUAL_COMPARISON_TYPES']],
            tl('managegroups_element_memberaccess') =>
                ["access", $data['EQUAL_COMPARISON_TYPES']],
            tl('managegroups_element_post_lifetime') =>
                ["lifetime", $data['EQUAL_COMPARISON_TYPES']]
        ];
        $dropdowns = [
            "register" => $data['REGISTER_CODES'],
            "access" => $data['ACCESS_CODES'],
            "voting" => $data['VOTING_CODES'],
            "lifetime" => $data['POST_LIFETIMES']
        ];
        $view->helper("searchform")->render($data, $controller, $activity,
            $view, $title, $fields, $dropdowns);
    }
    /**
     * Draws chart of the group statistics in terms of number
     * of views in different time periods.
     *
     * @param array $data from the social component controller
     *     containing statistical information of specific group item
     *     including time period, number of views, update timestamp
     */
    public function renderGraphStats($data)
    {
        $admin_url = htmlentities(B\controllerUrl('admin', true));
        $base_url = $admin_url . C\p('CSRF_TOKEN')."=".$data[C\p('CSRF_TOKEN')].
            "&amp;a=manageGroups&amp;arg=statistics&amp;group_id=".
            $data['CURRENT_GROUP']['id'];
        ?>
        <?php
        $stat_types = [
            C\GROUP_IMPRESSION => tl('managegroups_element_group_views'),
            C\THREAD_IMPRESSION => tl('managegroups_element_thread_views'),
            C\WIKI_IMPRESSION => tl('managegroups_element_wiki_views'),
            ];
        $time_periods = [
           C\ONE_HOUR => tl('managegroups_element_last_hour'),
           C\ONE_DAY => tl('managegroups_element_last_day'),
           C\ONE_MONTH => tl('managegroups_element_last_month'),
           C\ONE_YEAR => tl('managegroups_element_last_year'),
           C\FOREVER => tl('managegroups_element_all_time'),
        ];
        $total_view = 0;
        if (array_key_exists(C\ONE_DAY, $data['STATISTICS'])) {
            $period = C\ONE_DAY;
            $column_name = tl('managegroups_element_hour');
            $dt_format = "m-d-Y H:i";
        } else if (array_key_exists(C\ONE_MONTH, $data['STATISTICS'])) {
            $period = C\ONE_MONTH;
            $column_name = tl('managegroups_element_day');
            $dt_format = "m-d-Y";
        } else if (array_key_exists(C\ONE_YEAR, $data['STATISTICS'])) {
            $period = C\ONE_YEAR;
            $column_name = tl('managegroups_element_month');
            $dt_format = "m-d-Y";
        }
        ?>
        <h2><?= $data['CURRENT_GROUP']['name']." ".
            $stat_types[$data['STATISTICS'][$period][0]['TYPE']]." : ".
            $time_periods[$period] ?></h2>
        <div id="chart"></div>
        <table class="stat-table table-center">
            <tr>
                <th><?= $column_name ?></th>
                <th><?= tl('managegroups_element_num_visits')?></th>
            </tr>
        <?php
        foreach ($data['STATISTICS'] as $statistics => $statistics_array) {
            foreach ($statistics_array as $key => $statistics_value) {
                ?>
                <tr>
                <?php
                $timestamp = $statistics_value['UPDATE_TIMESTAMP'];
                $dt = date($dt_format, $timestamp);
                $total_view += $statistics_value['VIEWS'];
                ?>
                <td><?= $dt ?></td>
                <td><?= $statistics_value['VIEWS'] ?></td>
                </tr>
                <?php
            }
        }
        ?>
        <tr>
            <th>Total</th>
            <td><?= $total_view ?></td>
        </tr>
        </table>
        <?php
    }
    /**
     * renderOrganization draws the fieldset naming the group, saying who
     * may join it and who may post to it.
     *
     * renderGroupsForm calls it, so the group settings form is
     * read one fieldset at a time rather than in one long
     * method.
     *
     * @param array $data the group's settings and the token
     *     every form on the page carries
     * @param string $base_url the address a control on this
     *     fieldset sends the reader to
     */
    public function renderOrganization($data, $base_url)
    {
        $group_settings = ($data['FORM_TYPE'] == "groupsettings");
        ?>
        <fieldset><legend><?=
            tl('social_component_fieldset_organization') . "&nbsp;" ?><?=
            $this->view->helper("helpbutton")->render("Group Organization",
            $data[C\p('CSRF_TOKEN')]) ?></legend>
        <table class="name-table">
        <tr><th class="table-label"><label for="group-name"><?=
            tl('managegroups_element_groupname') ?></label>:</th>
            <td><input type="text" id="group-name"
                name="name"  maxlength="<?= C\SHORT_TITLE_LEN ?>"
                value="<?= $data['CURRENT_GROUP']['name'] ?>"
                class="narrow-field" <?php
                if (!empty($data['CURRENT_GROUP']['name'])) {
                    e(' disabled="disabled" ');
                }
                ?> ></td><?php
        ?></tr><?php
        ?>
        <?php
        if ($group_settings) {?>
            <tr><th class="table-label"><label for="owner-name"><?=
                tl('managegroups_element_owner') ?></label>:</th>
                <td><input type="text" id="owner-name"
                    name="owner"  maxlength="<?= C\SHORT_TITLE_LEN ?>"
                    value="<?= $data['CURRENT_GROUP']['owner'] ?>"
                    class="narrow-field" ></td></tr><?php
        }?>
        <tr><th class="table-label"><label for="register-type"><?=
            tl('managegroups_element_register')?></label>:</th>
            <td><?php
                $this->view->helper("options")->render(
                    "register-type", "register", $data["REGISTER_CODES"],
                     $data['CURRENT_GROUP']['register']);
                ?></td></tr>
        </table></fieldset>
        <?php
    }
    /**
     * renderMembership draws the fieldset listing the group's members and
     * what each of them may do.
     *
     * renderGroupsForm calls it, so the group settings form is
     * read one fieldset at a time rather than in one long
     * method.
     *
     * @param array $data the group's settings and the token
     *     every form on the page carries
     * @param string $base_url the address a control on this
     *     fieldset sends the reader to
     */
    public function renderMembership($data, $base_url)
    {
        $group_settings = ($data['FORM_TYPE'] == "groupsettings");
        $creategroup = ($data['FORM_TYPE'] == "addgroup");
        ?>
        <fieldset id="group-membership"><legend><?=
            tl('social_component_fieldset_membership') . "&nbsp;" ?><?=
            $this->view->helper("helpbutton")->render("Group Membership",
            $data[C\p('CSRF_TOKEN')]) ?></legend>
        <table class="name-table">
        <tr><th class="table-label"><label for="member-access"><?=
            tl('managegroups_element_memberaccess')?></label>:</th>
            <td><?php
                $this->view->helper("options")->render(
                    "member-access", "member_access", $data["ACCESS_CODES"],
                    $data['CURRENT_GROUP']['member_access']);
                ?></td></tr>
        <tr><th class="table-label"><label for="encryption"><?=
            tl('managegroups_element_encryption')?></label>:</th>
            <?php
            if ($group_settings) {
                ?>
                <td><input type="text" id="encryption"
                    name="encryption"
                    value="<?= ($data['CURRENT_GROUP']['encryption'] == 1) ?
                          "Enabled" : "Disabled" ?>"
                    class="narrow-field" <?php
                    if (isset($data['CURRENT_GROUP']['encryption'])) {
                        e(' disabled="disabled" ');
                    }
                ?> ></td><?php
            }
            if ($creategroup) { ?>
            <td><?php
                $this->view->helper("options")->render(
                    "encryption", "encryption",
                    $data["ENCRYPTION_CODES"],
                    $data['CURRENT_GROUP']['encryption']);
                ?></td>
                <?php
            }
        ?></tr><?php
        ?>
        <?php
        if (!empty($data['SHOW_MAIL_PREF'])) { ?>
        <tr><th class="table-label"><label for="receive-group-mail"><?=
            tl('managegroups_element_receive_group_mail')?></label>:</th>
            <td><input type="checkbox" id="receive-group-mail"
            name="receive_group_mail" value="1"<?=
            empty($data['RECEIVE_GROUP_MAIL']) ? '' : ' checked'?>><input
            type="hidden" name="mail_pref_shown" value="1"></td></tr>
        <?php }
        ?>
        <?php if ($group_settings) { ?>
            <tr class="stack-narrow"><th class="table-label"
                style="vertical-align:top;
                padding-top:9px;"><?=
                tl('managegroups_element_group_users') ?>:</th><?php
                $context = "";
                if (!empty($data['context'])) {
                    $context = '&amp;context=search';
                }
                $sort_string = urlencode(json_encode(
                    $data['USER_SORTS']));
                $action_url = "$base_url$context&amp;group_id=".
                    $data['CURRENT_GROUP']['id'].
                    "&amp;user_filter=" . $data['USER_FILTER'] .
                    "&amp;user_sorts=" . $sort_string;
                $dropdown_action_url = $action_url. "&amp;";
                $toggle_visible = ($data['visible_users'] == 'true') ?
                    'false' : "true";
                ?><td ><div class='light-gray-box'>
                <div class="center">
                    [<a href="<?=$action_url .
                        '&amp;arg=groupsettings&amp;visible_users='.
                        $toggle_visible . '#group-membership' ?>"><?=
                            tl('managegroups_element_num_users',
                            $data['NUM_USERS_GROUP'])?></a>]<?php
                        $user_actions = [
                            "&amp;arg=banuser" =>
                                tl('managegroups_element_ban'),
                            "&amp;arg=deleteuser" =>
                                tl('managegroups_element_delete'),
                            "&amp;arg=activateuser" =>
                                tl('managegroups_element_activate'),
                            "&amp;arg=makeeditor" =>
                                tl('managegroups_element_makeeditor')
                        ];
                        if ($data['visible_users'] == 'true') {
                            $with_selected_actions = [
                                -1 => tl('managegroups_element_with_selected')];
                            $with_selected_actions += $user_actions;
                            $this->view->helper("options")->render(
                                "with-selected-users", "with_selected",
                                $with_selected_actions, -1, '
                                    var ids_string = arrayIntoFormVariable(
                                        user_ids, "'.$dropdown_action_url.'",
                                        "user_ids");
                                    window.location = ids_string +
                                        this[this.selectedIndex].value;
                                ', ["aria-label" =>
                                $with_selected_actions[-1]]);
                        } ?>
                </div>
                <?php
                if ($data['visible_users'] == 'true') {
                    $action_url = "$base_url&amp;arg=groupsettings".
                        "$context&amp;group_id=" . $data['CURRENT_GROUP']['id'].
                        "&amp;user_filter=" . $data['USER_FILTER'];
                    $sort_urls = ['USER_NAME' => '', 'JOIN_DATE'  => '',
                        'STATUS' => ''];
                    foreach ($sort_urls as $field => $url) {
                        $user_sorts = $data['USER_SORTS'];
                        $sort_dir = (empty($user_sorts[$field]) ||
                            $user_sorts[$field]=='ASC') ? 'DESC' : 'ASC';
                        unset($user_sorts[$field]);
                        $user_sorts = array_merge([$field => $sort_dir],
                            $user_sorts);
                        $user_sorts = urlencode(json_encode($user_sorts));
                        $sort_urls[$field] =
                            "$action_url&amp;user_sorts=$user_sorts";
                    }
                    ?>
                    <table><tr><td></td>
                    <th><a href='<?=$sort_urls['USER_NAME'] ?>'><?=
                        tl('managegroups_element_name') ?></a></th><?php
                    ?>
                        <th class="hide-narrow"><a
                            href='<?=$sort_urls['JOIN_DATE'] ?>'><?=
                            tl('managegroups_element_join_date') ?></a></th>
                            <?php
                        ?>
                    <th><a href='<?=$sort_urls['STATUS'] ?>'><?=
                        tl('managegroups_element_status') ?></a></th>
                    </tr>
                    <?php
                    $stretch = ($_SERVER["MOBILE"]) ? 1 : 2;
                    foreach ($data['GROUP_USERS'] as $user_array) {
                        $action_url = $base_url."&amp;user_ids=" .
                            $user_array['USER_ID'] . "$context&amp;group_id=".
                            $data['CURRENT_GROUP']['id'].
                            "&amp;user_filter=".$data['USER_FILTER'] .
                            "&amp;user_sorts=$sort_string";
                        $out_name = $user_array['USER_NAME'];
                        $is_owner = $data['CURRENT_GROUP']['owner'] ==
                            $user_array['USER_NAME'];
                        if (strlen($out_name) > $stretch *
                            C\NAME_TRUNCATE_LEN) {
                            $out_name = wordwrap($out_name,
                                $stretch * C\NAME_TRUNCATE_LEN, "\n", true);
                        }
                        $join_date = (empty($user_array["JOIN_DATE"])) ? 0:
                            $user_array["JOIN_DATE"];
                        e("<tr><td><input type='checkbox' " .
                            "id='user-" . $user_array['USER_ID'].
                            "' class='user-id'".
                            " name='" . $user_array['USER_ID']. "' ".
                            (($is_owner) ? "disabled='disabled'": "").
                            " value= " . $user_array['USER_ID'] . " >");
                        e("</td><td><b><label for='user-" .
                        $user_array['USER_ID'] . "'>". $out_name.
                        "</label></b></td>");
                        e("<td class='hide-narrow'>" .
                            date('m/d/Y', $join_date). "</td>");
                        if ($is_owner) {
                            e("<td>" . tl('managegroups_element_groupowner') .
                                "</td>");
                        } else {
                            $current_user_actions = [-1 =>
                                $data['MEMBERSHIP_CODES'][$user_array['STATUS']]
                                ];
                            $limit = false;
                            if (!empty($data['USER_FILTER']) ||
                                (isset($data['NUM_USERS_GROUP']) &&
                                $data['NUM_USERS_GROUP'] >
                                C\NUM_RESULTS_PER_PAGE)) {
                                $limit = isset($data['GROUP_LIMIT']) ?
                                    "&amp;group_limit=" .$data['GROUP_LIMIT']
                                    : "";
                            }
                            foreach ($user_actions as $action_fragment =>
                                $action_name) {
                                $current_user_actions[$action_fragment .
                                    "&amp;user_ids=" . $user_array['USER_ID'].
                                    $limit] = $action_name;
                            }
                            e("<td>");
                            $this->view->helper("options")->render(
                                "actions-{$user_array['USER_ID']}",
                                "action_{$user_array['USER_ID']}",
                                $current_user_actions, -1,
                                'window.location = "'.
                                    rtrim($dropdown_action_url, "&amp;") .
                                    '" + this[this.selectedIndex].value;');
                            e("</td>");
                        }
                        e("</tr>");
                    }
                    $center = 'class="center-wide"';
                    if ($data['USER_FILTER'] != "" ||
                        (isset($data['NUM_USERS_GROUP']) &&
                        $data['NUM_USERS_GROUP'] > C\NUM_RESULTS_PER_PAGE)) {
                        $limit = isset($data['GROUP_LIMIT']) ?
                            $data['GROUP_LIMIT']:  0;
                        ?>
                        <tr>
                        <td class="right"><?php
                            if ($limit >= C\NUM_RESULTS_PER_PAGE) {
                                ?><a href='<?= $action_url .
                                    "&amp;arg=groupsettings&amp;group_limit=".
                                    ($limit - C\NUM_RESULTS_PER_PAGE) ?>'
                                    >&lt;&lt;</a><?php
                            }
                            ?>
                            </td>
                            <td class="center">
                                <input class="very-narrow-field center"
                                    id="user-filter"
                                    placeholder="<?=
                                        tl('managegroups_element_filter')?>"
                                    name="user_filter" type="text"
                                    maxlength="<?= C\NAME_LEN ?>"
                                    value='<?= $data['USER_FILTER'] ?>' >
                                </td>
                            <td class="left"><?php
                            if ($data['NUM_USERS_GROUP'] > $limit +
                                C\NUM_RESULTS_PER_PAGE) {
                                ?><a href='<?=$action_url.
                                    "&amp;arg=groupsettings&amp;group_limit=".
                                    ($limit + C\NUM_RESULTS_PER_PAGE) ?>'
                                    >&gt;&gt;</a>
                            <?php
                            }
                            ?>
                            </td>
                        </tr>
                    <?php
                    }
                    ?>
                    <tr>
                    <td colspan="6" <?=$center ?>>&nbsp;&nbsp;[<a href='<?=
                        $action_url ?>&amp;arg=inviteusers'><?=
                        tl('managegroups_element_invite')?></a>]&nbsp;&nbsp;
                    </td>
                    </tr>
                    </table>
                </div>
                </td></tr><?php
            } else {?>
                </div></td></tr><?php
            }
        } ?>
        </table></fieldset>
        <?php
    }
    /**
     * renderAppearance draws the fieldset naming the group's colors and
     * the header and footer its pages carry.
     *
     * renderGroupsForm calls it, so the group settings form is
     * read one fieldset at a time rather than in one long
     * method.
     *
     * @param array $data the group's settings and the token
     *     every form on the page carries
     * @param string $base_url the address a control on this
     *     fieldset sends the reader to
     */
    public function renderAppearance($data, $base_url)
    {
        ?>
        <fieldset><legend><?=
            tl('social_component_fieldset_appearance') . "&nbsp;" ?><?=
            $this->view->helper("helpbutton")->render("Group Appearance",
            $data[C\p('CSRF_TOKEN')]) ?></legend>
        <table class="name-table">
        <tr><th class="table-label"><label for="render-engine"><?=
            tl('managegroups_element_render_engine')?></label>:</th>
            <td><?php
                $this->view->helper("options")->render(
                    "render-engine", "render_engine",
                    $data["RENDER_CODES"],
                    $data['CURRENT_GROUP']['render_engine']);
                ?></td></tr>
        <tr><th class="table-label"><label for="group-theme"><?=
            tl('social_component_group_theme') ?></label>:</th>
            <td><?php
                $this->view->helper("options")->render("group-theme",
                    "group_theme", $data['GROUP_THEMES'],
                    $data['CURRENT_GROUP']['group_theme'] ?? "");
                ?></td></tr>
        <tr><th class="table-label"><label for="group-page-header"><?=
            tl('social_component_group_page_header') ?></label>:</th>
            <td><input type="text" id="group-page-header"
                name="page_header" maxlength="<?= C\TITLE_LEN ?>"
                value="<?= $data['CURRENT_GROUP']['page_header'] ?? ""
                ?>" class="narrow-field" ></td></tr>
        <tr><th class="table-label"><label for="group-page-footer"><?=
            tl('social_component_group_page_footer') ?></label>:</th>
            <td><input type="text" id="group-page-footer"
                name="page_footer" maxlength="<?= C\TITLE_LEN ?>"
                value="<?= $data['CURRENT_GROUP']['page_footer'] ?? ""
                ?>" class="narrow-field" ></td></tr>
        <tr><th class="table-label"><label for="page-customize"><?=
            tl('managegroups_element_page_customize') ?></label>:</th>
            <td><?php
                $this->view->helper("options")->render("page-customize",
                    "page_customize_allowed",
                    $data["PAGE_CUSTOMIZE_CODES"],
                    $data['CURRENT_GROUP']['page_customize_allowed'] ?? 1);
                ?></td></tr>
        </table></fieldset>
        <?php
    }
    /**
     * renderFeeds draws the fieldset saying how the group's posts reach a
     * reader and how long they are kept.
     *
     * renderGroupsForm calls it, so the group settings form is
     * read one fieldset at a time rather than in one long
     * method.
     *
     * @param array $data the group's settings and the token
     *     every form on the page carries
     * @param string $base_url the address a control on this
     *     fieldset sends the reader to
     */
    public function renderFeeds($data, $base_url)
    {
        $group_settings = ($data['FORM_TYPE'] == "groupsettings");
        ?>
        <fieldset><legend><?=
            tl('social_component_fieldset_feeds') . "&nbsp;" ?><?=
            $this->view->helper("helpbutton")->render("Group Feeds",
            $data[C\p('CSRF_TOKEN')]) ?></legend>
        <table class="name-table">
        <tr><th class="table-label"><label for="post-lifetime"><?=
            tl('managegroups_element_post_lifetime')?></label>:</th>
            <td><?php
                $this->view->helper("options")->render(
                    "post-lifetime", "post_lifetime",
                    $data["POST_LIFETIMES"],
                    $data['CURRENT_GROUP']['post_lifetime']);
                ?></td></tr>
        <tr><th class="table-label"><label for="vote-access"><?=
            tl('managegroups_element_voting')?></label>:</th>
            <td><?php
                $this->view->helper("options")->render(
                    "vote-access", "vote_access", $data["VOTING_CODES"],
                    $data['CURRENT_GROUP']['vote_access']);
                ?></td></tr>
        <?php if ($group_settings) { ?>
            <tr><th class="table-label" style="vertical-align:top;
                padding-top:9px;"><?=
                tl('managegroups_element_feed') ?>:</th>
                <td><div class='light-gray-box'>
                <div class="center">
                <script>
                document.write('[<a href="javascript:toggleDisplay('+
                    "'upload-toggle'" +
                    ')" ><?=tl('managegroups_element_import_discussions')
                    ?></a>]');
                </script>
                <noscript>
                [<?=tl('managegroups_element_import_discussions')?>]
                </noscript>
                </div>
                <div id='upload-toggle' >
                <div id='discussion-upload'
                    class="media-upload-box" >&nbsp;</div>
                <?php
                    $this->view->helper("fileupload")->render(
                        'discussion-upload',
                        'DISCUSSION_DATA', 'discussion-data',
                        min(L\metricToInt(ini_get('upload_max_filesize')),
                        L\metricToInt(ini_get('post_max_size'))),
                        'text', []);
                ?>
                </div></div>
                <script>
                document.getElementById('upload-toggle').style.display = "none";
                </script>
                </td>
                </tr>
        <?php } ?>
        </table></fieldset>
        <?php
    }
    /**
     * renderWikiSettings draws the fieldset saying what a reader may do
     * with the group's wiki pages.
     *
     * renderGroupsForm calls it, so the group settings form is
     * read one fieldset at a time rather than in one long
     * method.
     *
     * @param array $data the group's settings and the token
     *     every form on the page carries
     * @param string $base_url the address a control on this
     *     fieldset sends the reader to
     */
    public function renderWikiSettings($data, $base_url)
    {
        ?>
        <fieldset><legend><?=
            tl('social_component_fieldset_wiki') . "&nbsp;" ?><?=
            $this->view->helper("helpbutton")->render("Group Wiki",
            $data[C\p('CSRF_TOKEN')]) ?></legend>
        <table class="name-table">
        <tr><th class="table-label"><label for="default-page-type"><?=
            tl('social_component_group_default_page_type')?></label>:</th>
            <td><?php
                $this->view->helper("options")->render(
                    "default-page-type", "default_page_type",
                    $data["PAGE_TYPES"] ?? [],
                    $data['CURRENT_GROUP']['default_page_type'] ?? "");
                ?></td></tr>
        <tr><th class="table-label"><label for="page-source"><?=
            tl('managegroups_element_page_source')?></label>:</th>
            <td><?php
                $this->view->helper("options")->render(
                    "page-source", "page_source_allowed",
                    $data["PAGE_SOURCE_CODES"],
                    $data['CURRENT_GROUP']['page_source_allowed']);
                ?></td></tr>
        <tr><th class="table-label"><label for="page-list"><?=
            tl('managegroups_element_page_list')?></label>:</th>
            <td><?php
                $this->view->helper("options")->render(
                    "page-list", "page_list_allowed",
                    $data["PAGE_LIST_CODES"],
                    $data['CURRENT_GROUP']['page_list_allowed']);
                ?></td></tr>
        <tr><th class="table-label"><label for="group-category-add"><?=
            tl('social_component_group_categories')?></label>:</th>
            <td><?php
                /* The names this group's pages may be filed under. Each
                   stands on its own row with a way to drop it, and a
                   field below adds another, the way a domain is added on
                   the servers page. What is sent is still the one line
                   with commas between that the model expects, kept in
                   the hidden field below and rebuilt as rows come and
                   go. */
                $category_line = trim((string)
                    ($data['CURRENT_GROUP']['page_categories'] ?? ""));
                $category_names = ($category_line === "") ? [] :
                    array_filter(array_map('trim',
                    explode(",", $category_line)));
                ?><ul class="tag-list" id="group-category-list"><?php
                foreach ($category_names as $category_name) {
                    ?><li class="tag-item"><span class="tag-text"><?=
                        $category_name ?></span><button type="button"
                        class="tag-remove group-category-remove"
                        title="<?=
                        tl('social_component_group_category_remove')
                        ?>">&times;</button></li><?php
                }
                ?></ul>
                <div class="tag-add-row">
                    <input type="text" id="group-category-add"
                        class="wide-field" maxlength="<?= C\TITLE_LEN ?>"
                        placeholder="<?=
                        tl('social_component_group_category_placeholder')
                        ?>" >
                    <button type="button" id="group-category-add-button"
                        class="button-box" data-remove-label="<?=
                        tl('social_component_group_category_remove')
                        ?>"><?=
                        tl('social_component_group_category_add')
                        ?></button>
                </div>
                <input type="hidden" id="group-categories"
                    name="page_categories" value="<?=
                    implode(",", $category_names) ?>" >
                </td></tr>
        </table></fieldset>
        <?php
    }
}
