/ src / views / elements / ManageaccountElement.php
<?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;

/**
 * Element responsible for displaying the user account features
 * that someone can modify for their own SeekQuarry/Yioop account.
 *
 * @author Chris Pollett
 */
class ManageaccountElement extends Element
{
    /**
     * Draws a view with a summary of a user's account together with
     * a form for updating user info such as password as well as with
     * useful links for groups, etc
     *
     * @param array $data anti-CSRF token
     */
    public function render($data)
    {
        $token = C\p('CSRF_TOKEN') . "=" . $data[C\p('CSRF_TOKEN')];
        $admin_url = htmlentities(B\controllerUrl('admin', true));
        $feed_url =  htmlentities(B\feedsUrl("", "",
            true, "group")). "$token";
        $base_url = "{$admin_url}a=manageAccount&$token";
        $edit_or_no_url = $base_url . (
            (isset($data['EDIT_USER'])) ? "&edit=false":"&edit=true");
        $icon_helper = $this->view->helper('iconlink');
        $is_mobile = !empty($_SERVER['MOBILE']);
        if (isset($data['EDIT_USER'])) {
            return $this->renderEditUser($data);
        }
        $more_groups =
            (count(($data['RECENT_GROUPS'] ?? [])) < $data['NUM_GROUPS']);
        ?>
        <div class="current-activity">
            <div class="account-info">
            <h2><img class='home-icon'
                src="<?= $data['USER']['USER_ICON'] ?>" alt="<?=
                    tl('manageaccount_element_icon') ?>" >
                <span><?= $data['USERNAME'] ?></span>
            </h2> <?=
                $icon_helper->renderButton($edit_or_no_url,
                'account_settings'); ?>
            </div>
            <?php
            if (isset($data['CRAWL_MANAGER']) && $data['CRAWL_MANAGER']) {
                ?>
                <h2 class="medium-margin"><?php
                e(tl('manageaccount_element_search_and_index')); ?>
                </h2>
                <?=$this->view->element("crawlcontrols")->render($data) ?>
                <?php
            } ?>
            <h2 class="medium-margin"><?=
            tl('manageaccount_element_groups')?></h2>
            <?=$this->view->element("socialcontrols")->render($data) ?>
            <?php
            $this->view->helper("grouplist")->render($data['GROUPS'], $token,
                $icon_helper, "admin", "account", modifiers:
                $data['GROUP_MODIFIERS']);
            if ($more_groups) {?>
                <div class="more-groups"><b><a href="<?=$feed_url?>"><?=
                    tl('manageaccount_element_more_groups')?></a></b></div><?php
            }
            if (!empty($data['THREAD_RECOMMENDATIONS']) ||
                !empty($data['GROUP_RECOMMENDATIONS']) ||
                !empty($data['RESOURCE_RECOMMENDATIONS'])) {
                ?>
                <h2><?=tl('manageaccount_element_recommendations')?></h2>
                <div class="access-result">
                <?php
                if (!empty($data['THREAD_RECOMMENDATIONS'])) {
                    ?><b><?=tl('manageaccount_element_rec_threads')
                    ?></b><ul><?php
                    foreach ($data['THREAD_RECOMMENDATIONS'] as
                        $thread => $threadName) { ?>
                        <li><a href="<?=htmlentities(B\feedsUrl("thread",
                            $thread, true, "group")) .
                                $token ?>" ><?= $threadName ?></a></li>
                        <?php
                    }?></ul><?php
                }
                ?><br><?php
                if (!empty($data['GROUP_RECOMMENDATIONS'])) {
                    ?><b><?=tl('manageaccount_element_rec_groups')
                    ?></b><ul><?php
                    foreach ($data['GROUP_RECOMMENDATIONS'] as
                        $group_id => $group_name) { ?>
                        <li><a href="<?= htmlentities(B\feedsUrl("group",
                            $group_id, true, "group")) .
                            $token ?>" ><?= $group_name ?></a></li>
                        <?php
                    }?></ul><?php
                }
                ?><br><?php
                if (!empty($data['RESOURCE_RECOMMENDATIONS'])) {
                    ?><b><?=tl('manageaccount_element_rec_resources')
                    ?></b><ul><?php
                    foreach ($data['RESOURCE_RECOMMENDATIONS'] as
                        $recommendation) {
                        $encoded_name = str_replace(" ",
                            "+", $recommendation[3]); ?><li>
                        <a href="<?= htmlentities(B\controllerUrl("group")) .
                            "/$recommendation[0]/$recommendation[2]?" .
                            "$token&page_id=$recommendation[1]&" .
                            "sf=$recommendation[4]&arg=media&n=$encoded_name"
                            ?>" ><?= $recommendation[3] ?></a></li>
                        <?php
                    }?></div><?php
                }
            }
            ?>
        </div>
        <?php
    }
    /**
     *  Renders the form used to control account settings such as
     *  icon photo, email, password, etc. for a user
     *
     *  @param array $data has field with current values for these setting
     *   (except password) so that forms can be pre-populated.
     */
    public function renderEditUser($data)
    {
        $token = C\p('CSRF_TOKEN') . "=" . $data[C\p('CSRF_TOKEN')];
        $admin_url = htmlentities(B\controllerUrl('admin', true));
        $base_url = "{$admin_url}a=manageAccount&$token";
        $password_or_no_url = $base_url .(
            (isset($data['EDIT_PASSWORD'])) ? "&edit_pass=false":
            "&edit_pass=true");
        $recover_or_no_url = $base_url .(
            (isset($data['EDIT_RECOVERY'])) ? "&edit_recovery=false":
            "&edit_recovery=true");
        $edit_or_no_url = $base_url . (
            (isset($data['EDIT_USER'])) ? "&edit=false":"&edit=true");
        $close_url = (!empty($data['EDIT_PASSWORD'])) ?
            $password_or_no_url : ((!empty($data['EDIT_RECOVERY'])) ?
            $recover_or_no_url : $edit_or_no_url);
        $disabled = (isset($data['EDIT_USER'])) ? "" : "disabled='disabled'";
        $is_mobile = !empty($_SERVER['MOBILE']);
        ?>
        <div class="current-activity">
        <div class="account-info" tabindex="1">
        <?= $this->view->helper("close")->render($close_url); ?>
        <form id="changeUserForm" method="post" class="account-details"
        autocomplete="off" enctype="multipart/form-data">
        <h2><?php
            if (!empty($data['EDIT_PASSWORD'])) {
                e(tl('manageaccount_element_change_password'));
            } else if (!empty($data['EDIT_RECOVERY'])) {
                e(tl('manageaccount_element_change_recovery'));
            } else {
                e(tl('manageaccount_element_account_details'));
            }
        ?></h2><?php
        $account_rows = 11;
        if (!empty($data['USER']['IS_BOT_USER'])) {
            $account_rows = 15;
        }
        if (!empty($data['SELLABLE_ROLES_EXIST'])) {
            $account_rows++;
        }
        $row_col_span = 'rowspan="' . $account_rows . '"';
        if ($is_mobile) {
            $row_col_span = 'class="center" style="width:300px"';
        } ?>
        <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="manageAccount" >
        <input type="hidden" name="arg" value="updateuser" >
        <table class="name-table"><?php
        if (empty($data['EDIT_PASSWORD']) && empty($data['EDIT_RECOVERY'])) { ?>
            <tr>
            <td <?=$row_col_span?> class="user-icon-td" ><img
            class='user-icon' id='current-icon'
            src="<?= $data['USER']['USER_ICON'] ?>" alt="<?=
                tl('manageaccount_element_icon') ?>" ><?php
            $this->view->helper("fileupload")->render('current-icon',
                'user_icon', 'user-icon',  C\THUMB_SIZE, 'image',
                ['image/png', 'image/gif', 'image/jpeg', 'image/webp',
                'image/x-icon']);
            if ($is_mobile) { ?>
                </td></tr></table><table class="name-table">
                <?php
            } else {
                e('</td>');
            }?>
            <th class="table-label"><label for="user-name"><?=
            tl('manageaccount_element_username') ?>:</label></th>
            <td><input type="text" id="user-name"
                name="user_name"  maxlength="<?= C\NAME_LEN ?>"
                value="<?= $data['USER']['USER_NAME'] ?>"
                class="narrow-field" disabled="disabled" ></td>
                </tr>
            <tr><th class="table-label"><label for="first-name"><?php
                e(tl('manageaccount_element_firstname')); ?>:</label></th>
            <td><input type="text" id="first-name"
                name="FIRST_NAME"  maxlength="<?= C\NAME_LEN?>"
                value="<?php e($data['USER']['FIRST_NAME']); ?>"
                class="narrow-field" <?php e($disabled);?> ></td></tr>
            <tr><th class="table-label"><label for="last-name"><?php
                e(tl('manageaccount_element_lastname')); ?>:</label></th>
            <td><input type="text" id="last-name"
                name="LAST_NAME"  maxlength="<?= C\NAME_LEN ?>"
                value="<?php e($data['USER']['LAST_NAME']); ?>"
                class="narrow-field" <?php e($disabled);?> ></td></tr>
            <tr><th class="table-label"><label for="e-mail"><?php
                e(tl('manageaccount_element_email')); ?>:</label></th>
            <td><input type="email" id="e-mail"
                name="EMAIL"  maxlength="<?= C\LONG_NAME_LEN ?>"
                <?php e($disabled);?>
                value="<?php e($data['USER']['EMAIL']); ?>"
                class="narrow-field" ></td></tr>
            <tr>
            <th class="table-label"><label for="locale"><b><?=
                tl('options_element_language_label')
                ?></b></label></th>
            <td><?php
                $this->view->element("language")->render($data); ?></td>
            </tr><?php
            if (!empty($data['SELLABLE_ROLES_EXIST'])) { ?>
            <tr>
            <th class="table-label align-top"><label><b><?=
                tl('accountaccess_component_roles_label')
                ?></b></label></th>
            <td><div class="role-list"><?php
                $sellable = [];
                foreach ($data['USER_SELLABLE_ROLES'] as $sub_role) {
                    $sellable[(int)$sub_role['ROLE_ID']] = $sub_role;
                }
                $now = time();
                $role_parts = [];
                foreach ($data['USER_ROLE_LIST'] as $held_role) {
                    $name = htmlentities($held_role['ROLE_NAME']);
                    $held_id = (int)$held_role['ROLE_ID'];
                    if (empty($sellable[$held_id])) {
                        $role_parts[] = $name;
                        continue;
                    }
                    $sub = $sellable[$held_id];
                    $expires = (int)$sub['EXPIRES'];
                    if ((int)$sub['WILL_RENEW'] === 0 &&
                        $expires !== C\FOREVER && $expires > $now) {
                        $on_url = $base_url . "&arg=purchaserole" .
                            "&purchase_role_id=" . $held_id .
                            "&edit=true";
                        $when = date("Y-m-d", $expires);
                        $confirm = tl(
                            'accountaccess_component_confirm_resubscribe');
                        $role_parts[] = $name . " (<a href=\"" . $on_url .
                            "\" onclick=\"return confirm('" . $confirm .
                            "');\">" .
                            tl('accountaccess_component_role_expires',
                            $when) . "</a>)";
                    } else {
                        $off_url = $base_url .
                            "&arg=unsubscriberole" .
                            "&unsubscribe_role_id=" . $held_id .
                            "&edit=true";
                        $confirm = tl(
                            'accountaccess_component_confirm_unsubscribe');
                        $role_parts[] = "<a href=\"" . $off_url .
                            "\" onclick=\"return confirm('" . $confirm .
                            "');\">" . $name . "</a>";
                    }
                }
                echo implode(", ", $role_parts);
                ?><br>
                <a href="<?= $base_url . "&edit_purchase=true" ?>"><?=
                    tl('accountaccess_component_purchase_new_roles')
                    ?></a></div></td>
            </tr><?php
            }
            if (!empty($data['yioop_bot_configuration'])) {
                ?>
                <tr>
                <th class="table-label"><label for="is_bot"><?php
                        e(tl('manageaccount_element_is_bot'));
                        ?></label></th>
                <td><input type="checkbox" id="is_bot"
                           name="IS_BOT_USER" value="true"
                        <?php if (!empty($data['USER']['IS_BOT_USER'])
                            && $data['USER']['IS_BOT_USER'] == true) {
                                e("checked='checked'");
                        } ?>
                    >
                </td></tr><?php
                if ($data['USER']['IS_BOT_USER'] == true) { ?>
                    <tr><th class="table-label">
                        <label for="bot-unique-token"><?php
                        e(tl('manageaccount_element_bot_unique_token'))
                        ?></label></th>
                        <td><input type="text" id="bot-unique-token"
                            name="BOT_TOKEN" value="<?php
                            e($data['USER']['BOT_TOKEN']); ?>"
                            class="narrow-field" >
                        </td>
                    </tr>
                    <tr>
                        <th class="table-label">
                        <label for="bot-callback-url"><?php
                        e(tl('manageaccount_element_bot_callback_url'));
                        ?></label></th>
                        <td><input type="text" id="bot-callback-url"
                            name="BOT_CALLBACK_URL" value="<?php
                            e($data['USER']['CALLBACK_URL']); ?>"
                            class="narrow-field" >
                        </td>
                    </tr>
                    <?php
                }
            } ?>
            <tr><th class="table-label"><label for="password"><?php
            e(tl('manageaccount_element_password'))?></label></th>
            <td><input type="password" id="password"
                name="password"  maxlength="<?= C\LONG_NAME_LEN
                ?>" class="narrow-field" >
            </td></tr><?php
        } else if (!empty($data['EDIT_PASSWORD']) &&
            empty($_SESSION['LDAP_NAME'])) { ?>
            <tr><th class="table-label"><label for="password"><?php
            e(tl('manageaccount_element_password'))?></label></th>
            <td><input type="password" id="password"
                name="password"  maxlength="<?= C\LONG_NAME_LEN
                ?>" class="narrow-field" >
            </td></tr>
            <tr><th class="table-label"><label for="new-password"><?php
                e(tl('manageaccount_element_new_password'))?></label></th>
                <td><input type="password" id="new-password"
                    name="new_password"  maxlength="<?=
                    C\LONG_NAME_LEN?>" class="narrow-field" ><?php
                    $this->view->helper("passwordrequirements")->render(
                        "new-password"); ?>
                </td></tr>
            <tr><th class="table-label"><label for="retype-password"><?php
                e(tl('manageaccount_element_retype_password'));
                ?></label></th>
                <td><input type="password" id="retype-password"
                    name="retype_password"  maxlength="<?=
                    C\LONG_NAME_LEN?>" class="narrow-field" >
                </td></tr><?php
        } else if (empty($_SESSION['LDAP_NAME'])) {
            if (C\p('RECOVERY_MODE') == C\QUESTIONS_RECOVERY) {
                $recovery_question = $data['RECOVERY_QUESTION'] ?? "";
                $recovery_answer = $data['RECOVERY_ANSWER'] ?? "";
                ?>
                <tr><th class="table-label"><label
                    for="recovery-question"><?php
                    e(tl('manageaccount_element_recovery_question'));
                    ?></label></th>
                    <td class="table-input border-top">
                    <input type="text" id="recovery-question"
                        name="recovery_question" maxlength="<?=
                        C\RECOVERY_QUESTION_LEN ?>" class="narrow-field"
                        value="<?= $recovery_question ?>" >
                    </td></tr>
                <tr><th class="table-label"><label
                    for="recovery-answer"><?php
                    e(tl('manageaccount_element_recovery_answer'));
                    ?></label></th>
                    <td class="table-input">
                    <input type="text" id="recovery-answer"
                        name="recovery_answer" maxlength="<?=
                        C\LONG_NAME_LEN ?>" class="narrow-field"
                        value="<?= $recovery_answer ?>" >
                    </td></tr><?php
            }?>
            <tr><th class="table-label"><label for="password"><?php
            e(tl('manageaccount_element_password'))?></label></th>
            <td><input type="password" id="password"
                name="password"  maxlength="<?= C\LONG_NAME_LEN
                ?>" class="narrow-field" >
            </td></tr><?php
        }?>
        <tr><td></td>
        <td class="center"><button
            class="button-box" type="submit"><?php
            e(tl('manageaccount_element_save')); ?></button></td></tr><?php
        if (empty($data['EDIT_PASSWORD']) && empty($data['EDIT_RECOVERY'])
            && empty($_SESSION['LDAP_NAME'])) { ?>
            <tr><td>&nbsp;</td><td></td></tr>
            <tr><td></td><td><a href="<?php
                e($password_or_no_url);?>"><?php
                e(tl('manageaccount_element_change_password'))?></a>
            </td></tr><?php
            if (C\p('RECOVERY_MODE') == C\QUESTIONS_RECOVERY) {?>
                <tr><td></td><td><a href="<?php
                    e($recover_or_no_url);?>"><?php
                    e(tl('manageaccount_element_change_recovery'))?></a>
                </td></tr><?php
            }
        } ?>
        </table>
        </form><?php
        if (!empty($data['EDIT_PURCHASE'])) { ?>
        <form id="purchaseRoleForm" method="post"
            class="account-details">
        <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="manageAccount" >
        <input type="hidden" name="arg" value="purchaserole" >
        <input type="hidden" name="edit_purchase" value="true" >
        <h2><?= tl('accountaccess_component_purchase_new_roles') ?></h2>
        <p><?= tl('accountaccess_component_credit_balance',
            $data['CREDIT_BALANCE']) ?></p><?php
        if (empty($data['PURCHASABLE_ROLES'])) { ?>
            <p><?= tl('accountaccess_component_no_roles_to_buy')
                ?></p><?php
        } else { ?>
            <table class="name-table">
            <tr><th class="table-label"><label
                for="purchase_role_id"><b><?=
                tl('accountaccess_component_choose_role')
                ?></b></label></th>
            <td><select id="purchase_role_id"
                name="purchase_role_id"><?php
                foreach ($data['PURCHASABLE_ROLES'] as $buy_role) { ?>
                <option value="<?= (int)$buy_role['ROLE_ID'] ?>"><?php
                    e($buy_role['NAME'] . " - " .
                        $buy_role['ROLE_COST']);
                    ?></option><?php
                } ?>
            </select></td></tr>
            <tr><td></td><td><button type="submit"><?=
                tl('accountaccess_component_buy_role')
                ?></button></td></tr>
            </table><?php
        } ?>
        </form><?php
        } ?>
        </div>
        </div><?php
    }
}
X