Página 1 de 2

AJAX Registration Check

Enviado: 12 Mar 2026, 18:47
por Chico Gois
[Extensão] AJAX Registration Check (Atualização 3.3.x)

Autor Original: MarkusWME (pcgamingfreaks.at)
Versão Original: 1.0.0 / 1.0.1 (Lançada em 2017)
Versão atual: 1.0.5
Atualizada para: phpBB 3.3.15+ (Compatível com PHP 8.x)

Descrição
Esta extensão adiciona verificações em tempo real (via AJAX) ao formulário de registro de novos usuários. Ela checa a disponibilidade do nome de usuário, validade e disponibilidade do e-mail, força da senha e confirmação de senha instantaneamente, sem que o usuário precise recarregar a página. Isso melhora significativamente a experiência do usuário (UX) e evita submissões de formulários com erros.

Por que esta atualização?
Como a extensão original foi projetada para o phpBB 3.1 e 3.2, ela não possui validação oficial para versões modernas e contém bugs e chamadas depreciadas que geram erros críticos em ambientes phpBB 3.3.x e PHP 8.

Principais Mudanças e Correções:
  • Remoção de Configurações Depreciadas: O phpBB 3.3 removeu o limite de caracteres para senhas (max_pass_chars). Ajustei o listener.php, os templates HTML e o JavaScript para remover essas referências, substituindo o limite por um indicador de "infinito" (∞) nas mensagens de validação para evitar quebras de layout ou erros.
  • Correção na Verificação de E-mails Banidos: Corrigi uma falha no controller.php onde a checagem na tabela de banimentos (BANLIST_TABLE) só buscava correspondências exatas. Agora a extensão reconhece corretamente padrões com wildcards (ex: *.provedor.com) usando preg_quote.
  • Wildcards em Nomes de Usuário: Lógica atualizada para tratar o caractere * em nomes de usuário desativados com o devido "escaping", seguindo o padrão moderno do phpBB.
  • Melhorias em PHP 8.x e JS:
    • Compatibilidade total com PHP 8.x.
    • Alteração das chamadas AJAX para POST para maior segurança e consistência.
    • Integração de um círculo de carregamento (loading) personalizado para feedback visual durante as checagens.
  • Otimização Geral: Mantive o suporte à verificação de força de senha no lado do cliente, mas removi limitações obsoletas que causavam conflitos em versões recentes do core do fórum.
Compatibilidade
  • phpBB 3.3.0 até 3.3.15+
  • PHP 7.4 até 8.x
Nota: Esta versão mantém a essência da extensão original, garantindo estabilidade e segurança para as instalações atuais do phpBB.
format-zip
ajaxregistrationcheck.zip
23.33 KiB - Baixado 311 vezes

Re: AJAX Registration Check

Enviado: 13 Mar 2026, 18:36
por Chico Gois
Arquivo: controller.php =================================================================== --- controller.php (original) +++ controller.php (modificado) @@ -1,160 +1,151 @@ <?php - +/** -/** + * @author MarkusWME <markuswme@pcgamingfreaks.at> - * @author MarkusWME <markuswme@pcgamingfreaks.at> + * @copyright 2017 MarkusWME - * @copyright 2017 MarkusWME + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 + */ - */ +namespace pcgf\ajaxregistrationcheck\controller; - +use phpbb\db\driver\factory; -namespace pcgf\ajaxregistrationcheck\controller; +use phpbb\event\dispatcher; - +use phpbb\json_response; -use phpbb\db\driver\factory; +use phpbb\request\request; -use phpbb\event\dispatcher; +use phpbb\user; -use phpbb\json_response; +/** @version 1.0.1 (atualizado para phpBB 3.3.15) */ -use phpbb\request\request; +class controller -use phpbb\user; +{ -use rmcgirr83\stopforumspam\event\main_listener; + /** @var request $request Request object */ - + protected $request; -/** @version 1.0.0 */ + /** @var factory $db Database object */ -class controller + protected $db; -{ + /** @var user $user User object */ - /** @var request $request Request object */ + protected $user; - protected $request; + /** @var dispatcher $dispatcher phpBB event dispatcher */ - + protected $dispatcher; - /** @var factory $db Database object */ + /** - protected $db; + * Controller constructor - + * - /** @var user $user User object */ + * @access public - protected $user; + * @since 1.0.0 - + * - /** @var dispatcher $dispatcher phpBB event dispatcher */ + * @param request $request Request object - protected $dispatcher; + * @param factory $db Database object - + * @param user $user User object - /** + * @param dispatcher $dispatcher phpBB event dispatcher - * Controller constructor + */ - * + public function __construct(request $request, factory $db, user $user, dispatcher $dispatcher) - * @access public + { - * @since 1.0.0 + $this->request = $request; - * + $this->db = $db; - * @param request $request Request object + $this->user = $user; - * @param factory $db Database object + $this->dispatcher = $dispatcher; - * @param user $user User object + } - * @param dispatcher $dispatcher phpBB event dispatcher + /** - */ + * Function that checks the user input - public function __construct(request $request, factory $db, user $user, dispatcher $dispatcher) + * - { + * @access public - $this->request = $request; + * @since 1.0.0 - $this->db = $db; + * - $this->user = $user; + * @param string $type The input type - $this->dispatcher = $dispatcher; + */ - } + public function check($type) - + { - /** + // Load needed language data - * Function that checks the user input + $this->user->add_lang('ucp'); - * + $this->user->add_lang_ext('pcgf/ajaxregistrationcheck', array('ajaxregistrationcheck')); - * @access public + $response = new json_response(); - * @since 1.0.0 + $response_text = array('INVALID QUERY', $this->user->lang('PCGF_AJAXREGISTRATIONCHECK_INVALID_QUERY')); - * + if ($this->request->is_ajax()) - * @param string $type The input type + { - */ + switch ($type) - public function check($type) + { - { + case 'username': - // Load needed language data + $username = $this->request->variable('search', ''); - $this->user->add_lang('ucp'); + if ($username !== '') - $this->user->add_lang_ext('pcgf/ajaxregistrationcheck', array('ajaxregistrationcheck')); + { - $response = new json_response(); + $username_escaped = $this->db->sql_escape($username); - $response_text = array('INVALID QUERY', $this->user->lang('PCGF_AJAXREGISTRATIONCHECK_INVALID_QUERY')); + // Check if the name is already used - if ($this->request->is_ajax()) + $query = 'SELECT username - { + FROM ' . USERS_TABLE . " - switch ($type) + WHERE username = '" . $username_escaped . "'"; - { + $result = $this->db->sql_query($query); - case 'username': + if ($this->db->sql_fetchrow($result)) - $username = $this->request->variable('search', ''); + { - if ($username !== '') + $response_text[0] = 'NOT OK'; - { + $response_text[1] = $this->user->lang('USERNAME_TAKEN_USERNAME'); - $username_escaped = $this->db->sql_escape($username); + } - // Check if the name is already used + $this->db->sql_freeresult($result); - $query = 'SELECT username + if ($response_text[0] !== 'NOT OK') - FROM ' . USERS_TABLE . " + { - WHERE username = '" . $username_escaped . "'"; + // Check if the username is blocked by the board admin - $result = $this->db->sql_query($query); + $query = 'SELECT disallow_username - if ($this->db->sql_fetchrow($result)) + FROM ' . DISALLOW_TABLE; - { + $result = $this->db->sql_query($query); - $response_text[0] = 'NOT OK'; + while ($disallowed_user = $this->db->sql_fetchrow($result)) - $response_text[1] = $this->user->lang('USERNAME_TAKEN_USERNAME'); + { - } + // Check if the username matches the rule (corrigido com preg_quote e wildcard *) - $this->db->sql_freeresult($result); + $pattern = str_replace('\*', '.*', preg_quote($disallowed_user['disallow_username'], '/')); - if ($response_text[0] !== 'NOT OK') + if (preg_match('/^' . $pattern . '$/i', $username)) - { + { - // Check if the username is blocked by the board admin + $response_text[0] = 'NOT OK'; - $query = 'SELECT disallow_username + $response_text[1] = $this->user->lang('USERNAME_DISALLOWED_USERNAME'); - FROM ' . DISALLOW_TABLE; + break; - $result = $this->db->sql_query($query); + } - while ($disallowed_user = $this->db->sql_fetchrow($result)) + } - { + $this->db->sql_freeresult($result); - // Check if the username matches the rule + if ($response_text[0] !== 'NOT OK') - if (preg_match('/^' . str_replace('%', '.*', $disallowed_user['disallow_username']) . '$/i', $username)) + { - { + // All checks passed - set status to OK - $response_text[0] = 'NOT OK'; + $response_text[0] = 'OK'; - $response_text[1] = $this->user->lang('USERNAME_DISALLOWED_USERNAME'); + $response_text[1] = $this->user->lang('PCGF_AJAXREGISTRATIONCHECK_USERNAME_OK'); - break; + } - } + } - } + } - $this->db->sql_freeresult($result); + break; - if ($response_text[0] !== 'NOT OK') + case 'email': - { + $email = $this->request->variable('search', ''); - // All checks passed - set status to OK + if ($email !== '') - $response_text[0] = 'OK'; + { - $response_text[1] = $this->user->lang('PCGF_AJAXREGISTRATIONCHECK_USERNAME_OK'); + $email_escaped = $this->db->sql_escape($email); - } + // Check if the email is already used - } + $query = 'SELECT user_email - } + FROM ' . USERS_TABLE . " - break; + WHERE user_email = '" . $email_escaped . "'"; - case 'email': + $result = $this->db->sql_query($query); - $email = $this->request->variable('search', ''); + if ($this->db->sql_fetchrow($result)) - if ($email !== '') + { - { + $response_text[0] = 'NOT OK'; - $email_escaped = $this->db->sql_escape($email); + $response_text[1] = $this->user->lang('EMAIL_TAKEN_EMAIL'); - // Check if the email is already used + } - $query = 'SELECT user_email + $this->db->sql_freeresult($result); - FROM ' . USERS_TABLE . " + if ($response_text[0] !== 'NOT OK') - WHERE user_email = '" . $email_escaped . "'"; + { - $result = $this->db->sql_query($query); + // Check if the email is blocked (fix: busca todos os bans e verifica padrões com preg_quote e *) - if ($this->db->sql_fetchrow($result)) + $query = 'SELECT ban_email - { + FROM ' . BANLIST_TABLE . " - $response_text[0] = 'NOT OK'; + WHERE ban_email != ''"; - $response_text[1] = $this->user->lang('EMAIL_TAKEN_EMAIL'); + $result = $this->db->sql_query($query); - } + while ($banned_email = $this->db->sql_fetchrow($result)) - $this->db->sql_freeresult($result); + { - if ($response_text[0] !== 'NOT OK') + $pattern = str_replace('\*', '.*', preg_quote($banned_email['ban_email'], '/')); - { + if (preg_match('/^' . $pattern . '$/i', $email)) - // Check if the username is blocked by the board admin + { - $query = 'SELECT ban_email + $response_text[0] = 'NOT OK'; - FROM ' . BANLIST_TABLE . " + $response_text[1] = $this->user->lang('EMAIL_BANNED_EMAIL'); - WHERE ban_email = '" . $email_escaped . "'"; + break; - $result = $this->db->sql_query($query); + } - while ($disallowed_email = $this->db->sql_fetchrow($result)) + } - { + $this->db->sql_freeresult($result); - // Check if the username matches the rule + if ($response_text[0] !== 'NOT OK') - if (preg_match('/^' . str_replace('%', '.*', $disallowed_email['ban_email']) . '$/i', $email)) + { - { + // All checks passed - set status to OK - $response_text[0] = 'NOT OK'; + $response_text[0] = 'OK'; - $response_text[1] = $this->user->lang('EMAIL_BANNED_EMAIL'); + $response_text[1] = $this->user->lang('PCGF_AJAXREGISTRATIONCHECK_EMAIL_OK'); - break; + } - } + } - } + } - $this->db->sql_freeresult($result); + break; - if ($response_text[0] !== 'NOT OK') + } - { + } - // All checks passed - set status to OK + $response->send($response_text); - $response_text[0] = 'OK'; + } - $response_text[1] = $this->user->lang('PCGF_AJAXREGISTRATIONCHECK_EMAIL_OK'); +} - } - } - } - break; - } - } - $response->send($response_text); - } -}

Re: AJAX Registration Check

Enviado: 13 Mar 2026, 18:39
por Chico Gois
Arquivo: listener.php =================================================================== --- listener.php (original) +++ listener.php (modificado) @@ -1,129 +1,122 @@ <?php - +/** -/** + * @copyright 2017 MarkusWME - * @author MarkusWME <markuswme@pcgamingfreaks.at> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 - * @copyright 2017 MarkusWME + */ - * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 + - */ +namespace pcgf\ajaxregistrationcheck\event; -namespace pcgf\ajaxregistrationcheck\event; +use phpbb\config\config; - +use phpbb\controller\helper; -use phpbb\config\config; +use phpbb\template\template; -use phpbb\controller\helper; +use phpbb\user; -use phpbb\template\template; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; -use phpbb\user; + -use Symfony\Component\EventDispatcher\EventSubscriberInterface; +/** @version 1.0.1 (atualizado para phpBB 3.3.15) */ - +class listener implements EventSubscriberInterface -/** @version 1.0.0 */ +{ -class listener implements EventSubscriberInterface + /** @var config $config Configuration object */ -{ + protected $config; - /** @var config $config Configuration object */ + - protected $config; + /** @var helper $helper Controller helper object */ - + protected $helper; - /** @var helper $helper Controller helper object */ + - protected $helper; + /** @var template $template Template object */ - + protected $template; - /** @var template $template Template object */ + - protected $template; + /** @var user $user User object */ - + protected $user; - /** @var user $user User object */ + - protected $user; + /** - + * Listener constructor - /** + * @access public - * Listener constructor + * @since 1.0.0 - * + * @param config $config Configuration object - * @access public + * @param helper $helper Controller helper object - * @since 1.0.0 + * @param template $template Template object - * + * @param user $user User object - * @param config $config Configuration object + */ - * @param helper $helper Controller helper object + public function __construct(config $config, helper $helper, template $template, user $user) - * @param template $template Template object + { - * @param user $user User object + $this->config = $config; - */ + $this->helper = $helper; - public function __construct(config $config, helper $helper, template $template, user $user) + $this->template = $template; - { + $this->user = $user; - $this->config = $config; + } - $this->helper = $helper; + - $this->template = $template; + /** - $this->user = $user; + * Function that returns the subscribed events - } + * @access public - + * @since 1.0.0 - /** + * @return array Array with the subscribed events - * Function that returns the subscribed events + */ - * + static public function getSubscribedEvents() - * @access public + { - * @since 1.0.0 + return array( - * + 'core.ucp_register_data_before' => 'assign_register_data', - * @return array Array with the subscribed events + ); - */ + } - static public function getSubscribedEvents() + - { + /** - return array( + * Function to assign all needed data to the registration form - 'core.ucp_register_data_before' => 'assign_register_data', + * @access public - ); + * @since 1.0.0 - } + */ - + public function assign_register_data() - /** + { - * Function to assign all needed data to the registration form + // Load language data - * + $this->user->add_lang_ext('pcgf/ajaxregistrationcheck', array('ajaxregistrationcheck')); - * @access public + $username_rule = $this->config['allow_name_chars']; - * @since 1.0.0 + switch ($username_rule) - */ + { - public function assign_register_data() + case 'USERNAME_CHARS_ANY': - { + $username_rule = "^.+$"; - // Load language data + break; - $this->user->add_lang_ext('pcgf/ajaxregistrationcheck', array('ajaxregistrationcheck')); + case 'USERNAME_ALPHA_ONLY': - $username_rule = $this->config['allow_name_chars']; + $username_rule = "^[a-zA-Z0-9]+$"; - switch ($username_rule) + break; - { + case 'USERNAME_ALPHA_SPACERS': - case 'USERNAME_CHARS_ANY': + $username_rule = "^[a-zA-Z0-9 \\-\\+_\\[\\\]]+$"; - $username_rule = "^.+$"; + break; - break; + case 'USERNAME_LETTER_NUM': - case 'USERNAME_ALPHA_ONLY': + $username_rule = "^[a-zA-Z0-9äöüÄÖÜ]+$"; - $username_rule = "^[a-zA-Z0-9]+$"; + break; - break; + case 'USERNAME_LETTER_NUM_SPACERS': - case 'USERNAME_ALPHA_SPACERS': + $username_rule = "^[a-zA-Z0-9äöüÄÖÜ \\-\\+_\\[\\\]]+$"; - $username_rule = "^[a-zA-Z0-9 \\-\\+_\\[\\\]]+$"; + break; - break; + case 'USERNAME_ASCII': - case 'USERNAME_LETTER_NUM': + $username_rule = "^[a-zA-Z0-9 !\\\"#\\$%&'\\(\\)\\*\\+,\\-\\.\\/:;<=>\\?@\\[\\\]\\^_`\\{\\|\\}~]+$"; - $username_rule = "^[a-zA-Z0-9äöüÄÖÜ]+$"; + break; - break; + } - case 'USERNAME_LETTER_NUM_SPACERS': + $password_rule = $this->config['pass_complex']; - $username_rule = "^[a-zA-Z0-9äöüÄÖÜ \\-\\+_\\[\\\]]+$"; + switch ($password_rule) - break; + { - case 'USERNAME_ASCII': + case 'PASS_TYPE_ANY': - $username_rule = "^[a-zA-Z0-9 !\\\"#\\$%&'\\(\\)\\*\\+,\\-\\.\\/:;<=>\\?@\\[\\\]\\^_`\\{\\|\\}~]+$"; + $password_rule = 0; break; - } + case 'PASS_TYPE_CASE': - $password_rule = $this->config['pass_complex']; + $password_rule = 10; - switch ($password_rule) + break; - { + case 'PASS_TYPE_ALPHA': - case 'PASS_TYPE_ANY': + $password_rule = 100; - $password_rule = 0; + break; - break; + case 'PASS_TYPE_SYMBOL': - case 'PASS_TYPE_CASE': + $password_rule = 1000; - $password_rule = 10; + break; - break; + } - case 'PASS_TYPE_ALPHA': + $this->template->assign_vars(array( - $password_rule = 100; + 'PCGF_AJAXREGISTRATIONCHECK' => true, - break; + 'PCGF_AJAXREGISTRATIONCHECK_USERNAME_MIN' => $this->config['min_name_chars'], - case 'PASS_TYPE_SYMBOL': + 'PCGF_AJAXREGISTRATIONCHECK_USERNAME_MAX' => $this->config['max_name_chars'], - $password_rule = 1000; + 'PCGF_AJAXREGISTRATIONCHECK_USERNAME_RULE' => $username_rule, - break; + 'PCGF_AJAXREGISTRATIONCHECK_USERNAME_INVALID_BOUNDARIES' => $this->user->lang($this->config['allow_name_chars'] . '_EXPLAIN', $this->config['min_name_chars'], $this->config['max_name_chars']), - } + 'PCGF_AJAXREGISTRATIONCHECK_EMAIL_RULE' => str_replace('\\', '\\\\', get_preg_expression('email')), - $this->template->assign_vars(array( + 'PCGF_AJAXREGISTRATIONCHECK_PASSWORD_MIN' => $this->config['min_pass_chars'], - 'PCGF_AJAXREGISTRATIONCHECK' => true, + // Removido PASSWORD_MAX para 3.3.x - 'PCGF_AJAXREGISTRATIONCHECK_USERNAME_MIN' => $this->config['min_name_chars'], + 'PCGF_AJAXREGISTRATIONCHECK_PASSWORD_RULE' => $password_rule, - 'PCGF_AJAXREGISTRATIONCHECK_USERNAME_MAX' => $this->config['max_name_chars'], + 'PCGF_AJAXREGISTRATIONCHECK_PASSWORD_INVALID_BOUNDARIES' => $this->user->lang($this->config['pass_complex'] . '_EXPLAIN', $this->config['min_pass_chars'], '∞'), // Max infinito - 'PCGF_AJAXREGISTRATIONCHECK_USERNAME_RULE' => $username_rule, + 'PCGF_AJAXREGISTRATIONCHECK_CHECK_USERNAME_LINK' => $this->helper->route('pcgf_ajaxregistrationcheck_controller', array('type' => 'username')), - 'PCGF_AJAXREGISTRATIONCHECK_USERNAME_INVALID_BOUNDARIES' => $this->user->lang($this->config['allow_name_chars'] . '_EXPLAIN', $this->config['min_name_chars'], $this->config['max_name_chars']), + 'PCGF_AJAXREGISTRATIONCHECK_CHECK_EMAIL_LINK' => $this->helper->route('pcgf_ajaxregistrationcheck_controller', array('type' => 'email')), - 'PCGF_AJAXREGISTRATIONCHECK_EMAIL_RULE' => str_replace('\\', '\\\\', get_preg_expression('email')), + )); - 'PCGF_AJAXREGISTRATIONCHECK_PASSWORD_MIN' => $this->config['min_pass_chars'], + } - 'PCGF_AJAXREGISTRATIONCHECK_PASSWORD_MAX' => $this->config['max_pass_chars'], +} - 'PCGF_AJAXREGISTRATIONCHECK_PASSWORD_RULE' => $password_rule, - 'PCGF_AJAXREGISTRATIONCHECK_PASSWORD_INVALID_BOUNDARIES' => $this->user->lang($this->config['pass_complex'] . '_EXPLAIN', $this->config['min_pass_chars'], $this->config['max_pass_chars']), - 'PCGF_AJAXREGISTRATIONCHECK_CHECK_USERNAME_LINK' => $this->helper->route('pcgf_ajaxregistrationcheck_controller', array('type' => 'username')), - 'PCGF_AJAXREGISTRATIONCHECK_CHECK_EMAIL_LINK' => $this->helper->route('pcgf_ajaxregistrationcheck_controller', array('type' => 'email')), - )); - } -}

Re: AJAX Registration Check

Enviado: 13 Mar 2026, 18:39
por Chico Gois
Arquivo: ajaxregistrationcheck.js =================================================================== --- ajaxregistrationcheck.js (original) +++ ajaxregistrationcheck.js (modificado) @@ -1,30 +1,181 @@ -<input id="pcgf-ajaxregistrationcheck-sfs-field" name="sfs" class="hidden" type="text"/> +var pcgfAJAXRegistrationCheckUsername = $('#pcgf-ajaxregistrationcheck-username'); -<div id="pcgf-ajaxregistrationcheck-sfs" class="sfs invalid"></div> +var pcgfAJAXRegistrationCheckEMail = $('#pcgf-ajaxregistrationcheck-email'); -<div id="pcgf-ajaxregistrationcheck-username" class="inline"></div> +var pcgfAJAXRegistrationCheckPassword = $('#pcgf-ajaxregistrationcheck-password'); -<div id="pcgf-ajaxregistrationcheck-email" class="inline"></div> +var pcgfAJAXRegistrationCheckConfirmPassword = $('#pcgf-ajaxregistrationcheck-confirm-password'); -<div id="pcgf-ajaxregistrationcheck-password" class="inline"></div> + -<div id="pcgf-ajaxregistrationcheck-confirm-password" class="inline"></div> +pcgfAJAXRegistrationCheckEMailRule = new RegExp(pcgfAJAXRegistrationCheckEMailRule, 'i'); -<script type="text/javascript"> +pcgfAJAXRegistrationCheckUsernameRule = new RegExp(pcgfAJAXRegistrationCheckUsernameRule, 'i'); - var pcgfAJAXRegistrationCheckLoading = '{LA_LOADING}...'; + - var pcgfAJAXRegistrationCheckUsernameMin = '{PCGF_AJAXREGISTRATIONCHECK_USERNAME_MIN}'; +function setInvalid(message, messageField, field) { - var pcgfAJAXRegistrationCheckUsernameMax = '{PCGF_AJAXREGISTRATIONCHECK_USERNAME_MAX}'; + messageField.removeClass('valid').addClass('invalid'); - var pcgfAJAXRegistrationCheckUsernameRule = "{PCGF_AJAXREGISTRATIONCHECK_USERNAME_RULE}"; + messageField.html(message); - var pcgfAJAXRegistrationCheckUsernameInvalidBoundaries = '{PCGF_AJAXREGISTRATIONCHECK_USERNAME_INVALID_BOUNDARIES}'; + field.get(0).setCustomValidity(message); - var pcgfAJAXRegistrationCheckUsernameCheckLink = '{PCGF_AJAXREGISTRATIONCHECK_CHECK_USERNAME_LINK}'; +} - var pcgfAJAXRegistrationCheckEMailRule = "{PCGF_AJAXREGISTRATIONCHECK_EMAIL_RULE}"; + - var pcgfAJAXRegistrationCheckEMailInvalid = '{LA_PCGF_AJAXREGISTRATIONCHECK_EMAIL_INVALID}'; +function setValid(message, messageField, field) { - var pcgfAJAXRegistrationCheckEMailCheckLink = '{PCGF_AJAXREGISTRATIONCHECK_CHECK_EMAIL_LINK}'; + messageField.removeClass('invalid').addClass('valid'); - var pcgfAJAXRegistrationCheckPasswordMin = '{PCGF_AJAXREGISTRATIONCHECK_PASSWORD_MIN}'; + messageField.html(message); - var pcgfAJAXRegistrationCheckPasswordMax = '{PCGF_AJAXREGISTRATIONCHECK_PASSWORD_MAX}'; + field.get(0).setCustomValidity(''); - var pcgfAJAXRegistrationCheckPasswordRule = "{PCGF_AJAXREGISTRATIONCHECK_PASSWORD_RULE}"; +} - var pcgfAJAXRegistrationCheckPasswordInvalid = '{PCGF_AJAXREGISTRATIONCHECK_PASSWORD_INVALID_BOUNDARIES}'; + - var pcgfAJAXRegistrationCheckConfirmPasswordValid = '{LA_PCGF_AJAXREGISTRATIONCHECK_CONFIRM_PASSWORD_OK}'; +function setLoading(message, messageField, field) { - var pcgfAJAXRegistrationCheckConfirmPasswordInvalid = '{LA_NEW_PASSWORD_ERROR}'; + messageField.removeClass('invalid').removeClass('valid'); - var pcgfAJAXRegistrationCheckPasswordStrength = '{LA_PCGF_AJAXREGISTRATIONCHECK_PASSWORD_STRENGTH}{LA_COLON}'; + messageField.html('<div class="loading-circle"><div class="circle1 circle"></div><div class="circle2 circle"></div><div class="circle3 circle"></div><div class="circle4 circle"></div><div class="circle5 circle"></div><div class="circle6 circle"></div><div class="circle7 circle"></div><div class="circle8 circle"></div><div class="circle9 circle"></div><div class="circle10 circle"></div><div class="circle11 circle"></div><div class="circle12 circle"></div></div>&nbsp;&nbsp;&nbsp;' + message); - var pcgfAJAXRegistrationCheckPasswordVeryWeak = '{LA_PCGF_AJAXREGISTRATIONCHECK_PASSWORD_VERY_WEAK}'; + field.get(0).setCustomValidity(''); - var pcgfAJAXRegistrationCheckPasswordWeak = '{LA_PCGF_AJAXREGISTRATIONCHECK_PASSWORD_WEAK}'; +} - var pcgfAJAXRegistrationCheckPasswordNormal = '{LA_PCGF_AJAXREGISTRATIONCHECK_PASSWORD_NORMAL}'; + - var pcgfAJAXRegistrationCheckPasswordStrong = '{LA_PCGF_AJAXREGISTRATIONCHECK_PASSWORD_STRONG}'; +$(document).ready(function() { - var pcgfAJAXRegistrationCheckPasswordVeryStrong = '{LA_PCGF_AJAXREGISTRATIONCHECK_PASSWORD_VERY_STRONG}'; + var passwordField = $('#new_password'); -</script> + var passwordConfirmationField = $('#password_confirm'); -<!-- INCLUDEJS @pcgf_ajaxregistrationcheck/javascript/ajaxregistrationcheck.js --> + pcgfAJAXRegistrationCheckConfirmPassword.insertAfter(passwordConfirmationField); + passwordConfirmationField.on('keyup', function() { + if ($(this).val() === passwordField.val()) { + setValid(pcgfAJAXRegistrationCheckConfirmPasswordValid, pcgfAJAXRegistrationCheckConfirmPassword, $(this)); + } else { + setInvalid(pcgfAJAXRegistrationCheckConfirmPasswordInvalid, pcgfAJAXRegistrationCheckConfirmPassword, $(this)); + } + }); + passwordConfirmationField.trigger('keyup'); + pcgfAJAXRegistrationCheckPassword.insertAfter(passwordField); + passwordField.on('keyup', function() { + passwordConfirmationField.trigger('keyup'); + var value = $(this).val(); + var containsLowerCase = value.match(/[a-z]/g); + var containsUpperCase = value.match(/[A-Z]/g); + var containsNumber = value.match(/[0-9]/g); + var containsSymbol = value.match(/[^a-zA-Z0-9]/g); + var valid = false; + if (value.length < pcgfAJAXRegistrationCheckPasswordMin) { + // The password is too short (removido 'or too long' para 3.3.x) + setInvalid(pcgfAJAXRegistrationCheckPasswordInvalid, pcgfAJAXRegistrationCheckPassword, $(this)); + } else { + if (pcgfAJAXRegistrationCheckPasswordRule <= 0) { + valid = true; + } else if (containsLowerCase && containsUpperCase) { + if (pcgfAJAXRegistrationCheckPasswordRule <= 10) { + valid = true; + } else if (containsNumber) { + if (pcgfAJAXRegistrationCheckPasswordRule <= 100) { + valid = true; + } else if (containsSymbol) { + valid = true; + } else { + setInvalid(pcgfAJAXRegistrationCheckPasswordInvalid, pcgfAJAXRegistrationCheckPassword, $(this)); + } + } else { + setInvalid(pcgfAJAXRegistrationCheckPasswordInvalid, pcgfAJAXRegistrationCheckPassword, $(this)); + } + } else { + setInvalid(pcgfAJAXRegistrationCheckPasswordInvalid, pcgfAJAXRegistrationCheckPassword, $(this)); + } + } + if (valid) { + var percentage = 0; + if (containsLowerCase) { + percentage += (containsLowerCase.length > 5 ? 5 : containsLowerCase.length) * 5; + } + if (containsUpperCase) { + percentage += (containsUpperCase.length > 3 ? 3 : containsUpperCase.length) * 7; + } + if (containsNumber) { + percentage += (containsNumber.length > 2 ? 2 : containsNumber.length) * 10; + } + if (containsSymbol) { + percentage += (containsSymbol.length > 2 ? 2 : containsSymbol.length) * 14; + } + var usernameField = $('#username'); + var eMailField = $('#email'); + if ((usernameField.val() === '' || value.indexOf(usernameField.val()) < 0) && (eMailField.val() === '' || value.indexOf(eMailField.val()) < 0)) { + percentage += 6; + } + if (pcgfAJAXRegistrationCheckPassword.hasClass('invalid')) { + pcgfAJAXRegistrationCheckPassword.removeClass('invalid').addClass('password-strength'); + var securityHTML = '<span>' + pcgfAJAXRegistrationCheckPasswordStrength + '</span>'; + securityHTML += '<div class="progressbar"><div id="pcgf-ajaxregistrationcheck-security">&nbsp;</div></div>'; + securityHTML += '<span id="pcgf-ajaxregistrationcheck-strength"></span>'; + pcgfAJAXRegistrationCheckPassword.html(securityHTML); + } + $(this).get(0).setCustomValidity(''); + var securityPB = $('#pcgf-ajaxregistrationcheck-security'); + var strengthText = $('#pcgf-ajaxregistrationcheck-strength'); + securityPB.stop().animate({width: percentage + '%', overflow: 'overflow'}, 800); + if (percentage >= 95) { + strengthText.html(pcgfAJAXRegistrationCheckPasswordVeryStrong); + securityPB.removeClass().addClass('very-strong'); + } else if (percentage >= 85) { + strengthText.html(pcgfAJAXRegistrationCheckPasswordStrong); + securityPB.removeClass().addClass('strong'); + } else if (percentage >= 60) { + strengthText.html(pcgfAJAXRegistrationCheckPasswordNormal); + securityPB.removeClass().addClass('normal'); + } else if (percentage >= 45) { + strengthText.html(pcgfAJAXRegistrationCheckPasswordWeak); + securityPB.removeClass().addClass('weak'); + } else { + strengthText.html(pcgfAJAXRegistrationCheckPasswordVeryWeak); + securityPB.removeClass().addClass('very-weak'); + } + } else { + pcgfAJAXRegistrationCheckPassword.removeClass('password-strength'); + } + }); + passwordField.trigger('keyup'); + var usernameField = $('#username'); + pcgfAJAXRegistrationCheckUsername.insertAfter(usernameField); + usernameField.on('keyup', function() { + passwordField.trigger('keyup'); + var value = $(this).val(); + if (value.length < pcgfAJAXRegistrationCheckUsernameMin || value.length > pcgfAJAXRegistrationCheckUsernameMax || value.match(pcgfAJAXRegistrationCheckUsernameRule) === null) { + setInvalid(pcgfAJAXRegistrationCheckUsernameInvalidBoundaries, pcgfAJAXRegistrationCheckUsername, $(this)); + } else { + setLoading(pcgfAJAXRegistrationCheckLoading, pcgfAJAXRegistrationCheckUsername, $(this)); + $.ajax({ + url: pcgfAJAXRegistrationCheckUsernameCheckLink, + type: 'POST', + data: {'search': value}, + success: function(result) { + if (result[0] === 'OK') { + setValid(result[1], pcgfAJAXRegistrationCheckUsername, usernameField); + } else if (result[0] === 'INVALID QUERY') { + setLoading(result[1], pcgfAJAXRegistrationCheckUsername, usernameField); + } else { + setInvalid(result[1], pcgfAJAXRegistrationCheckUsername, usernameField); + } + } + }); + } + }); + usernameField.trigger('keyup'); + var eMailField = $('#email'); + pcgfAJAXRegistrationCheckEMail.insertAfter(eMailField); + eMailField.on('keyup', function() { + passwordField.trigger('keyup'); + var value = $(this).val(); + if (value.match(pcgfAJAXRegistrationCheckEMailRule) === null) { + setInvalid(pcgfAJAXRegistrationCheckEMailInvalid, pcgfAJAXRegistrationCheckEMail, $(this)); + } else { + setLoading(pcgfAJAXRegistrationCheckLoading, pcgfAJAXRegistrationCheckEMail, $(this)); + $.ajax({ + url: pcgfAJAXRegistrationCheckEMailCheckLink, + type: 'POST', + data: {'search': value}, + success: function(result) { + if (result[0] === 'OK') { + setValid(result[1], pcgfAJAXRegistrationCheckEMail, eMailField); + } else if (result[0] === 'INVALID QUERY') { + setLoading(result[1], pcgfAJAXRegistrationCheckEMail, eMailField); + } else { + setInvalid(result[1], pcgfAJAXRegistrationCheckEMail, eMailField); + } + } + }); + } + }); + eMailField.trigger('keyup'); + $('#ucp').on('submit', function() { + if (pcgfAJAXRegistrationCheckUsername.hasClass('invalid') || pcgfAJAXRegistrationCheckEMail.hasClass('invalid') || pcgfAJAXRegistrationCheckPassword.hasClass('invalid') || pcgfAJAXRegistrationCheckConfirmPassword.hasClass('invalid')) { + return false; + } + return true; + }); +});

Re: AJAX Registration Check

Enviado: 03 Mai 2026, 18:39
por Octopus
Olá, testei o AJAX Registration Check na versão 1.0.3 em alemão com phpBB 3.3.15 e PHP 8.3, e notei dois problemas:

1. A barra de força da senha é exibida, mas o texto antes (Força da senha) e depois (fraca/normal/forte) não aparece.
2. Não é exibida nenhuma confirmação indicando se as duas senhas são diferentes ou iguais.

Há alguma ideia de como resolver isso? Na versão original, ambos funcionam normalmente...

Re: AJAX Registration Check

Enviado: 03 Mai 2026, 21:45
por Chico Gois
Vou analisar e corrigir se necessário.
Obrigado por reportar.

Re: AJAX Registration Check

Enviado: 04 Mai 2026, 12:37
por Chico Gois
Olá,

obrigado pelo teste e pelo retorno detalhado.

Sim, consegui reproduzir o problema. Ele não está relacionado diretamente ao alemão, PHP 8.3 ou phpBB 3.3.15, mas sim à forma como algumas mensagens estavam sendo passadas do template para o JavaScript.

Na versão ajustada, algumas strings de idioma usadas dentro do JavaScript não estavam chegando corretamente ao script. Com isso, a barra de força da senha ainda era criada, mas o texto “Força da senha” e os níveis “fraca / normal / forte” ficavam vazios. O mesmo afetava a mensagem de confirmação entre os dois campos de senha.

A correção foi feita passando essas mensagens de idioma de forma segura para o JavaScript, já escapadas corretamente para uso em contexto JS. Também ajustei o evento dos campos de senha para escutar `input`, `keyup`, `change` e `blur`, porque em alguns navegadores ou temas o comportamento pode variar, especialmente com preenchimento automático ou colar texto.

Além disso, aproveitei para revisar a validação de e-mail e atualizar o `composer.json` para uma versão de PHP mais compatível com phpBB 3.3.x.

Em resumo, a correção inclui:

* exibição correta do texto da força da senha;
* exibição correta do nível da senha;
* exibição correta da confirmação quando as senhas coincidem ou são diferentes;
* validação de e-mail revisada;
* compatibilidade declarada no `composer.json` atualizada para phpBB 3.3.x.

Vou disponibilizar uma versão corrigida para novos testes no primeiro tópico.

Obrigado novamente por apontar o problema.

Re: AJAX Registration Check

Enviado: 06 Mai 2026, 08:48
por Octopus
Olá e muito obrigado. Os problemas mencionados desapareceram e agora tudo está funcionando. Como última otimização, o script poderia ser melhorado para que os textos de validação só sejam exibidos após a entrada de dados em um campo. Atualmente, eles aparecem o tempo todo nos campos, mesmo quando ainda não foi digitado nada...

Muitos cumprimentos e obrigado por este trabalho!!

Re: AJAX Registration Check

Enviado: 06 Mai 2026, 09:56
por Octopus
E também notei mais um ponto. Pelo menos na tradução para o alemão, a unidade está faltando após os números. Na explicação dos campos do formulário de registro do phpBB está escrito:

* O nome de usuário deve ter entre 3 e 20 caracteres.
* A senha deve ter no mínimo 8 caracteres e conter letras maiúsculas, minúsculas e números.

Mas a extensão de registro via Ajax escreve:

* O nome de usuário deve ter entre 3 e 20.
* A senha deve ter no mínimo 8 e conter letras maiúsculas, minúsculas e números.

Re: AJAX Registration Check

Enviado: 06 Mai 2026, 10:56
por Chico Gois
Está era uma extensão para phpbb 3.2 ja no repositório do phpBB, apenas atualizei para versão 3.3

Mesmo assim vou verificar.