Метод для генерации пароля в Joomla с учетом настроек компонента com_users
. Также ссылка на gist в GitHub. Метод бывает нужен при разработке плагинов авторегистрации пользователей.
<?php
use Joomla\CMS\Component\ComponentHelper;
/**
* Method to generate password.
*
* @return string Generated password.
*
* @since 1.0.0
*/
public static function generatePassword(): string
{
$comUsersParams = ComponentHelper::getParams('com_users');
// Минимальная длина. В Joomla по умолчанию минимальная длина - 8.
$minimumLength = $comUsersParams->get('minimum_length', 8);
// Минимальное количество цифр
$minimumIntegers = $comUsersParams->get('minimum_integers', 4);
// Минимальное количество символов
$minimumSymbols = $comUsersParams->get('minimum_symbols', 0);
// Минимальное количество букв в верхнем регистре
$minimumUppercase = $comUsersParams->get('minimum_uppercase', 0);
// Минимальное количество букв в нижнем регистре
$minimumLowercase = $comUsersParams->get('minimum_lowercase', 0);
// Словари
$integers = ['1', '2', '3', '4', '5', '6', '7', '8', '9'];
$countIntegers = count($integers);
$symbols = ['~', '!', '#', '$', '%', '^', '&', '*', '(', ')', '-',
'_', '.', ',', '<', '>', '?', '{', '}', '[',
']', '|', ':', ';'];
$countSymbols = count($symbols);
$lettersUppercase = ['A', 'B', 'C', 'D', 'E', 'F', 'G',
'H', 'J', 'K', 'M', 'N', 'P', 'Q', 'R',
'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
$countlettersUppercase = count($lettersUppercase);
$lettersLowercase = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'j', 'k',
'm', 'n', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z'];
$countLettersLowercase = count($lettersLowercase);
// Массивы
$passwordLowercase = [];
$passwordIntegers = [];
$passwordSymbols = [];
$passwordUppercase = [];
// Считаем длину пароля.
$passwordLenght = $minimumIntegers + $minimumSymbols + $minimumUppercase + $minimumLowercase;
$passwordLenght = ($passwordLenght < $minimumLength) ? $minimumLength : $passwordLenght;
// Комбинации
// основа пароля - нижний регистр и цифры. Остальное до кучи, поэтому если указаны символы и верхний регистр,
// то вычитаем их количество из общей длины. Везде, блин, могут оказаться нули...
//
// ПОВЕДЕНИЕ ПО УМОЛЧАНИЮ
// По умолчанию все пустые значения. Буквы в нижнем регистре и цифры используем обязательно.
if (empty($minimumIntegers) && empty($minimumSymbols) && empty($minimumUppercase) && empty($minimumLowercase))
{
// Пополам, если не указано.
$minimumIntegers = ceil($passwordLenght / 2); // Если общее количество - нечётное число
$minimumLowercase = $passwordLenght - $minimumIntegers;
}
else
{
/**
* Представим различные комбинации 4-х параметров, где часть - нули,
* а часть - указаны. Мы должны зарезервировать "место" в пароле
* под обязательные количества, а остальное поделить поровну между
* нижним регистром и цифрами.
* Соответственно - вычисляем "свободный остаток".
*
* Случаи противоречивых настроек???
*/
$tmp_password_lenght = $passwordLenght;
if (!empty($minimumUppercase))
{
$tmp_password_lenght = $tmp_password_lenght - $minimumUppercase;
}
if (!empty($minimumSymbols))
{
$tmp_password_lenght = $tmp_password_lenght - $minimumSymbols;
}
if (!empty($minimumIntegers))
{
$tmp_password_lenght = $tmp_password_lenght - $minimumIntegers;
}
if (!empty($minimumLowercase))
{
$tmp_password_lenght = $tmp_password_lenght - $minimumLowercase;
}
/**
* Если "пустое место" есть - делим его пополам между числами
* и нижним регистром.
* Если есть уже указанные минимальные значения для
* нижнего регистра и чисел, то прибавляем к ним.
*/
if(!empty($tmp_password_lenght)){
if(!empty($minimumIntegers) || !empty($minimumLowercase)){
$minimumIntegersTmp = ceil($tmp_password_lenght / 2);
$minimumLowercaseTmp = $tmp_password_lenght - $minimumIntegersTmp;
$minimumIntegers = $minimumIntegers + $minimumIntegersTmp;
$minimumLowercase = $minimumLowercase + $minimumLowercaseTmp;
} else {
$minimumIntegers = ceil($tmp_password_lenght / 2);
$minimumLowercase = $tmp_password_lenght - $minimumIntegers;
}
}
}
// Собираем буквы в ВЕРХНЕМ регистре, если указаны в настройках
if (!empty($minimumUppercase))
{
while (count($passwordUppercase) < $minimumUppercase)
{
$key = rand(0, ($countlettersUppercase - 1));
$char = $lettersUppercase[$key];
$passwordUppercase[] = $char;
}
}
// Собираем символы, если указаны в настройках
if (!empty($minimumSymbols))
{
while (count($passwordSymbols) < $minimumSymbols)
{
$key = rand(0, ($countSymbols - 1));
$char = $symbols[$key];
$passwordSymbols[] = $char;
}
}
// Собираем буквы в нижнем регистре
if (!empty($minimumLowercase))
{
while (count($passwordLowercase) < $minimumLowercase)
{
$key = rand(0, ($countLettersLowercase - 1));
$char = $lettersLowercase[$key];
$passwordLowercase[] = $char;
}
}
// Собираем числа
if (!empty($minimumIntegers))
{
while (count($passwordIntegers) < $minimumIntegers)
{
$key = rand(0, ($countIntegers - 1));
$char = $integers[$key];
$passwordIntegers[] = $char;
}
}
$password = array_merge($passwordLowercase, $passwordIntegers, $passwordSymbols, $passwordUppercase);
shuffle($password);
$password = implode($password);
return $password;
}