Creative Commons Attribution 2.5 License. See
http://www.famfamfam.com/lab/icons/silk/ for more informations.
+- pseudo-throbber.gif files has been generated with http://ajaxload.info/
+ generator and is free for use.
+
===============================================================================
resources.router.routes.user.route = "user/"
resources.router.routes.user.defaults.controller = "user"
resources.router.routes.user.defaults.action = "user"
+; userexists/
+resources.router.routes.userexists.route = "userexists/:name"
+resources.router.routes.userexists.defaults.controller = "user"
+resources.router.routes.userexists.defaults.action = "exists"
; logout/
resources.router.routes.logout.route = "logout/"
resources.router.routes.logout.defaults.controller = "login"
'acceptTermsofuseWarn' => __("You must accept terms of use"),
'emailEmptyWarn' => __("you must enter an email"),
'emailInvalidWarn' => __("invalid email"),
- 'invalidPseudo' => __("pseudo must only contain letters, digits, dots or underscores"),
- 'uniqueUserError' => __("unavailable pseudo"),
'uniqueEmailError' => __("an user is already registered with this email"),
'userSuccess' => __("Account created"),
'newpwdSuccess' => __("A link to reset your password has been emailed to you"),
'canResubmit' => __("Now, you can retry to save"),
'routeBy' => __("route by"),
- 'osmAttribution' => __("Map by <a href='http://openstreetmap.org/'>OpenStreetMap</a>")
+ 'osmAttribution' => __("Map by <a href='http://openstreetmap.org/'>OpenStreetMap</a>"),
+ 'pseudoChecking' => __("checking availibilty"),
+ 'availablePseudo' => __("available pseudo"),
+ 'unavailablePseudo' => __("unavailable pseudo"),
);
}
class UserController extends Zend_Controller_Action
{
+ public function existsAction() {
+ $name = $this->getRequest()->getUserParam('name');
+
+ $userMapper = new Syj_Model_UserMapper();
+ $user = new Syj_Model_User();
+
+ if ($userMapper->findByPseudo($name, $user)) {
+ $this->_helper->SyjApi->setCode(200);
+ } else {
+ // opera needs some body content with 404 code, otherwise, it
+ // reports a xmlhttprequest.status of 0
+ $this->_helper->SyjApi->setCode(404)->setBody(' ');
+ }
+ }
+
public function userAction() {
$formData = $this->_helper->SyjPostData->getPostData('Syj_Form_User');
public function init() {
$translator = $this->getTranslator();
+ $desc = $translator->translate("only letters, numbers, underscores or dots");
$name = array('Text', 'user_pseudo', array(
'label' => __("user name"),
- 'attribs' => array('maxlength' => '20'),
+ 'attribs' => array('maxlength' => '20', 'autocomplete' => 'off'),
+ 'description' => $desc,
'validators' => array(new Zend_Validate_StringLength(0, 20),
new Zend_Validate_Regex('/^[a-zA-Z0-9_\.]+$/')),
'required' => true
msgstr ""
"Project-Id-Version: syj\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-08-11 21:44+0200\n"
+"POT-Creation-Date: 2010-08-12 14:16+0200\n"
"PO-Revision-Date: \n"
"Last-Translator: arno <arno@renevier.net>\n"
"Language-Team: arno <arno@renevier.net>\n"
msgstr "Sources of the software running the website are <a href=\"http://dev.renevier.net/?p=syj.git\">publicly available</a> under a agpl license. The map used to display the routes comes from <a href=\"http://www.openstreetmap.org/\">openstreetmap</a>."
#: application/views/scripts/newpwd/success.phtml:4
-#: application/controllers/IdxController.php:103
+#: application/controllers/IdxController.php:101
msgid "A link to reset your password has been emailed to you"
msgstr "A link to reset your password has been emailed to you"
#: application/controllers/TermsofuseController.php:12
#: application/layouts/scripts/footer.phtml:85
#: application/forms/Geom.php:24
-#: application/forms/User.php:41
+#: application/forms/User.php:43
msgid "terms of use"
msgstr "terms of use"
msgstr "Wrong password"
#: application/controllers/AccountController.php:44
-#: application/controllers/IdxController.php:101
+#: application/controllers/IdxController.php:99
msgid "an user is already registered with this email"
msgstr "an user is already registered with this email"
#: application/controllers/AccountController.php:73
#: application/forms/Account.php:33
-#: application/forms/User.php:18
+#: application/forms/User.php:20
#, php-format
msgid "At least %d characters"
msgstr "At least %d characters"
msgid "invalid email"
msgstr "invalid email"
-#: application/controllers/IdxController.php:99
-msgid "pseudo must only contain letters, digits, dots or underscores"
-msgstr "pseudo must only contain letters, digits, dots or underscores"
-
#: application/controllers/IdxController.php:100
-msgid "unavailable pseudo"
-msgstr "unavailable pseudo"
-
-#: application/controllers/IdxController.php:102
msgid "Account created"
msgstr "Account created"
-#: application/controllers/IdxController.php:104
+#: application/controllers/IdxController.php:102
msgid "Now, you can retry to save"
msgstr "Now, you can retry to save"
-#: application/controllers/IdxController.php:105
+#: application/controllers/IdxController.php:103
msgid "route by"
msgstr "route by"
-#: application/controllers/IdxController.php:106
+#: application/controllers/IdxController.php:104
msgid "Map by <a href='http://openstreetmap.org/'>OpenStreetMap</a>"
msgstr "Map by <a href='http://openstreetmap.org/'>OpenStreetMap</a>"
+#: application/controllers/IdxController.php:105
+msgid "checking availibilty"
+msgstr "checking availibilty"
+
+#: application/controllers/IdxController.php:106
+msgid "available pseudo"
+msgstr "available pseudo"
+
+#: application/controllers/IdxController.php:107
+msgid "unavailable pseudo"
+msgstr "unavailable pseudo"
+
#: application/layouts/scripts/footer.phtml:28
msgid "contact"
msgstr "contact"
#: application/forms/Login.php:10
#: application/forms/Account.php:35
-#: application/forms/User.php:21
+#: application/forms/User.php:23
msgid "password"
msgstr "password"
msgstr "optional title for this journey"
#: application/forms/Geom.php:25
-#: application/forms/User.php:42
+#: application/forms/User.php:44
#, php-format
msgid "I've read and accepted %s"
msgstr "I've read and accepted %s"
msgstr "save"
#: application/forms/Account.php:27
-#: application/forms/User.php:34
+#: application/forms/User.php:36
#: application/forms/Newpwd.php:28
msgid "email"
msgstr "email"
#: application/forms/Account.php:42
-#: application/forms/User.php:28
+#: application/forms/User.php:30
msgid "confirm password"
msgstr "confirm password"
msgid "modify my informations"
msgstr "modify my informations"
-#: application/forms/User.php:11
+#: application/forms/User.php:10
+msgid "only letters, numbers, underscores or dots"
+msgstr "only letters, numbers, underscores or dots"
+
+#: application/forms/User.php:12
msgid "user name"
msgstr "user name"
-#: application/forms/User.php:35
+#: application/forms/User.php:37
msgid "After creating your account, you will receive a confirmation email. You have 7 days to confirm otherwise, your account and your routes will all be deleted."
msgstr "After creating your account, you will receive a confirmation email. You have 7 days to confirm otherwise, your account and your routes will all be deleted."
-#: application/forms/User.php:54
+#: application/forms/User.php:56
msgid "create account"
msgstr "create account"
msgid "To cancel account creation, press following button. The account and all its data will be deleted."
msgstr "To cancel account creation, press following button. The account and all its data will be deleted."
+#~ msgid "pseudo available"
+#~ msgstr "pseudo available"
+#~ msgid "pseudo not available"
+#~ msgstr "pseudo not available"
+#~ msgid "pseudo must only contain letters, digits, dots or underscores"
+#~ msgstr "pseudo must only contain letters, digits, dots or underscores"
#~ msgid "route has been deleted from the server."
#~ msgstr "route has been deleted from the server."
#~ msgid "You need to login before retrying to save"
msgstr ""
"Project-Id-Version: syj\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-08-11 21:44+0200\n"
+"POT-Creation-Date: 2010-08-12 14:16+0200\n"
"PO-Revision-Date: \n"
"Last-Translator: arno <arno@renevier.net>\n"
"Language-Team: arno <arno@renevier.net>\n"
msgstr "Les sources du logiciel qui fait tourner le site web sont <a href=\"http://dev.renevier.net/?p=syj.git\">disponibles publiquement</a> sous une licence agpl. La carte utilisée pour l'affichage des itinéraires vient d'<a href=\"http://www.openstreetmap.org/\">openstreetmap</a>."
#: application/views/scripts/newpwd/success.phtml:4
-#: application/controllers/IdxController.php:103
+#: application/controllers/IdxController.php:101
msgid "A link to reset your password has been emailed to you"
msgstr "Un email contenant un lien pour réinitialiser votre mot de passe vous a été envoyé"
#: application/controllers/TermsofuseController.php:12
#: application/layouts/scripts/footer.phtml:85
#: application/forms/Geom.php:24
-#: application/forms/User.php:41
+#: application/forms/User.php:43
msgid "terms of use"
msgstr "conditions d'utilisation"
msgstr "Mauvais mot de passe"
#: application/controllers/AccountController.php:44
-#: application/controllers/IdxController.php:101
+#: application/controllers/IdxController.php:99
msgid "an user is already registered with this email"
msgstr "il y'a déjà un utilisateur enregistré avec cet email"
#: application/controllers/AccountController.php:73
#: application/forms/Account.php:33
-#: application/forms/User.php:18
+#: application/forms/User.php:20
#, php-format
msgid "At least %d characters"
msgstr "Au moins %d caractères"
msgid "invalid email"
msgstr "email invalide"
-#: application/controllers/IdxController.php:99
-msgid "pseudo must only contain letters, digits, dots or underscores"
-msgstr "le pseudo ne peut contenir que des lettres, des chiffres, des points ou des soulignés"
-
#: application/controllers/IdxController.php:100
-msgid "unavailable pseudo"
-msgstr "pseudo non disponible"
-
-#: application/controllers/IdxController.php:102
msgid "Account created"
msgstr "Compte créé"
-#: application/controllers/IdxController.php:104
+#: application/controllers/IdxController.php:102
msgid "Now, you can retry to save"
msgstr "Maintenant, vous pouvez réessayer de sauvegarder"
-#: application/controllers/IdxController.php:105
+#: application/controllers/IdxController.php:103
msgid "route by"
msgstr "tracé par"
-#: application/controllers/IdxController.php:106
+#: application/controllers/IdxController.php:104
msgid "Map by <a href='http://openstreetmap.org/'>OpenStreetMap</a>"
msgstr "Carte par <a href='http://openstreetmap.org/'>OpenStreetMap</a>"
+#: application/controllers/IdxController.php:105
+msgid "checking availibilty"
+msgstr "vérification de la disponibilité"
+
+#: application/controllers/IdxController.php:106
+msgid "available pseudo"
+msgstr "pseudo disponible"
+
+#: application/controllers/IdxController.php:107
+msgid "unavailable pseudo"
+msgstr "pseudo non disponible"
+
#: application/layouts/scripts/footer.phtml:28
msgid "contact"
msgstr "contact"
#: application/forms/Login.php:10
#: application/forms/Account.php:35
-#: application/forms/User.php:21
+#: application/forms/User.php:23
msgid "password"
msgstr "mot de passe"
msgstr "titre facultatif pour ce trajet"
#: application/forms/Geom.php:25
-#: application/forms/User.php:42
+#: application/forms/User.php:44
#, php-format
msgid "I've read and accepted %s"
msgstr "J'ai lu et accepté les %s"
msgstr "enregistrer"
#: application/forms/Account.php:27
-#: application/forms/User.php:34
+#: application/forms/User.php:36
#: application/forms/Newpwd.php:28
msgid "email"
msgstr "email"
#: application/forms/Account.php:42
-#: application/forms/User.php:28
+#: application/forms/User.php:30
msgid "confirm password"
msgstr "confirmation du mot de passe"
msgid "modify my informations"
msgstr "modifier mes informations"
-#: application/forms/User.php:11
+#: application/forms/User.php:10
+msgid "only letters, numbers, underscores or dots"
+msgstr "seulement des lettres, des chiffres, des soulignés ou des points"
+
+#: application/forms/User.php:12
msgid "user name"
msgstr "nom d'utilisateur"
-#: application/forms/User.php:35
+#: application/forms/User.php:37
msgid "After creating your account, you will receive a confirmation email. You have 7 days to confirm otherwise, your account and your routes will all be deleted."
msgstr "Après la création de votre compte, vous recevrez un mail de confirmation. Vous avez 7 jours pour confirmer sinon, votre compte et tous vos tracés seront supprimés."
-#: application/forms/User.php:54
+#: application/forms/User.php:56
msgid "create account"
msgstr "créer le compte"
msgid "To cancel account creation, press following button. The account and all its data will be deleted."
msgstr "Pour annuler la création du compte, pressez le bouton suivant. Le compte ainsi que toutes ses données seront supprimés."
+#~ msgid "pseudo available"
+#~ msgstr "pseudo disponible"
+#~ msgid "pseudo not available"
+#~ msgstr "pseudo non disponible"
+#~ msgid "pseudo must only contain letters, digits, dots or underscores"
+#~ msgstr ""
+#~ "le pseudo ne peut contenir que des lettres, des chiffres, des points ou "
+#~ "des soulignés"
#~ msgid "You need to login before retrying to save"
#~ msgstr "Vous devez vous connecter avant de réesayer de sauvegarder"
#~ msgid "You need to have cookies enabled to login to SYJ"
return true;
}
+ public function findByPseudo($pseudo, Syj_Model_User $user) {
+ $table = $this->getDbTable();
+ $select = $table->select()->where('pseudo = ?', (string)$pseudo);
+ $row = $table->fetchRow($select);
+ if (!$row) {
+ return false;
+ }
+ $this->_itemFromRow($user, $row);
+ return true;
+ }
+
public function findByEmail($email, Syj_Model_User $user) {
$table = $this->getDbTable();
$select = $table->select()->where('email = ?', (string)$email);
/* This file is part of Syj, Copyright (c) 2010 Arnaud Renevier,
and is published under the AGPL license. */
-Element.addMethods('input', {
- observe : Element.Methods.observe.wrap(function(proceed, element, eventName, handler) {
- if (eventName === "contentchange") {
- proceed(element, 'keyup', function(evt) {
- if (evt.keyCode === 13) {
- return;
- }
- handler.apply(null, arguments);
- });
- proceed(element, 'paste', handler);
- return proceed(element, 'change', handler);
- }
- return proceed(element, eventName, handler);
- })
-});
// avoid openlayers alerts
OpenLayers.Console.userError = function(error) {
},
prepareForm: function(form) {
- if (!loginMgr.logged && !$("geom_accept").checked) {
+ if (!LoginMgr.logged && !$("geom_accept").checked) {
this.messenger.setMessage(SyjStrings.acceptTermsofuseWarn, "warn");
$("geom_accept_container").highlight('#F08080');
$("geom_accept").activate();
evt.stop();
}.bindAsEventListener(this));
+ $("user_pseudo-desc").hide();
+ $("user_pseudo").observe('contentchange', function(evt) {
+ var value = evt.target.value;
+ PseudoChecker.reset();
+ if (value && !(value.match(/^[a-zA-Z0-9_.]+$/))) {
+ $("user_pseudo-desc").show().setMessageStatus("warn");
+ } else {
+ $("user_pseudo-desc").hide();
+ }
+ }).timedobserve(function() {
+ PseudoChecker.check();
+ });
+
$("user_password").observe('contentchange', function(evt) {
if (evt.target.value.length < 6) {
$("user_password-desc").setMessageStatus("warn");
},
presubmit: function() {
+ this.messenger.hide();
+ PseudoChecker.reset();
if (!(this.checkNotEmpty("user_pseudo", SyjStrings.userEmptyWarn))) {
return false;
}
if (!($("user_pseudo").value.match(/^[a-zA-Z0-9_.]+$/))) {
- this.messenger.setMessage(SyjStrings.invalidPseudo, "warn");
+ $("user_pseudo-desc").show().setMessageStatus("warn");
+ $("user_pseudo").highlight('#F08080').activate();
+ return false;
+ }
+
+ if (PseudoChecker.exists[$("user_pseudo").value]) {
+ PseudoChecker.availableMessage(false);
$("user_pseudo").highlight('#F08080').activate();
return false;
}
},
success: function(transport) {
- loginMgr.login();
+ LoginMgr.login();
SYJView.messenger.setMessage(SyjStrings.userSuccess, "success");
this.modalbox.hide();
if (SYJView.needsFormResubmit) {
focusInput = $("user_email");
break;
case "uniquepseudo":
- message = SyjStrings.uniqueUserError;
+ PseudoChecker.availableMessage(false);
focusInput = $("user_pseudo");
break;
case "uniqueemail":
break;
}
- if (message) {
- this.messenger.setMessage(message, "error");
- if (focusInput) {
- focusInput.highlight('#F08080').activate();
+ if (focusInput) {
+ if (message) {
+ this.messenger.setMessage(message, "error");
}
+ focusInput.highlight('#F08080').activate();
return;
}
},
presubmit: function() {
+ this.messenger.hide();
if (!(this.checkNotEmpty("login_user", SyjStrings.userEmptyWarn))) {
return false;
}
success: function(transport) {
if (transport.responseText === "1") {
- loginMgr.login(true);
+ LoginMgr.login(true);
} else {
- loginMgr.login();
+ LoginMgr.login();
}
SYJView.messenger.setMessage(SyjStrings.loginSuccess, "success");
this.modalbox.hide();
});
var SYJNewpwd = new SYJNewpwdClass();
-var loginMgr = Object.extend(gLoggedInfo, {
+var LoginMgr = Object.extend(gLoggedInfo, {
controlsdeck: null,
updateUI: function() {
}
});
+var PseudoChecker = {
+ req: null,
+ exists: {},
+ currentvalue: null,
+ messageelt: null,
+ throbber: null,
+
+ message: function(str, status, throbber) {
+ var row;
+ if (!this.messageelt) {
+ row = new Element('tr');
+ // we can't use row.update('<td></td><td><div></div></td>')
+ // because gecko would mangle the <td>s
+ row.insert(new Element('td'))
+ .insert((new Element('td')).update(new Element('div')));
+
+ $("user_pseudo").up('tr').insert({after: row});
+ this.messageelt = new Element('span');
+ this.throbber = new Element("img", { src: "icons/pseudo-throbber.gif"});
+ row.down('div').insert(this.throbber).insert(this.messageelt);
+ }
+ if (throbber) {
+ this.throbber.show();
+ } else {
+ this.throbber.hide();
+ }
+ this.messageelt.up().setStyle({visibility: ''});
+ this.messageelt.className = status;
+ this.messageelt.update(str);
+ },
+
+ availableMessage: function(available) {
+ var message = available ? SyjStrings.availablePseudo: SyjStrings.unavailablePseudo,
+ status = available ? "success": "warn";
+ this.message(message, status, false);
+ },
+
+ reset: function() {
+ if (this.req) {
+ this.req.abort();
+ this.req = this.currentvalue = null;
+ }
+ if (this.messageelt) {
+ this.messageelt.up().setStyle({visibility: 'hidden'});
+ }
+ },
+
+ check: function() {
+ var pseudo = $("user_pseudo").value;
+
+ this.reset();
+
+ if (!pseudo || !(pseudo.match(/^[a-zA-Z0-9_.]+$/))) {
+ return;
+ }
+
+ if (typeof this.exists[pseudo] === "boolean") {
+ this.reset();
+ this.availableMessage(!this.exists[pseudo]);
+ return;
+ }
+
+ this.message(SyjStrings.pseudoChecking, "", true);
+
+ this.currentvalue = pseudo;
+ this.req = new Ajax.TimedRequest('userexists/' + encodeURIComponent(pseudo), 20, {
+ onFailure: this.failure.bind(this),
+ onSuccess: this.success.bind(this)
+ });
+ },
+
+ failure: function(transport) {
+ var httpCode = 0, value = this.currentvalue;
+
+ if (transport) {
+ httpCode = transport.getStatus();
+ }
+ this.reset();
+ if (httpCode === 404) {
+ this.exists[value] = false;
+ this.availableMessage(true);
+ }
+
+ },
+
+ success: function(transport) {
+ var httpCode = transport.getStatus(), value = this.currentvalue;
+ this.reset();
+ this.exists[value] = true;
+ this.availableMessage(false);
+ }
+};
+
+
document.observe("dom:loaded", function() {
SYJLogin.init();
SYJUser.init();
SYJView.init();
SYJNewpwd.init();
- loginMgr.updateUI();
+ LoginMgr.updateUI();
});
initialize: function($super, url, delay, options) {
this.delay = delay;
+ if (!options) {
+ options = {};
+ }
- options.onSuccess = options.onSuccess.wrap(function(proceed, transport, json) {
+ options.onSuccess = options.onSuccess &&
+ options.onSuccess.wrap(function(proceed, transport, json) {
if (this.timeout) {
window.clearTimeout(this.timeout);
this.timeout = null;
}
}).bind(this);
- options.onFailure = options.onFailure.wrap(function(proceed, transport, json) {
+ options.onFailure = options.onFailure &&
+ options.onFailure.wrap(function(proceed, transport, json) {
if (this.timeout) {
window.clearTimeout(this.timeout);
this.timeout = null;
request: function($super, url) {
this.timeout = (function() {
- this.options.onFailure(null);
+ if (this.options.onFailure) {
+ this.options.onFailure(null);
+ }
this.abort();
}).bind(this).delay(this.delay);
$super(url);
after: new Element("div", {className: 'error'}).update(errorMessage)
});
return false;
+ },
+
+ observe : Element.Methods.observe.wrap(function(proceed, element, eventName, handler) {
+ if (eventName === "contentchange") {
+ proceed(element, 'keyup', function(evt) {
+ if (evt.keyCode === 13) {
+ return;
+ }
+ handler.apply(null, arguments);
+ });
+ proceed(element, 'paste', handler);
+ return proceed(element, 'change', handler);
+ }
+ return proceed(element, eventName, handler);
+ }),
+
+ timedobserve: function(element, callback, delay) {
+ var timeout = null, initialvalue = element.value;
+
+ if (typeof delay !== "number") {
+ delay = 0.5;
+ }
+ delay = delay * 1000;
+
+ var canceltimer = function() {
+ if (timeout) {
+ clearTimeout(timeout);
+ timeout = null;
+ }
+ };
+ var resettimer = function() {
+ canceltimer();
+ timeout = setTimeout(triggercallback, delay);
+ };
+ var triggercallback = function() {
+ canceltimer();
+ if (initialvalue !== element.value) {
+ initialvalue = element.value;
+ callback.call(element);
+ }
+ };
+
+ element.observe('blur', triggercallback).
+ observe('keyup', resettimer).
+ observe('paste', resettimer);
+ return element;
}
});