<?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 Chris Pollett chris@pollett.org
 * @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;

/**
 * Used to draw the admin screen on which admin users can create roles, delete
 * roles and add and delete activitiess from roles
 *
 * @author Chris Pollett
 */
class ManagerolesElement extends Element
{
    /**
     * renders the screen in which roles can be created, deleted, and activities
     * can be added to and deleted from a selected roles
     *
     * @param array $data  contains antiCSRF token, as well as data on
     *     available roles or which activity has what role
     */
    public function render($data)
    {?>
        <div class="current-activity">
        <?= $this->renderRoleTable($data); ?>
        </div>
        <?php
    }
    /**
     * Draws the table to display thhe currently available roles
     * and their properties in this Yioop system
     * @param array $data info about current users and current roles, CSRF token
     */
    public function renderRoleTable($data)
    {
        $data['TABLE_TITLE'] = tl('manageroles_element_roles');
        $data['ACTIVITY'] = 'manageRoles';
        $data['VIEW'] = $this->view;
        $data['NO_FLOAT_TABLE'] = false;
        if (in_array($data['FORM_TYPE'], ['editrole', 'search'])) {
            $data['DISABLE_ADD_TOGGLE'] = true;
        }
        $admin_url = htmlentities(B\controllerUrl('admin', true));
        $base_url = $admin_url . C\p('CSRF_TOKEN')."=".$data[C\p('CSRF_TOKEN')].
            "&amp;a=manageRoles";
        $context = "";
        $arg_context = "";
        if ($data['FORM_TYPE'] == 'search' ||
            !empty($data['context']) && $data['context'] == 'search') {
            $context = 'context=search&amp;';
            $arg_context = "&amp;arg=search";
        }
        if ($data['FORM_TYPE'] == 'editrole') {
            $this->view->helper("close")->render($base_url . $arg_context);
            $this->renderRoleForm($data);
            return;
        }
        $icon_helper = $this->view->helper('iconlink');
        ?>
        <div id='role-info' >
        <table class="admin-table">
            <tr><td class="no-border" colspan="3"><?=$this->view->helper(
                "pagingtable")->render($data); ?><?php
                if ($data['FORM_TYPE'] != "editrole") { ?>
                    <div id='admin-form-row' class='admin-form-row'><?php
                    if ($data['FORM_TYPE'] == "search") {
                        $this->renderSearchForm($data);
                    } else {
                        $this->renderRoleForm($data);
                    }?>
                    </div><?php
                }?></td>
            </tr>
            <tr>
                <th><?= tl('manageroles_element_rolename')?></th>
                <th colspan='2'><?= tl('manageroles_element_actions') ?></th>
            </tr><?php
            if (isset($data['START_ROW'])) {
                $base_url .= "&amp;start_row=".$data['START_ROW'].
                    "&amp;end_row=".$data['END_ROW'].
                    "&amp;num_show=".$data['NUM_SHOW'];
            }
            $delete_url = $base_url . "&amp;arg=deleterole&amp;$context";
            $edit_url = $base_url . "&amp;arg=editrole&amp;$context";
            $stretch = ($_SERVER["MOBILE"]) ? 1 :2;
            foreach ($data['ROLES'] as $role) {?>
                <tr><?php
                foreach ($role as $colname => $role_column) {
                    if (strlen($role_column) > $stretch * C\NAME_TRUNCATE_LEN) {
                        $role_column = wordwrap($role_column,
                             $stretch * C\NAME_TRUNCATE_LEN, "\n", true);
                    }
                    e("<td>$role_column</td>");
                }?>
                <td><?=
                    $icon_helper->renderLink($edit_url . 'name='.
                        urlencode($role['NAME']), "edit", "",
                        false, "large-padding"); ?></td><?php
                $disabled = in_array($role['NAME'], ['Admin', 'User',
                    'Bot User']);
                $back_gray = ($disabled ) ? " class='back-light-gray' " : "";
                ?>
                <td<?=$back_gray?>><?php
                    if ($disabled) {
                        $icon_helper->renderLink("javascript:return false;",
                            "delete", "", false, "large-padding disabled");
                    } else {
                        $icon_helper->renderLink($delete_url . 'name='.
                            $role['NAME'], "delete", "",false, "large-padding");
                    } ?></td>
                </tr><?php
            }?>
        </table>
        <div class="clear show-narrow">&nbsp;</div>
        </div><?php
    }
    /**
     * Draws the add role and edit role 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 renderRoleForm($data)
    {
        $admin_url = htmlentities(B\controllerUrl('admin', true));
        $base_url = $admin_url . C\p('CSRF_TOKEN')."=".$data[C\p('CSRF_TOKEN')].
            "&amp;a=manageRoles";
        $paging = "";
        $is_mobile = !empty($data['MOBILE']);
        if (isset($data['START_ROW'])) {
            $paging = "&amp;start_row=".$data['START_ROW'].
                "&amp;end_row=".$data['END_ROW'].
                "&amp;num_show=".$data['NUM_SHOW'];
            $base_url .= $paging;
        }
        $editrole = ($data['FORM_TYPE'] == "editrole") ? true: false;?>
        <form id="admin-form" method="post"><?php
        if ($editrole) {
            e("<h2>" . tl('manageroles_element_role_info') . "</h2>");
        } else {
            e("<h2>" . tl('manageroles_element_add_role') . "</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="manageRoles" >
        <input type="hidden" name="arg" value="<?= $data['FORM_TYPE'] ?>" >
        <table class="name-table">
        <tr><th class="table-label"><label for="role-name"><?=
            tl('manageroles_element_rolename') ?></label>:</th>
            <td><input type="text" id="role-name"
                name="name"  maxlength="<?= C\NAME_LEN  ?>"
                value="<?= $data['CURRENT_ROLE']['name'] ?>"
                class="narrow-field <?=(!$editrole) ? "adjacent-button-field" :
                    "" ?>" <?php
                if ($editrole) {
                    e(' disabled="disabled" ');
                }
                ?> ><?php
                if ($editrole) {
                    /* The box above is shown but cannot be typed in
                       while a role is being edited, and a browser sends
                       nothing for a box in that state. Every action on
                       this screen needs to say which role it is acting
                       on, so the name rides in a field of its own. */
                    ?><input type="hidden" name="name" value="<?=
                        $data['CURRENT_ROLE']['name'] ?>" ><?php
                }
                if (!$editrole) {
                    ?><button class="button-box"
                    type="submit"><?= tl('manageroles_element_save')
                    ?></button><?php
                }?></td></tr>
        <?php
        if ($editrole) {
            $context = "";
            $mobile_span = ($is_mobile) ? " colspan='2' " : "";
            $mobile_end_row = ($is_mobile) ? "</tr><tr> " : "";
            $mobile_align = ($is_mobile) ? " align-same " : "";
            if (!empty($data['context']) && $data['context'] == 'search') {
                $context = 'context=search&amp;';
            }
            $icon_helper = $this->view->helper('iconlink');
            ?>
            <tr><th class="table-label align-top <?=$mobile_align?>" <?=
                $mobile_span ?> ><?=
                tl('manageroles_element_role_activities') ?>:</th><?=
                $mobile_end_row ?><td <?=$mobile_span
                ?>><div class='light-gray-box'>
                <table class='role-activity-table'>
                <tr><th><?=tl('manageroles_element_activity_name')?></th>
                    <th><?=tl('manageroles_element_modifiers')?></th>
                    <th><?=tl('manageroles_element_activity_actions')?></th>
                    <?php
                foreach ($data['ROLE_ACTIVITIES'] as $activity_array) {
                    $modifiers = $data['AVAILABLE_MODIFIERS'][
                        $activity_array['ACTIVITY_ID']];
                    $allowed_modifiers = preg_split("/\s*\,\s*/",
                        trim($activity_array['ALLOWED_ARGUMENTS']));
                    if (count($allowed_modifiers) == 1 && ($allowed_modifiers[0]
                        == "all" || empty( $allowed_modifiers[0]))) {
                        $allowed_modifiers = [];
                    }
                    ?>
                    <tr><td><b><?=$activity_array['ACTIVITY_NAME']
                    ?></b></td><?php
                    if ($data['CURRENT_ROLE']['name'] == 'Admin' &&
                        in_array($activity_array['ACTIVITY_NAME'],
                        ["Manage Account", "Manage Users",
                        "Manage Roles", "Manage Groups",
                        "Server Settings", "Security", "Configure"])) {?>
                        <td><input type="hidden"
                            name="activities[<?=$activity_array['ACTIVITY_ID']
                            ?>]" value="<?=
                            $activity_array['ALLOWED_ARGUMENTS']
                            ?>" ><?=tl('manageroles_element_admin_has_all');
                            ?></td>
                        <td class='back-light-gray'><?=
                            $icon_helper->renderLink(
                                "javascript:return false;", "delete", "", false,
                                "large-padding disabled"); ?></td><?php
                    } else if (empty($modifiers)) {?>
                        <td><input type="hidden"
                            name="activities[<?=$activity_array['ACTIVITY_ID']
                            ?>]" value="<?=
                            $activity_array['ALLOWED_ARGUMENTS']
                            ?>" ><?=tl('manageroles_element_no_modifiers');
                            ?></td>
                        <td><?= $icon_helper->renderLink($admin_url .
                            "a=manageRoles&amp;arg=deleteactivity&amp;$context".
                            "selectactivity=". $activity_array['ACTIVITY_ID'] .
                            "&amp;name=".$data['CURRENT_ROLE']['name'] .
                            "&amp;" . C\p('CSRF_TOKEN') . "=" .
                                $data[C\p('CSRF_TOKEN')].
                            $paging, "delete", "", false, "large-padding");
                            ?></td><?php
                    } else { ?>
                        <td><div><input type="hidden"
                            name="activities[<?=$activity_array['ACTIVITY_ID']
                            ?>]" value="<?=
                            $activity_array['ALLOWED_ARGUMENTS']
                            ?>" ><?php
                            if (empty($allowed_modifiers)) {
                                e(tl('manageroles_element_no_modifiers'));
                            } else {
                                foreach ($allowed_modifiers as $modifier) {
                                    ?><div class="delete-modifier"><span
                                        class="modifier-name"><?=
                                    $modifiers[$modifier];
                                    ?></span><a
                                        class="modifier-remove"
                                        title="<?= tl(
                                        'manageroles_element_remove_modifier'
                                        ) ?>"
                                        aria-label="<?= tl(
                                        'manageroles_element_remove_modifier'
                                        ) ?>" href="<?=
                                        $admin_url . "a=manageRoles&amp;" .
                                        "arg=deletemodifier&amp;$context".
                                        "selectactivity=".
                                        $activity_array['ACTIVITY_ID'] .
                                        "&amp;modifier=$modifier&amp;name=".
                                        $data['CURRENT_ROLE']['name'] .
                                        "&amp;" . C\p('CSRF_TOKEN') . "=" .
                                        $data[C\p('CSRF_TOKEN')].
                                        $paging; ?>">&#10005;</a></div> <?php
                                }
                                $modifiers = array_diff($modifiers,
                                    array_flip($allowed_modifiers));
                            }
                            ?>
                            </div>
                            <div>
                            <?php
                            $modifiers =
                                [-1 => tl('manageroles_element_add_modifier')] +
                                $modifiers;
                            $this->view->helper("options")->render(
                                "add-activity-modifier",
                                "selectmodifier[".
                                $activity_array['ACTIVITY_ID']."]", $modifiers,
                                -1, true);
                            ?>
                            </div>
                        </td>
                        <td><?= $icon_helper->renderLink($admin_url .
                            "a=manageRoles&amp;arg=deleteactivity&amp;$context".
                            "selectactivity=". $activity_array['ACTIVITY_ID'] .
                            "&amp;name=".$data['CURRENT_ROLE']['name'] .
                            "&amp;" . C\p('CSRF_TOKEN') . "=" .
                                $data[C\p('CSRF_TOKEN')].
                            $paging, "delete", "", false, "large-padding");
                            ?></td><?php
                    }?>
                </tr><?php
                } ?>
                </table><?php
                if (count($data['AVAILABLE_ACTIVITIES']) > 1) {
                    $this->view->helper("options")->render(
                        "add-roleactivity",
                        "selectactivity", $data['AVAILABLE_ACTIVITIES'],
                        $data['SELECT_ACTIVITY'], true);?><?php
                } ?>
                </div>
            </td></tr>
            <?php
        } ?>
        </table>
        </form><?php
    }
    /**
     * Draws the search for roles 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 = "manageRoles";
        $view = $this->view;
        $title = tl('manageroles_element_search_role');
        $fields = [
            tl('manageroles_element_rolename') => "name",
        ];
        $view->helper("searchform")->render($data, $controller, $activity,
                $view, $title, $fields);
    }
}
