first commit
This commit is contained in:
35
components/com_users/forms/frontend.xml
Normal file
35
components/com_users/forms/frontend.xml
Normal file
@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form>
|
||||
<fields name="params">
|
||||
<!-- Basic user account settings. -->
|
||||
<fieldset name="params" label="COM_USERS_SETTINGS_FIELDSET_LABEL">
|
||||
<field
|
||||
name="editor"
|
||||
type="plugins"
|
||||
label="COM_USERS_USER_FIELD_EDITOR_LABEL"
|
||||
folder="editors"
|
||||
useaccess="true"
|
||||
>
|
||||
<option value="">JOPTION_USE_DEFAULT</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="timezone"
|
||||
type="timezone"
|
||||
label="COM_USERS_USER_FIELD_TIMEZONE_LABEL"
|
||||
>
|
||||
<option value="">JOPTION_USE_DEFAULT</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="language"
|
||||
type="language"
|
||||
label="COM_USERS_USER_FIELD_FRONTEND_LANGUAGE_LABEL"
|
||||
client="site"
|
||||
filter="cmd"
|
||||
>
|
||||
<option value="">JOPTION_USE_DEFAULT</option>
|
||||
</field>
|
||||
</fieldset>
|
||||
</fields>
|
||||
</form>
|
||||
27
components/com_users/forms/frontend_admin.xml
Normal file
27
components/com_users/forms/frontend_admin.xml
Normal file
@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form>
|
||||
<fields name="params">
|
||||
<!-- Backend user account settings. -->
|
||||
<fieldset name="params" label="COM_USERS_SETTINGS_FIELDSET_LABEL">
|
||||
<field
|
||||
name="admin_style"
|
||||
type="templatestyle"
|
||||
label="COM_USERS_USER_FIELD_BACKEND_TEMPLATE_LABEL"
|
||||
client="administrator"
|
||||
filter="uint"
|
||||
>
|
||||
<option value="">JOPTION_USE_DEFAULT</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="admin_language"
|
||||
type="language"
|
||||
label="COM_USERS_USER_FIELD_BACKEND_LANGUAGE_LABEL"
|
||||
client="administrator"
|
||||
filter="cmd"
|
||||
>
|
||||
<option value="">JOPTION_USE_DEFAULT</option>
|
||||
</field>
|
||||
</fieldset>
|
||||
</fields>
|
||||
</form>
|
||||
34
components/com_users/forms/login.xml
Normal file
34
components/com_users/forms/login.xml
Normal file
@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form>
|
||||
<fieldset name="credentials" label="COM_USERS_LOGIN_DEFAULT_LABEL">
|
||||
<field
|
||||
name="username"
|
||||
type="text"
|
||||
label="COM_USERS_LOGIN_USERNAME_LABEL"
|
||||
class="validate-username"
|
||||
filter="username"
|
||||
size="25"
|
||||
required="true"
|
||||
validate="username"
|
||||
autofocus="true"
|
||||
autocomplete="username"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="password"
|
||||
type="password"
|
||||
label="JGLOBAL_PASSWORD"
|
||||
required="true"
|
||||
filter="raw"
|
||||
size="25"
|
||||
autocomplete="current-password"
|
||||
/>
|
||||
</fieldset>
|
||||
|
||||
<fieldset>
|
||||
<field
|
||||
name="return"
|
||||
type="hidden"
|
||||
/>
|
||||
</fieldset>
|
||||
</form>
|
||||
73
components/com_users/forms/profile.xml
Normal file
73
components/com_users/forms/profile.xml
Normal file
@ -0,0 +1,73 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form>
|
||||
<fieldset name="core" label="COM_USERS_PROFILE_DEFAULT_LABEL">
|
||||
<field
|
||||
name="id"
|
||||
type="hidden"
|
||||
filter="integer"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="name"
|
||||
type="text"
|
||||
label="COM_USERS_PROFILE_NAME_LABEL"
|
||||
filter="string"
|
||||
required="true"
|
||||
size="30"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="username"
|
||||
type="text"
|
||||
label="COM_USERS_PROFILE_USERNAME_LABEL"
|
||||
class="validate-username"
|
||||
filter="username"
|
||||
message="COM_USERS_PROFILE_USERNAME_MESSAGE"
|
||||
required="true"
|
||||
size="30"
|
||||
validate="username"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="password1"
|
||||
type="password"
|
||||
label="COM_USERS_PROFILE_PASSWORD1_LABEL"
|
||||
autocomplete="new-password"
|
||||
class="validate-password"
|
||||
filter="raw"
|
||||
size="30"
|
||||
validate="password"
|
||||
strengthmeter="true"
|
||||
rules="true"
|
||||
force="on"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="password2"
|
||||
type="password"
|
||||
label="COM_USERS_PROFILE_PASSWORD2_LABEL"
|
||||
autocomplete="new-password"
|
||||
class="validate-password"
|
||||
field="password1"
|
||||
filter="raw"
|
||||
message="COM_USERS_PROFILE_PASSWORD1_MESSAGE"
|
||||
size="30"
|
||||
validate="equals"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="email1"
|
||||
type="email"
|
||||
label="COM_USERS_PROFILE_EMAIL1_LABEL"
|
||||
filter="string"
|
||||
required="true"
|
||||
size="30"
|
||||
unique="true"
|
||||
validate="email"
|
||||
validDomains="com_users.domains"
|
||||
autocomplete="email"
|
||||
/>
|
||||
|
||||
</fieldset>
|
||||
|
||||
</form>
|
||||
86
components/com_users/forms/registration.xml
Normal file
86
components/com_users/forms/registration.xml
Normal file
@ -0,0 +1,86 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form>
|
||||
<fieldset name="default" label="COM_USERS_REGISTRATION_DEFAULT_LABEL">
|
||||
<field
|
||||
name="spacer"
|
||||
type="spacer"
|
||||
label="COM_USERS_REGISTER_REQUIRED"
|
||||
class="text"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="name"
|
||||
type="text"
|
||||
label="COM_USERS_REGISTER_NAME_LABEL"
|
||||
filter="string"
|
||||
required="true"
|
||||
size="30"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="username"
|
||||
type="text"
|
||||
label="COM_USERS_REGISTER_USERNAME_LABEL"
|
||||
class="validate-username"
|
||||
filter="username"
|
||||
message="COM_USERS_REGISTER_USERNAME_MESSAGE"
|
||||
required="true"
|
||||
size="30"
|
||||
validate="username"
|
||||
autocomplete="username"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="password1"
|
||||
type="password"
|
||||
label="COM_USERS_PROFILE_PASSWORD1_LABEL"
|
||||
required="true"
|
||||
autocomplete="new-password"
|
||||
class="validate-password"
|
||||
field="password1"
|
||||
size="30"
|
||||
validate="password"
|
||||
strengthmeter="true"
|
||||
rules="true"
|
||||
force="on"
|
||||
filter="raw"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="password2"
|
||||
type="password"
|
||||
label="COM_USERS_PROFILE_PASSWORD2_LABEL"
|
||||
autocomplete="new-password"
|
||||
class="validate-password"
|
||||
field="password1"
|
||||
filter="raw"
|
||||
message="COM_USERS_PROFILE_PASSWORD1_MESSAGE"
|
||||
size="30"
|
||||
validate="equals"
|
||||
required="true"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="email1"
|
||||
type="email"
|
||||
label="COM_USERS_REGISTER_EMAIL1_LABEL"
|
||||
field="id"
|
||||
filter="string"
|
||||
required="true"
|
||||
size="30"
|
||||
unique="true"
|
||||
validate="email"
|
||||
validDomains="com_users.domains"
|
||||
autocomplete="email"
|
||||
/>
|
||||
</fieldset>
|
||||
|
||||
<fieldset name="captcha">
|
||||
<field
|
||||
name="captcha"
|
||||
type="captcha"
|
||||
label="COM_USERS_CAPTCHA_LABEL"
|
||||
validate="captcha"
|
||||
/>
|
||||
</fieldset>
|
||||
</form>
|
||||
21
components/com_users/forms/remind.xml
Normal file
21
components/com_users/forms/remind.xml
Normal file
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form>
|
||||
<fieldset name="default" label="COM_USERS_REMIND_DEFAULT_LABEL">
|
||||
<field
|
||||
name="email"
|
||||
type="email"
|
||||
label="COM_USERS_FIELD_REMIND_EMAIL_LABEL"
|
||||
required="true"
|
||||
size="30"
|
||||
validate="email"
|
||||
autocomplete="email"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="captcha"
|
||||
type="captcha"
|
||||
label="COM_USERS_CAPTCHA_LABEL"
|
||||
validate="captcha"
|
||||
/>
|
||||
</fieldset>
|
||||
</form>
|
||||
33
components/com_users/forms/reset_complete.xml
Normal file
33
components/com_users/forms/reset_complete.xml
Normal file
@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form>
|
||||
<fieldset name="default" label="COM_USERS_RESET_COMPLETE_LABEL">
|
||||
<field
|
||||
name="password1"
|
||||
type="password"
|
||||
label="COM_USERS_FIELD_RESET_PASSWORD1_LABEL"
|
||||
required="true"
|
||||
autocomplete="new-password"
|
||||
class="validate-password"
|
||||
field="password2"
|
||||
size="30"
|
||||
validate="password"
|
||||
strengthmeter="true"
|
||||
rules="true"
|
||||
force="on"
|
||||
filter="raw"
|
||||
/>
|
||||
<field
|
||||
name="password2"
|
||||
type="password"
|
||||
label="COM_USERS_FIELD_RESET_PASSWORD2_LABEL"
|
||||
autocomplete="new-password"
|
||||
class="validate-password"
|
||||
field="password1"
|
||||
filter="raw"
|
||||
message="COM_USERS_FIELD_RESET_PASSWORD1_MESSAGE"
|
||||
size="30"
|
||||
validate="equals"
|
||||
required="true"
|
||||
/>
|
||||
</fieldset>
|
||||
</form>
|
||||
22
components/com_users/forms/reset_confirm.xml
Normal file
22
components/com_users/forms/reset_confirm.xml
Normal file
@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form>
|
||||
<fieldset name="default" label="COM_USERS_RESET_CONFIRM_LABEL">
|
||||
<field
|
||||
name="username"
|
||||
type="text"
|
||||
label="COM_USERS_FIELD_RESET_CONFIRM_USERNAME_LABEL"
|
||||
filter="username"
|
||||
required="true"
|
||||
size="30"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="token"
|
||||
type="text"
|
||||
label="COM_USERS_FIELD_RESET_CONFIRM_TOKEN_LABEL"
|
||||
filter="alnum"
|
||||
required="true"
|
||||
size="32"
|
||||
/>
|
||||
</fieldset>
|
||||
</form>
|
||||
21
components/com_users/forms/reset_request.xml
Normal file
21
components/com_users/forms/reset_request.xml
Normal file
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form>
|
||||
<fieldset name="default" label="COM_USERS_RESET_REQUEST_LABEL">
|
||||
<field
|
||||
name="email"
|
||||
type="email"
|
||||
label="COM_USERS_FIELD_PASSWORD_RESET_LABEL"
|
||||
required="true"
|
||||
size="30"
|
||||
validate="email"
|
||||
autocomplete="email"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="captcha"
|
||||
type="captcha"
|
||||
label="COM_USERS_CAPTCHA_LABEL"
|
||||
validate="captcha"
|
||||
/>
|
||||
</fieldset>
|
||||
</form>
|
||||
15
components/com_users/forms/sitelang.xml
Normal file
15
components/com_users/forms/sitelang.xml
Normal file
@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form>
|
||||
<fields name="params">
|
||||
<fieldset name="params" label="COM_USERS_SETTINGS_FIELDSET_LABEL">
|
||||
<field
|
||||
name="language"
|
||||
type="language"
|
||||
label="COM_USERS_USER_FIELD_FRONTEND_LANGUAGE_LABEL"
|
||||
client="site"
|
||||
filter="cmd"
|
||||
default="active"
|
||||
/>
|
||||
</fieldset>
|
||||
</fields>
|
||||
</form>
|
||||
26
components/com_users/src/Controller/CallbackController.php
Normal file
26
components/com_users/src/Controller/CallbackController.php
Normal file
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_users
|
||||
*
|
||||
* @copyright (C) 2022 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Users\Site\Controller;
|
||||
|
||||
use Joomla\Component\Users\Administrator\Controller\CallbackController as AdminCallbackController;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Multi-factor Authentication plugins' AJAX callback controller
|
||||
*
|
||||
* @since 4.2.0
|
||||
*/
|
||||
class CallbackController extends AdminCallbackController
|
||||
{
|
||||
}
|
||||
55
components/com_users/src/Controller/CaptiveController.php
Normal file
55
components/com_users/src/Controller/CaptiveController.php
Normal file
@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_users
|
||||
*
|
||||
* @copyright (C) 2022 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Users\Site\Controller;
|
||||
|
||||
use Joomla\CMS\Router\Route;
|
||||
use Joomla\Component\Users\Administrator\Controller\CaptiveController as AdminCaptiveController;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Captive Multi-factor Authentication page controller
|
||||
*
|
||||
* @since 4.2.0
|
||||
*/
|
||||
class CaptiveController extends AdminCaptiveController
|
||||
{
|
||||
/**
|
||||
* Execute a task by triggering a Method in the derived class.
|
||||
*
|
||||
* @param string $task The task to perform.
|
||||
*
|
||||
* @return mixed The value returned by the called Method.
|
||||
*
|
||||
* @throws \Exception
|
||||
* @since 4.2.0
|
||||
*/
|
||||
public function execute($task)
|
||||
{
|
||||
try {
|
||||
return parent::execute($task);
|
||||
} catch (\Exception $e) {
|
||||
if ($e->getCode() !== 403) {
|
||||
throw $e;
|
||||
}
|
||||
|
||||
if ($this->app->getIdentity()->guest) {
|
||||
$this->setRedirect(Route::_('index.php?option=com_users&view=login', false));
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
139
components/com_users/src/Controller/DisplayController.php
Normal file
139
components/com_users/src/Controller/DisplayController.php
Normal file
@ -0,0 +1,139 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage com_users
|
||||
*
|
||||
* @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Users\Site\Controller;
|
||||
|
||||
use Joomla\CMS\Component\ComponentHelper;
|
||||
use Joomla\CMS\MVC\Controller\BaseController;
|
||||
use Joomla\CMS\Router\Route;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Base controller class for Users.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
class DisplayController extends BaseController
|
||||
{
|
||||
/**
|
||||
* Method to display a view.
|
||||
*
|
||||
* @param boolean $cachable If true, the view output will be cached
|
||||
* @param array|boolean $urlparams An array of safe URL parameters and their variable types.
|
||||
* @see \Joomla\CMS\Filter\InputFilter::clean() for valid values.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 1.5
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function display($cachable = false, $urlparams = false)
|
||||
{
|
||||
// Get the document object.
|
||||
$document = $this->app->getDocument();
|
||||
|
||||
// Set the default view name and format from the Request.
|
||||
$vName = $this->input->getCmd('view', 'login');
|
||||
$vFormat = $document->getType();
|
||||
$lName = $this->input->getCmd('layout', 'default');
|
||||
|
||||
if ($view = $this->getView($vName, $vFormat)) {
|
||||
// Do any specific processing by view.
|
||||
switch ($vName) {
|
||||
case 'registration':
|
||||
// If the user is already logged in, redirect to the profile page.
|
||||
$user = $this->app->getIdentity();
|
||||
|
||||
if ($user->get('guest') != 1) {
|
||||
// Redirect to profile page.
|
||||
$this->setRedirect(Route::_('index.php?option=com_users&view=profile', false));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if user registration is enabled
|
||||
if (ComponentHelper::getParams('com_users')->get('allowUserRegistration') == 0) {
|
||||
// Registration is disabled - Redirect to login page.
|
||||
$this->setRedirect(Route::_('index.php?option=com_users&view=login', false));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// The user is a guest, load the registration model and show the registration page.
|
||||
$model = $this->getModel('Registration');
|
||||
break;
|
||||
|
||||
// Handle view specific models.
|
||||
case 'profile':
|
||||
// If the user is a guest, redirect to the login page.
|
||||
$user = $this->app->getIdentity();
|
||||
|
||||
if ($user->get('guest') == 1) {
|
||||
// Redirect to login page.
|
||||
$this->setRedirect(Route::_('index.php?option=com_users&view=login', false));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$model = $this->getModel($vName);
|
||||
break;
|
||||
|
||||
// Handle the default views.
|
||||
case 'login':
|
||||
$model = $this->getModel($vName);
|
||||
break;
|
||||
|
||||
case 'remind':
|
||||
case 'reset':
|
||||
// If the user is already logged in, redirect to the profile page.
|
||||
$user = $this->app->getIdentity();
|
||||
|
||||
if ($user->get('guest') != 1) {
|
||||
// Redirect to profile page.
|
||||
$this->setRedirect(Route::_('index.php?option=com_users&view=profile', false));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$model = $this->getModel($vName);
|
||||
break;
|
||||
|
||||
case 'captive':
|
||||
case 'methods':
|
||||
case 'method':
|
||||
$controller = $this->factory->createController($vName, 'Site', [], $this->app, $this->input);
|
||||
$task = $this->input->get('task', '');
|
||||
|
||||
return $controller->execute($task);
|
||||
|
||||
default:
|
||||
$model = $this->getModel('Login');
|
||||
break;
|
||||
}
|
||||
|
||||
// Make sure we don't send a referer
|
||||
if (\in_array($vName, ['remind', 'reset'])) {
|
||||
$this->app->setHeader('Referrer-Policy', 'no-referrer', true);
|
||||
}
|
||||
|
||||
// Push the model into the view (as default).
|
||||
$view->setModel($model, true);
|
||||
$view->setLayout($lName);
|
||||
|
||||
// Push document object into the view.
|
||||
$view->document = $document;
|
||||
|
||||
$view->display();
|
||||
}
|
||||
}
|
||||
}
|
||||
55
components/com_users/src/Controller/MethodController.php
Normal file
55
components/com_users/src/Controller/MethodController.php
Normal file
@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_users
|
||||
*
|
||||
* @copyright (C) 2022 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Users\Site\Controller;
|
||||
|
||||
use Joomla\CMS\Router\Route;
|
||||
use Joomla\Component\Users\Administrator\Controller\MethodController as AdminMethodController;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Multi-factor Authentication method controller
|
||||
*
|
||||
* @since 4.2.0
|
||||
*/
|
||||
class MethodController extends AdminMethodController
|
||||
{
|
||||
/**
|
||||
* Execute a task by triggering a Method in the derived class.
|
||||
*
|
||||
* @param string $task The task to perform.
|
||||
*
|
||||
* @return mixed The value returned by the called Method.
|
||||
*
|
||||
* @throws \Exception
|
||||
* @since 4.2.0
|
||||
*/
|
||||
public function execute($task)
|
||||
{
|
||||
try {
|
||||
return parent::execute($task);
|
||||
} catch (\Exception $e) {
|
||||
if ($e->getCode() !== 403) {
|
||||
throw $e;
|
||||
}
|
||||
|
||||
if ($this->app->getIdentity()->guest) {
|
||||
$this->setRedirect(Route::_('index.php?option=com_users&view=login', false));
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
55
components/com_users/src/Controller/MethodsController.php
Normal file
55
components/com_users/src/Controller/MethodsController.php
Normal file
@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_users
|
||||
*
|
||||
* @copyright (C) 2022 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Users\Site\Controller;
|
||||
|
||||
use Joomla\CMS\Router\Route;
|
||||
use Joomla\Component\Users\Administrator\Controller\MethodsController as AdminMethodsController;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Multi-factor Authentication methods selection and management controller
|
||||
*
|
||||
* @since 4.2.0
|
||||
*/
|
||||
class MethodsController extends AdminMethodsController
|
||||
{
|
||||
/**
|
||||
* Execute a task by triggering a Method in the derived class.
|
||||
*
|
||||
* @param string $task The task to perform.
|
||||
*
|
||||
* @return mixed The value returned by the called Method.
|
||||
*
|
||||
* @throws \Exception
|
||||
* @since 4.2.0
|
||||
*/
|
||||
public function execute($task)
|
||||
{
|
||||
try {
|
||||
return parent::execute($task);
|
||||
} catch (\Exception $e) {
|
||||
if ($e->getCode() !== 403) {
|
||||
throw $e;
|
||||
}
|
||||
|
||||
if ($this->app->getIdentity()->guest) {
|
||||
$this->setRedirect(Route::_('index.php?option=com_users&view=login', false));
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
231
components/com_users/src/Controller/ProfileController.php
Normal file
231
components/com_users/src/Controller/ProfileController.php
Normal file
@ -0,0 +1,231 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage com_users
|
||||
*
|
||||
* @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Users\Site\Controller;
|
||||
|
||||
use Joomla\CMS\Event\Model;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\MVC\Controller\BaseController;
|
||||
use Joomla\CMS\Router\Route;
|
||||
use Joomla\CMS\Uri\Uri;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Profile controller class for Users.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
class ProfileController extends BaseController
|
||||
{
|
||||
/**
|
||||
* Method to check out a user for editing and redirect to the edit form.
|
||||
*
|
||||
* @return boolean
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public function edit()
|
||||
{
|
||||
$app = $this->app;
|
||||
$user = $this->app->getIdentity();
|
||||
$loginUserId = (int) $user->get('id');
|
||||
|
||||
// Get the current user id.
|
||||
$userId = $this->input->getInt('user_id');
|
||||
|
||||
// Check if the user is trying to edit another users profile.
|
||||
if ($userId != $loginUserId) {
|
||||
$app->enqueueMessage(Text::_('JERROR_ALERTNOAUTHOR'), 'error');
|
||||
$app->setHeader('status', 403, true);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$cookieLogin = $user->get('cookieLogin');
|
||||
|
||||
// Check if the user logged in with a cookie
|
||||
if (!empty($cookieLogin)) {
|
||||
// If so, the user must login to edit the password and other data.
|
||||
$app->enqueueMessage(Text::_('JGLOBAL_REMEMBER_MUST_LOGIN'), 'message');
|
||||
$this->setRedirect(Route::_('index.php?option=com_users&view=login', false));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set the user id for the user to edit in the session.
|
||||
$app->setUserState('com_users.edit.profile.id', $userId);
|
||||
|
||||
// Redirect to the edit screen.
|
||||
$this->setRedirect(Route::_('index.php?option=com_users&view=profile&layout=edit', false));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to save a user's profile data.
|
||||
*
|
||||
* @return void|boolean
|
||||
*
|
||||
* @since 1.6
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function save()
|
||||
{
|
||||
// Check for request forgeries.
|
||||
$this->checkToken();
|
||||
|
||||
$app = $this->app;
|
||||
|
||||
/** @var \Joomla\Component\Users\Site\Model\ProfileModel $model */
|
||||
$model = $this->getModel('Profile', 'Site');
|
||||
$user = $this->app->getIdentity();
|
||||
$userId = (int) $user->get('id');
|
||||
|
||||
// Get the user data.
|
||||
$requestData = $app->getInput()->post->get('jform', [], 'array');
|
||||
|
||||
// Force the ID to this user.
|
||||
$requestData['id'] = $userId;
|
||||
|
||||
// Validate the posted data.
|
||||
$form = $model->getForm();
|
||||
|
||||
if (!$form) {
|
||||
throw new \Exception($model->getError(), 500);
|
||||
}
|
||||
|
||||
// Send an object which can be modified through the plugin event
|
||||
$objData = (object) $requestData;
|
||||
$this->getDispatcher()->dispatch(
|
||||
'onContentNormaliseRequestData',
|
||||
new Model\NormaliseRequestDataEvent('onContentNormaliseRequestData', [
|
||||
'context' => 'com_users.user',
|
||||
'data' => $objData,
|
||||
'subject' => $form,
|
||||
])
|
||||
);
|
||||
$requestData = (array) $objData;
|
||||
|
||||
// Validate the posted data.
|
||||
$data = $model->validate($form, $requestData);
|
||||
|
||||
// Check for errors.
|
||||
if ($data === false) {
|
||||
// Get the validation messages.
|
||||
$errors = $model->getErrors();
|
||||
|
||||
// Push up to three validation messages out to the user.
|
||||
for ($i = 0, $n = \count($errors); $i < $n && $i < 3; $i++) {
|
||||
if ($errors[$i] instanceof \Exception) {
|
||||
$app->enqueueMessage($errors[$i]->getMessage(), 'warning');
|
||||
} else {
|
||||
$app->enqueueMessage($errors[$i], 'warning');
|
||||
}
|
||||
}
|
||||
|
||||
// Unset the passwords.
|
||||
unset($requestData['password1'], $requestData['password2']);
|
||||
|
||||
// Save the data in the session.
|
||||
$app->setUserState('com_users.edit.profile.data', $requestData);
|
||||
|
||||
// Redirect back to the edit screen.
|
||||
$userId = (int) $app->getUserState('com_users.edit.profile.id');
|
||||
$this->setRedirect(Route::_('index.php?option=com_users&view=profile&layout=edit&user_id=' . $userId, false));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Attempt to save the data.
|
||||
$return = $model->save($data);
|
||||
|
||||
// Check for errors.
|
||||
if ($return === false) {
|
||||
// Save the data in the session.
|
||||
$app->setUserState('com_users.edit.profile.data', $data);
|
||||
|
||||
// Redirect back to the edit screen.
|
||||
$userId = (int) $app->getUserState('com_users.edit.profile.id');
|
||||
$this->setMessage(Text::sprintf('COM_USERS_PROFILE_SAVE_FAILED', $model->getError()), 'warning');
|
||||
$this->setRedirect(Route::_('index.php?option=com_users&view=profile&layout=edit&user_id=' . $userId, false));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Redirect the user and adjust session state based on the chosen task.
|
||||
switch ($this->getTask()) {
|
||||
case 'apply':
|
||||
// Check out the profile.
|
||||
$app->setUserState('com_users.edit.profile.id', $return);
|
||||
|
||||
// Redirect back to the edit screen.
|
||||
$this->setMessage(Text::_('COM_USERS_PROFILE_SAVE_SUCCESS'));
|
||||
|
||||
$redirect = $app->getUserState('com_users.edit.profile.redirect');
|
||||
|
||||
// Don't redirect to an external URL.
|
||||
if (!Uri::isInternal($redirect)) {
|
||||
$redirect = null;
|
||||
}
|
||||
|
||||
if (!$redirect) {
|
||||
$redirect = 'index.php?option=com_users&view=profile&layout=edit&hidemainmenu=1';
|
||||
}
|
||||
|
||||
$this->setRedirect(Route::_($redirect, false));
|
||||
break;
|
||||
|
||||
default:
|
||||
// Clear the profile id from the session.
|
||||
$app->setUserState('com_users.edit.profile.id', null);
|
||||
|
||||
$redirect = $app->getUserState('com_users.edit.profile.redirect');
|
||||
|
||||
// Don't redirect to an external URL.
|
||||
if (!Uri::isInternal($redirect)) {
|
||||
$redirect = null;
|
||||
}
|
||||
|
||||
if (!$redirect) {
|
||||
$redirect = 'index.php?option=com_users&view=profile&user_id=' . $return;
|
||||
}
|
||||
|
||||
// Redirect to the list screen.
|
||||
$this->setMessage(Text::_('COM_USERS_PROFILE_SAVE_SUCCESS'));
|
||||
$this->setRedirect(Route::_($redirect, false));
|
||||
break;
|
||||
}
|
||||
|
||||
// Flush the data from the session.
|
||||
$app->setUserState('com_users.edit.profile.data', null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to cancel an edit.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public function cancel()
|
||||
{
|
||||
// Check for request forgeries.
|
||||
$this->checkToken();
|
||||
|
||||
// Flush the data from the session.
|
||||
$this->app->setUserState('com_users.edit.profile', null);
|
||||
|
||||
// Redirect to user profile.
|
||||
$this->setRedirect(Route::_('index.php?option=com_users&view=profile', false));
|
||||
}
|
||||
}
|
||||
250
components/com_users/src/Controller/RegistrationController.php
Normal file
250
components/com_users/src/Controller/RegistrationController.php
Normal file
@ -0,0 +1,250 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage com_users
|
||||
*
|
||||
* @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Users\Site\Controller;
|
||||
|
||||
use Joomla\CMS\Component\ComponentHelper;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\MVC\Controller\BaseController;
|
||||
use Joomla\CMS\Router\Route;
|
||||
use Joomla\CMS\User\UserFactoryAwareInterface;
|
||||
use Joomla\CMS\User\UserFactoryAwareTrait;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Registration controller class for Users.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
class RegistrationController extends BaseController implements UserFactoryAwareInterface
|
||||
{
|
||||
use UserFactoryAwareTrait;
|
||||
|
||||
/**
|
||||
* Method to activate a user.
|
||||
*
|
||||
* @return boolean True on success, false on failure.
|
||||
*
|
||||
* @since 1.6
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function activate()
|
||||
{
|
||||
$user = $this->app->getIdentity();
|
||||
$input = $this->input;
|
||||
$uParams = ComponentHelper::getParams('com_users');
|
||||
|
||||
// Check for admin activation. Don't allow non-super-admin to delete a super admin
|
||||
if ($uParams->get('useractivation') != 2 && $user->get('id')) {
|
||||
$this->setRedirect('index.php');
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// If user registration or account activation is disabled, throw a 403.
|
||||
if ($uParams->get('useractivation') == 0 || $uParams->get('allowUserRegistration') == 0) {
|
||||
throw new \Exception(Text::_('JLIB_APPLICATION_ERROR_ACCESS_FORBIDDEN'), 403);
|
||||
}
|
||||
|
||||
/** @var \Joomla\Component\Users\Site\Model\RegistrationModel $model */
|
||||
$model = $this->getModel('Registration', 'Site');
|
||||
$token = $input->getAlnum('token');
|
||||
|
||||
// Check that the token is in a valid format.
|
||||
if ($token === null || \strlen($token) !== 32) {
|
||||
throw new \Exception(Text::_('JINVALID_TOKEN'), 403);
|
||||
}
|
||||
|
||||
// Get the User ID
|
||||
$userIdToActivate = $model->getUserIdFromToken($token);
|
||||
|
||||
if (!$userIdToActivate) {
|
||||
$this->setMessage(Text::_('COM_USERS_ACTIVATION_TOKEN_NOT_FOUND'));
|
||||
$this->setRedirect(Route::_('index.php?option=com_users&view=login', false));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the user we want to activate
|
||||
$userToActivate = $this->getUserFactory()->loadUserById($userIdToActivate);
|
||||
|
||||
// Admin activation is on and admin is activating the account
|
||||
if (($uParams->get('useractivation') == 2) && $userToActivate->getParam('activate', 0)) {
|
||||
// If a user admin is not logged in, redirect them to the login page with an error message
|
||||
if (!$user->authorise('core.create', 'com_users') || !$user->authorise('core.manage', 'com_users')) {
|
||||
$activationUrl = 'index.php?option=com_users&task=registration.activate&token=' . $token;
|
||||
$loginUrl = 'index.php?option=com_users&view=login&return=' . base64_encode($activationUrl);
|
||||
|
||||
// In case we still run into this in the second step the user does not have the right permissions
|
||||
$message = Text::_('COM_USERS_REGISTRATION_ACL_ADMIN_ACTIVATION_PERMISSIONS');
|
||||
|
||||
// When we are not logged in we should login
|
||||
if ($user->guest) {
|
||||
$message = Text::_('COM_USERS_REGISTRATION_ACL_ADMIN_ACTIVATION');
|
||||
}
|
||||
|
||||
$this->setMessage($message);
|
||||
$this->setRedirect(Route::_($loginUrl, false));
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Attempt to activate the user.
|
||||
$return = $model->activate($token);
|
||||
|
||||
// Check for errors.
|
||||
if ($return === false) {
|
||||
// Redirect back to the home page.
|
||||
$this->setMessage(Text::sprintf('COM_USERS_REGISTRATION_SAVE_FAILED', $model->getError()), 'error');
|
||||
$this->setRedirect('index.php');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$useractivation = $uParams->get('useractivation');
|
||||
|
||||
// Redirect to the login screen.
|
||||
if ($useractivation == 0) {
|
||||
$this->setMessage(Text::_('COM_USERS_REGISTRATION_SAVE_SUCCESS'));
|
||||
$this->setRedirect(Route::_('index.php?option=com_users&view=login', false));
|
||||
} elseif ($useractivation == 1) {
|
||||
$this->setMessage(Text::_('COM_USERS_REGISTRATION_ACTIVATE_SUCCESS'));
|
||||
$this->setRedirect(Route::_('index.php?option=com_users&view=login', false));
|
||||
} elseif ($return->getParam('activate')) {
|
||||
$this->setMessage(Text::_('COM_USERS_REGISTRATION_VERIFY_SUCCESS'));
|
||||
$this->setRedirect(Route::_('index.php?option=com_users&view=registration&layout=complete', false));
|
||||
} else {
|
||||
$this->setMessage(Text::_('COM_USERS_REGISTRATION_ADMINACTIVATE_SUCCESS'));
|
||||
$this->setRedirect(Route::_('index.php?option=com_users&view=registration&layout=complete', false));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to register a user.
|
||||
*
|
||||
* @return boolean True on success, false on failure.
|
||||
*
|
||||
* @since 1.6
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
// Check for request forgeries.
|
||||
$this->checkToken();
|
||||
|
||||
// If registration is disabled - Redirect to login page.
|
||||
if (ComponentHelper::getParams('com_users')->get('allowUserRegistration') == 0) {
|
||||
$this->setRedirect(Route::_('index.php?option=com_users&view=login', false));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$app = $this->app;
|
||||
|
||||
/** @var \Joomla\Component\Users\Site\Model\RegistrationModel $model */
|
||||
$model = $this->getModel('Registration', 'Site');
|
||||
|
||||
// Get the user data.
|
||||
$requestData = $this->input->post->get('jform', [], 'array');
|
||||
|
||||
// Validate the posted data.
|
||||
$form = $model->getForm();
|
||||
|
||||
if (!$form) {
|
||||
throw new \Exception($model->getError(), 500);
|
||||
}
|
||||
|
||||
$data = $model->validate($form, $requestData);
|
||||
|
||||
// Check for validation errors.
|
||||
if ($data === false) {
|
||||
// Get the validation messages.
|
||||
$errors = $model->getErrors();
|
||||
|
||||
// Push up to three validation messages out to the user.
|
||||
for ($i = 0, $n = \count($errors); $i < $n && $i < 3; $i++) {
|
||||
if ($errors[$i] instanceof \Exception) {
|
||||
$app->enqueueMessage($errors[$i]->getMessage(), 'error');
|
||||
} else {
|
||||
$app->enqueueMessage($errors[$i], 'error');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* We need the filtered value of calendar fields because the UTC normalisation is
|
||||
* done in the filter and on output. This would apply the Timezone offset on
|
||||
* reload. We set the calendar values we save to the processed date.
|
||||
*/
|
||||
$filteredData = $form->filter($requestData);
|
||||
|
||||
foreach ($form->getFieldset() as $field) {
|
||||
if ($field->type === 'Calendar') {
|
||||
$fieldName = $field->fieldname;
|
||||
|
||||
if ($field->group) {
|
||||
if (isset($filteredData[$field->group][$fieldName])) {
|
||||
$requestData[$field->group][$fieldName] = $filteredData[$field->group][$fieldName];
|
||||
}
|
||||
} else {
|
||||
if (isset($filteredData[$fieldName])) {
|
||||
$requestData[$fieldName] = $filteredData[$fieldName];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Save the data in the session.
|
||||
$app->setUserState('com_users.registration.data', $requestData);
|
||||
|
||||
// Redirect back to the registration screen.
|
||||
$this->setRedirect(Route::_('index.php?option=com_users&view=registration', false));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Attempt to save the data.
|
||||
$return = $model->register($data);
|
||||
|
||||
// Check for errors.
|
||||
if ($return === false) {
|
||||
// Save the data in the session.
|
||||
$app->setUserState('com_users.registration.data', $data);
|
||||
|
||||
// Redirect back to the edit screen.
|
||||
$this->setMessage($model->getError(), 'error');
|
||||
$this->setRedirect(Route::_('index.php?option=com_users&view=registration', false));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Flush the data from the session.
|
||||
$app->setUserState('com_users.registration.data', null);
|
||||
|
||||
// Redirect to the profile screen.
|
||||
if ($return === 'adminactivate') {
|
||||
$this->setMessage(Text::_('COM_USERS_REGISTRATION_COMPLETE_VERIFY'));
|
||||
$this->setRedirect(Route::_('index.php?option=com_users&view=registration&layout=complete', false));
|
||||
} elseif ($return === 'useractivate') {
|
||||
$this->setMessage(Text::_('COM_USERS_REGISTRATION_COMPLETE_ACTIVATE'));
|
||||
$this->setRedirect(Route::_('index.php?option=com_users&view=registration&layout=complete', false));
|
||||
} else {
|
||||
$this->setMessage(Text::_('COM_USERS_REGISTRATION_SAVE_SUCCESS'));
|
||||
$this->setRedirect(Route::_('index.php?option=com_users&view=login', false));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
63
components/com_users/src/Controller/RemindController.php
Normal file
63
components/com_users/src/Controller/RemindController.php
Normal file
@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage com_users
|
||||
*
|
||||
* @copyright (C) 2010 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Users\Site\Controller;
|
||||
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\MVC\Controller\BaseController;
|
||||
use Joomla\CMS\Router\Route;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Reset controller class for Users.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
class RemindController extends BaseController
|
||||
{
|
||||
/**
|
||||
* Method to request a username reminder.
|
||||
*
|
||||
* @return boolean
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public function remind()
|
||||
{
|
||||
// Check the request token.
|
||||
$this->checkToken('post');
|
||||
|
||||
/** @var \Joomla\Component\Users\Site\Model\RemindModel $model */
|
||||
$model = $this->getModel('Remind', 'Site');
|
||||
$data = $this->input->post->get('jform', [], 'array');
|
||||
|
||||
// Submit the password reset request.
|
||||
$return = $model->processRemindRequest($data);
|
||||
|
||||
// Check for a hard error.
|
||||
if ($return == false && JDEBUG) {
|
||||
// The request failed.
|
||||
// Go back to the request form.
|
||||
$message = Text::sprintf('COM_USERS_REMIND_REQUEST_FAILED', $model->getError());
|
||||
$this->setRedirect(Route::_('index.php?option=com_users&view=remind', false), $message, 'notice');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// To not expose if the user exists or not we send a generic message.
|
||||
$message = Text::_('COM_USERS_REMIND_REQUEST');
|
||||
$this->setRedirect(Route::_('index.php?option=com_users&view=login', false), $message, 'notice');
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
185
components/com_users/src/Controller/ResetController.php
Normal file
185
components/com_users/src/Controller/ResetController.php
Normal file
@ -0,0 +1,185 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage com_users
|
||||
*
|
||||
* @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Users\Site\Controller;
|
||||
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\MVC\Controller\BaseController;
|
||||
use Joomla\CMS\Router\Route;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Reset controller class for Users.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
class ResetController extends BaseController
|
||||
{
|
||||
/**
|
||||
* Method to request a password reset.
|
||||
*
|
||||
* @return boolean
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public function request()
|
||||
{
|
||||
// Check the request token.
|
||||
$this->checkToken('post');
|
||||
|
||||
$app = $this->app;
|
||||
|
||||
/** @var \Joomla\Component\Users\Site\Model\ResetModel $model */
|
||||
$model = $this->getModel('Reset', 'Site');
|
||||
$data = $this->input->post->get('jform', [], 'array');
|
||||
|
||||
// Submit the password reset request.
|
||||
$return = $model->processResetRequest($data);
|
||||
|
||||
// Check for a hard error.
|
||||
if ($return instanceof \Exception && JDEBUG) {
|
||||
// Get the error message to display.
|
||||
if ($app->get('error_reporting')) {
|
||||
$message = $return->getMessage();
|
||||
} else {
|
||||
$message = Text::_('COM_USERS_RESET_REQUEST_ERROR');
|
||||
}
|
||||
|
||||
// Go back to the request form.
|
||||
$this->setRedirect(Route::_('index.php?option=com_users&view=reset', false), $message, 'error');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($return === false && JDEBUG) {
|
||||
// The request failed.
|
||||
// Go back to the request form.
|
||||
$message = Text::sprintf('COM_USERS_RESET_REQUEST_FAILED', $model->getError());
|
||||
$this->setRedirect(Route::_('index.php?option=com_users&view=reset', false), $message, 'notice');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// To not expose if the user exists or not we send a generic message.
|
||||
$message = Text::_('COM_USERS_RESET_REQUEST');
|
||||
$this->setRedirect(Route::_('index.php?option=com_users&view=reset&layout=confirm', false), $message, 'notice');
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to confirm the password request.
|
||||
*
|
||||
* @return boolean
|
||||
*
|
||||
* @access public
|
||||
* @since 1.6
|
||||
*/
|
||||
public function confirm()
|
||||
{
|
||||
// Check the request token.
|
||||
$this->checkToken('request');
|
||||
|
||||
$app = $this->app;
|
||||
|
||||
/** @var \Joomla\Component\Users\Site\Model\ResetModel $model */
|
||||
$model = $this->getModel('Reset', 'Site');
|
||||
$data = $this->input->get('jform', [], 'array');
|
||||
|
||||
// Confirm the password reset request.
|
||||
$return = $model->processResetConfirm($data);
|
||||
|
||||
// Check for a hard error.
|
||||
if ($return instanceof \Exception) {
|
||||
// Get the error message to display.
|
||||
if ($app->get('error_reporting')) {
|
||||
$message = $return->getMessage();
|
||||
} else {
|
||||
$message = Text::_('COM_USERS_RESET_CONFIRM_ERROR');
|
||||
}
|
||||
|
||||
// Go back to the confirm form.
|
||||
$this->setRedirect(Route::_('index.php?option=com_users&view=reset&layout=confirm', false), $message, 'error');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($return === false) {
|
||||
// Confirm failed.
|
||||
// Go back to the confirm form.
|
||||
$message = Text::sprintf('COM_USERS_RESET_CONFIRM_FAILED', $model->getError());
|
||||
$this->setRedirect(Route::_('index.php?option=com_users&view=reset&layout=confirm', false), $message, 'notice');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Confirm succeeded.
|
||||
// Proceed to step three.
|
||||
$this->setRedirect(Route::_('index.php?option=com_users&view=reset&layout=complete', false));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to complete the password reset process.
|
||||
*
|
||||
* @return boolean
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public function complete()
|
||||
{
|
||||
// Check for request forgeries
|
||||
$this->checkToken('post');
|
||||
|
||||
$app = $this->app;
|
||||
|
||||
/** @var \Joomla\Component\Users\Site\Model\ResetModel $model */
|
||||
$model = $this->getModel('Reset', 'Site');
|
||||
$data = $this->input->post->get('jform', [], 'array');
|
||||
|
||||
// Complete the password reset request.
|
||||
$return = $model->processResetComplete($data);
|
||||
|
||||
// Check for a hard error.
|
||||
if ($return instanceof \Exception) {
|
||||
// Get the error message to display.
|
||||
if ($app->get('error_reporting')) {
|
||||
$message = $return->getMessage();
|
||||
} else {
|
||||
$message = Text::_('COM_USERS_RESET_COMPLETE_ERROR');
|
||||
}
|
||||
|
||||
// Go back to the complete form.
|
||||
$this->setRedirect(Route::_('index.php?option=com_users&view=reset&layout=complete', false), $message, 'error');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($return === false) {
|
||||
// Complete failed.
|
||||
// Go back to the complete form.
|
||||
$message = Text::sprintf('COM_USERS_RESET_COMPLETE_FAILED', $model->getError());
|
||||
$this->setRedirect(Route::_('index.php?option=com_users&view=reset&layout=complete', false), $message, 'notice');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Complete succeeded.
|
||||
// Proceed to the login form.
|
||||
$message = Text::_('COM_USERS_RESET_COMPLETE_SUCCESS');
|
||||
$this->setRedirect(Route::_('index.php?option=com_users&view=login', false), $message);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
270
components/com_users/src/Controller/UserController.php
Normal file
270
components/com_users/src/Controller/UserController.php
Normal file
@ -0,0 +1,270 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage com_users
|
||||
*
|
||||
* @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Users\Site\Controller;
|
||||
|
||||
use Joomla\CMS\Application\ApplicationHelper;
|
||||
use Joomla\CMS\Language\Multilanguage;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\MVC\Controller\BaseController;
|
||||
use Joomla\CMS\Router\Route;
|
||||
use Joomla\CMS\Session\Session;
|
||||
use Joomla\CMS\Uri\Uri;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Registration controller class for Users.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
class UserController extends BaseController
|
||||
{
|
||||
/**
|
||||
* Method to log in a user.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public function login()
|
||||
{
|
||||
$this->checkToken('post');
|
||||
|
||||
$input = $this->input->getInputForRequestMethod();
|
||||
|
||||
// Populate the data array:
|
||||
$data = [];
|
||||
|
||||
$data['return'] = base64_decode($input->get('return', '', 'BASE64'));
|
||||
$data['username'] = $input->get('username', '', 'USERNAME');
|
||||
$data['password'] = $input->get('password', '', 'RAW');
|
||||
$data['secretkey'] = $input->get('secretkey', '', 'RAW');
|
||||
|
||||
// Check for a simple menu item id
|
||||
if (is_numeric($data['return'])) {
|
||||
$itemId = (int) $data['return'];
|
||||
$data['return'] = 'index.php?Itemid=' . $itemId;
|
||||
|
||||
if (Multilanguage::isEnabled()) {
|
||||
$language = $this->getModel('Login', 'Site')->getMenuLanguage($itemId);
|
||||
|
||||
if ($language !== '*') {
|
||||
$data['return'] .= '&lang=' . $language;
|
||||
}
|
||||
}
|
||||
} elseif (!Uri::isInternal($data['return'])) {
|
||||
// Don't redirect to an external URL.
|
||||
$data['return'] = '';
|
||||
}
|
||||
|
||||
// Set the return URL if empty.
|
||||
if (empty($data['return'])) {
|
||||
$data['return'] = 'index.php?option=com_users&view=profile';
|
||||
}
|
||||
|
||||
// Set the return URL in the user state to allow modification by plugins
|
||||
$this->app->setUserState('users.login.form.return', $data['return']);
|
||||
|
||||
// Get the log in options.
|
||||
$options = [];
|
||||
$options['remember'] = $this->input->getBool('remember', false);
|
||||
$options['return'] = $data['return'];
|
||||
|
||||
// Get the log in credentials.
|
||||
$credentials = [];
|
||||
$credentials['username'] = $data['username'];
|
||||
$credentials['password'] = $data['password'];
|
||||
$credentials['secretkey'] = $data['secretkey'];
|
||||
|
||||
// Perform the log in.
|
||||
if (true !== $this->app->login($credentials, $options)) {
|
||||
// Login failed !
|
||||
// Clear user name, password and secret key before sending the login form back to the user.
|
||||
$data['remember'] = (int) $options['remember'];
|
||||
$data['username'] = '';
|
||||
$data['password'] = '';
|
||||
$data['secretkey'] = '';
|
||||
$this->app->setUserState('users.login.form.data', $data);
|
||||
$this->app->redirect(Route::_('index.php?option=com_users&view=login', false));
|
||||
}
|
||||
|
||||
// Success
|
||||
if ($options['remember'] == true) {
|
||||
$this->app->setUserState('rememberLogin', true);
|
||||
}
|
||||
|
||||
$this->app->setUserState('users.login.form.data', []);
|
||||
|
||||
$this->app->redirect(Route::_($this->app->getUserState('users.login.form.return'), false));
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to log out a user.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public function logout()
|
||||
{
|
||||
$this->checkToken('request');
|
||||
|
||||
$app = $this->app;
|
||||
|
||||
// Prepare the logout options.
|
||||
$options = [
|
||||
'clientid' => $app->get('shared_session', '0') ? null : 0,
|
||||
];
|
||||
|
||||
// Perform the log out.
|
||||
$error = $app->logout(null, $options);
|
||||
$input = $app->getInput()->getInputForRequestMethod();
|
||||
|
||||
// Check if the log out succeeded.
|
||||
if ($error instanceof \Exception) {
|
||||
$app->redirect(Route::_('index.php?option=com_users&view=login', false));
|
||||
}
|
||||
|
||||
// Get the return URL from the request and validate that it is internal.
|
||||
$return = $input->get('return', '', 'BASE64');
|
||||
$return = base64_decode($return);
|
||||
|
||||
// Check for a simple menu item id
|
||||
if (is_numeric($return)) {
|
||||
$itemId = (int) $return;
|
||||
$return = 'index.php?Itemid=' . $itemId;
|
||||
|
||||
if (Multilanguage::isEnabled()) {
|
||||
$language = $this->getModel('Login', 'Site')->getMenuLanguage($itemId);
|
||||
|
||||
if ($language !== '*') {
|
||||
$return .= '&lang=' . $language;
|
||||
}
|
||||
}
|
||||
} elseif (!Uri::isInternal($return)) {
|
||||
$return = '';
|
||||
}
|
||||
|
||||
// In case redirect url is not set, redirect user to homepage
|
||||
if (empty($return)) {
|
||||
$return = Uri::root();
|
||||
}
|
||||
|
||||
// Show a message when a user is logged out.
|
||||
$app->enqueueMessage(Text::_('COM_USERS_FRONTEND_LOGOUT_SUCCESS'), 'message');
|
||||
|
||||
// Redirect the user.
|
||||
$app->redirect(Route::_($return, false));
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to logout directly and redirect to page.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 3.5
|
||||
*/
|
||||
public function menulogout()
|
||||
{
|
||||
// Get the ItemID of the page to redirect after logout
|
||||
$app = $this->app;
|
||||
$active = $app->getMenu()->getActive();
|
||||
$itemid = $active ? $active->getParams()->get('logout') : 0;
|
||||
|
||||
// Get the language of the page when multilang is on
|
||||
if (Multilanguage::isEnabled()) {
|
||||
if ($itemid) {
|
||||
$language = $this->getModel('Login', 'Site')->getMenuLanguage($itemid);
|
||||
|
||||
// URL to redirect after logout
|
||||
$url = 'index.php?Itemid=' . $itemid . ($language !== '*' ? '&lang=' . $language : '');
|
||||
} else {
|
||||
// Logout is set to default. Get the home page ItemID
|
||||
$lang_code = $app->getInput()->cookie->getString(ApplicationHelper::getHash('language'));
|
||||
$item = $app->getMenu()->getDefault($lang_code);
|
||||
$itemid = $item->id;
|
||||
|
||||
// Redirect to Home page after logout
|
||||
$url = 'index.php?Itemid=' . $itemid;
|
||||
}
|
||||
} else {
|
||||
// URL to redirect after logout, default page if no ItemID is set
|
||||
$url = $itemid ? 'index.php?Itemid=' . $itemid : Uri::root();
|
||||
}
|
||||
|
||||
// Logout and redirect
|
||||
$this->setRedirect('index.php?option=com_users&task=user.logout&' . Session::getFormToken() . '=1&return=' . base64_encode($url));
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to request a username reminder.
|
||||
*
|
||||
* @return boolean
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public function remind()
|
||||
{
|
||||
// Check the request token.
|
||||
$this->checkToken('post');
|
||||
|
||||
$app = $this->app;
|
||||
|
||||
/** @var \Joomla\Component\Users\Site\Model\RemindModel $model */
|
||||
$model = $this->getModel('Remind', 'Site');
|
||||
$data = $this->input->post->get('jform', [], 'array');
|
||||
|
||||
// Submit the username remind request.
|
||||
$return = $model->processRemindRequest($data);
|
||||
|
||||
// Check for a hard error.
|
||||
if ($return instanceof \Exception) {
|
||||
// Get the error message to display.
|
||||
$message = $app->get('error_reporting')
|
||||
? $return->getMessage()
|
||||
: Text::_('COM_USERS_REMIND_REQUEST_ERROR');
|
||||
|
||||
// Go back to the complete form.
|
||||
$this->setRedirect(Route::_('index.php?option=com_users&view=remind', false), $message, 'error');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($return === false) {
|
||||
// Go back to the complete form.
|
||||
$message = Text::sprintf('COM_USERS_REMIND_REQUEST_FAILED', $model->getError());
|
||||
$this->setRedirect(Route::_('index.php?option=com_users&view=remind', false), $message, 'notice');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Proceed to the login form.
|
||||
$message = Text::_('COM_USERS_REMIND_REQUEST_SUCCESS');
|
||||
$this->setRedirect(Route::_('index.php?option=com_users&view=login', false), $message);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to resend a user.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public function resend()
|
||||
{
|
||||
// Check for request forgeries
|
||||
// $this->checkToken('post');
|
||||
}
|
||||
}
|
||||
24
components/com_users/src/Model/BackupcodesModel.php
Normal file
24
components/com_users/src/Model/BackupcodesModel.php
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_users
|
||||
*
|
||||
* @copyright (C) 2022 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Users\Site\Model;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Model for managing backup codes
|
||||
*
|
||||
* @since 4.2.0
|
||||
*/
|
||||
class BackupcodesModel extends \Joomla\Component\Users\Administrator\Model\BackupcodesModel
|
||||
{
|
||||
}
|
||||
24
components/com_users/src/Model/CaptiveModel.php
Normal file
24
components/com_users/src/Model/CaptiveModel.php
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_users
|
||||
*
|
||||
* @copyright (C) 2022 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Users\Site\Model;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Captive Multi-factor Authentication page's model
|
||||
*
|
||||
* @since 4.2.0
|
||||
*/
|
||||
class CaptiveModel extends \Joomla\Component\Users\Administrator\Model\CaptiveModel
|
||||
{
|
||||
}
|
||||
155
components/com_users/src/Model/LoginModel.php
Normal file
155
components/com_users/src/Model/LoginModel.php
Normal file
@ -0,0 +1,155 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage com_users
|
||||
*
|
||||
* @copyright (C) 2010 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Users\Site\Model;
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Form\Form;
|
||||
use Joomla\CMS\Language\Multilanguage;
|
||||
use Joomla\CMS\MVC\Model\FormModel;
|
||||
use Joomla\CMS\Uri\Uri;
|
||||
use Joomla\Database\ParameterType;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Login model class for Users.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
class LoginModel extends FormModel
|
||||
{
|
||||
/**
|
||||
* Method to get the login form.
|
||||
*
|
||||
* The base form is loaded from XML and then an event is fired
|
||||
* for users plugins to extend the form with extra fields.
|
||||
*
|
||||
* @param array $data An optional array of data for the form to interrogate.
|
||||
* @param boolean $loadData True if the form is to load its own data (default case), false if not.
|
||||
*
|
||||
* @return Form A Form object on success, false on failure
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public function getForm($data = [], $loadData = true)
|
||||
{
|
||||
// Get the form.
|
||||
$form = $this->loadForm('com_users.login', 'login', ['load_data' => $loadData]);
|
||||
|
||||
if (empty($form)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get the data that should be injected in the form.
|
||||
*
|
||||
* @return array The default data is an empty array.
|
||||
*
|
||||
* @since 1.6
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function loadFormData()
|
||||
{
|
||||
// Check the session for previously entered login form data.
|
||||
$app = Factory::getApplication();
|
||||
$data = $app->getUserState('users.login.form.data', []);
|
||||
|
||||
$input = $app->getInput()->getInputForRequestMethod();
|
||||
|
||||
// Check for return URL from the request first
|
||||
if ($return = $input->get('return', '', 'BASE64')) {
|
||||
$data['return'] = base64_decode($return);
|
||||
|
||||
if (!Uri::isInternal($data['return'])) {
|
||||
$data['return'] = '';
|
||||
}
|
||||
}
|
||||
|
||||
$app->setUserState('users.login.form.data', $data);
|
||||
|
||||
$this->preprocessData('com_users.login', $data);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to auto-populate the model state.
|
||||
*
|
||||
* Calling getState in this method will result in recursion.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 1.6
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function populateState()
|
||||
{
|
||||
// Get the application object.
|
||||
$params = Factory::getApplication()->getParams('com_users');
|
||||
|
||||
// Load the parameters.
|
||||
$this->setState('params', $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Override Joomla\CMS\MVC\Model\AdminModel::preprocessForm to ensure the correct plugin group is loaded.
|
||||
*
|
||||
* @param Form $form A Form object.
|
||||
* @param mixed $data The data expected for the form.
|
||||
* @param string $group The name of the plugin group to import (defaults to "content").
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 1.6
|
||||
* @throws \Exception if there is an error in the form event.
|
||||
*/
|
||||
protected function preprocessForm(Form $form, $data, $group = 'user')
|
||||
{
|
||||
parent::preprocessForm($form, $data, $group);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the language for the given menu id.
|
||||
*
|
||||
* @param int $id The menu id
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @since 4.2.0
|
||||
*/
|
||||
public function getMenuLanguage(int $id): string
|
||||
{
|
||||
if (!Multilanguage::isEnabled()) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$db = $this->getDatabase();
|
||||
$query = $db->getQuery(true)
|
||||
->select($db->quoteName('language'))
|
||||
->from($db->quoteName('#__menu'))
|
||||
->where($db->quoteName('client_id') . ' = 0')
|
||||
->where($db->quoteName('id') . ' = :id')
|
||||
->bind(':id', $id, ParameterType::INTEGER);
|
||||
|
||||
$db->setQuery($query);
|
||||
|
||||
try {
|
||||
return $db->loadResult();
|
||||
} catch (\RuntimeException $e) {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
}
|
||||
24
components/com_users/src/Model/MethodModel.php
Normal file
24
components/com_users/src/Model/MethodModel.php
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_users
|
||||
*
|
||||
* @copyright (C) 2022 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Users\Site\Model;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Multi-factor Authentication Method management model
|
||||
*
|
||||
* @since 4.2.0
|
||||
*/
|
||||
class MethodModel extends \Joomla\Component\Users\Administrator\Model\MethodModel
|
||||
{
|
||||
}
|
||||
24
components/com_users/src/Model/MethodsModel.php
Normal file
24
components/com_users/src/Model/MethodsModel.php
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_users
|
||||
*
|
||||
* @copyright (C) 2022 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Users\Site\Model;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Multi-factor Authentication Methods list page's model
|
||||
*
|
||||
* @since 4.2.0
|
||||
*/
|
||||
class MethodsModel extends \Joomla\Component\Users\Administrator\Model\MethodsModel
|
||||
{
|
||||
}
|
||||
337
components/com_users/src/Model/ProfileModel.php
Normal file
337
components/com_users/src/Model/ProfileModel.php
Normal file
@ -0,0 +1,337 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage com_users
|
||||
*
|
||||
* @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Users\Site\Model;
|
||||
|
||||
use Joomla\CMS\Access\Access;
|
||||
use Joomla\CMS\Component\ComponentHelper;
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Form\Form;
|
||||
use Joomla\CMS\Form\FormFactoryInterface;
|
||||
use Joomla\CMS\Language\Multilanguage;
|
||||
use Joomla\CMS\MVC\Factory\MVCFactoryInterface;
|
||||
use Joomla\CMS\MVC\Model\FormModel;
|
||||
use Joomla\CMS\Plugin\PluginHelper;
|
||||
use Joomla\CMS\String\PunycodeHelper;
|
||||
use Joomla\CMS\User\User;
|
||||
use Joomla\CMS\User\UserHelper;
|
||||
use Joomla\Component\Users\Administrator\Model\UserModel;
|
||||
use Joomla\Registry\Registry;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Profile model class for Users.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
class ProfileModel extends FormModel
|
||||
{
|
||||
/**
|
||||
* @var object The user profile data.
|
||||
* @since 1.6
|
||||
*/
|
||||
protected $data;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param array $config An array of configuration options (name, state, dbo, table_path, ignore_request).
|
||||
* @param MVCFactoryInterface $factory The factory.
|
||||
* @param FormFactoryInterface $formFactory The form factory.
|
||||
*
|
||||
* @see \Joomla\CMS\MVC\Model\BaseDatabaseModel
|
||||
* @since 3.2
|
||||
*/
|
||||
public function __construct($config = [], MVCFactoryInterface $factory = null, FormFactoryInterface $formFactory = null)
|
||||
{
|
||||
$config = array_merge(
|
||||
[
|
||||
'events_map' => ['validate' => 'user'],
|
||||
],
|
||||
$config
|
||||
);
|
||||
|
||||
parent::__construct($config, $factory, $formFactory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get the profile form data.
|
||||
*
|
||||
* The base form data is loaded and then an event is fired
|
||||
* for users plugins to extend the data.
|
||||
*
|
||||
* @return User
|
||||
*
|
||||
* @since 1.6
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getData()
|
||||
{
|
||||
if ($this->data === null) {
|
||||
$userId = $this->getState('user.id');
|
||||
|
||||
// Initialise the table with Joomla\CMS\User\User.
|
||||
$this->data = new User($userId);
|
||||
|
||||
// Set the base user data.
|
||||
$this->data->email1 = $this->data->get('email');
|
||||
|
||||
// Override the base user data with any data in the session.
|
||||
$temp = (array) Factory::getApplication()->getUserState('com_users.edit.profile.data', []);
|
||||
|
||||
foreach ($temp as $k => $v) {
|
||||
$this->data->$k = $v;
|
||||
}
|
||||
|
||||
// Unset the passwords.
|
||||
unset($this->data->password1, $this->data->password2);
|
||||
|
||||
$registry = new Registry($this->data->params);
|
||||
$this->data->params = $registry->toArray();
|
||||
}
|
||||
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get the profile form.
|
||||
*
|
||||
* The base form is loaded from XML and then an event is fired
|
||||
* for users plugins to extend the form with extra fields.
|
||||
*
|
||||
* @param array $data An optional array of data for the form to interrogate.
|
||||
* @param boolean $loadData True if the form is to load its own data (default case), false if not.
|
||||
*
|
||||
* @return Form|bool A Form object on success, false on failure
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public function getForm($data = [], $loadData = true)
|
||||
{
|
||||
// Get the form.
|
||||
$form = $this->loadForm('com_users.profile', 'profile', ['control' => 'jform', 'load_data' => $loadData]);
|
||||
|
||||
if (empty($form)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check for username compliance and parameter set
|
||||
$isUsernameCompliant = true;
|
||||
$username = $loadData ? $form->getValue('username') : $this->loadFormData()->username;
|
||||
|
||||
if ($username) {
|
||||
$isUsernameCompliant = !(preg_match('#[<>"\'%;()&\\\\]|\\.\\./#', $username)
|
||||
|| \strlen(mb_convert_encoding($username, 'ISO-8859-1', 'UTF-8')) < 2
|
||||
|| trim($username) !== $username);
|
||||
}
|
||||
|
||||
$this->setState('user.username.compliant', $isUsernameCompliant);
|
||||
|
||||
if ($isUsernameCompliant && !ComponentHelper::getParams('com_users')->get('change_login_name')) {
|
||||
$form->setFieldAttribute('username', 'class', '');
|
||||
$form->setFieldAttribute('username', 'filter', '');
|
||||
$form->setFieldAttribute('username', 'description', 'COM_USERS_PROFILE_NOCHANGE_USERNAME_DESC');
|
||||
$form->setFieldAttribute('username', 'validate', '');
|
||||
$form->setFieldAttribute('username', 'message', '');
|
||||
$form->setFieldAttribute('username', 'readonly', 'true');
|
||||
$form->setFieldAttribute('username', 'required', 'false');
|
||||
}
|
||||
|
||||
// When multilanguage is set, a user's default site language should also be a Content Language
|
||||
if (Multilanguage::isEnabled()) {
|
||||
$form->setFieldAttribute('language', 'type', 'frontend_language', 'params');
|
||||
}
|
||||
|
||||
// If the user needs to change their password, mark the password fields as required
|
||||
if ($this->getCurrentUser()->requireReset) {
|
||||
$form->setFieldAttribute('password1', 'required', 'true');
|
||||
$form->setFieldAttribute('password2', 'required', 'true');
|
||||
}
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get the data that should be injected in the form.
|
||||
*
|
||||
* @return mixed The data for the form.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
protected function loadFormData()
|
||||
{
|
||||
$data = $this->getData();
|
||||
|
||||
$this->preprocessData('com_users.profile', $data, 'user');
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override preprocessForm to load the user plugin group instead of content.
|
||||
*
|
||||
* @param Form $form A Form object.
|
||||
* @param mixed $data The data expected for the form.
|
||||
* @param string $group The name of the plugin group to import (defaults to "content").
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws \Exception if there is an error in the form event.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
protected function preprocessForm(Form $form, $data, $group = 'user')
|
||||
{
|
||||
if (ComponentHelper::getParams('com_users')->get('frontend_userparams')) {
|
||||
$form->loadFile('frontend', false);
|
||||
|
||||
if ($this->getCurrentUser()->authorise('core.login.admin')) {
|
||||
$form->loadFile('frontend_admin', false);
|
||||
}
|
||||
}
|
||||
|
||||
parent::preprocessForm($form, $data, $group);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to auto-populate the model state.
|
||||
*
|
||||
* Note. Calling getState in this method will result in recursion.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 1.6
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function populateState()
|
||||
{
|
||||
// Get the application object.
|
||||
$params = Factory::getApplication()->getParams('com_users');
|
||||
|
||||
// Get the user id.
|
||||
$userId = Factory::getApplication()->getUserState('com_users.edit.profile.id');
|
||||
$userId = !empty($userId) ? $userId : (int) $this->getCurrentUser()->get('id');
|
||||
|
||||
// Set the user id.
|
||||
$this->setState('user.id', $userId);
|
||||
|
||||
// Load the parameters.
|
||||
$this->setState('params', $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to save the form data.
|
||||
*
|
||||
* @param array $data The form data.
|
||||
*
|
||||
* @return mixed The user id on success, false on failure.
|
||||
*
|
||||
* @since 1.6
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function save($data)
|
||||
{
|
||||
$userId = (!empty($data['id'])) ? $data['id'] : (int) $this->getState('user.id');
|
||||
|
||||
$user = new User($userId);
|
||||
|
||||
// Prepare the data for the user object.
|
||||
$data['email'] = PunycodeHelper::emailToPunycode($data['email1']);
|
||||
$data['password'] = $data['password1'];
|
||||
|
||||
// Unset the username if it should not be overwritten
|
||||
$isUsernameCompliant = $this->getState('user.username.compliant');
|
||||
|
||||
if ($isUsernameCompliant && !ComponentHelper::getParams('com_users')->get('change_login_name')) {
|
||||
unset($data['username']);
|
||||
}
|
||||
|
||||
// Unset block and sendEmail so they do not get overwritten
|
||||
unset($data['block'], $data['sendEmail']);
|
||||
|
||||
// Bind the data.
|
||||
if (!$user->bind($data)) {
|
||||
$this->setError($user->getError());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Load the users plugin group.
|
||||
PluginHelper::importPlugin('user');
|
||||
|
||||
// Retrieve the user groups so they don't get overwritten
|
||||
unset($user->groups);
|
||||
$user->groups = Access::getGroupsByUser($user->id, false);
|
||||
|
||||
// Store the data.
|
||||
if (!$user->save()) {
|
||||
$this->setError($user->getError());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Destroy all active sessions for the user after changing the password
|
||||
if ($data['password']) {
|
||||
UserHelper::destroyUserSessions($user->id, true);
|
||||
}
|
||||
|
||||
return $user->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the configuration forms for all two-factor authentication methods
|
||||
* in an array.
|
||||
*
|
||||
* @param integer $userId The user ID to load the forms for (optional)
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 3.2
|
||||
*
|
||||
* @deprecated 4.2 will be removed in 6.0.
|
||||
* Will be removed without replacement
|
||||
*/
|
||||
public function getTwofactorform($userId = null)
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* No longer used
|
||||
*
|
||||
* @param integer $userId Ignored
|
||||
*
|
||||
* @return \stdClass
|
||||
*
|
||||
* @since 3.2
|
||||
*
|
||||
* @deprecated 4.2 will be removed in 6.0.
|
||||
* Will be removed without replacement
|
||||
*/
|
||||
public function getOtpConfig($userId = null)
|
||||
{
|
||||
@trigger_error(
|
||||
sprintf(
|
||||
'%s() is deprecated. Use \Joomla\Component\Users\Administrator\Helper\Mfa::getUserMfaRecords() instead.',
|
||||
__METHOD__
|
||||
),
|
||||
E_USER_DEPRECATED
|
||||
);
|
||||
|
||||
/** @var UserModel $model */
|
||||
$model = $this->bootComponent('com_users')
|
||||
->getMVCFactory()->createModel('User', 'Administrator');
|
||||
|
||||
return $model->getOtpConfig();
|
||||
}
|
||||
}
|
||||
654
components/com_users/src/Model/RegistrationModel.php
Normal file
654
components/com_users/src/Model/RegistrationModel.php
Normal file
@ -0,0 +1,654 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage com_users
|
||||
*
|
||||
* @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Users\Site\Model;
|
||||
|
||||
use Joomla\CMS\Application\ApplicationHelper;
|
||||
use Joomla\CMS\Component\ComponentHelper;
|
||||
use Joomla\CMS\Date\Date;
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Form\Form;
|
||||
use Joomla\CMS\Form\FormFactoryInterface;
|
||||
use Joomla\CMS\Language\Multilanguage;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\Log\Log;
|
||||
use Joomla\CMS\Mail\MailTemplate;
|
||||
use Joomla\CMS\MVC\Factory\MVCFactoryInterface;
|
||||
use Joomla\CMS\MVC\Model\FormModel;
|
||||
use Joomla\CMS\Plugin\PluginHelper;
|
||||
use Joomla\CMS\Router\Route;
|
||||
use Joomla\CMS\String\PunycodeHelper;
|
||||
use Joomla\CMS\Uri\Uri;
|
||||
use Joomla\CMS\User\User;
|
||||
use Joomla\CMS\User\UserFactoryAwareInterface;
|
||||
use Joomla\CMS\User\UserFactoryAwareTrait;
|
||||
use Joomla\CMS\User\UserHelper;
|
||||
use Joomla\Database\ParameterType;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Registration model class for Users.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
class RegistrationModel extends FormModel implements UserFactoryAwareInterface
|
||||
{
|
||||
use UserFactoryAwareTrait;
|
||||
|
||||
/**
|
||||
* @var object The user registration data.
|
||||
* @since 1.6
|
||||
*/
|
||||
protected $data;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param array $config An array of configuration options (name, state, dbo, table_path, ignore_request).
|
||||
* @param MVCFactoryInterface $factory The factory.
|
||||
* @param FormFactoryInterface $formFactory The form factory.
|
||||
*
|
||||
* @see \Joomla\CMS\MVC\Model\BaseDatabaseModel
|
||||
* @since 3.2
|
||||
*/
|
||||
public function __construct($config = [], MVCFactoryInterface $factory = null, FormFactoryInterface $formFactory = null)
|
||||
{
|
||||
$config = array_merge(
|
||||
[
|
||||
'events_map' => ['validate' => 'user'],
|
||||
],
|
||||
$config
|
||||
);
|
||||
|
||||
parent::__construct($config, $factory, $formFactory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get the user ID from the given token
|
||||
*
|
||||
* @param string $token The activation token.
|
||||
*
|
||||
* @return mixed False on failure, id of the user on success
|
||||
*
|
||||
* @since 3.8.13
|
||||
*/
|
||||
public function getUserIdFromToken($token)
|
||||
{
|
||||
$db = $this->getDatabase();
|
||||
|
||||
// Get the user id based on the token.
|
||||
$query = $db->getQuery(true);
|
||||
$query->select($db->quoteName('id'))
|
||||
->from($db->quoteName('#__users'))
|
||||
->where($db->quoteName('activation') . ' = :activation')
|
||||
->where($db->quoteName('block') . ' = 1')
|
||||
->where($db->quoteName('lastvisitDate') . ' IS NULL')
|
||||
->bind(':activation', $token);
|
||||
$db->setQuery($query);
|
||||
|
||||
try {
|
||||
return (int) $db->loadResult();
|
||||
} catch (\RuntimeException $e) {
|
||||
$this->setError(Text::sprintf('COM_USERS_DATABASE_ERROR', $e->getMessage()));
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to activate a user account.
|
||||
*
|
||||
* @param string $token The activation token.
|
||||
*
|
||||
* @return mixed False on failure, user object on success.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public function activate($token)
|
||||
{
|
||||
$app = Factory::getApplication();
|
||||
$userParams = ComponentHelper::getParams('com_users');
|
||||
$userId = $this->getUserIdFromToken($token);
|
||||
|
||||
// Check for a valid user id.
|
||||
if (!$userId) {
|
||||
$this->setError(Text::_('COM_USERS_ACTIVATION_TOKEN_NOT_FOUND'));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Load the users plugin group.
|
||||
PluginHelper::importPlugin('user');
|
||||
|
||||
// Activate the user.
|
||||
$user = $this->getUserFactory()->loadUserById($userId);
|
||||
|
||||
// Admin activation is on and user is verifying their email
|
||||
if (($userParams->get('useractivation') == 2) && !$user->getParam('activate', 0)) {
|
||||
$linkMode = $app->get('force_ssl', 0) == 2 ? Route::TLS_FORCE : Route::TLS_IGNORE;
|
||||
|
||||
// Compile the admin notification mail values.
|
||||
$data = $user->getProperties();
|
||||
$data['activation'] = ApplicationHelper::getHash(UserHelper::genRandomPassword());
|
||||
$user->set('activation', $data['activation']);
|
||||
$data['siteurl'] = Uri::base();
|
||||
$data['activate'] = Route::link(
|
||||
'site',
|
||||
'index.php?option=com_users&task=registration.activate&token=' . $data['activation'],
|
||||
false,
|
||||
$linkMode,
|
||||
true
|
||||
);
|
||||
|
||||
$data['fromname'] = $app->get('fromname');
|
||||
$data['mailfrom'] = $app->get('mailfrom');
|
||||
$data['sitename'] = $app->get('sitename');
|
||||
$user->setParam('activate', 1);
|
||||
|
||||
// Get all admin users
|
||||
$db = $this->getDatabase();
|
||||
$query = $db->getQuery(true)
|
||||
->select($db->quoteName(['name', 'email', 'sendEmail', 'id']))
|
||||
->from($db->quoteName('#__users'))
|
||||
->where($db->quoteName('sendEmail') . ' = 1')
|
||||
->where($db->quoteName('block') . ' = 0');
|
||||
|
||||
$db->setQuery($query);
|
||||
|
||||
try {
|
||||
$rows = $db->loadObjectList();
|
||||
} catch (\RuntimeException $e) {
|
||||
$this->setError(Text::sprintf('COM_USERS_DATABASE_ERROR', $e->getMessage()));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Send mail to all users with users creating permissions and receiving system emails
|
||||
foreach ($rows as $row) {
|
||||
$usercreator = $this->getUserFactory()->loadUserById($row->id);
|
||||
|
||||
if ($usercreator->authorise('core.create', 'com_users') && $usercreator->authorise('core.manage', 'com_users')) {
|
||||
try {
|
||||
$mailer = new MailTemplate('com_users.registration.admin.verification_request', $app->getLanguage()->getTag());
|
||||
$mailer->addTemplateData($data);
|
||||
$mailer->addRecipient($row->email);
|
||||
$return = $mailer->send();
|
||||
} catch (\Exception $exception) {
|
||||
try {
|
||||
Log::add(Text::_($exception->getMessage()), Log::WARNING, 'jerror');
|
||||
|
||||
$return = false;
|
||||
} catch (\RuntimeException $exception) {
|
||||
Factory::getApplication()->enqueueMessage(Text::_($exception->errorMessage()), 'warning');
|
||||
|
||||
$return = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for an error.
|
||||
if ($return !== true) {
|
||||
$this->setError(Text::_('COM_USERS_REGISTRATION_ACTIVATION_NOTIFY_SEND_MAIL_FAILED'));
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
} elseif (($userParams->get('useractivation') == 2) && $user->getParam('activate', 0)) {
|
||||
// Admin activation is on and admin is activating the account
|
||||
$user->set('activation', '');
|
||||
$user->set('block', '0');
|
||||
|
||||
// Compile the user activated notification mail values.
|
||||
$data = $user->getProperties();
|
||||
$user->setParam('activate', 0);
|
||||
$data['fromname'] = $app->get('fromname');
|
||||
$data['mailfrom'] = $app->get('mailfrom');
|
||||
$data['sitename'] = $app->get('sitename');
|
||||
$data['siteurl'] = Uri::base();
|
||||
$mailer = new MailTemplate('com_users.registration.user.admin_activated', $app->getLanguage()->getTag());
|
||||
$mailer->addTemplateData($data);
|
||||
$mailer->addRecipient($data['email']);
|
||||
|
||||
try {
|
||||
$return = $mailer->send();
|
||||
} catch (\Exception $exception) {
|
||||
try {
|
||||
Log::add(Text::_($exception->getMessage()), Log::WARNING, 'jerror');
|
||||
|
||||
$return = false;
|
||||
} catch (\RuntimeException $exception) {
|
||||
Factory::getApplication()->enqueueMessage(Text::_($exception->errorMessage()), 'warning');
|
||||
|
||||
$return = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for an error.
|
||||
if ($return !== true) {
|
||||
$this->setError(Text::_('COM_USERS_REGISTRATION_ACTIVATION_NOTIFY_SEND_MAIL_FAILED'));
|
||||
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
$user->set('activation', '');
|
||||
$user->set('block', '0');
|
||||
}
|
||||
|
||||
// Store the user object.
|
||||
if (!$user->save()) {
|
||||
$this->setError(Text::sprintf('COM_USERS_REGISTRATION_ACTIVATION_SAVE_FAILED', $user->getError()));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get the registration form data.
|
||||
*
|
||||
* The base form data is loaded and then an event is fired
|
||||
* for users plugins to extend the data.
|
||||
*
|
||||
* @return mixed Data object on success, false on failure.
|
||||
*
|
||||
* @since 1.6
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getData()
|
||||
{
|
||||
if ($this->data === null) {
|
||||
$this->data = new \stdClass();
|
||||
$app = Factory::getApplication();
|
||||
$params = ComponentHelper::getParams('com_users');
|
||||
|
||||
// Override the base user data with any data in the session.
|
||||
$temp = (array) $app->getUserState('com_users.registration.data', []);
|
||||
|
||||
// Don't load the data in this getForm call, or we'll call ourself
|
||||
$form = $this->getForm([], false);
|
||||
|
||||
foreach ($temp as $k => $v) {
|
||||
// Here we could have a grouped field, let's check it
|
||||
if (\is_array($v)) {
|
||||
$this->data->$k = new \stdClass();
|
||||
|
||||
foreach ($v as $key => $val) {
|
||||
if ($form->getField($key, $k) !== false) {
|
||||
$this->data->$k->$key = $val;
|
||||
}
|
||||
}
|
||||
} elseif ($form->getField($k) !== false) {
|
||||
// Only merge the field if it exists in the form.
|
||||
$this->data->$k = $v;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the groups the user should be added to after registration.
|
||||
$this->data->groups = [];
|
||||
|
||||
// Get the default new user group, guest or public group if not specified.
|
||||
$system = $params->get('new_usertype', $params->get('guest_usergroup', 1));
|
||||
|
||||
$this->data->groups[] = $system;
|
||||
|
||||
// Unset the passwords.
|
||||
unset($this->data->password1, $this->data->password2);
|
||||
|
||||
// Get the dispatcher and load the users plugins.
|
||||
PluginHelper::importPlugin('user');
|
||||
|
||||
// Trigger the data preparation event.
|
||||
Factory::getApplication()->triggerEvent('onContentPrepareData', ['com_users.registration', $this->data]);
|
||||
}
|
||||
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get the registration form.
|
||||
*
|
||||
* The base form is loaded from XML and then an event is fired
|
||||
* for users plugins to extend the form with extra fields.
|
||||
*
|
||||
* @param array $data An optional array of data for the form to interrogate.
|
||||
* @param boolean $loadData True if the form is to load its own data (default case), false if not.
|
||||
*
|
||||
* @return Form A Form object on success, false on failure
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public function getForm($data = [], $loadData = true)
|
||||
{
|
||||
// Get the form.
|
||||
$form = $this->loadForm('com_users.registration', 'registration', ['control' => 'jform', 'load_data' => $loadData]);
|
||||
|
||||
if (empty($form)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// When multilanguage is set, a user's default site language should also be a Content Language
|
||||
if (Multilanguage::isEnabled()) {
|
||||
$form->setFieldAttribute('language', 'type', 'frontend_language', 'params');
|
||||
}
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get the data that should be injected in the form.
|
||||
*
|
||||
* @return mixed The data for the form.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
protected function loadFormData()
|
||||
{
|
||||
$data = $this->getData();
|
||||
|
||||
if (Multilanguage::isEnabled() && empty($data->language)) {
|
||||
$data->language = Factory::getLanguage()->getTag();
|
||||
}
|
||||
|
||||
$this->preprocessData('com_users.registration', $data);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override preprocessForm to load the user plugin group instead of content.
|
||||
*
|
||||
* @param Form $form A Form object.
|
||||
* @param mixed $data The data expected for the form.
|
||||
* @param string $group The name of the plugin group to import (defaults to "content").
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 1.6
|
||||
* @throws \Exception if there is an error in the form event.
|
||||
*/
|
||||
protected function preprocessForm(Form $form, $data, $group = 'user')
|
||||
{
|
||||
$userParams = ComponentHelper::getParams('com_users');
|
||||
|
||||
// Add the choice for site language at registration time
|
||||
if ($userParams->get('site_language') == 1 && $userParams->get('frontend_userparams') == 1) {
|
||||
$form->loadFile('sitelang', false);
|
||||
}
|
||||
|
||||
parent::preprocessForm($form, $data, $group);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to auto-populate the model state.
|
||||
*
|
||||
* Note. Calling getState in this method will result in recursion.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 1.6
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function populateState()
|
||||
{
|
||||
// Get the application object.
|
||||
$app = Factory::getApplication();
|
||||
$params = $app->getParams('com_users');
|
||||
|
||||
// Load the parameters.
|
||||
$this->setState('params', $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to save the form data.
|
||||
*
|
||||
* @param array $temp The form data.
|
||||
*
|
||||
* @return mixed The user id on success, false on failure.
|
||||
*
|
||||
* @since 1.6
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function register($temp)
|
||||
{
|
||||
$params = ComponentHelper::getParams('com_users');
|
||||
|
||||
// Initialise the table with Joomla\CMS\User\User.
|
||||
$user = new User();
|
||||
$data = (array) $this->getData();
|
||||
|
||||
// Merge in the registration data.
|
||||
foreach ($temp as $k => $v) {
|
||||
$data[$k] = $v;
|
||||
}
|
||||
|
||||
// Prepare the data for the user object.
|
||||
$data['email'] = PunycodeHelper::emailToPunycode($data['email1']);
|
||||
$data['password'] = $data['password1'];
|
||||
$useractivation = $params->get('useractivation');
|
||||
$sendpassword = $params->get('sendpassword', 1);
|
||||
|
||||
// Check if the user needs to activate their account.
|
||||
if (($useractivation == 1) || ($useractivation == 2)) {
|
||||
$data['activation'] = ApplicationHelper::getHash(UserHelper::genRandomPassword());
|
||||
$data['block'] = 1;
|
||||
}
|
||||
|
||||
// Bind the data.
|
||||
if (!$user->bind($data)) {
|
||||
$this->setError($user->getError());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Load the users plugin group.
|
||||
PluginHelper::importPlugin('user');
|
||||
|
||||
// Store the data.
|
||||
if (!$user->save()) {
|
||||
$this->setError(Text::sprintf('COM_USERS_REGISTRATION_SAVE_FAILED', $user->getError()));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$app = Factory::getApplication();
|
||||
$db = $this->getDatabase();
|
||||
$query = $db->getQuery(true);
|
||||
|
||||
// Compile the notification mail values.
|
||||
$data = $user->getProperties();
|
||||
$data['fromname'] = $app->get('fromname');
|
||||
$data['mailfrom'] = $app->get('mailfrom');
|
||||
$data['sitename'] = $app->get('sitename');
|
||||
$data['siteurl'] = Uri::root();
|
||||
|
||||
// Handle account activation/confirmation emails.
|
||||
if ($useractivation == 2) {
|
||||
// Set the link to confirm the user email.
|
||||
$linkMode = $app->get('force_ssl', 0) == 2 ? Route::TLS_FORCE : Route::TLS_IGNORE;
|
||||
|
||||
$data['activate'] = Route::link(
|
||||
'site',
|
||||
'index.php?option=com_users&task=registration.activate&token=' . $data['activation'],
|
||||
false,
|
||||
$linkMode,
|
||||
true
|
||||
);
|
||||
|
||||
$mailtemplate = 'com_users.registration.user.admin_activation';
|
||||
} elseif ($useractivation == 1) {
|
||||
// Set the link to activate the user account.
|
||||
$linkMode = $app->get('force_ssl', 0) == 2 ? Route::TLS_FORCE : Route::TLS_IGNORE;
|
||||
|
||||
$data['activate'] = Route::link(
|
||||
'site',
|
||||
'index.php?option=com_users&task=registration.activate&token=' . $data['activation'],
|
||||
false,
|
||||
$linkMode,
|
||||
true
|
||||
);
|
||||
|
||||
$mailtemplate = 'com_users.registration.user.self_activation';
|
||||
} else {
|
||||
$mailtemplate = 'com_users.registration.user.registration_mail';
|
||||
}
|
||||
|
||||
if ($sendpassword) {
|
||||
$mailtemplate .= '_w_pw';
|
||||
}
|
||||
|
||||
// Try to send the registration email.
|
||||
try {
|
||||
$mailer = new MailTemplate($mailtemplate, $app->getLanguage()->getTag());
|
||||
$mailer->addTemplateData($data);
|
||||
$mailer->addRecipient($data['email']);
|
||||
$return = $mailer->send();
|
||||
} catch (\Exception $exception) {
|
||||
try {
|
||||
Log::add(Text::_($exception->getMessage()), Log::WARNING, 'jerror');
|
||||
|
||||
$return = false;
|
||||
} catch (\RuntimeException $exception) {
|
||||
Factory::getApplication()->enqueueMessage(Text::_($exception->errorMessage()), 'warning');
|
||||
|
||||
$this->setError(Text::_('COM_MESSAGES_ERROR_MAIL_FAILED'));
|
||||
|
||||
$return = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Send mail to all users with user creating permissions and receiving system emails
|
||||
if (($params->get('useractivation') < 2) && ($params->get('mail_to_admin') == 1)) {
|
||||
// Get all admin users
|
||||
$query->clear()
|
||||
->select($db->quoteName(['name', 'email', 'sendEmail', 'id']))
|
||||
->from($db->quoteName('#__users'))
|
||||
->where($db->quoteName('sendEmail') . ' = 1')
|
||||
->where($db->quoteName('block') . ' = 0');
|
||||
|
||||
$db->setQuery($query);
|
||||
|
||||
try {
|
||||
$rows = $db->loadObjectList();
|
||||
} catch (\RuntimeException $e) {
|
||||
$this->setError(Text::sprintf('COM_USERS_DATABASE_ERROR', $e->getMessage()));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Send mail to all superadministrators id
|
||||
foreach ($rows as $row) {
|
||||
$usercreator = $this->getUserFactory()->loadUserById($row->id);
|
||||
|
||||
if (!$usercreator->authorise('core.create', 'com_users') || !$usercreator->authorise('core.manage', 'com_users')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
$mailer = new MailTemplate('com_users.registration.admin.new_notification', $app->getLanguage()->getTag());
|
||||
$mailer->addTemplateData($data);
|
||||
$mailer->addRecipient($row->email);
|
||||
$return = $mailer->send();
|
||||
} catch (\Exception $exception) {
|
||||
try {
|
||||
Log::add(Text::_($exception->getMessage()), Log::WARNING, 'jerror');
|
||||
|
||||
$return = false;
|
||||
} catch (\RuntimeException $exception) {
|
||||
Factory::getApplication()->enqueueMessage(Text::_($exception->errorMessage()), 'warning');
|
||||
|
||||
$return = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for an error.
|
||||
if ($return !== true) {
|
||||
$this->setError(Text::_('COM_USERS_REGISTRATION_ACTIVATION_NOTIFY_SEND_MAIL_FAILED'));
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check for an error.
|
||||
if ($return !== true) {
|
||||
$this->setError(Text::_('COM_USERS_REGISTRATION_SEND_MAIL_FAILED'));
|
||||
|
||||
// Send a system message to administrators receiving system mails
|
||||
$db = $this->getDatabase();
|
||||
$query->clear()
|
||||
->select($db->quoteName('id'))
|
||||
->from($db->quoteName('#__users'))
|
||||
->where($db->quoteName('block') . ' = 0')
|
||||
->where($db->quoteName('sendEmail') . ' = 1');
|
||||
$db->setQuery($query);
|
||||
|
||||
try {
|
||||
$userids = $db->loadColumn();
|
||||
} catch (\RuntimeException $e) {
|
||||
$this->setError(Text::sprintf('COM_USERS_DATABASE_ERROR', $e->getMessage()));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (\count($userids) > 0) {
|
||||
$jdate = new Date();
|
||||
$dateToSql = $jdate->toSql();
|
||||
$subject = Text::_('COM_USERS_MAIL_SEND_FAILURE_SUBJECT');
|
||||
$message = Text::sprintf('COM_USERS_MAIL_SEND_FAILURE_BODY', $data['username']);
|
||||
|
||||
// Build the query to add the messages
|
||||
foreach ($userids as $userid) {
|
||||
$values = [
|
||||
':user_id_from',
|
||||
':user_id_to',
|
||||
':date_time',
|
||||
':subject',
|
||||
':message',
|
||||
];
|
||||
$query->clear()
|
||||
->insert($db->quoteName('#__messages'))
|
||||
->columns($db->quoteName(['user_id_from', 'user_id_to', 'date_time', 'subject', 'message']))
|
||||
->values(implode(',', $values));
|
||||
$query->bind(':user_id_from', $userid, ParameterType::INTEGER)
|
||||
->bind(':user_id_to', $userid, ParameterType::INTEGER)
|
||||
->bind(':date_time', $dateToSql)
|
||||
->bind(':subject', $subject)
|
||||
->bind(':message', $message);
|
||||
|
||||
$db->setQuery($query);
|
||||
|
||||
try {
|
||||
$db->execute();
|
||||
} catch (\RuntimeException $e) {
|
||||
$this->setError(Text::sprintf('COM_USERS_DATABASE_ERROR', $e->getMessage()));
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($useractivation == 1) {
|
||||
return 'useractivate';
|
||||
}
|
||||
|
||||
if ($useractivation == 2) {
|
||||
return 'adminactivate';
|
||||
}
|
||||
|
||||
return $user->id;
|
||||
}
|
||||
}
|
||||
211
components/com_users/src/Model/RemindModel.php
Normal file
211
components/com_users/src/Model/RemindModel.php
Normal file
@ -0,0 +1,211 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage com_users
|
||||
*
|
||||
* @copyright (C) 2010 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Users\Site\Model;
|
||||
|
||||
use Joomla\CMS\Event\User\AfterRemindEvent;
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Form\Form;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\Log\Log;
|
||||
use Joomla\CMS\Mail\MailTemplate;
|
||||
use Joomla\CMS\MVC\Model\FormModel;
|
||||
use Joomla\CMS\Router\Route;
|
||||
use Joomla\CMS\String\PunycodeHelper;
|
||||
use Joomla\Utilities\ArrayHelper;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Remind model class for Users.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
class RemindModel extends FormModel
|
||||
{
|
||||
/**
|
||||
* Method to get the username remind request form.
|
||||
*
|
||||
* @param array $data An optional array of data for the form to interrogate.
|
||||
* @param boolean $loadData True if the form is to load its own data (default case), false if not.
|
||||
*
|
||||
* @return Form|bool A Form object on success, false on failure
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public function getForm($data = [], $loadData = true)
|
||||
{
|
||||
// Get the form.
|
||||
$form = $this->loadForm('com_users.remind', 'remind', ['control' => 'jform', 'load_data' => $loadData]);
|
||||
|
||||
if (empty($form)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override preprocessForm to load the user plugin group instead of content.
|
||||
*
|
||||
* @param Form $form A Form object.
|
||||
* @param mixed $data The data expected for the form.
|
||||
* @param string $group The name of the plugin group to import (defaults to "content").
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws \Exception if there is an error in the form event.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
protected function preprocessForm(Form $form, $data, $group = 'user')
|
||||
{
|
||||
parent::preprocessForm($form, $data, 'user');
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to auto-populate the model state.
|
||||
*
|
||||
* Note. Calling getState in this method will result in recursion.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 1.6
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function populateState()
|
||||
{
|
||||
// Get the application object.
|
||||
$app = Factory::getApplication();
|
||||
$params = $app->getParams('com_users');
|
||||
|
||||
// Load the parameters.
|
||||
$this->setState('params', $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the remind username email
|
||||
*
|
||||
* @param array $data Array with the data received from the form
|
||||
*
|
||||
* @return boolean
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public function processRemindRequest($data)
|
||||
{
|
||||
// Get the form.
|
||||
$form = $this->getForm();
|
||||
$data['email'] = PunycodeHelper::emailToPunycode($data['email']);
|
||||
|
||||
// Check for an error.
|
||||
if (empty($form)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Validate the data.
|
||||
$data = $this->validate($form, $data);
|
||||
|
||||
// Check for an error.
|
||||
if ($data instanceof \Exception) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check the validation results.
|
||||
if ($data === false) {
|
||||
// Get the validation messages from the form.
|
||||
foreach ($form->getErrors() as $formError) {
|
||||
$this->setError($formError->getMessage());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Find the user id for the given email address.
|
||||
$db = $this->getDatabase();
|
||||
$query = $db->getQuery(true)
|
||||
->select('*')
|
||||
->from($db->quoteName('#__users'))
|
||||
->where('LOWER(' . $db->quoteName('email') . ') = LOWER(:email)')
|
||||
->bind(':email', $data['email']);
|
||||
|
||||
// Get the user id.
|
||||
$db->setQuery($query);
|
||||
|
||||
try {
|
||||
$user = $db->loadObject();
|
||||
} catch (\RuntimeException $e) {
|
||||
$this->setError(Text::sprintf('COM_USERS_DATABASE_ERROR', $e->getMessage()));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check for a user.
|
||||
if (empty($user)) {
|
||||
$this->setError(Text::_('COM_USERS_USER_NOT_FOUND'));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Make sure the user isn't blocked.
|
||||
if ($user->block) {
|
||||
$this->setError(Text::_('COM_USERS_USER_BLOCKED'));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$app = Factory::getApplication();
|
||||
|
||||
// Assemble the login link.
|
||||
$link = 'index.php?option=com_users&view=login';
|
||||
$mode = $app->get('force_ssl', 0) == 2 ? 1 : (-1);
|
||||
|
||||
// Put together the email template data.
|
||||
$data = ArrayHelper::fromObject($user);
|
||||
$data['sitename'] = $app->get('sitename');
|
||||
$data['link_text'] = Route::_($link, false, $mode);
|
||||
$data['link_html'] = Route::_($link, true, $mode);
|
||||
|
||||
$mailer = new MailTemplate('com_users.reminder', $app->getLanguage()->getTag());
|
||||
$mailer->addTemplateData($data);
|
||||
$mailer->addRecipient($user->email, $user->name);
|
||||
|
||||
// Try to send the password reset request email.
|
||||
try {
|
||||
$return = $mailer->send();
|
||||
} catch (\Exception $exception) {
|
||||
try {
|
||||
Log::add(Text::_($exception->getMessage()), Log::WARNING, 'jerror');
|
||||
|
||||
$return = false;
|
||||
} catch (\RuntimeException $exception) {
|
||||
Factory::getApplication()->enqueueMessage(Text::_($exception->errorMessage()), 'warning');
|
||||
|
||||
$return = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for an error.
|
||||
if ($return !== true) {
|
||||
$this->setError(Text::_('COM_USERS_MAIL_FAILED'));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->getDispatcher()->dispatch('onUserAfterRemind', new AfterRemindEvent('onUserAfterRemind', [
|
||||
'subject' => $user,
|
||||
]));
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
547
components/com_users/src/Model/ResetModel.php
Normal file
547
components/com_users/src/Model/ResetModel.php
Normal file
@ -0,0 +1,547 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage com_users
|
||||
*
|
||||
* @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Users\Site\Model;
|
||||
|
||||
use Joomla\CMS\Application\ApplicationHelper;
|
||||
use Joomla\CMS\Event\AbstractEvent;
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Form\Form;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\Log\Log;
|
||||
use Joomla\CMS\Mail\MailTemplate;
|
||||
use Joomla\CMS\MVC\Model\FormModel;
|
||||
use Joomla\CMS\Router\Route;
|
||||
use Joomla\CMS\String\PunycodeHelper;
|
||||
use Joomla\CMS\User\User;
|
||||
use Joomla\CMS\User\UserFactoryAwareInterface;
|
||||
use Joomla\CMS\User\UserFactoryAwareTrait;
|
||||
use Joomla\CMS\User\UserHelper;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Reset model class for Users.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
class ResetModel extends FormModel implements UserFactoryAwareInterface
|
||||
{
|
||||
use UserFactoryAwareTrait;
|
||||
|
||||
/**
|
||||
* Method to get the password reset request form.
|
||||
*
|
||||
* The base form is loaded from XML and then an event is fired
|
||||
* for users plugins to extend the form with extra fields.
|
||||
*
|
||||
* @param array $data An optional array of data for the form to interrogate.
|
||||
* @param boolean $loadData True if the form is to load its own data (default case), false if not.
|
||||
*
|
||||
* @return Form A Form object on success, false on failure
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public function getForm($data = [], $loadData = true)
|
||||
{
|
||||
// Get the form.
|
||||
$form = $this->loadForm('com_users.reset_request', 'reset_request', ['control' => 'jform', 'load_data' => $loadData]);
|
||||
|
||||
if (empty($form)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get the password reset complete form.
|
||||
*
|
||||
* @param array $data Data for the form.
|
||||
* @param boolean $loadData True if the form is to load its own data (default case), false if not.
|
||||
*
|
||||
* @return Form A Form object on success, false on failure
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public function getResetCompleteForm($data = [], $loadData = true)
|
||||
{
|
||||
// Get the form.
|
||||
$form = $this->loadForm('com_users.reset_complete', 'reset_complete', $options = ['control' => 'jform']);
|
||||
|
||||
if (empty($form)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get the password reset confirm form.
|
||||
*
|
||||
* @param array $data Data for the form.
|
||||
* @param boolean $loadData True if the form is to load its own data (default case), false if not.
|
||||
*
|
||||
* @return Form A Form object on success, false on failure
|
||||
*
|
||||
* @since 1.6
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getResetConfirmForm($data = [], $loadData = true)
|
||||
{
|
||||
// Get the form.
|
||||
$form = $this->loadForm('com_users.reset_confirm', 'reset_confirm', $options = ['control' => 'jform']);
|
||||
|
||||
if (empty($form)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$form->setValue('token', '', Factory::getApplication()->getInput()->get('token'));
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override preprocessForm to load the user plugin group instead of content.
|
||||
*
|
||||
* @param Form $form A Form object.
|
||||
* @param mixed $data The data expected for the form.
|
||||
* @param string $group The name of the plugin group to import (defaults to "content").
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws \Exception if there is an error in the form event.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
protected function preprocessForm(Form $form, $data, $group = 'user')
|
||||
{
|
||||
parent::preprocessForm($form, $data, $group);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to auto-populate the model state.
|
||||
*
|
||||
* Note. Calling getState in this method will result in recursion.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 1.6
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function populateState()
|
||||
{
|
||||
// Get the application object.
|
||||
$params = Factory::getApplication()->getParams('com_users');
|
||||
|
||||
// Load the parameters.
|
||||
$this->setState('params', $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the new password after reset is done
|
||||
*
|
||||
* @param array $data The data expected for the form.
|
||||
*
|
||||
* @return mixed \Exception | boolean
|
||||
*
|
||||
* @since 1.6
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function processResetComplete($data)
|
||||
{
|
||||
// Get the form.
|
||||
$form = $this->getResetCompleteForm();
|
||||
|
||||
// Check for an error.
|
||||
if ($form instanceof \Exception) {
|
||||
return $form;
|
||||
}
|
||||
|
||||
// Filter and validate the form data.
|
||||
$data = $form->filter($data);
|
||||
$return = $form->validate($data);
|
||||
|
||||
// Check for an error.
|
||||
if ($return instanceof \Exception) {
|
||||
return $return;
|
||||
}
|
||||
|
||||
// Check the validation results.
|
||||
if ($return === false) {
|
||||
// Get the validation messages from the form.
|
||||
foreach ($form->getErrors() as $formError) {
|
||||
$this->setError($formError->getMessage());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the token and user id from the confirmation process.
|
||||
$app = Factory::getApplication();
|
||||
$token = $app->getUserState('com_users.reset.token', null);
|
||||
$userId = $app->getUserState('com_users.reset.user', null);
|
||||
|
||||
// Check the token and user id.
|
||||
if (empty($token) || empty($userId)) {
|
||||
return new \Exception(Text::_('COM_USERS_RESET_COMPLETE_TOKENS_MISSING'), 403);
|
||||
}
|
||||
|
||||
// Get the user object.
|
||||
$user = $this->getUserFactory()->loadUserById($userId);
|
||||
|
||||
$event = AbstractEvent::create(
|
||||
'onUserBeforeResetComplete',
|
||||
[
|
||||
'subject' => $user,
|
||||
]
|
||||
);
|
||||
$app->getDispatcher()->dispatch($event->getName(), $event);
|
||||
|
||||
// Check for a user and that the tokens match.
|
||||
if (empty($user) || $user->activation !== $token) {
|
||||
$this->setError(Text::_('COM_USERS_USER_NOT_FOUND'));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Make sure the user isn't blocked.
|
||||
if ($user->block) {
|
||||
$this->setError(Text::_('COM_USERS_USER_BLOCKED'));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if the user is reusing the current password if required to reset their password
|
||||
if ($user->requireReset == 1 && UserHelper::verifyPassword($data['password1'], $user->password)) {
|
||||
$this->setError(Text::_('JLIB_USER_ERROR_CANNOT_REUSE_PASSWORD'));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Prepare user data.
|
||||
$data['password'] = $data['password1'];
|
||||
$data['activation'] = '';
|
||||
|
||||
// Update the user object.
|
||||
if (!$user->bind($data)) {
|
||||
return new \Exception($user->getError(), 500);
|
||||
}
|
||||
|
||||
// Save the user to the database.
|
||||
if (!$user->save(true)) {
|
||||
return new \Exception(Text::sprintf('COM_USERS_USER_SAVE_FAILED', $user->getError()), 500);
|
||||
}
|
||||
|
||||
// Destroy all active sessions for the user
|
||||
UserHelper::destroyUserSessions($user->id);
|
||||
|
||||
// Flush the user data from the session.
|
||||
$app->setUserState('com_users.reset.token', null);
|
||||
$app->setUserState('com_users.reset.user', null);
|
||||
|
||||
$event = AbstractEvent::create(
|
||||
'onUserAfterResetComplete',
|
||||
[
|
||||
'subject' => $user,
|
||||
]
|
||||
);
|
||||
$app->getDispatcher()->dispatch($event->getName(), $event);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Receive the reset password request
|
||||
*
|
||||
* @param array $data The data expected for the form.
|
||||
*
|
||||
* @return mixed \Exception | boolean
|
||||
*
|
||||
* @since 1.6
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function processResetConfirm($data)
|
||||
{
|
||||
// Get the form.
|
||||
$form = $this->getResetConfirmForm();
|
||||
|
||||
// Check for an error.
|
||||
if ($form instanceof \Exception) {
|
||||
return $form;
|
||||
}
|
||||
|
||||
// Filter and validate the form data.
|
||||
$data = $form->filter($data);
|
||||
$return = $form->validate($data);
|
||||
|
||||
// Check for an error.
|
||||
if ($return instanceof \Exception) {
|
||||
return $return;
|
||||
}
|
||||
|
||||
// Check the validation results.
|
||||
if ($return === false) {
|
||||
// Get the validation messages from the form.
|
||||
foreach ($form->getErrors() as $formError) {
|
||||
$this->setError($formError->getMessage());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Find the user id for the given token.
|
||||
$db = $this->getDatabase();
|
||||
$query = $db->getQuery(true)
|
||||
->select($db->quoteName(['activation', 'id', 'block']))
|
||||
->from($db->quoteName('#__users'))
|
||||
->where($db->quoteName('username') . ' = :username')
|
||||
->bind(':username', $data['username']);
|
||||
|
||||
// Get the user id.
|
||||
$db->setQuery($query);
|
||||
|
||||
try {
|
||||
$user = $db->loadObject();
|
||||
} catch (\RuntimeException $e) {
|
||||
return new \Exception(Text::sprintf('COM_USERS_DATABASE_ERROR', $e->getMessage()), 500);
|
||||
}
|
||||
|
||||
// Check for a user.
|
||||
if (empty($user)) {
|
||||
$this->setError(Text::_('COM_USERS_USER_NOT_FOUND'));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$user->activation) {
|
||||
$this->setError(Text::_('COM_USERS_USER_NOT_FOUND'));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Verify the token
|
||||
if (!UserHelper::verifyPassword($data['token'], $user->activation)) {
|
||||
$this->setError(Text::_('COM_USERS_USER_NOT_FOUND'));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Make sure the user isn't blocked.
|
||||
if ($user->block) {
|
||||
$this->setError(Text::_('COM_USERS_USER_BLOCKED'));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Push the user data into the session.
|
||||
$app = Factory::getApplication();
|
||||
$app->setUserState('com_users.reset.token', $user->activation);
|
||||
$app->setUserState('com_users.reset.user', $user->id);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to start the password reset process.
|
||||
*
|
||||
* @param array $data The data expected for the form.
|
||||
*
|
||||
* @return mixed \Exception | boolean
|
||||
*
|
||||
* @since 1.6
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function processResetRequest($data)
|
||||
{
|
||||
$app = Factory::getApplication();
|
||||
|
||||
// Get the form.
|
||||
$form = $this->getForm();
|
||||
|
||||
$data['email'] = PunycodeHelper::emailToPunycode($data['email']);
|
||||
|
||||
// Check for an error.
|
||||
if ($form instanceof \Exception) {
|
||||
return $form;
|
||||
}
|
||||
|
||||
// Filter and validate the form data.
|
||||
$data = $form->filter($data);
|
||||
$return = $form->validate($data);
|
||||
|
||||
// Check for an error.
|
||||
if ($return instanceof \Exception) {
|
||||
return $return;
|
||||
}
|
||||
|
||||
// Check the validation results.
|
||||
if ($return === false) {
|
||||
// Get the validation messages from the form.
|
||||
foreach ($form->getErrors() as $formError) {
|
||||
$this->setError($formError->getMessage());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Find the user id for the given email address.
|
||||
$db = $this->getDatabase();
|
||||
$query = $db->getQuery(true)
|
||||
->select($db->quoteName('id'))
|
||||
->from($db->quoteName('#__users'))
|
||||
->where('LOWER(' . $db->quoteName('email') . ') = LOWER(:email)')
|
||||
->bind(':email', $data['email']);
|
||||
|
||||
// Get the user object.
|
||||
$db->setQuery($query);
|
||||
|
||||
try {
|
||||
$userId = $db->loadResult();
|
||||
} catch (\RuntimeException $e) {
|
||||
$this->setError(Text::sprintf('COM_USERS_DATABASE_ERROR', $e->getMessage()));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check for a user.
|
||||
if (empty($userId)) {
|
||||
$this->setError(Text::_('COM_USERS_INVALID_EMAIL'));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the user object.
|
||||
$user = $this->getUserFactory()->loadUserById($userId);
|
||||
|
||||
// Make sure the user isn't blocked.
|
||||
if ($user->block) {
|
||||
$this->setError(Text::_('COM_USERS_USER_BLOCKED'));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Make sure the user isn't a Super Admin.
|
||||
if ($user->authorise('core.admin')) {
|
||||
$this->setError(Text::_('COM_USERS_REMIND_SUPERADMIN_ERROR'));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Make sure the user has not exceeded the reset limit
|
||||
if (!$this->checkResetLimit($user)) {
|
||||
$resetLimit = (int) Factory::getApplication()->getParams()->get('reset_time');
|
||||
$this->setError(Text::plural('COM_USERS_REMIND_LIMIT_ERROR_N_HOURS', $resetLimit));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set the confirmation token.
|
||||
$token = ApplicationHelper::getHash(UserHelper::genRandomPassword());
|
||||
$hashedToken = UserHelper::hashPassword($token);
|
||||
|
||||
$user->activation = $hashedToken;
|
||||
|
||||
$event = AbstractEvent::create(
|
||||
'onUserBeforeResetRequest',
|
||||
[
|
||||
'subject' => $user,
|
||||
]
|
||||
);
|
||||
$app->getDispatcher()->dispatch($event->getName(), $event);
|
||||
|
||||
// Save the user to the database.
|
||||
if (!$user->save(true)) {
|
||||
return new \Exception(Text::sprintf('COM_USERS_USER_SAVE_FAILED', $user->getError()), 500);
|
||||
}
|
||||
|
||||
// Assemble the password reset confirmation link.
|
||||
$mode = $app->get('force_ssl', 0) == 2 ? 1 : (-1);
|
||||
$link = 'index.php?option=com_users&view=reset&layout=confirm&token=' . $token;
|
||||
|
||||
// Put together the email template data.
|
||||
$data = $user->getProperties();
|
||||
$data['sitename'] = $app->get('sitename');
|
||||
$data['link_text'] = Route::_($link, false, $mode);
|
||||
$data['link_html'] = Route::_($link, true, $mode);
|
||||
$data['token'] = $token;
|
||||
|
||||
$mailer = new MailTemplate('com_users.password_reset', $app->getLanguage()->getTag());
|
||||
$mailer->addTemplateData($data);
|
||||
$mailer->addRecipient($user->email, $user->name);
|
||||
|
||||
// Try to send the password reset request email.
|
||||
try {
|
||||
$return = $mailer->send();
|
||||
} catch (\Exception $exception) {
|
||||
try {
|
||||
Log::add(Text::_($exception->getMessage()), Log::WARNING, 'jerror');
|
||||
|
||||
$return = false;
|
||||
} catch (\RuntimeException $exception) {
|
||||
$app->enqueueMessage(Text::_($exception->errorMessage()), 'warning');
|
||||
|
||||
$return = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for an error.
|
||||
if ($return !== true) {
|
||||
return new \Exception(Text::_('COM_USERS_MAIL_FAILED'), 500);
|
||||
}
|
||||
|
||||
$event = AbstractEvent::create(
|
||||
'onUserAfterResetRequest',
|
||||
[
|
||||
'subject' => $user,
|
||||
]
|
||||
);
|
||||
$app->getDispatcher()->dispatch($event->getName(), $event);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to check if user reset limit has been exceeded within the allowed time period.
|
||||
*
|
||||
* @param User $user User doing the password reset
|
||||
*
|
||||
* @return boolean true if user can do the reset, false if limit exceeded
|
||||
*
|
||||
* @since 2.5
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function checkResetLimit($user)
|
||||
{
|
||||
$params = Factory::getApplication()->getParams();
|
||||
$maxCount = (int) $params->get('reset_count');
|
||||
$resetHours = (int) $params->get('reset_time');
|
||||
$result = true;
|
||||
|
||||
$lastResetTime = strtotime($user->lastResetTime) ?: 0;
|
||||
$hoursSinceLastReset = (strtotime(Factory::getDate()->toSql()) - $lastResetTime) / 3600;
|
||||
|
||||
if ($hoursSinceLastReset > $resetHours) {
|
||||
// If it's been long enough, start a new reset count
|
||||
$user->lastResetTime = Factory::getDate()->toSql();
|
||||
$user->resetCount = 1;
|
||||
} elseif ($user->resetCount < $maxCount) {
|
||||
// If we are under the max count, just increment the counter
|
||||
++$user->resetCount;
|
||||
} else {
|
||||
// At this point, we know we have exceeded the maximum resets for the time period
|
||||
$result = false;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
66
components/com_users/src/Rule/LoginUniqueFieldRule.php
Normal file
66
components/com_users/src/Rule/LoginUniqueFieldRule.php
Normal file
@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage com_users
|
||||
*
|
||||
* @copyright (C) 2017 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Users\Site\Rule;
|
||||
|
||||
use Joomla\CMS\Form\Form;
|
||||
use Joomla\CMS\Form\FormRule;
|
||||
use Joomla\Registry\Registry;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* FormRule for com_users to be sure only one redirect login field has a value
|
||||
*
|
||||
* @since 3.6
|
||||
*/
|
||||
class LoginUniqueFieldRule extends FormRule
|
||||
{
|
||||
/**
|
||||
* Method to test if two fields have a value in order to use only one field.
|
||||
* To use this rule, the form
|
||||
* XML needs a validate attribute of loginuniquefield and a field attribute
|
||||
* that is equal to the field to test against.
|
||||
*
|
||||
* @param \SimpleXMLElement $element The SimpleXMLElement object representing the `<field>` tag for the form field object.
|
||||
* @param mixed $value The form field value to validate.
|
||||
* @param string $group The field name group control value. This acts as an array container for the field.
|
||||
* For example if the field has name="foo" and the group value is set to "bar" then the
|
||||
* full field name would end up being "bar[foo]".
|
||||
* @param Registry $input An optional Registry object with the entire data set to validate against the entire form.
|
||||
* @param Form $form The form object for which the field is being tested.
|
||||
*
|
||||
* @return boolean True if the value is valid, false otherwise.
|
||||
*
|
||||
* @since 3.6
|
||||
*/
|
||||
public function test(\SimpleXMLElement $element, $value, $group = null, Registry $input = null, Form $form = null)
|
||||
{
|
||||
$loginRedirectUrl = $input['params']->login_redirect_url;
|
||||
$loginRedirectMenuitem = $input['params']->login_redirect_menuitem;
|
||||
|
||||
if ($form === null) {
|
||||
throw new \InvalidArgumentException(sprintf('The value for $form must not be null in %s', \get_class($this)));
|
||||
}
|
||||
|
||||
if ($input === null) {
|
||||
throw new \InvalidArgumentException(sprintf('The value for $input must not be null in %s', \get_class($this)));
|
||||
}
|
||||
|
||||
// Test the input values for login.
|
||||
if ($loginRedirectUrl != '' && $loginRedirectMenuitem != '') {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
66
components/com_users/src/Rule/LogoutUniqueFieldRule.php
Normal file
66
components/com_users/src/Rule/LogoutUniqueFieldRule.php
Normal file
@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage com_users
|
||||
*
|
||||
* @copyright (C) 2017 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Users\Site\Rule;
|
||||
|
||||
use Joomla\CMS\Form\Form;
|
||||
use Joomla\CMS\Form\FormRule;
|
||||
use Joomla\Registry\Registry;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* FormRule for com_users to be sure only one redirect logout field has a value
|
||||
*
|
||||
* @since 3.6
|
||||
*/
|
||||
class LogoutUniqueFieldRule extends FormRule
|
||||
{
|
||||
/**
|
||||
* Method to test if two fields have a value in order to use only one field.
|
||||
* To use this rule, the form
|
||||
* XML needs a validate attribute of logoutuniquefield and a field attribute
|
||||
* that is equal to the field to test against.
|
||||
*
|
||||
* @param \SimpleXMLElement $element The SimpleXMLElement object representing the `<field>` tag for the form field object.
|
||||
* @param mixed $value The form field value to validate.
|
||||
* @param string $group The field name group control value. This acts as an array container for the field.
|
||||
* For example if the field has name="foo" and the group value is set to "bar" then the
|
||||
* full field name would end up being "bar[foo]".
|
||||
* @param Registry $input An optional Registry object with the entire data set to validate against the entire form.
|
||||
* @param Form $form The form object for which the field is being tested.
|
||||
*
|
||||
* @return boolean True if the value is valid, false otherwise.
|
||||
*
|
||||
* @since 3.6
|
||||
*/
|
||||
public function test(\SimpleXMLElement $element, $value, $group = null, Registry $input = null, Form $form = null)
|
||||
{
|
||||
$logoutRedirectUrl = $input['params']->logout_redirect_url;
|
||||
$logoutRedirectMenuitem = $input['params']->logout_redirect_menuitem;
|
||||
|
||||
if ($form === null) {
|
||||
throw new \InvalidArgumentException(sprintf('The value for $form must not be null in %s', \get_class($this)));
|
||||
}
|
||||
|
||||
if ($input === null) {
|
||||
throw new \InvalidArgumentException(sprintf('The value for $input must not be null in %s', \get_class($this)));
|
||||
}
|
||||
|
||||
// Test the input values for logout.
|
||||
if ($logoutRedirectUrl != '' && $logoutRedirectMenuitem != '') {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
89
components/com_users/src/Service/Router.php
Normal file
89
components/com_users/src/Service/Router.php
Normal file
@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage com_users
|
||||
*
|
||||
* @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Users\Site\Service;
|
||||
|
||||
use Joomla\CMS\Application\SiteApplication;
|
||||
use Joomla\CMS\Component\Router\RouterView;
|
||||
use Joomla\CMS\Component\Router\RouterViewConfiguration;
|
||||
use Joomla\CMS\Component\Router\Rules\MenuRules;
|
||||
use Joomla\CMS\Component\Router\Rules\NomenuRules;
|
||||
use Joomla\CMS\Component\Router\Rules\StandardRules;
|
||||
use Joomla\CMS\Menu\AbstractMenu;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Routing class from com_users
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
class Router extends RouterView
|
||||
{
|
||||
/**
|
||||
* Users Component router constructor
|
||||
*
|
||||
* @param SiteApplication $app The application object
|
||||
* @param AbstractMenu $menu The menu object to work with
|
||||
*/
|
||||
public function __construct(SiteApplication $app, AbstractMenu $menu)
|
||||
{
|
||||
$this->registerView(new RouterViewConfiguration('login'));
|
||||
$profile = new RouterViewConfiguration('profile');
|
||||
$profile->addLayout('edit');
|
||||
$this->registerView($profile);
|
||||
$this->registerView(new RouterViewConfiguration('registration'));
|
||||
$this->registerView(new RouterViewConfiguration('remind'));
|
||||
$this->registerView(new RouterViewConfiguration('reset'));
|
||||
$this->registerView(new RouterViewConfiguration('callback'));
|
||||
$this->registerView(new RouterViewConfiguration('captive'));
|
||||
$this->registerView(new RouterViewConfiguration('methods'));
|
||||
|
||||
$method = new RouterViewConfiguration('method');
|
||||
$method->setKey('id');
|
||||
$this->registerView($method);
|
||||
|
||||
parent::__construct($app, $menu);
|
||||
|
||||
$this->attachRule(new MenuRules($this));
|
||||
$this->attachRule(new StandardRules($this));
|
||||
$this->attachRule(new NomenuRules($this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the method ID from a URL segment
|
||||
*
|
||||
* @param string $segment The URL segment
|
||||
* @param array $query The URL query parameters
|
||||
*
|
||||
* @return integer
|
||||
* @since 4.2.0
|
||||
*/
|
||||
public function getMethodId($segment, $query)
|
||||
{
|
||||
return (int) $segment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a segment from a method ID
|
||||
*
|
||||
* @param integer $id The method ID
|
||||
* @param array $query The URL query parameters
|
||||
*
|
||||
* @return int[]
|
||||
* @since 4.2.0
|
||||
*/
|
||||
public function getMethodSegment($id, $query)
|
||||
{
|
||||
return [$id => (int) $id];
|
||||
}
|
||||
}
|
||||
24
components/com_users/src/View/Captive/HtmlView.php
Normal file
24
components/com_users/src/View/Captive/HtmlView.php
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_users
|
||||
*
|
||||
* @copyright (C) 2022 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Users\Site\View\Captive;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* View for Multi-factor Authentication captive page
|
||||
*
|
||||
* @since 4.2.0
|
||||
*/
|
||||
class HtmlView extends \Joomla\Component\Users\Administrator\View\Captive\HtmlView
|
||||
{
|
||||
}
|
||||
158
components/com_users/src/View/Login/HtmlView.php
Normal file
158
components/com_users/src/View/Login/HtmlView.php
Normal file
@ -0,0 +1,158 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage com_users
|
||||
*
|
||||
* @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Users\Site\View\Login;
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Helper\AuthenticationHelper;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\MVC\View\GenericDataException;
|
||||
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
|
||||
use Joomla\CMS\User\User;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Login view class for Users.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
class HtmlView extends BaseHtmlView
|
||||
{
|
||||
/**
|
||||
* The Form object
|
||||
*
|
||||
* @var \Joomla\CMS\Form\Form
|
||||
*/
|
||||
protected $form;
|
||||
|
||||
/**
|
||||
* The page parameters
|
||||
*
|
||||
* @var \Joomla\Registry\Registry|null
|
||||
*/
|
||||
protected $params;
|
||||
|
||||
/**
|
||||
* The model state
|
||||
*
|
||||
* @var \Joomla\Registry\Registry
|
||||
*/
|
||||
protected $state;
|
||||
|
||||
/**
|
||||
* The logged in user
|
||||
*
|
||||
* @var User
|
||||
*/
|
||||
protected $user;
|
||||
|
||||
/**
|
||||
* The page class suffix
|
||||
*
|
||||
* @var string
|
||||
* @since 4.0.0
|
||||
*/
|
||||
protected $pageclass_sfx = '';
|
||||
|
||||
/**
|
||||
* No longer used
|
||||
*
|
||||
* @var boolean
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @deprecated 4.3 will be removed in 6.0
|
||||
* Will be removed without replacement
|
||||
*/
|
||||
protected $tfa = false;
|
||||
|
||||
/**
|
||||
* Additional buttons to show on the login page
|
||||
*
|
||||
* @var array
|
||||
* @since 4.0.0
|
||||
*/
|
||||
protected $extraButtons = [];
|
||||
|
||||
/**
|
||||
* Method to display the view.
|
||||
*
|
||||
* @param string $tpl The name of the template file to parse; automatically searches through the template paths.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 1.5
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function display($tpl = null)
|
||||
{
|
||||
// Get the view data.
|
||||
$this->user = $this->getCurrentUser();
|
||||
$this->form = $this->get('Form');
|
||||
$this->state = $this->get('State');
|
||||
$this->params = $this->state->get('params');
|
||||
|
||||
// Check for errors.
|
||||
if (\count($errors = $this->get('Errors'))) {
|
||||
throw new GenericDataException(implode("\n", $errors), 500);
|
||||
}
|
||||
|
||||
// Check for layout override
|
||||
$active = Factory::getApplication()->getMenu()->getActive();
|
||||
|
||||
if (isset($active->query['layout'])) {
|
||||
$this->setLayout($active->query['layout']);
|
||||
}
|
||||
|
||||
$this->extraButtons = AuthenticationHelper::getLoginButtons('com-users-login__form');
|
||||
|
||||
// Escape strings for HTML output
|
||||
$this->pageclass_sfx = htmlspecialchars($this->params->get('pageclass_sfx', ''), ENT_COMPAT, 'UTF-8');
|
||||
|
||||
$this->prepareDocument();
|
||||
|
||||
parent::display($tpl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares the document
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 1.6
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function prepareDocument()
|
||||
{
|
||||
$login = (bool) $this->getCurrentUser()->get('guest');
|
||||
|
||||
// Because the application sets a default page title,
|
||||
// we need to get it from the menu item itself
|
||||
$menu = Factory::getApplication()->getMenu()->getActive();
|
||||
|
||||
if ($menu) {
|
||||
$this->params->def('page_heading', $this->params->get('page_title', $menu->title));
|
||||
} else {
|
||||
$this->params->def('page_heading', $login ? Text::_('JLOGIN') : Text::_('JLOGOUT'));
|
||||
}
|
||||
|
||||
$this->setDocumentTitle($this->params->get('page_title', ''));
|
||||
|
||||
if ($this->params->get('menu-meta_description')) {
|
||||
$this->getDocument()->setDescription($this->params->get('menu-meta_description'));
|
||||
}
|
||||
|
||||
if ($this->params->get('robots')) {
|
||||
$this->getDocument()->setMetaData('robots', $this->params->get('robots'));
|
||||
}
|
||||
}
|
||||
}
|
||||
24
components/com_users/src/View/Method/HtmlView.php
Normal file
24
components/com_users/src/View/Method/HtmlView.php
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_users
|
||||
*
|
||||
* @copyright (C) 2022 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Users\Site\View\Method;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* View for Multi-factor Authentication method add/edit page
|
||||
*
|
||||
* @since 4.2.0
|
||||
*/
|
||||
class HtmlView extends \Joomla\Component\Users\Administrator\View\Method\HtmlView
|
||||
{
|
||||
}
|
||||
24
components/com_users/src/View/Methods/HtmlView.php
Normal file
24
components/com_users/src/View/Methods/HtmlView.php
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_users
|
||||
*
|
||||
* @copyright (C) 2022 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Users\Site\View\Methods;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* View for Multi-factor Authentication methods list page
|
||||
*
|
||||
* @since 4.2.0
|
||||
*/
|
||||
class HtmlView extends \Joomla\Component\Users\Administrator\View\Methods\HtmlView
|
||||
{
|
||||
}
|
||||
189
components/com_users/src/View/Profile/HtmlView.php
Normal file
189
components/com_users/src/View/Profile/HtmlView.php
Normal file
@ -0,0 +1,189 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage com_users
|
||||
*
|
||||
* @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Users\Site\View\Profile;
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\MVC\View\GenericDataException;
|
||||
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
|
||||
use Joomla\CMS\Object\CMSObject;
|
||||
use Joomla\CMS\Plugin\PluginHelper;
|
||||
use Joomla\CMS\Router\Route;
|
||||
use Joomla\CMS\User\User;
|
||||
use Joomla\Component\Users\Administrator\Helper\Mfa;
|
||||
use Joomla\Database\DatabaseDriver;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Profile view class for Users.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
class HtmlView extends BaseHtmlView
|
||||
{
|
||||
/**
|
||||
* Profile form data for the user
|
||||
*
|
||||
* @var User
|
||||
*/
|
||||
protected $data;
|
||||
|
||||
/**
|
||||
* The Form object
|
||||
*
|
||||
* @var \Joomla\CMS\Form\Form
|
||||
*/
|
||||
protected $form;
|
||||
|
||||
/**
|
||||
* The page parameters
|
||||
*
|
||||
* @var \Joomla\Registry\Registry|null
|
||||
*/
|
||||
protected $params;
|
||||
|
||||
/**
|
||||
* The model state
|
||||
*
|
||||
* @var \Joomla\Registry\Registry
|
||||
*/
|
||||
protected $state;
|
||||
|
||||
/**
|
||||
* An instance of DatabaseDriver.
|
||||
*
|
||||
* @var DatabaseDriver
|
||||
* @since 3.6.3
|
||||
*
|
||||
* @deprecated 4.3 will be removed in 6.0
|
||||
* Will be removed without replacement use database from the container instead
|
||||
* Example: Factory::getContainer()->get(DatabaseInterface::class);
|
||||
*/
|
||||
protected $db;
|
||||
|
||||
/**
|
||||
* The page class suffix
|
||||
*
|
||||
* @var string
|
||||
* @since 4.0.0
|
||||
*/
|
||||
protected $pageclass_sfx = '';
|
||||
|
||||
/**
|
||||
* The Multi-factor Authentication configuration interface for the user.
|
||||
*
|
||||
* @var string|null
|
||||
* @since 4.2.0
|
||||
*/
|
||||
protected $mfaConfigurationUI;
|
||||
|
||||
/**
|
||||
* Execute and display a template script.
|
||||
*
|
||||
* @param string $tpl The name of the template file to parse; automatically searches through the template paths.
|
||||
*
|
||||
* @return void|boolean
|
||||
*
|
||||
* @since 1.6
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function display($tpl = null)
|
||||
{
|
||||
$user = $this->getCurrentUser();
|
||||
|
||||
// Get the view data.
|
||||
$this->data = $this->get('Data');
|
||||
$this->form = $this->getModel()->getForm(new CMSObject(['id' => $user->id]));
|
||||
$this->state = $this->get('State');
|
||||
$this->params = $this->state->get('params');
|
||||
$this->mfaConfigurationUI = Mfa::getConfigurationInterface($user);
|
||||
$this->db = Factory::getDbo();
|
||||
|
||||
// Check for errors.
|
||||
if (\count($errors = $this->get('Errors'))) {
|
||||
throw new GenericDataException(implode("\n", $errors), 500);
|
||||
}
|
||||
|
||||
// View also takes responsibility for checking if the user logged in with remember me.
|
||||
$cookieLogin = $user->get('cookieLogin');
|
||||
|
||||
if (!empty($cookieLogin)) {
|
||||
// If so, the user must login to edit the password and other data.
|
||||
// What should happen here? Should we force a logout which destroys the cookies?
|
||||
$app = Factory::getApplication();
|
||||
$app->enqueueMessage(Text::_('JGLOBAL_REMEMBER_MUST_LOGIN'), 'message');
|
||||
$app->redirect(Route::_('index.php?option=com_users&view=login', false));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if a user was found.
|
||||
if (!$this->data->id) {
|
||||
throw new \Exception(Text::_('JERROR_USERS_PROFILE_NOT_FOUND'), 404);
|
||||
}
|
||||
|
||||
PluginHelper::importPlugin('content');
|
||||
$this->data->text = '';
|
||||
Factory::getApplication()->triggerEvent('onContentPrepare', ['com_users.user', &$this->data, &$this->data->params, 0]);
|
||||
unset($this->data->text);
|
||||
|
||||
// Check for layout from menu item.
|
||||
$query = Factory::getApplication()->getMenu()->getActive()->query;
|
||||
|
||||
if (
|
||||
isset($query['layout']) && isset($query['option']) && $query['option'] === 'com_users'
|
||||
&& isset($query['view']) && $query['view'] === 'profile'
|
||||
) {
|
||||
$this->setLayout($query['layout']);
|
||||
}
|
||||
|
||||
// Escape strings for HTML output
|
||||
$this->pageclass_sfx = htmlspecialchars($this->params->get('pageclass_sfx', ''));
|
||||
|
||||
$this->prepareDocument();
|
||||
|
||||
parent::display($tpl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares the document
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 1.6
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function prepareDocument()
|
||||
{
|
||||
// Because the application sets a default page title,
|
||||
// we need to get it from the menu item itself
|
||||
$menu = Factory::getApplication()->getMenu()->getActive();
|
||||
|
||||
if ($menu) {
|
||||
$this->params->def('page_heading', $this->params->get('page_title', $this->getCurrentUser()->name));
|
||||
} else {
|
||||
$this->params->def('page_heading', Text::_('COM_USERS_PROFILE'));
|
||||
}
|
||||
|
||||
$this->setDocumentTitle($this->params->get('page_title', ''));
|
||||
|
||||
if ($this->params->get('menu-meta_description')) {
|
||||
$this->getDocument()->setDescription($this->params->get('menu-meta_description'));
|
||||
}
|
||||
|
||||
if ($this->params->get('robots')) {
|
||||
$this->getDocument()->setMetaData('robots', $this->params->get('robots'));
|
||||
}
|
||||
}
|
||||
}
|
||||
160
components/com_users/src/View/Registration/HtmlView.php
Normal file
160
components/com_users/src/View/Registration/HtmlView.php
Normal file
@ -0,0 +1,160 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage com_users
|
||||
*
|
||||
* @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Users\Site\View\Registration;
|
||||
|
||||
use Joomla\CMS\Document\HtmlDocument;
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\MVC\View\GenericDataException;
|
||||
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
|
||||
use Joomla\CMS\Plugin\PluginHelper;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Registration view class for Users.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
class HtmlView extends BaseHtmlView
|
||||
{
|
||||
/**
|
||||
* Registration form data
|
||||
*
|
||||
* @var \stdClass|false
|
||||
*/
|
||||
protected $data;
|
||||
|
||||
/**
|
||||
* The Form object
|
||||
*
|
||||
* @var \Joomla\CMS\Form\Form
|
||||
*/
|
||||
protected $form;
|
||||
|
||||
/**
|
||||
* The page parameters
|
||||
*
|
||||
* @var \Joomla\Registry\Registry|null
|
||||
*/
|
||||
protected $params;
|
||||
|
||||
/**
|
||||
* The model state
|
||||
*
|
||||
* @var \Joomla\Registry\Registry
|
||||
*/
|
||||
protected $state;
|
||||
|
||||
/**
|
||||
* The HtmlDocument instance
|
||||
*
|
||||
* @var HtmlDocument
|
||||
*/
|
||||
public $document;
|
||||
|
||||
/**
|
||||
* Should we show a captcha form for the submission of the article?
|
||||
*
|
||||
* @var boolean
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
protected $captchaEnabled = false;
|
||||
|
||||
/**
|
||||
* The page class suffix
|
||||
*
|
||||
* @var string
|
||||
* @since 4.0.0
|
||||
*/
|
||||
protected $pageclass_sfx = '';
|
||||
|
||||
/**
|
||||
* Method to display the view.
|
||||
*
|
||||
* @param string $tpl The template file to include
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 1.6
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function display($tpl = null)
|
||||
{
|
||||
// Get the view data.
|
||||
$this->form = $this->get('Form');
|
||||
$this->data = $this->get('Data');
|
||||
$this->state = $this->get('State');
|
||||
$this->params = $this->state->get('params');
|
||||
|
||||
// Check for errors.
|
||||
if (\count($errors = $this->get('Errors'))) {
|
||||
throw new GenericDataException(implode("\n", $errors), 500);
|
||||
}
|
||||
|
||||
// Check for layout override
|
||||
$active = Factory::getApplication()->getMenu()->getActive();
|
||||
|
||||
if (isset($active->query['layout'])) {
|
||||
$this->setLayout($active->query['layout']);
|
||||
}
|
||||
|
||||
$captchaSet = $this->params->get('captcha', Factory::getApplication()->get('captcha', '0'));
|
||||
|
||||
foreach (PluginHelper::getPlugin('captcha') as $plugin) {
|
||||
if ($captchaSet === $plugin->name) {
|
||||
$this->captchaEnabled = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Escape strings for HTML output
|
||||
$this->pageclass_sfx = htmlspecialchars($this->params->get('pageclass_sfx', ''), ENT_COMPAT, 'UTF-8');
|
||||
|
||||
$this->prepareDocument();
|
||||
|
||||
parent::display($tpl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares the document.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 1.6
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function prepareDocument()
|
||||
{
|
||||
// Because the application sets a default page title,
|
||||
// we need to get it from the menu item itself
|
||||
$menu = Factory::getApplication()->getMenu()->getActive();
|
||||
|
||||
if ($menu) {
|
||||
$this->params->def('page_heading', $this->params->get('page_title', $menu->title));
|
||||
} else {
|
||||
$this->params->def('page_heading', Text::_('COM_USERS_REGISTRATION'));
|
||||
}
|
||||
|
||||
$this->setDocumentTitle($this->params->get('page_title', ''));
|
||||
|
||||
if ($this->params->get('menu-meta_description')) {
|
||||
$this->getDocument()->setDescription($this->params->get('menu-meta_description'));
|
||||
}
|
||||
|
||||
if ($this->params->get('robots')) {
|
||||
$this->getDocument()->setMetaData('robots', $this->params->get('robots'));
|
||||
}
|
||||
}
|
||||
}
|
||||
125
components/com_users/src/View/Remind/HtmlView.php
Normal file
125
components/com_users/src/View/Remind/HtmlView.php
Normal file
@ -0,0 +1,125 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage com_users
|
||||
*
|
||||
* @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Users\Site\View\Remind;
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\MVC\View\GenericDataException;
|
||||
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Remind view class for Users.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
class HtmlView extends BaseHtmlView
|
||||
{
|
||||
/**
|
||||
* The Form object
|
||||
*
|
||||
* @var \Joomla\CMS\Form\Form
|
||||
*/
|
||||
protected $form;
|
||||
|
||||
/**
|
||||
* The page parameters
|
||||
*
|
||||
* @var \Joomla\Registry\Registry|null
|
||||
*/
|
||||
protected $params;
|
||||
|
||||
/**
|
||||
* The model state
|
||||
*
|
||||
* @var \Joomla\Registry\Registry
|
||||
*/
|
||||
protected $state;
|
||||
|
||||
/**
|
||||
* The page class suffix
|
||||
*
|
||||
* @var string
|
||||
* @since 4.0.0
|
||||
*/
|
||||
protected $pageclass_sfx = '';
|
||||
|
||||
/**
|
||||
* Method to display the view.
|
||||
*
|
||||
* @param string $tpl The template file to include
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 1.5
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function display($tpl = null)
|
||||
{
|
||||
// Get the view data.
|
||||
$this->form = $this->get('Form');
|
||||
$this->state = $this->get('State');
|
||||
$this->params = $this->state->params;
|
||||
|
||||
// Check for errors.
|
||||
if (\count($errors = $this->get('Errors'))) {
|
||||
throw new GenericDataException(implode("\n", $errors), 500);
|
||||
}
|
||||
|
||||
// Check for layout override
|
||||
$active = Factory::getApplication()->getMenu()->getActive();
|
||||
|
||||
if (isset($active->query['layout'])) {
|
||||
$this->setLayout($active->query['layout']);
|
||||
}
|
||||
|
||||
// Escape strings for HTML output
|
||||
$this->pageclass_sfx = htmlspecialchars($this->params->get('pageclass_sfx', ''), ENT_COMPAT, 'UTF-8');
|
||||
|
||||
$this->prepareDocument();
|
||||
|
||||
parent::display($tpl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares the document.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 1.6
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function prepareDocument()
|
||||
{
|
||||
// Because the application sets a default page title,
|
||||
// we need to get it from the menu item itself
|
||||
$menu = Factory::getApplication()->getMenu()->getActive();
|
||||
|
||||
if ($menu) {
|
||||
$this->params->def('page_heading', $this->params->get('page_title', $menu->title));
|
||||
} else {
|
||||
$this->params->def('page_heading', Text::_('COM_USERS_REMIND'));
|
||||
}
|
||||
|
||||
$this->setDocumentTitle($this->params->get('page_title', ''));
|
||||
|
||||
if ($this->params->get('menu-meta_description')) {
|
||||
$this->getDocument()->setDescription($this->params->get('menu-meta_description'));
|
||||
}
|
||||
|
||||
if ($this->params->get('robots')) {
|
||||
$this->getDocument()->setMetaData('robots', $this->params->get('robots'));
|
||||
}
|
||||
}
|
||||
}
|
||||
131
components/com_users/src/View/Reset/HtmlView.php
Normal file
131
components/com_users/src/View/Reset/HtmlView.php
Normal file
@ -0,0 +1,131 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage com_users
|
||||
*
|
||||
* @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Users\Site\View\Reset;
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\MVC\View\GenericDataException;
|
||||
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Reset view class for Users.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
class HtmlView extends BaseHtmlView
|
||||
{
|
||||
/**
|
||||
* The Form object
|
||||
*
|
||||
* @var \Joomla\CMS\Form\Form
|
||||
*/
|
||||
protected $form;
|
||||
|
||||
/**
|
||||
* The page parameters
|
||||
*
|
||||
* @var \Joomla\Registry\Registry|null
|
||||
*/
|
||||
protected $params;
|
||||
|
||||
/**
|
||||
* The model state
|
||||
*
|
||||
* @var \Joomla\Registry\Registry
|
||||
*/
|
||||
protected $state;
|
||||
|
||||
/**
|
||||
* The page class suffix
|
||||
*
|
||||
* @var string
|
||||
* @since 4.0.0
|
||||
*/
|
||||
protected $pageclass_sfx = '';
|
||||
|
||||
/**
|
||||
* Method to display the view.
|
||||
*
|
||||
* @param string $tpl The template file to include
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public function display($tpl = null)
|
||||
{
|
||||
// This name will be used to get the model
|
||||
$name = $this->getLayout();
|
||||
|
||||
// Check that the name is valid - has an associated model.
|
||||
if (!\in_array($name, ['confirm', 'complete'])) {
|
||||
$name = 'default';
|
||||
}
|
||||
|
||||
if ('default' === $name) {
|
||||
$formname = 'Form';
|
||||
} else {
|
||||
$formname = ucfirst($this->_name) . ucfirst($name) . 'Form';
|
||||
}
|
||||
|
||||
// Get the view data.
|
||||
$this->form = $this->get($formname);
|
||||
$this->state = $this->get('State');
|
||||
$this->params = $this->state->params;
|
||||
|
||||
// Check for errors.
|
||||
if (\count($errors = $this->get('Errors'))) {
|
||||
throw new GenericDataException(implode("\n", $errors), 500);
|
||||
}
|
||||
|
||||
// Escape strings for HTML output
|
||||
$this->pageclass_sfx = htmlspecialchars($this->params->get('pageclass_sfx', ''), ENT_COMPAT, 'UTF-8');
|
||||
|
||||
$this->prepareDocument();
|
||||
|
||||
parent::display($tpl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares the document.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 1.6
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function prepareDocument()
|
||||
{
|
||||
// Because the application sets a default page title,
|
||||
// we need to get it from the menu item itself
|
||||
$menu = Factory::getApplication()->getMenu()->getActive();
|
||||
|
||||
if ($menu) {
|
||||
$this->params->def('page_heading', $this->params->get('page_title', $menu->title));
|
||||
} else {
|
||||
$this->params->def('page_heading', Text::_('COM_USERS_RESET'));
|
||||
}
|
||||
|
||||
$this->setDocumentTitle($this->params->get('page_title', ''));
|
||||
|
||||
if ($this->params->get('menu-meta_description')) {
|
||||
$this->getDocument()->setDescription($this->params->get('menu-meta_description'));
|
||||
}
|
||||
|
||||
if ($this->params->get('robots')) {
|
||||
$this->getDocument()->setMetaData('robots', $this->params->get('robots'));
|
||||
}
|
||||
}
|
||||
}
|
||||
135
components/com_users/tmpl/captive/default.php
Normal file
135
components/com_users/tmpl/captive/default.php
Normal file
@ -0,0 +1,135 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage com_users
|
||||
*
|
||||
* @copyright (C) 2022 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\HTML\HTMLHelper;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\Router\Route;
|
||||
use Joomla\Component\Users\Site\Model\CaptiveModel;
|
||||
use Joomla\Component\Users\Site\View\Captive\HtmlView;
|
||||
use Joomla\Utilities\ArrayHelper;
|
||||
|
||||
/**
|
||||
* @var HtmlView $this View object
|
||||
* @var CaptiveModel $model The model
|
||||
*/
|
||||
$model = $this->getModel();
|
||||
|
||||
$this->document->getWebAssetManager()
|
||||
->useScript('com_users.two-factor-focus');
|
||||
|
||||
?>
|
||||
<div class="users-mfa-captive card card-body">
|
||||
<h2 id="users-mfa-title">
|
||||
<?php if (!empty($this->renderOptions['help_url'])) : ?>
|
||||
<span class="float-end">
|
||||
<a href="<?php echo $this->renderOptions['help_url'] ?>"
|
||||
class="btn btn-sm btn-secondary"
|
||||
target="_blank"
|
||||
>
|
||||
<span class="icon icon-question-sign" aria-hidden="true"></span>
|
||||
<span class="visually-hidden"><?php echo Text::_('JHELP') ?></span>
|
||||
</a>
|
||||
</span>
|
||||
<?php endif;?>
|
||||
<?php if (!empty($this->title)) : ?>
|
||||
<?php echo $this->title ?> <small> –
|
||||
<?php endif; ?>
|
||||
<?php if (!$this->allowEntryBatching) : ?>
|
||||
<?php echo $this->escape($this->record->title) ?>
|
||||
<?php else : ?>
|
||||
<?php echo $this->escape($this->getModel()->translateMethodName($this->record->method)) ?>
|
||||
<?php endif; ?>
|
||||
<?php if (!empty($this->title)) : ?>
|
||||
</small>
|
||||
<?php endif; ?>
|
||||
</h2>
|
||||
|
||||
<?php if ($this->renderOptions['pre_message']) : ?>
|
||||
<div class="users-mfa-captive-pre-message text-muted mb-3">
|
||||
<?php echo $this->renderOptions['pre_message'] ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<form action="<?php echo Route::_('index.php?option=com_users&task=captive.validate&record_id=' . ((int) $this->record->id)) ?>"
|
||||
id="users-mfa-captive-form"
|
||||
method="post"
|
||||
class="form-horizontal"
|
||||
>
|
||||
<?php echo HTMLHelper::_('form.token') ?>
|
||||
|
||||
<div id="users-mfa-captive-form-method-fields">
|
||||
<?php if ($this->renderOptions['field_type'] == 'custom') : ?>
|
||||
<?php echo $this->renderOptions['html']; ?>
|
||||
<?php endif; ?>
|
||||
<div class="row mb-3">
|
||||
<?php if ($this->renderOptions['label']) : ?>
|
||||
<label for="users-mfa-code" class="col-sm-3 col-form-label">
|
||||
<?php echo $this->renderOptions['label'] ?>
|
||||
</label>
|
||||
<?php endif; ?>
|
||||
<div class="col-sm-9 <?php echo $this->renderOptions['label'] ? '' : 'offset-sm-3' ?>">
|
||||
<?php
|
||||
$attributes = array_merge(
|
||||
[
|
||||
'type' => $this->renderOptions['input_type'],
|
||||
'name' => 'code',
|
||||
'value' => '',
|
||||
'placeholder' => $this->renderOptions['placeholder'] ?? null,
|
||||
'id' => 'users-mfa-code',
|
||||
'class' => 'form-control',
|
||||
'autocomplete' => $this->renderOptions['autocomplete'] ?? 'one-time-code'
|
||||
],
|
||||
$this->renderOptions['input_attributes']
|
||||
);
|
||||
|
||||
if (strpos($attributes['class'], 'form-control') === false) {
|
||||
$attributes['class'] .= ' form-control';
|
||||
}
|
||||
?>
|
||||
<input <?php echo ArrayHelper::toString($attributes) ?>>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="users-mfa-captive-form-standard-buttons" class="row my-3">
|
||||
<div class="col-sm-9 offset-sm-3">
|
||||
<button class="btn btn-primary me-3 <?php echo $this->renderOptions['submit_class'] ?>"
|
||||
id="users-mfa-captive-button-submit"
|
||||
style="<?php echo $this->renderOptions['hide_submit'] ? 'display: none' : '' ?>"
|
||||
type="submit">
|
||||
<span class="<?php echo $this->renderOptions['submit_icon'] ?>" aria-hidden="true"></span>
|
||||
<?php echo Text::_($this->renderOptions['submit_text']); ?>
|
||||
</button>
|
||||
|
||||
<a href="<?php echo Route::_('index.php?option=com_users&task=user.logout&' . Factory::getApplication()->getFormToken() . '=1') ?>"
|
||||
class="btn btn-danger btn-sm" id="users-mfa-captive-button-logout">
|
||||
<span class="icon icon-lock" aria-hidden="true"></span>
|
||||
<?php echo Text::_('COM_USERS_MFA_LOGOUT'); ?>
|
||||
</a>
|
||||
|
||||
<?php if (count($this->records) > 1) : ?>
|
||||
<div id="users-mfa-captive-form-choose-another" class="my-3">
|
||||
<a href="<?php echo Route::_('index.php?option=com_users&view=captive&task=select') ?>">
|
||||
<?php echo Text::_('COM_USERS_MFA_USE_DIFFERENT_METHOD'); ?>
|
||||
</a>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php if ($this->renderOptions['post_message']) : ?>
|
||||
<div class="users-mfa-captive-post-message">
|
||||
<?php echo $this->renderOptions['post_message'] ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
</div>
|
||||
78
components/com_users/tmpl/captive/select.php
Normal file
78
components/com_users/tmpl/captive/select.php
Normal file
@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage com_users
|
||||
*
|
||||
* @copyright (C) 2022 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
// Prevent direct access
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\Router\Route;
|
||||
use Joomla\CMS\Uri\Uri;
|
||||
use Joomla\Component\Users\Site\View\Captive\HtmlView;
|
||||
|
||||
/** @var HtmlView $this */
|
||||
|
||||
$shownMethods = [];
|
||||
|
||||
?>
|
||||
<div id="com-users-select">
|
||||
<h2 id="com-users-select-heading">
|
||||
<?php echo Text::_('COM_USERS_MFA_SELECT_PAGE_HEAD'); ?>
|
||||
</h2>
|
||||
<div id="com-users-select-information">
|
||||
<p>
|
||||
<?php echo Text::_('COM_USERS_LBL_SELECT_INSTRUCTIONS'); ?>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="com-users-select-methods p-2">
|
||||
<?php foreach ($this->records as $record) :
|
||||
if (!array_key_exists($record->method, $this->mfaMethods) && ($record->method != 'backupcodes')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$allowEntryBatching = isset($this->mfaMethods[$record->method]) ? $this->mfaMethods[$record->method]['allowEntryBatching'] : false;
|
||||
|
||||
if ($this->allowEntryBatching) {
|
||||
if ($allowEntryBatching && in_array($record->method, $shownMethods)) {
|
||||
continue;
|
||||
}
|
||||
$shownMethods[] = $record->method;
|
||||
}
|
||||
|
||||
$methodName = $this->getModel()->translateMethodName($record->method);
|
||||
?>
|
||||
<a class="com-users-method p-2 border-top border-dark bg-light d-flex flex-row flex-wrap justify-content-start align-items-center text-decoration-none gap-2 text-body"
|
||||
href="<?php echo Route::_('index.php?option=com_users&view=captive&record_id=' . $record->id)?>">
|
||||
<img src="<?php echo Uri::root() . $this->getModel()->getMethodImage($record->method) ?>"
|
||||
alt="<?php echo $this->escape(strip_tags($record->title)) ?>"
|
||||
class="com-users-method-image img-fluid" />
|
||||
<?php if (!$this->allowEntryBatching || !$allowEntryBatching) : ?>
|
||||
<span class="com-users-method-title flex-grow-1 fs-5 fw-bold">
|
||||
<?php if ($record->method === 'backupcodes') : ?>
|
||||
<?php echo $record->title ?>
|
||||
<?php else : ?>
|
||||
<?php echo $this->escape($record->title) ?>
|
||||
<?php endif; ?>
|
||||
</span>
|
||||
<small class="com-users-method-name text-muted">
|
||||
<?php echo $methodName ?>
|
||||
</small>
|
||||
<?php else : ?>
|
||||
<span class="com-users-method-title flex-grow-1 fs-5 fw-bold">
|
||||
<?php echo $methodName ?>
|
||||
</span>
|
||||
<small class="com-users-method-name text-muted">
|
||||
<?php echo $methodName ?>
|
||||
</small>
|
||||
<?php endif; ?>
|
||||
</a>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
23
components/com_users/tmpl/login/default.php
Normal file
23
components/com_users/tmpl/login/default.php
Normal file
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage com_users
|
||||
*
|
||||
* @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
/** @var \Joomla\Component\Users\Site\View\Login\HtmlView $this */
|
||||
|
||||
$cookieLogin = $this->user->get('cookieLogin');
|
||||
|
||||
if (!empty($cookieLogin) || $this->user->get('guest')) {
|
||||
// The user is not logged in or needs to provide a password.
|
||||
echo $this->loadTemplate('login');
|
||||
} else {
|
||||
// The user is already logged in.
|
||||
echo $this->loadTemplate('logout');
|
||||
}
|
||||
179
components/com_users/tmpl/login/default.xml
Normal file
179
components/com_users/tmpl/login/default.xml
Normal file
@ -0,0 +1,179 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<metadata>
|
||||
<layout title="COM_USERS_LOGIN_VIEW_DEFAULT_TITLE" option="COM_USERS_LOGIN_VIEW_DEFAULT_OPTION">
|
||||
<help
|
||||
key = "Menu_Item:_Login_Form"
|
||||
/>
|
||||
<message>
|
||||
<![CDATA[COM_USERS_LOGIN_VIEW_DEFAULT_DESC]]>
|
||||
</message>
|
||||
</layout>
|
||||
|
||||
<!-- Add fields to the parameters object for the layout. -->
|
||||
<fields name="params">
|
||||
|
||||
<!-- Basic options. -->
|
||||
<fieldset name="basic" addruleprefix="Joomla\Component\Users\Site\Rule" label="COM_MENUS_BASIC_FIELDSET_LABEL">
|
||||
<fieldset name="login" label="COM_USERS_FIELD_OPTIONS_LOGIN">
|
||||
<field
|
||||
name="loginredirectchoice"
|
||||
type="radio"
|
||||
label="COM_USERS_FIELD_LOGIN_REDIRECT_CHOICE_LABEL"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
default="1"
|
||||
>
|
||||
<option value="0">COM_USERS_FIELD_LOGIN_URL</option>
|
||||
<option value="1">COM_USERS_FIELD_LOGIN_MENUITEM</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="login_redirect_url"
|
||||
type="text"
|
||||
label="JFIELD_LOGIN_REDIRECT_URL_LABEL"
|
||||
description="JFIELD_LOGIN_REDIRECT_URL_DESC"
|
||||
validate="LoginUniqueField"
|
||||
field="login_redirect_menuitem"
|
||||
hint="COM_USERS_FIELD_LOGIN_REDIRECT_PLACEHOLDER"
|
||||
message="COM_USERS_FIELD_LOGIN_REDIRECT_ERROR"
|
||||
showon="loginredirectchoice:0"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="login_redirect_menuitem"
|
||||
type="modal_menu"
|
||||
label="COM_USERS_FIELD_LOGIN_REDIRECTMENU_LABEL"
|
||||
description="COM_USERS_FIELD_LOGIN_REDIRECTMENU_DESC"
|
||||
disable="separator,alias,heading,url"
|
||||
showon="loginredirectchoice:1"
|
||||
select="true"
|
||||
new="true"
|
||||
edit="true"
|
||||
clear="true"
|
||||
>
|
||||
<option value="">JOPTION_SELECT_MENU</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="logindescription_show"
|
||||
type="list"
|
||||
label="JFIELD_BASIC_LOGIN_DESCRIPTION_SHOW_LABEL"
|
||||
default="1"
|
||||
class="form-select-color-state"
|
||||
validate="options"
|
||||
>
|
||||
<option value="0">JHIDE</option>
|
||||
<option value="1">JSHOW</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="login_description"
|
||||
type="textarea"
|
||||
label="JFIELD_BASIC_LOGIN_DESCRIPTION_LABEL"
|
||||
rows="3"
|
||||
cols="40"
|
||||
filter="safehtml"
|
||||
showon="logindescription_show:1"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="login_image"
|
||||
type="media"
|
||||
label="JFIELD_LOGIN_IMAGE_LABEL"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="login_image_alt"
|
||||
type="text"
|
||||
label="COM_USERS_FIELD_IMAGE_ALT_LABEL"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="login_image_alt_empty"
|
||||
type="checkbox"
|
||||
label="COM_USERS_FIELD_IMAGE_ALT_EMPTY_LABEL"
|
||||
description="COM_USERS_FIELD_IMAGE_ALT_EMPTY_DESC"
|
||||
/>
|
||||
</fieldset>
|
||||
|
||||
<fieldset name="logout" label="COM_USERS_FIELD_OPTIONS_LOGOUT">
|
||||
<field
|
||||
name="logoutredirectchoice"
|
||||
type="radio"
|
||||
label="COM_USERS_FIELD_LOGOUT_REDIRECT_CHOICE_LABEL"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
default="1"
|
||||
>
|
||||
<option value="0">COM_USERS_FIELD_LOGIN_URL</option>
|
||||
<option value="1">COM_USERS_FIELD_LOGIN_MENUITEM</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="logout_redirect_url"
|
||||
type="text"
|
||||
label="JFIELD_LOGOUT_REDIRECT_URL_LABEL"
|
||||
field="logout_redirect_menuitem"
|
||||
validate="LogoutUniqueField"
|
||||
hint="COM_USERS_FIELD_LOGIN_REDIRECT_PLACEHOLDER"
|
||||
message="COM_USERS_FIELD_LOGOUT_REDIRECT_ERROR"
|
||||
showon="logoutredirectchoice:0"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="logout_redirect_menuitem"
|
||||
type="modal_menu"
|
||||
label="COM_USERS_FIELD_LOGOUT_REDIRECTMENU_LABEL"
|
||||
description="COM_USERS_FIELD_LOGOUT_REDIRECTMENU_DESC"
|
||||
disable="separator,alias,heading,url"
|
||||
showon="logoutredirectchoice:1"
|
||||
select="true"
|
||||
new="true"
|
||||
edit="true"
|
||||
clear="true"
|
||||
>
|
||||
<option value="">JOPTION_SELECT_MENU</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="logoutdescription_show"
|
||||
type="list"
|
||||
label="JFIELD_BASIC_LOGOUT_DESCRIPTION_SHOW_LABEL"
|
||||
default="1"
|
||||
class="form-select-color-state"
|
||||
validate="options"
|
||||
>
|
||||
<option value="0">JHIDE</option>
|
||||
<option value="1">JSHOW</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="logout_description"
|
||||
type="textarea"
|
||||
label="JFIELD_BASIC_LOGOUT_DESCRIPTION_LABEL"
|
||||
rows="3"
|
||||
cols="40"
|
||||
filter="safehtml"
|
||||
showon="logoutdescription_show:1"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="logout_image"
|
||||
type="media"
|
||||
label="JFIELD_LOGOUT_IMAGE_LABEL"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="logout_image_alt"
|
||||
type="text"
|
||||
label="COM_USERS_FIELD_IMAGE_ALT_LABEL"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="logout_image_alt_empty"
|
||||
type="checkbox"
|
||||
label="COM_USERS_FIELD_IMAGE_ALT_EMPTY_LABEL"
|
||||
description="COM_USERS_FIELD_IMAGE_ALT_EMPTY_DESC"
|
||||
/>
|
||||
</fieldset>
|
||||
</fieldset>
|
||||
</fields>
|
||||
</metadata>
|
||||
129
components/com_users/tmpl/login/default_login.php
Normal file
129
components/com_users/tmpl/login/default_login.php
Normal file
@ -0,0 +1,129 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage com_users
|
||||
*
|
||||
* @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Component\ComponentHelper;
|
||||
use Joomla\CMS\HTML\HTMLHelper;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\Plugin\PluginHelper;
|
||||
use Joomla\CMS\Router\Route;
|
||||
|
||||
/** @var \Joomla\Component\Users\Site\View\Login\HtmlView $cookieLogin */
|
||||
|
||||
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */
|
||||
$wa = $this->document->getWebAssetManager();
|
||||
$wa->useScript('keepalive')
|
||||
->useScript('form.validate');
|
||||
|
||||
$usersConfig = ComponentHelper::getParams('com_users');
|
||||
|
||||
?>
|
||||
<div class="com-users-login login">
|
||||
<?php if ($this->params->get('show_page_heading')) : ?>
|
||||
<div class="page-header">
|
||||
<h1>
|
||||
<?php echo $this->escape($this->params->get('page_heading')); ?>
|
||||
</h1>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (($this->params->get('logindescription_show') == 1 && str_replace(' ', '', $this->params->get('login_description', '')) != '') || $this->params->get('login_image') != '') : ?>
|
||||
<div class="com-users-login__description login-description">
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($this->params->get('logindescription_show') == 1) : ?>
|
||||
<?php echo $this->params->get('login_description'); ?>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($this->params->get('login_image') != '') : ?>
|
||||
<?php echo HTMLHelper::_('image', $this->params->get('login_image'), empty($this->params->get('login_image_alt')) && empty($this->params->get('login_image_alt_empty')) ? false : $this->params->get('login_image_alt'), ['class' => 'com-users-login__image login-image']); ?>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (($this->params->get('logindescription_show') == 1 && str_replace(' ', '', $this->params->get('login_description', '')) != '') || $this->params->get('login_image') != '') : ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<form action="<?php echo Route::_('index.php?option=com_users&task=user.login'); ?>" method="post" class="com-users-login__form form-validate form-horizontal well" id="com-users-login__form">
|
||||
|
||||
<fieldset>
|
||||
<?php echo $this->form->renderFieldset('credentials', ['class' => 'com-users-login__input']); ?>
|
||||
|
||||
<?php if (PluginHelper::isEnabled('system', 'remember')) : ?>
|
||||
<div class="com-users-login__remember">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" id="remember" type="checkbox" name="remember" value="yes">
|
||||
<label class="form-check-label" for="remember">
|
||||
<?php echo Text::_('COM_USERS_LOGIN_REMEMBER_ME'); ?>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php foreach ($this->extraButtons as $button) :
|
||||
$dataAttributeKeys = array_filter(array_keys($button), function ($key) {
|
||||
return substr($key, 0, 5) == 'data-';
|
||||
});
|
||||
?>
|
||||
<div class="com-users-login__submit control-group">
|
||||
<div class="controls">
|
||||
<button type="button"
|
||||
class="btn btn-secondary w-100 <?php echo $button['class'] ?? '' ?>"
|
||||
<?php foreach ($dataAttributeKeys as $key) : ?>
|
||||
<?php echo $key ?>="<?php echo $button[$key] ?>"
|
||||
<?php endforeach; ?>
|
||||
<?php if ($button['onclick']) : ?>
|
||||
onclick="<?php echo $button['onclick'] ?>"
|
||||
<?php endif; ?>
|
||||
title="<?php echo Text::_($button['label']) ?>"
|
||||
id="<?php echo $button['id'] ?>"
|
||||
>
|
||||
<?php if (!empty($button['icon'])) : ?>
|
||||
<span class="<?php echo $button['icon'] ?>"></span>
|
||||
<?php elseif (!empty($button['image'])) : ?>
|
||||
<?php echo HTMLHelper::_('image', $button['image'], Text::_($button['tooltip'] ?? ''), [
|
||||
'class' => 'icon',
|
||||
], true) ?>
|
||||
<?php elseif (!empty($button['svg'])) : ?>
|
||||
<?php echo $button['svg']; ?>
|
||||
<?php endif; ?>
|
||||
<?php echo Text::_($button['label']) ?>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
|
||||
<div class="com-users-login__submit control-group">
|
||||
<div class="controls">
|
||||
<button type="submit" class="btn btn-primary">
|
||||
<?php echo Text::_('JLOGIN'); ?>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php $return = $this->form->getValue('return', '', $this->params->get('login_redirect_url', $this->params->get('login_redirect_menuitem', ''))); ?>
|
||||
<input type="hidden" name="return" value="<?php echo base64_encode($return); ?>">
|
||||
<?php echo HTMLHelper::_('form.token'); ?>
|
||||
</fieldset>
|
||||
</form>
|
||||
<div class="com-users-login__options list-group">
|
||||
<a class="com-users-login__reset list-group-item" href="<?php echo Route::_('index.php?option=com_users&view=reset'); ?>">
|
||||
<?php echo Text::_('COM_USERS_LOGIN_RESET'); ?>
|
||||
</a>
|
||||
<a class="com-users-login__remind list-group-item" href="<?php echo Route::_('index.php?option=com_users&view=remind'); ?>">
|
||||
<?php echo Text::_('COM_USERS_LOGIN_REMIND'); ?>
|
||||
</a>
|
||||
<?php if ($usersConfig->get('allowUserRegistration')) : ?>
|
||||
<a class="com-users-login__register list-group-item" href="<?php echo Route::_('index.php?option=com_users&view=registration'); ?>">
|
||||
<?php echo Text::_('COM_USERS_LOGIN_REGISTER'); ?>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
60
components/com_users/tmpl/login/default_logout.php
Normal file
60
components/com_users/tmpl/login/default_logout.php
Normal file
@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage com_users
|
||||
*
|
||||
* @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\HTML\HTMLHelper;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\Router\Route;
|
||||
|
||||
/** @var \Joomla\Component\Users\Site\View\Login\HtmlView $this */
|
||||
?>
|
||||
<div class="com-users-logout logout">
|
||||
<?php if ($this->params->get('show_page_heading')) : ?>
|
||||
<div class="page-header">
|
||||
<h1>
|
||||
<?php echo $this->escape($this->params->get('page_heading')); ?>
|
||||
</h1>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (($this->params->get('logoutdescription_show') == 1 && str_replace(' ', '', $this->params->get('logout_description', '')) != '') || $this->params->get('logout_image') != '') : ?>
|
||||
<div class="com-users-logout__description logout-description">
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($this->params->get('logoutdescription_show') == 1) : ?>
|
||||
<?php echo $this->params->get('logout_description'); ?>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($this->params->get('logout_image') != '') : ?>
|
||||
<?php echo HTMLHelper::_('image', $this->params->get('logout_image'), empty($this->params->get('logout_image_alt')) && empty($this->params->get('logout_image_alt_empty')) ? false : $this->params->get('logout_image_alt'), ['class' => 'com-users-logout__image thumbnail float-end logout-image']); ?>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (($this->params->get('logoutdescription_show') == 1 && str_replace(' ', '', $this->params->get('logout_description', '')) != '') || $this->params->get('logout_image') != '') : ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<form action="<?php echo Route::_('index.php?option=com_users&task=user.logout'); ?>" method="post" class="com-users-logout__form form-horizontal well">
|
||||
<div class="com-users-logout__submit control-group">
|
||||
<div class="controls">
|
||||
<button type="submit" class="btn btn-primary">
|
||||
<span class="icon-backward-2 icon-white" aria-hidden="true"></span>
|
||||
<?php echo Text::_('JLOGOUT'); ?>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<?php if ($this->params->get('logout_redirect_url')) : ?>
|
||||
<input type="hidden" name="return" value="<?php echo base64_encode($this->params->get('logout_redirect_url', $this->form->getValue('return', null, ''))); ?>">
|
||||
<?php else : ?>
|
||||
<input type="hidden" name="return" value="<?php echo base64_encode($this->params->get('logout_redirect_menuitem', $this->form->getValue('return', null, ''))); ?>">
|
||||
<?php endif; ?>
|
||||
<?php echo HTMLHelper::_('form.token'); ?>
|
||||
</form>
|
||||
</div>
|
||||
39
components/com_users/tmpl/login/logout.xml
Normal file
39
components/com_users/tmpl/login/logout.xml
Normal file
@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<metadata>
|
||||
<layout title="COM_USERS_LOGOUT_VIEW_DEFAULT_TITLE" option="COM_USERS_LOGOUT_VIEW_DEFAULT_OPTION">
|
||||
<help key = "Menu_Item:_Logout"/>
|
||||
<message>
|
||||
<![CDATA[COM_USERS_LOGOUT_VIEW_DEFAULT_DESC]]>
|
||||
</message>
|
||||
</layout>
|
||||
|
||||
<!-- Add fields to the request variables for the layout. -->
|
||||
<fields name="request">
|
||||
<fieldset name="request">
|
||||
<field
|
||||
name="task"
|
||||
type="hidden"
|
||||
default="user.menulogout"
|
||||
/>
|
||||
</fieldset>
|
||||
</fields>
|
||||
|
||||
<!-- Add fields to the parameters object for the layout. -->
|
||||
<fields name="params">
|
||||
<fieldset name="basic" label="COM_MENUS_BASIC_FIELDSET_LABEL">
|
||||
<field
|
||||
name="logout"
|
||||
type="modal_menu"
|
||||
label="JFIELD_LOGOUT_REDIRECT_PAGE_LABEL"
|
||||
description="JFIELD_LOGOUT_REDIRECT_PAGE_DESC"
|
||||
disable="separator,alias,heading,url"
|
||||
select="true"
|
||||
new="true"
|
||||
edit="true"
|
||||
clear="true"
|
||||
>
|
||||
<option value="">JOPTION_SELECT_MENU</option>
|
||||
</field>
|
||||
</fieldset>
|
||||
</fields>
|
||||
</metadata>
|
||||
77
components/com_users/tmpl/method/backupcodes.php
Normal file
77
components/com_users/tmpl/method/backupcodes.php
Normal file
@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage com_users
|
||||
*
|
||||
* @copyright (C) 2022 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
// Prevent direct access
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\HTML\HTMLHelper;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\Router\Route;
|
||||
use Joomla\Component\Users\Site\View\Method\HtmlView;
|
||||
|
||||
/** @var HtmlView $this */
|
||||
|
||||
HTMLHelper::_('bootstrap.tooltip', '.hasTooltip');
|
||||
|
||||
$cancelURL = Route::_('index.php?option=com_users&task=methods.display&user_id=' . $this->user->id);
|
||||
|
||||
if (!empty($this->returnURL)) {
|
||||
$cancelURL = $this->escape(base64_decode($this->returnURL));
|
||||
}
|
||||
|
||||
if ($this->record->method != 'backupcodes') {
|
||||
throw new RuntimeException(Text::_('JERROR_ALERTNOAUTHOR'), 403);
|
||||
}
|
||||
|
||||
?>
|
||||
<h2>
|
||||
<?php echo Text::_('COM_USERS_USER_BACKUPCODES') ?>
|
||||
</h2>
|
||||
|
||||
<div class="alert alert-info">
|
||||
<?php echo Text::_('COM_USERS_USER_BACKUPCODES_DESC') ?>
|
||||
</div>
|
||||
|
||||
<table class="table table-striped">
|
||||
<?php for ($i = 0; $i < (count($this->backupCodes) / 2); $i++) : ?>
|
||||
<tr>
|
||||
<td>
|
||||
<?php if (!empty($this->backupCodes[2 * $i])) : ?>
|
||||
<?php // This is a Key emoji; we can hide it from screen readers ?>
|
||||
<span aria-hidden="true">🔑</span>
|
||||
<?php echo $this->backupCodes[2 * $i] ?>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td>
|
||||
<?php if (!empty($this->backupCodes[1 + 2 * $i])) : ?>
|
||||
<?php // This is a Key emoji; we can hide it from screen readers ?>
|
||||
<span aria-hidden="true">🔑</span>
|
||||
<?php echo $this->backupCodes[1 + 2 * $i] ?>
|
||||
<?php endif ;?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endfor; ?>
|
||||
</table>
|
||||
|
||||
<p>
|
||||
<?php echo Text::_('COM_USERS_MFA_BACKUPCODES_RESET_INFO'); ?>
|
||||
</p>
|
||||
|
||||
<a class="btn btn-danger" href="<?php echo Route::_(sprintf("index.php?option=com_users&task=method.regenerateBackupCodes&user_id=%s&%s=1%s", $this->user->id, Factory::getApplication()->getFormToken(), empty($this->returnURL) ? '' : '&returnurl=' . $this->returnURL)) ?>">
|
||||
<span class="icon icon-refresh" aria-hidden="true"></span>
|
||||
<?php echo Text::_('COM_USERS_MFA_BACKUPCODES_RESET'); ?>
|
||||
</a>
|
||||
|
||||
<a href="<?php echo $cancelURL ?>"
|
||||
class="btn btn-secondary">
|
||||
<span class="icon icon-cancel-2 icon-ban-circle"></span>
|
||||
<?php echo Text::_('JCANCEL'); ?>
|
||||
</a>
|
||||
181
components/com_users/tmpl/method/edit.php
Normal file
181
components/com_users/tmpl/method/edit.php
Normal file
@ -0,0 +1,181 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage com_users
|
||||
*
|
||||
* @copyright (C) 2022 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
// Prevent direct access
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\HTML\HTMLHelper;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\Router\Route;
|
||||
use Joomla\Component\Users\Site\View\Method\HtmlView;
|
||||
use Joomla\Utilities\ArrayHelper;
|
||||
|
||||
/** @var HtmlView $this */
|
||||
|
||||
$cancelURL = Route::_('index.php?option=com_users&task=methods.display&user_id=' . $this->user->id);
|
||||
|
||||
if (!empty($this->returnURL)) {
|
||||
$cancelURL = $this->escape(base64_decode($this->returnURL));
|
||||
}
|
||||
|
||||
$recordId = (int) $this->record->id ?? 0;
|
||||
$method = $this->record->method ?? $this->getModel()->getState('method');
|
||||
$userId = (int) $this->user->id ?? 0;
|
||||
$headingLevel = 2;
|
||||
$hideSubmit = !$this->renderOptions['show_submit'] && !$this->isEditExisting
|
||||
?>
|
||||
<div class="card card-body">
|
||||
<form action="<?php echo Route::_(sprintf("index.php?option=com_users&task=method.save&id=%d&method=%s&user_id=%d", $recordId, $method, $userId)) ?>"
|
||||
class="form form-horizontal" id="com-users-method-edit" method="post">
|
||||
<?php echo HTMLHelper::_('form.token') ?>
|
||||
<?php if (!empty($this->returnURL)) : ?>
|
||||
<input type="hidden" name="returnurl" value="<?php echo $this->escape($this->returnURL) ?>">
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!empty($this->renderOptions['hidden_data'])) : ?>
|
||||
<?php foreach ($this->renderOptions['hidden_data'] as $key => $value) : ?>
|
||||
<input type="hidden" name="<?php echo $this->escape($key) ?>" value="<?php echo $this->escape($value) ?>">
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!empty($this->title)) : ?>
|
||||
<?php if (!empty($this->renderOptions['help_url'])) : ?>
|
||||
<span class="float-end">
|
||||
<a href="<?php echo $this->renderOptions['help_url'] ?>"
|
||||
class="btn btn-sm btn-dark"
|
||||
target="_blank"
|
||||
>
|
||||
<span class="icon icon-question-sign" aria-hidden="true"></span>
|
||||
<span class="visually-hidden"><?php echo Text::_('JHELP') ?></span>
|
||||
</a>
|
||||
</span>
|
||||
<?php endif;?>
|
||||
<h<?php echo $headingLevel ?> id="com-users-method-edit-head">
|
||||
<?php echo Text::_($this->title) ?>
|
||||
</h<?php echo $headingLevel ?>>
|
||||
<?php $headingLevel++ ?>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="row">
|
||||
<label class="col-sm-3 col-form-label"
|
||||
for="com-users-method-edit-title">
|
||||
<?php echo Text::_('COM_USERS_MFA_EDIT_FIELD_TITLE'); ?>
|
||||
</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text"
|
||||
class="form-control"
|
||||
id="com-users-method-edit-title"
|
||||
name="title"
|
||||
value="<?php echo $this->escape($this->record->title) ?>"
|
||||
aria-describedby="com-users-method-edit-help">
|
||||
<p class="form-text" id="com-users-method-edit-help">
|
||||
<?php echo $this->escape(Text::_('COM_USERS_MFA_EDIT_FIELD_TITLE_DESC')) ?>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm-9 offset-sm-3">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" id="com-users-is-default-method" <?php echo $this->record->default ? 'checked="checked"' : ''; ?> name="default">
|
||||
<label class="form-check-label" for="com-users-is-default-method">
|
||||
<?php echo Text::_('COM_USERS_MFA_EDIT_FIELD_DEFAULT'); ?>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if (!empty($this->renderOptions['pre_message'])) : ?>
|
||||
<div class="com-users-method-edit-pre-message text-muted mt-4 mb-3">
|
||||
<?php echo $this->renderOptions['pre_message'] ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!empty($this->renderOptions['tabular_data'])) : ?>
|
||||
<div class="com-users-method-edit-tabular-container">
|
||||
<?php if (!empty($this->renderOptions['table_heading'])) : ?>
|
||||
<h<?php echo $headingLevel ?> class="h3 border-bottom mb-3">
|
||||
<?php echo $this->renderOptions['table_heading'] ?>
|
||||
</h<?php echo $headingLevel ?>>
|
||||
<?php endif; ?>
|
||||
<table class="table table-striped">
|
||||
<tbody>
|
||||
<?php foreach ($this->renderOptions['tabular_data'] as $cell1 => $cell2) : ?>
|
||||
<tr>
|
||||
<td>
|
||||
<?php echo $cell1 ?>
|
||||
</td>
|
||||
<td>
|
||||
<?php echo $cell2 ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($this->renderOptions['field_type'] == 'custom') : ?>
|
||||
<?php echo $this->renderOptions['html']; ?>
|
||||
<?php endif; ?>
|
||||
<div class="row mb-3 <?php echo $this->renderOptions['input_type'] === 'hidden' ? 'd-none' : '' ?>">
|
||||
<?php if ($this->renderOptions['label']) : ?>
|
||||
<label class="col-sm-3 col-form-label" for="com-users-method-code">
|
||||
<?php echo $this->renderOptions['label']; ?>
|
||||
</label>
|
||||
<?php endif; ?>
|
||||
<div class="col-sm-9" <?php echo $this->renderOptions['label'] ? '' : 'offset-sm-3' ?>>
|
||||
<?php
|
||||
$attributes = array_merge(
|
||||
[
|
||||
'type' => $this->renderOptions['input_type'],
|
||||
'name' => 'code',
|
||||
'value' => $this->escape($this->renderOptions['input_value']),
|
||||
'id' => 'com-users-method-code',
|
||||
'class' => 'form-control',
|
||||
'aria-describedby' => 'com-users-method-code-help',
|
||||
],
|
||||
$this->renderOptions['input_attributes']
|
||||
);
|
||||
|
||||
if (strpos($attributes['class'], 'form-control') === false) {
|
||||
$attributes['class'] .= ' form-control';
|
||||
}
|
||||
?>
|
||||
<input <?php echo ArrayHelper::toString($attributes) ?>>
|
||||
|
||||
<p class="form-text" id="com-users-method-code-help">
|
||||
<?php echo $this->escape($this->renderOptions['placeholder']) ?>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<div class="col-sm-9 offset-sm-3">
|
||||
<button type="submit" class="btn btn-primary me-3 <?php echo $hideSubmit ? 'd-none' : '' ?> <?php echo $this->renderOptions['submit_class'] ?>">
|
||||
<span class="<?php echo $this->renderOptions['submit_icon'] ?>" aria-hidden="true"></span>
|
||||
<?php echo Text::_($this->renderOptions['submit_text']); ?>
|
||||
</button>
|
||||
|
||||
<a href="<?php echo $cancelURL ?>"
|
||||
class="btn btn-sm btn-danger">
|
||||
<span class="icon icon-cancel-2" aria-hidden="true"></span>
|
||||
<?php echo Text::_('JCANCEL'); ?>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if (!empty($this->renderOptions['post_message'])) : ?>
|
||||
<div class="com-users-method-edit-post-message text-muted">
|
||||
<?php echo $this->renderOptions['post_message'] ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</form>
|
||||
</div>
|
||||
60
components/com_users/tmpl/methods/default.php
Normal file
60
components/com_users/tmpl/methods/default.php
Normal file
@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage com_users
|
||||
*
|
||||
* @copyright (C) 2022 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
// Prevent direct access
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\Router\Route;
|
||||
use Joomla\Component\Users\Site\View\Methods\HtmlView;
|
||||
|
||||
/** @var HtmlView $this */
|
||||
?>
|
||||
<div id="com-users-methods-list">
|
||||
<?php if (!$this->get('forHMVC', false)) : ?>
|
||||
<h2 id="com-users-methods-list-head">
|
||||
<?php echo Text::_('COM_USERS_MFA_LIST_PAGE_HEAD'); ?>
|
||||
</h2>
|
||||
<?php endif ?>
|
||||
|
||||
<div id="com-users-methods-reset-container" class="d-flex align-items-center border border-1 rounded-3 p-2 bg-light">
|
||||
<div id="com-users-methods-reset-message" class="flex-grow-1">
|
||||
<?php echo Text::_('COM_USERS_MFA_LIST_STATUS_' . ($this->mfaActive ? 'ON' : 'OFF')) ?>
|
||||
</div>
|
||||
<?php if ($this->mfaActive) : ?>
|
||||
<div>
|
||||
<a href="<?php echo Route::_('index.php?option=com_users&task=methods.disable&' . Factory::getApplication()->getFormToken() . '=1' . ($this->returnURL ? '&returnurl=' . $this->escape(urlencode($this->returnURL)) : '') . '&user_id=' . $this->user->id) ?>"
|
||||
class="btn btn-danger btn-sm">
|
||||
<?php echo Text::_('COM_USERS_MFA_LIST_REMOVEALL'); ?>
|
||||
</a>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<?php if (!count($this->methods)) : ?>
|
||||
<div id="com-users-methods-list-instructions" class="alert alert-info mt-2">
|
||||
<span class="icon icon-info-circle" aria-hidden="true"></span>
|
||||
<?php echo Text::_('COM_USERS_MFA_LIST_INSTRUCTIONS'); ?>
|
||||
</div>
|
||||
<?php elseif ($this->isMandatoryMFASetup) : ?>
|
||||
<div class="alert alert-info my-3">
|
||||
<h3 class="alert-heading">
|
||||
<?php echo Text::_('COM_USERS_MFA_MANDATORY_NOTICE_HEAD') ?>
|
||||
</h3>
|
||||
<p>
|
||||
<?php echo Text::_('COM_USERS_MFA_MANDATORY_NOTICE_BODY') ?>
|
||||
</p>
|
||||
</div>
|
||||
<?php endif ?>
|
||||
|
||||
<?php $this->setLayout('list');
|
||||
echo $this->loadTemplate(); ?>
|
||||
</div>
|
||||
50
components/com_users/tmpl/methods/firsttime.php
Normal file
50
components/com_users/tmpl/methods/firsttime.php
Normal file
@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage com_users
|
||||
*
|
||||
* @copyright (C) 2022 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
// Prevent direct access
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\Router\Route;
|
||||
use Joomla\Component\Users\Site\View\Methods\HtmlView;
|
||||
|
||||
/** @var HtmlView $this */
|
||||
|
||||
$headingLevel = 2;
|
||||
?>
|
||||
<div id="com-users-methods-list">
|
||||
<?php if (!$this->isAdmin) : ?>
|
||||
<h<?php echo $headingLevel ?> id="com-users-methods-list-head">
|
||||
<?php echo Text::_('COM_USERS_MFA_FIRSTTIME_PAGE_HEAD'); ?>
|
||||
</h<?php echo $headingLevel++ ?>>
|
||||
<?php endif; ?>
|
||||
<div id="com-users-methods-list-instructions" class="alert alert-info">
|
||||
<h<?php echo $headingLevel ?> class="alert-heading">
|
||||
<span class="fa fa-shield-alt" aria-hidden="true"></span>
|
||||
<?php echo Text::_('COM_USERS_MFA_FIRSTTIME_INSTRUCTIONS_HEAD'); ?>
|
||||
</h<?php echo $headingLevel ?>>
|
||||
<p>
|
||||
<?php echo Text::_('COM_USERS_MFA_FIRSTTIME_INSTRUCTIONS_WHATITDOES'); ?>
|
||||
</p>
|
||||
<a href="<?php echo Route::_(
|
||||
'index.php?option=com_users&task=methods.doNotShowThisAgain' .
|
||||
($this->returnURL ? '&returnurl=' . $this->escape(urlencode($this->returnURL)) : '') .
|
||||
'&user_id=' . $this->user->id .
|
||||
'&' . Factory::getApplication()->getFormToken() . '=1'
|
||||
)?>"
|
||||
class="btn btn-danger w-100">
|
||||
<?php echo Text::_('COM_USERS_MFA_FIRSTTIME_NOTINTERESTED'); ?>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<?php $this->setLayout('list');
|
||||
echo $this->loadTemplate(); ?>
|
||||
</div>
|
||||
144
components/com_users/tmpl/methods/list.php
Normal file
144
components/com_users/tmpl/methods/list.php
Normal file
@ -0,0 +1,144 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage com_users
|
||||
*
|
||||
* @copyright (C) 2022 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
// Prevent direct access
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\HTML\HTMLHelper;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\Router\Route;
|
||||
use Joomla\CMS\Uri\Uri;
|
||||
use Joomla\Component\Users\Administrator\Helper\Mfa as MfaHelper;
|
||||
use Joomla\Component\Users\Site\Model\MethodsModel;
|
||||
use Joomla\Component\Users\Site\View\Methods\HtmlView;
|
||||
|
||||
/** @var HtmlView $this */
|
||||
|
||||
/** @var MethodsModel $model */
|
||||
$model = $this->getModel();
|
||||
|
||||
$this->document->getWebAssetManager()->useScript('com_users.two-factor-list');
|
||||
|
||||
HTMLHelper::_('bootstrap.tooltip', '.hasTooltip');
|
||||
|
||||
$canAddEdit = MfaHelper::canAddEditMethod($this->user);
|
||||
$canDelete = MfaHelper::canDeleteMethod($this->user);
|
||||
?>
|
||||
<div id="com-users-methods-list-container">
|
||||
<?php foreach ($this->methods as $methodName => $method) :
|
||||
$methodClass = 'com-users-methods-list-method-name-' . htmlentities($method['name'])
|
||||
. ($this->defaultMethod == $methodName ? ' com-users-methods-list-method-default' : '');
|
||||
?>
|
||||
<div class="com-users-methods-list-method <?php echo $methodClass?> mx-1 my-3 card <?php echo count($method['active']) ? 'border-secondary' : '' ?>">
|
||||
<div class="com-users-methods-list-method-header card-header <?php echo count($method['active']) ? 'border-secondary bg-secondary text-white' : '' ?> d-flex flex-wrap align-items-center gap-2">
|
||||
<div class="com-users-methods-list-method-image pt-1 px-3 pb-2 bg-light rounded-2">
|
||||
<img src="<?php echo Uri::root() . $method['image'] ?>"
|
||||
alt="<?php echo $this->escape($method['display']) ?>"
|
||||
class="img-fluid"
|
||||
>
|
||||
</div>
|
||||
<div class="com-users-methods-list-method-title flex-grow-1 d-flex flex-column">
|
||||
<h2 class="h4 p-0 m-0 d-flex gap-3 align-items-center">
|
||||
<span class="me-1 flex-grow-1">
|
||||
<?php echo $method['display'] ?>
|
||||
</span>
|
||||
<?php if ($this->defaultMethod == $methodName) : ?>
|
||||
<span id="com-users-methods-list-method-default-tag" class="badge bg-info me-1 fs-6">
|
||||
<?php echo Text::_('COM_USERS_MFA_LIST_DEFAULTTAG') ?>
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="com-users-methods-list-method-records-container card-body">
|
||||
<div class="com-users-methods-list-method-info my-1 pb-1 small text-muted">
|
||||
<?php echo $method['shortinfo'] ?>
|
||||
</div>
|
||||
|
||||
<?php if (count($method['active'])) : ?>
|
||||
<div class="com-users-methods-list-method-records pt-2 my-2">
|
||||
<?php foreach ($method['active'] as $record) : ?>
|
||||
<div class="com-users-methods-list-method-record d-flex flex-row flex-wrap justify-content-start border-top py-2">
|
||||
<div class="com-users-methods-list-method-record-info flex-grow-1 d-flex flex-column align-items-start gap-1">
|
||||
<?php if ($methodName === 'backupcodes') : ?>
|
||||
<?php if ($canAddEdit) : ?>
|
||||
<div class="alert alert-info mt-1 w-100">
|
||||
<?php echo Text::sprintf('COM_USERS_MFA_BACKUPCODES_PRINT_PROMPT_HEAD', Route::_('index.php?option=com_users&task=method.edit&id=' . (int) $record->id . ($this->returnURL ? '&returnurl=' . $this->escape(urlencode($this->returnURL)) : '') . '&user_id=' . $this->user->id)) ?>
|
||||
</div>
|
||||
<?php endif ?>
|
||||
<?php else : ?>
|
||||
<h3 class="com-users-methods-list-method-record-title-container mb-1 fs-5">
|
||||
<?php if ($record->default) : ?>
|
||||
<span id="com-users-methods-list-method-default-badge-small"
|
||||
class="text-warning me-1 hasTooltip"
|
||||
title="<?php echo $this->escape(Text::_('COM_USERS_MFA_LIST_DEFAULTTAG')) ?>">
|
||||
<span class="icon icon-star" aria-hidden="true"></span>
|
||||
<span class="visually-hidden"><?php echo $this->escape(Text::_('COM_USERS_MFA_LIST_DEFAULTTAG')) ?></span>
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
<span class="com-users-methods-list-method-record-title fw-bold">
|
||||
<?php echo $this->escape($record->title); ?>
|
||||
</span>
|
||||
</h3>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="com-users-methods-list-method-record-lastused my-1 d-flex flex-row flex-wrap justify-content-start gap-5 text-muted small w-100">
|
||||
<span class="com-users-methods-list-method-record-createdon">
|
||||
<?php echo Text::sprintf('COM_USERS_MFA_LBL_CREATEDON', $model->formatRelative($record->created_on)) ?>
|
||||
</span>
|
||||
<span class="com-users-methods-list-method-record-lastused-date">
|
||||
<?php echo Text::sprintf('COM_USERS_MFA_LBL_LASTUSED', $model->formatRelative($record->last_used)) ?>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<?php if ($methodName !== 'backupcodes' && ($canAddEdit || $canDelete)) : ?>
|
||||
<div class="com-users-methods-list-method-record-actions my-2 d-flex flex-row flex-wrap justify-content-center align-content-center align-items-start">
|
||||
<?php if ($canAddEdit) : ?>
|
||||
<a class="com-users-methods-list-method-record-edit btn btn-secondary btn-sm mx-1 hasTooltip"
|
||||
href="<?php echo Route::_('index.php?option=com_users&task=method.edit&id=' . (int) $record->id . ($this->returnURL ? '&returnurl=' . $this->escape(urlencode($this->returnURL)) : '') . '&user_id=' . $this->user->id)?>"
|
||||
title="<?php echo Text::_('JACTION_EDIT') ?> <?php echo $this->escape($record->title); ?>">
|
||||
<span class="icon icon-pencil" aria-hidden="true"></span>
|
||||
<span class="visually-hidden"><?php echo Text::_('JACTION_EDIT') ?> <?php echo $this->escape($record->title); ?></span>
|
||||
</a>
|
||||
<?php endif ?>
|
||||
|
||||
<?php if ($method['canDisable'] && $canDelete) : ?>
|
||||
<a class="com-users-methods-list-method-record-delete btn btn-danger btn-sm mx-1 hasTooltip"
|
||||
href="<?php echo Route::_('index.php?option=com_users&task=method.delete&id=' . (int) $record->id . ($this->returnURL ? '&returnurl=' . $this->escape(urlencode($this->returnURL)) : '') . '&user_id=' . $this->user->id . '&' . Factory::getApplication()->getFormToken() . '=1')?>"
|
||||
title="<?php echo Text::_('JACTION_DELETE') ?> <?php echo $this->escape($record->title); ?>">
|
||||
<span class="icon icon-trash" aria-hidden="true"></span>
|
||||
<span class="visually-hidden"><?php echo Text::_('JACTION_DELETE') ?> <?php echo $this->escape($record->title); ?></span>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($canAddEdit && (empty($method['active']) || $method['allowMultiple'])) : ?>
|
||||
<div class="com-users-methods-list-method-addnew-container border-top pt-2">
|
||||
<a href="<?php echo Route::_('index.php?option=com_users&task=method.add&method=' . $this->escape(urlencode($method['name'])) . ($this->returnURL ? '&returnurl=' . $this->escape(urlencode($this->returnURL)) : '') . '&user_id=' . $this->user->id)?>"
|
||||
class="com-users-methods-list-method-addnew btn btn-outline-primary btn-sm"
|
||||
>
|
||||
<span class="icon-plus-2" aria-hidden="true"></span>
|
||||
<?php echo Text::sprintf('COM_USERS_MFA_ADD_AUTHENTICATOR_OF_TYPE', $method['display']) ?>
|
||||
</a>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
39
components/com_users/tmpl/profile/default.php
Normal file
39
components/com_users/tmpl/profile/default.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage com_users
|
||||
*
|
||||
* @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\Router\Route;
|
||||
|
||||
?>
|
||||
<div class="com-users-profile profile">
|
||||
<?php if ($this->params->get('show_page_heading')) : ?>
|
||||
<div class="page-header">
|
||||
<h1>
|
||||
<?php echo $this->escape($this->params->get('page_heading')); ?>
|
||||
</h1>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($this->getCurrentUser()->id == $this->data->id) : ?>
|
||||
<ul class="com-users-profile__edit btn-toolbar float-end">
|
||||
<li class="btn-group">
|
||||
<a class="btn btn-primary" href="<?php echo Route::_('index.php?option=com_users&task=profile.edit&user_id=' . (int) $this->data->id); ?>">
|
||||
<span class="icon-user-edit" aria-hidden="true"></span> <?php echo Text::_('COM_USERS_EDIT_PROFILE'); ?>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php echo $this->loadTemplate('core'); ?>
|
||||
<?php echo $this->loadTemplate('params'); ?>
|
||||
<?php echo $this->loadTemplate('custom'); ?>
|
||||
</div>
|
||||
11
components/com_users/tmpl/profile/default.xml
Normal file
11
components/com_users/tmpl/profile/default.xml
Normal file
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<metadata>
|
||||
<layout title="COM_USERS_PROFILE_VIEW_DEFAULT_TITLE" option="COM_USERS_PROFILE_VIEW_DEFAULT_OPTION">
|
||||
<help
|
||||
key = "Menu_Item:_User_Profile"
|
||||
/>
|
||||
<message>
|
||||
<![CDATA[COM_USERS_PROFILE_VIEW_DEFAULT_DESC]]>
|
||||
</message>
|
||||
</layout>
|
||||
</metadata>
|
||||
53
components/com_users/tmpl/profile/default_core.php
Normal file
53
components/com_users/tmpl/profile/default_core.php
Normal file
@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage com_users
|
||||
*
|
||||
* @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\HTML\HTMLHelper;
|
||||
use Joomla\CMS\Language\Text;
|
||||
|
||||
?>
|
||||
<fieldset id="users-profile-core" class="com-users-profile__core">
|
||||
<legend>
|
||||
<?php echo Text::_('COM_USERS_PROFILE_CORE_LEGEND'); ?>
|
||||
</legend>
|
||||
<dl class="dl-horizontal">
|
||||
<dt>
|
||||
<?php echo Text::_('COM_USERS_PROFILE_NAME_LABEL'); ?>
|
||||
</dt>
|
||||
<dd>
|
||||
<?php echo $this->escape($this->data->name); ?>
|
||||
</dd>
|
||||
<dt>
|
||||
<?php echo Text::_('COM_USERS_PROFILE_USERNAME_LABEL'); ?>
|
||||
</dt>
|
||||
<dd>
|
||||
<?php echo $this->escape($this->data->username); ?>
|
||||
</dd>
|
||||
<dt>
|
||||
<?php echo Text::_('COM_USERS_PROFILE_REGISTERED_DATE_LABEL'); ?>
|
||||
</dt>
|
||||
<dd>
|
||||
<?php echo HTMLHelper::_('date', $this->data->registerDate, Text::_('DATE_FORMAT_LC1')); ?>
|
||||
</dd>
|
||||
<dt>
|
||||
<?php echo Text::_('COM_USERS_PROFILE_LAST_VISITED_DATE_LABEL'); ?>
|
||||
</dt>
|
||||
<?php if ($this->data->lastvisitDate !== null) : ?>
|
||||
<dd>
|
||||
<?php echo HTMLHelper::_('date', $this->data->lastvisitDate, Text::_('DATE_FORMAT_LC1')); ?>
|
||||
</dd>
|
||||
<?php else : ?>
|
||||
<dd>
|
||||
<?php echo Text::_('COM_USERS_PROFILE_NEVER_VISITED'); ?>
|
||||
</dd>
|
||||
<?php endif; ?>
|
||||
</dl>
|
||||
</fieldset>
|
||||
75
components/com_users/tmpl/profile/default_custom.php
Normal file
75
components/com_users/tmpl/profile/default_custom.php
Normal file
@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage com_users
|
||||
*
|
||||
* @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\HTML\HTMLHelper;
|
||||
use Joomla\CMS\Language\Text;
|
||||
|
||||
$fieldsets = $this->form->getFieldsets();
|
||||
|
||||
if (isset($fieldsets['core'])) {
|
||||
unset($fieldsets['core']);
|
||||
}
|
||||
|
||||
if (isset($fieldsets['params'])) {
|
||||
unset($fieldsets['params']);
|
||||
}
|
||||
|
||||
$tmp = $this->data->jcfields ?? [];
|
||||
$customFields = [];
|
||||
|
||||
foreach ($tmp as $customField) {
|
||||
$customFields[$customField->name] = $customField;
|
||||
}
|
||||
|
||||
unset($tmp);
|
||||
|
||||
?>
|
||||
<?php foreach ($fieldsets as $group => $fieldset) : ?>
|
||||
<?php $fields = $this->form->getFieldset($group); ?>
|
||||
<?php if (count($fields)) : ?>
|
||||
<fieldset id="users-profile-custom-<?php echo $group; ?>" class="com-users-profile__custom users-profile-custom-<?php echo $group; ?>">
|
||||
<?php if (isset($fieldset->label) && ($legend = trim(Text::_($fieldset->label))) !== '') : ?>
|
||||
<legend><?php echo $legend; ?></legend>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($fieldset->description) && trim($fieldset->description)) : ?>
|
||||
<p><?php echo $this->escape(Text::_($fieldset->description)); ?></p>
|
||||
<?php endif; ?>
|
||||
<dl class="dl-horizontal">
|
||||
<?php foreach ($fields as $field) : ?>
|
||||
<?php // Correct the field name so that subform custom fields show up. ?>
|
||||
<?php if ($field->type === 'Subform' && $field->fieldname === 'row') : ?>
|
||||
<?php preg_match("/jform\[com_fields]\[(.*)]/", $field->name, $matches); ?>
|
||||
<?php $field->fieldname = $matches[1]; ?>
|
||||
<?php endif; ?>
|
||||
<?php if (!$field->hidden && $field->type !== 'Spacer') : ?>
|
||||
<dt>
|
||||
<?php echo $field->title; ?>
|
||||
</dt>
|
||||
<dd>
|
||||
<?php if (array_key_exists($field->fieldname, $customFields)) : ?>
|
||||
<?php echo strlen($customFields[$field->fieldname]->value) ? $customFields[$field->fieldname]->value : Text::_('COM_USERS_PROFILE_VALUE_NOT_FOUND'); ?>
|
||||
<?php elseif (HTMLHelper::isRegistered('users.' . $field->id)) : ?>
|
||||
<?php echo HTMLHelper::_('users.' . $field->id, $field->value); ?>
|
||||
<?php elseif (HTMLHelper::isRegistered('users.' . $field->fieldname)) : ?>
|
||||
<?php echo HTMLHelper::_('users.' . $field->fieldname, $field->value); ?>
|
||||
<?php elseif (HTMLHelper::isRegistered('users.' . $field->type)) : ?>
|
||||
<?php echo HTMLHelper::_('users.' . $field->type, $field->value); ?>
|
||||
<?php else : ?>
|
||||
<?php echo HTMLHelper::_('users.value', $field->value); ?>
|
||||
<?php endif; ?>
|
||||
</dd>
|
||||
<?php endif; ?>
|
||||
<?php endforeach; ?>
|
||||
</dl>
|
||||
</fieldset>
|
||||
<?php endif; ?>
|
||||
<?php endforeach; ?>
|
||||
42
components/com_users/tmpl/profile/default_params.php
Normal file
42
components/com_users/tmpl/profile/default_params.php
Normal file
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage com_users
|
||||
*
|
||||
* @copyright (C) 2010 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\HTML\HTMLHelper;
|
||||
use Joomla\CMS\Language\Text;
|
||||
|
||||
?>
|
||||
<?php $fields = $this->form->getFieldset('params'); ?>
|
||||
<?php if (count($fields)) : ?>
|
||||
<fieldset id="users-profile-custom" class="com-users-profile__params">
|
||||
<legend><?php echo Text::_('COM_USERS_SETTINGS_FIELDSET_LABEL'); ?></legend>
|
||||
<dl class="dl-horizontal">
|
||||
<?php foreach ($fields as $field) : ?>
|
||||
<?php if (!$field->hidden) : ?>
|
||||
<dt>
|
||||
<?php echo $field->title; ?>
|
||||
</dt>
|
||||
<dd>
|
||||
<?php if (HTMLHelper::isRegistered('users.' . $field->id)) : ?>
|
||||
<?php echo HTMLHelper::_('users.' . $field->id, $field->value); ?>
|
||||
<?php elseif (HTMLHelper::isRegistered('users.' . $field->fieldname)) : ?>
|
||||
<?php echo HTMLHelper::_('users.' . $field->fieldname, $field->value); ?>
|
||||
<?php elseif (HTMLHelper::isRegistered('users.' . $field->type)) : ?>
|
||||
<?php echo HTMLHelper::_('users.' . $field->type, $field->value); ?>
|
||||
<?php else : ?>
|
||||
<?php echo HTMLHelper::_('users.value', $field->value); ?>
|
||||
<?php endif; ?>
|
||||
</dd>
|
||||
<?php endif; ?>
|
||||
<?php endforeach; ?>
|
||||
</dl>
|
||||
</fieldset>
|
||||
<?php endif; ?>
|
||||
87
components/com_users/tmpl/profile/edit.php
Normal file
87
components/com_users/tmpl/profile/edit.php
Normal file
@ -0,0 +1,87 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage com_users
|
||||
*
|
||||
* @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\HTML\HTMLHelper;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\Router\Route;
|
||||
|
||||
/** @var Joomla\Component\Users\Site\View\Profile\HtmlView $this */
|
||||
|
||||
HTMLHelper::_('bootstrap.tooltip', '.hasTooltip');
|
||||
|
||||
// Load user_profile plugin language
|
||||
$lang = $this->getLanguage();
|
||||
$lang->load('plg_user_profile', JPATH_ADMINISTRATOR);
|
||||
|
||||
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */
|
||||
$wa = $this->document->getWebAssetManager();
|
||||
$wa->useScript('keepalive')
|
||||
->useScript('form.validate');
|
||||
|
||||
?>
|
||||
<div class="com-users-profile__edit profile-edit">
|
||||
<?php if ($this->params->get('show_page_heading')) : ?>
|
||||
<div class="page-header">
|
||||
<h1>
|
||||
<?php echo $this->escape($this->params->get('page_heading')); ?>
|
||||
</h1>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<form id="member-profile" action="<?php echo Route::_('index.php?option=com_users'); ?>" method="post" class="com-users-profile__edit-form form-validate form-horizontal well" enctype="multipart/form-data">
|
||||
<?php // Iterate through the form fieldsets and display each one. ?>
|
||||
<?php foreach ($this->form->getFieldsets() as $group => $fieldset) : ?>
|
||||
<?php $fields = $this->form->getFieldset($group); ?>
|
||||
<?php if (count($fields)) : ?>
|
||||
<fieldset>
|
||||
<?php // If the fieldset has a label set, display it as the legend. ?>
|
||||
<?php if (isset($fieldset->label)) : ?>
|
||||
<legend>
|
||||
<?php echo Text::_($fieldset->label); ?>
|
||||
</legend>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($fieldset->description) && trim($fieldset->description)) : ?>
|
||||
<p>
|
||||
<?php echo $this->escape(Text::_($fieldset->description)); ?>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
<?php // Iterate through the fields in the set and display them. ?>
|
||||
<?php foreach ($fields as $field) : ?>
|
||||
<?php echo $field->renderField(); ?>
|
||||
<?php endforeach; ?>
|
||||
</fieldset>
|
||||
<?php endif; ?>
|
||||
<?php endforeach; ?>
|
||||
|
||||
<?php if ($this->mfaConfigurationUI) : ?>
|
||||
<fieldset class="com-users-profile__multifactor">
|
||||
<legend><?php echo Text::_('COM_USERS_PROFILE_MULTIFACTOR_AUTH'); ?></legend>
|
||||
<?php echo $this->mfaConfigurationUI ?>
|
||||
</fieldset>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="com-users-profile__edit-submit control-group">
|
||||
<div class="controls">
|
||||
<button type="submit" class="btn btn-primary validate" name="task" value="profile.save">
|
||||
<span class="icon-check" aria-hidden="true"></span>
|
||||
<?php echo Text::_('JSAVE'); ?>
|
||||
</button>
|
||||
<button type="submit" class="btn btn-danger" name="task" value="profile.cancel" formnovalidate>
|
||||
<span class="icon-times" aria-hidden="true"></span>
|
||||
<?php echo Text::_('JCANCEL'); ?>
|
||||
</button>
|
||||
<input type="hidden" name="option" value="com_users">
|
||||
</div>
|
||||
</div>
|
||||
<?php echo HTMLHelper::_('form.token'); ?>
|
||||
</form>
|
||||
</div>
|
||||
11
components/com_users/tmpl/profile/edit.xml
Normal file
11
components/com_users/tmpl/profile/edit.xml
Normal file
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<metadata>
|
||||
<layout title="COM_USERS_PROFILE_EDIT_DEFAULT_TITLE" option="COM_USERS_PROFILE_EDIT_DEFAULT_OPTION">
|
||||
<help
|
||||
key = "Menu_Item:_Edit_User_Profile"
|
||||
/>
|
||||
<message>
|
||||
<![CDATA[COM_USERS_PROFILE_EDIT_DEFAULT_DESC]]>
|
||||
</message>
|
||||
</layout>
|
||||
</metadata>
|
||||
20
components/com_users/tmpl/registration/complete.php
Normal file
20
components/com_users/tmpl/registration/complete.php
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage com_users
|
||||
*
|
||||
* @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
?>
|
||||
<div class="com-users-registration-complete registration-complete">
|
||||
<?php if ($this->params->get('show_page_heading')) : ?>
|
||||
<h1>
|
||||
<?php echo $this->escape($this->params->get('page_heading')); ?>
|
||||
</h1>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
61
components/com_users/tmpl/registration/default.php
Normal file
61
components/com_users/tmpl/registration/default.php
Normal file
@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage com_users
|
||||
*
|
||||
* @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\HTML\HTMLHelper;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\Router\Route;
|
||||
|
||||
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */
|
||||
$wa = $this->document->getWebAssetManager();
|
||||
$wa->useScript('keepalive')
|
||||
->useScript('form.validate');
|
||||
|
||||
?>
|
||||
<div class="com-users-registration registration">
|
||||
<?php if ($this->params->get('show_page_heading')) : ?>
|
||||
<div class="page-header">
|
||||
<h1><?php echo $this->escape($this->params->get('page_heading')); ?></h1>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<form id="member-registration" action="<?php echo Route::_('index.php?option=com_users&task=registration.register'); ?>" method="post" class="com-users-registration__form form-validate" enctype="multipart/form-data">
|
||||
<?php // Iterate through the form fieldsets and display each one. ?>
|
||||
<?php foreach ($this->form->getFieldsets() as $fieldset) : ?>
|
||||
<?php if ($fieldset->name === 'captcha' && $this->captchaEnabled) : ?>
|
||||
<?php continue; ?>
|
||||
<?php endif; ?>
|
||||
<?php $fields = $this->form->getFieldset($fieldset->name); ?>
|
||||
<?php if (count($fields)) : ?>
|
||||
<fieldset>
|
||||
<?php // If the fieldset has a label set, display it as the legend. ?>
|
||||
<?php if (isset($fieldset->label)) : ?>
|
||||
<legend><?php echo Text::_($fieldset->label); ?></legend>
|
||||
<?php endif; ?>
|
||||
<?php echo $this->form->renderFieldset($fieldset->name); ?>
|
||||
</fieldset>
|
||||
<?php endif; ?>
|
||||
<?php endforeach; ?>
|
||||
<?php if ($this->captchaEnabled) : ?>
|
||||
<?php echo $this->form->renderFieldset('captcha'); ?>
|
||||
<?php endif; ?>
|
||||
<div class="com-users-registration__submit control-group">
|
||||
<div class="controls">
|
||||
<button type="submit" class="com-users-registration__register btn btn-primary validate">
|
||||
<?php echo Text::_('JREGISTER'); ?>
|
||||
</button>
|
||||
<input type="hidden" name="option" value="com_users">
|
||||
<input type="hidden" name="task" value="registration.register">
|
||||
</div>
|
||||
</div>
|
||||
<?php echo HTMLHelper::_('form.token'); ?>
|
||||
</form>
|
||||
</div>
|
||||
11
components/com_users/tmpl/registration/default.xml
Normal file
11
components/com_users/tmpl/registration/default.xml
Normal file
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<metadata>
|
||||
<layout title="COM_USERS_REGISTRATION_VIEW_DEFAULT_TITLE" option="COM_USERS_REGISTRATION_VIEW_DEFAULT_OPTION">
|
||||
<help
|
||||
key="Menu_Item:_Registration_Form"
|
||||
/>
|
||||
<message>
|
||||
<![CDATA[COM_USERS_REGISTRATION_VIEW_DEFAULT_DESC]]>
|
||||
</message>
|
||||
</layout>
|
||||
</metadata>
|
||||
49
components/com_users/tmpl/remind/default.php
Normal file
49
components/com_users/tmpl/remind/default.php
Normal file
@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage com_users
|
||||
*
|
||||
* @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\HTML\HTMLHelper;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\Router\Route;
|
||||
|
||||
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */
|
||||
$wa = $this->document->getWebAssetManager();
|
||||
$wa->useScript('keepalive')
|
||||
->useScript('form.validate');
|
||||
|
||||
?>
|
||||
<div class="com-users-remind remind">
|
||||
<?php if ($this->params->get('show_page_heading')) : ?>
|
||||
<div class="page-header">
|
||||
<h1>
|
||||
<?php echo $this->escape($this->params->get('page_heading')); ?>
|
||||
</h1>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<form id="user-registration" action="<?php echo Route::_('index.php?option=com_users&task=remind.remind'); ?>" method="post" class="com-users-remind__form form-validate form-horizontal well">
|
||||
<?php foreach ($this->form->getFieldsets() as $fieldset) : ?>
|
||||
<fieldset>
|
||||
<?php if (isset($fieldset->label)) : ?>
|
||||
<legend><?php echo Text::_($fieldset->label); ?></legend>
|
||||
<?php endif; ?>
|
||||
<?php echo $this->form->renderFieldset($fieldset->name); ?>
|
||||
</fieldset>
|
||||
<?php endforeach; ?>
|
||||
<div class="com-users-remind__submit control-group">
|
||||
<div class="controls">
|
||||
<button type="submit" class="btn btn-primary validate">
|
||||
<?php echo Text::_('JSUBMIT'); ?>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<?php echo HTMLHelper::_('form.token'); ?>
|
||||
</form>
|
||||
</div>
|
||||
11
components/com_users/tmpl/remind/default.xml
Normal file
11
components/com_users/tmpl/remind/default.xml
Normal file
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<metadata>
|
||||
<layout title="COM_USERS_REMIND_VIEW_DEFAULT_TITLE" option="COM_USERS_REMIND_VIEW_DEFAULT_OPTION">
|
||||
<help
|
||||
key = "Menu_Item:_Username_Reminder_Request"
|
||||
/>
|
||||
<message>
|
||||
<![CDATA[COM_USERS_REMIND_VIEW_DEFAULT_DESC]]>
|
||||
</message>
|
||||
</layout>
|
||||
</metadata>
|
||||
49
components/com_users/tmpl/reset/complete.php
Normal file
49
components/com_users/tmpl/reset/complete.php
Normal file
@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage com_users
|
||||
*
|
||||
* @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\HTML\HTMLHelper;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\Router\Route;
|
||||
|
||||
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */
|
||||
$wa = $this->document->getWebAssetManager();
|
||||
$wa->useScript('keepalive')
|
||||
->useScript('form.validate');
|
||||
|
||||
?>
|
||||
<div class="com-users-reset-complete reset-complete">
|
||||
<?php if ($this->params->get('show_page_heading')) : ?>
|
||||
<div class="page-header">
|
||||
<h1>
|
||||
<?php echo $this->escape($this->params->get('page_heading')); ?>
|
||||
</h1>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<form action="<?php echo Route::_('index.php?option=com_users&task=reset.complete'); ?>" method="post" class="com-users-reset-complete__form form-validate form-horizontal well">
|
||||
<?php foreach ($this->form->getFieldsets() as $fieldset) : ?>
|
||||
<fieldset>
|
||||
<?php if (isset($fieldset->label)) : ?>
|
||||
<legend><?php echo Text::_($fieldset->label); ?></legend>
|
||||
<?php endif; ?>
|
||||
<?php echo $this->form->renderFieldset($fieldset->name); ?>
|
||||
</fieldset>
|
||||
<?php endforeach; ?>
|
||||
<div class="com-users-reset-complete__submit control-group">
|
||||
<div class="controls">
|
||||
<button type="submit" class="btn btn-primary validate">
|
||||
<?php echo Text::_('JSUBMIT'); ?>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<?php echo HTMLHelper::_('form.token'); ?>
|
||||
</form>
|
||||
</div>
|
||||
49
components/com_users/tmpl/reset/confirm.php
Normal file
49
components/com_users/tmpl/reset/confirm.php
Normal file
@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage com_users
|
||||
*
|
||||
* @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\HTML\HTMLHelper;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\Router\Route;
|
||||
|
||||
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */
|
||||
$wa = $this->document->getWebAssetManager();
|
||||
$wa->useScript('keepalive')
|
||||
->useScript('form.validate');
|
||||
|
||||
?>
|
||||
<div class="com-users-reset-confirm reset-confirm">
|
||||
<?php if ($this->params->get('show_page_heading')) : ?>
|
||||
<div class="page-header">
|
||||
<h1>
|
||||
<?php echo $this->escape($this->params->get('page_heading')); ?>
|
||||
</h1>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<form action="<?php echo Route::_('index.php?option=com_users&task=reset.confirm'); ?>" method="post" class="com-users-reset-confirm__form form-validate form-horizontal well">
|
||||
<?php foreach ($this->form->getFieldsets() as $fieldset) : ?>
|
||||
<fieldset>
|
||||
<?php if (isset($fieldset->label)) : ?>
|
||||
<legend><?php echo Text::_($fieldset->label); ?></legend>
|
||||
<?php endif; ?>
|
||||
<?php echo $this->form->renderFieldset($fieldset->name); ?>
|
||||
</fieldset>
|
||||
<?php endforeach; ?>
|
||||
<div class="com-users-reset-confirm__submit control-group">
|
||||
<div class="controls">
|
||||
<button type="submit" class="btn btn-primary validate">
|
||||
<?php echo Text::_('JSUBMIT'); ?>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<?php echo HTMLHelper::_('form.token'); ?>
|
||||
</form>
|
||||
</div>
|
||||
49
components/com_users/tmpl/reset/default.php
Normal file
49
components/com_users/tmpl/reset/default.php
Normal file
@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage com_users
|
||||
*
|
||||
* @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\HTML\HTMLHelper;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\Router\Route;
|
||||
|
||||
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */
|
||||
$wa = $this->document->getWebAssetManager();
|
||||
$wa->useScript('keepalive')
|
||||
->useScript('form.validate');
|
||||
|
||||
?>
|
||||
<div class="com-users-reset reset">
|
||||
<?php if ($this->params->get('show_page_heading')) : ?>
|
||||
<div class="page-header">
|
||||
<h1>
|
||||
<?php echo $this->escape($this->params->get('page_heading')); ?>
|
||||
</h1>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<form id="user-registration" action="<?php echo Route::_('index.php?option=com_users&task=reset.request'); ?>" method="post" class="com-users-reset__form form-validate form-horizontal well">
|
||||
<?php foreach ($this->form->getFieldsets() as $fieldset) : ?>
|
||||
<fieldset>
|
||||
<?php if (isset($fieldset->label)) : ?>
|
||||
<legend><?php echo Text::_($fieldset->label); ?></legend>
|
||||
<?php endif; ?>
|
||||
<?php echo $this->form->renderFieldset($fieldset->name); ?>
|
||||
</fieldset>
|
||||
<?php endforeach; ?>
|
||||
<div class="com-users-reset__submit control-group">
|
||||
<div class="controls">
|
||||
<button type="submit" class="btn btn-primary validate">
|
||||
<?php echo Text::_('JSUBMIT'); ?>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<?php echo HTMLHelper::_('form.token'); ?>
|
||||
</form>
|
||||
</div>
|
||||
11
components/com_users/tmpl/reset/default.xml
Normal file
11
components/com_users/tmpl/reset/default.xml
Normal file
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<metadata>
|
||||
<layout title="COM_USERS_RESET_VIEW_DEFAULT_TITLE" option="COM_USERS_RESET_VIEW_DEFAULT_OPTION">
|
||||
<help
|
||||
key="Menu_Item:_Password_Reset"
|
||||
/>
|
||||
<message>
|
||||
<![CDATA[COM_USERS_RESET_VIEW_DEFAULT_DESC]]>
|
||||
</message>
|
||||
</layout>
|
||||
</metadata>
|
||||
Reference in New Issue
Block a user