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.
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> ' + 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"> </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.