* @copyright 2001-2007 VIKO team and contributors * @license http://www.gnu.org/licenses/gpl.html GPL 2.0 */ require_once 'Module.php'; require_once 'FormList.php'; require_once 'HTML.php'; require_once 'HTML/QuickForm.php'; require_once 'HTML/QuickForm/Renderer/VIKO.php'; /** * Manages registering new students * * */ class Module_Register extends Module { /** * Constructs new Register Module * * @param array $parameters parameters to the module */ function Module_Register( $parameters ) { if ( isset($parameters[0]) && (int)$parameters[0] > 0 ) { $this->_school =& new School( (int)$parameters[0] ); } } /** * Returns the module identifier string * * @access public * @static * @return string Identificator of module */ function getID() { return "register"; } /** * Returns Register page in HTML * * @return string HTML fragment */ function toHTML() { // if school is chosen, then try to load it from database // if the school does not exist, show error message if ( isset( $this->_school ) ) { if ( !$this->_school->loadFromDatabaseByID() ) { return $this->errorPage( _("The school you have chosen does not exist.") ); } // show registration page for selected school return $this->_registerUser(); } else { // no school is chosen, so ask user to select one return $this->_selectSchool(); } } /** * Returns page with form for selecting school * * When user selects a school, then redirects to the /register/#school_id. * Also performs an immediate redirect, when there exists only one school. * * @access private * @return string HTML fragment */ function _selectSchool() { // check, that this module is enabled - if not, show error if ( !Configuration::getAllowRegistration() ) { return $this->accessDeniedPage( _("Registration of students has been disabled.") ); } $school_count = $this->_getNrOfSchools(); if ( $school_count == 0 ) { // show error, indicating that there are no schools in VIKO return $this->errorPage( _("There are no schools in VIKO to choose form.") ); } elseif ( $school_count == 1 ) { // perform a redirect, if there is only one school to choose from $school_id = $this->_getFirstSchoolID(); $this->redirect("register", $school_id ); return false; } // create form for selecting school $school_select_form = $this->_createSchoolSelectForm(); // if the user has selected a school, perform redirect if ( $school_select_form->validate() ) { $school_id = $school_select_form->exportValue("school_id"); $this->redirect( "register", $school_id ); return false; } // present the form to the user $html = $this->title( _("User registration: select school") ); $html.= HTML_QuickForm_Renderer_VIKO::render( $school_select_form ); $html.= HTML::backLink( $this->URI(), _("Return to the front page of VIKO"), STANDALONE ); return $html; } /** * Returns HTML_QuickForm form for selecting school * * @access private * @return HTML_QuickForm */ function _createSchoolSelectForm() { $form =& new HTML_QuickForm(); $school_list = $this->_getArrayOfSchools(); $form->addElement( 'select', 'school_id', _("School") . ':', $school_list, array( 'id'=>'school_id' ) ); $form->addElement( 'submit', 'submit', _("Choose") ); return $form; } /** * Returns associative array of school ID-s and names for all schools in VIKO * * Only these schools are included to the list, where forms exist. * * @access private * @return array all schools */ function _getArrayOfSchools() { $db = DBInstance::get(); $order_by = DBUtils::createOrderBy( array( "school_name" ) ); $result = $db->query(" SELECT Schools.school_id, school_name FROM Schools RIGHT JOIN Forms USING(school_id) $order_by "); if ( PEAR::isError( $result ) ) { trigger_error( $result->getMessage(), E_USER_ERROR ); } $school_list = array(); while ( $result->fetchInto( $school ) ) { $school_list[ $school["school_id"] ] = $school["school_name"]; } return $school_list; } /** * Returns ID of the only school in VIKO * * Actually this method returns the ID of first school (with forms) in Schools table. * This method is used after is checked, that there is only one school in VIKO. * * @access private * @return mixed */ function _getFirstSchoolID() { // get the ID of school and return it $db = DBInstance::get(); $school_id = $db->getOne(" SELECT Schools.school_id FROM Schools RIGHT JOIN Forms USING(school_id) LIMIT 1 "); if ( PEAR::isError( $school_id ) ) { trigger_error( $school_id->getMessage(), E_USER_ERROR ); } return $school_id; } /** * Returns the number of schools that have at least one form in VIKO * * @access private * @return int school count */ function _getNrOfSchools() { $db = DBInstance::get(); $count = $db->getOne(" SELECT COUNT(*) FROM Schools RIGHT JOIN Forms USING(school_id) "); if ( PEAR::isError( $count ) ) { trigger_error( $count->getMessage(), E_USER_ERROR ); } return $count; } /** * Shows form that allows user to register to school as student * * @access private * @return string HTML fragment */ function _registerUser() { // create the HTML form $register_form = $this->_createRegistrationForm(); // set default heading for the page $html = $this->title( _("User registration: student data") ); // if the form is correctly filled in, add new user to database if ( $register_form->validate() ) { if ( $this->_registerNewStudent( $register_form ) ) { // on successful registration congratulate the user $html = $this->title( _("Registration successful!") ); $html.= HTML::notice( _("You have successfully registered as new VIKO user.") ); $html.= HTML::p( _("You may now go to the front page of VIKO and log in.") ); $html.= HTML::backLink( $this->URI(), _("Return to the front page of VIKO"), STANDALONE ); return $html; } else { // if registration somehow fails at this point, show error message // and ask the user to try again $html .= HTML::error( _("Sorry, but registering your account failed. Please try again, maybe it succeeds this time.") ); } } // render the form and other parts of the page to HTML $html.= HTML_QuickForm_Renderer_VIKO::render( $register_form ); $html.= HTML::backLink( $this->URI(), _("Return to the front page of VIKO"), STANDALONE ); return $html; } /** * Adds new user to database * * @access private * @param HTML_QuickForm $form * @return bool true on successful registration, false, when error accoured */ function _registerNewStudent( &$form ) { $user =& new User(); $user->setFirstName( $form->exportValue("firstname") ); $user->setLastName( $form->exportValue("lastname") ); $user->setUsername( $form->exportValue("username") ); $user->setEmail( $form->exportValue("email") ); $user->setSchool( $this->_school ); $school_form =& new Form( $form->exportValue("form") ); $user->setForm( $school_form ); $user->setGroup( "STUDENT" ); $user->setPassword( $form->exportValue("password") ); return $user->save(); } /** * Returns HTML_QuickForm form for entering student data * * @access private * @return HTML_QuickForm */ function _createRegistrationForm() { $form =& new HTML_QuickForm(); $this->_addFirstAndLastNameField( $form ); $this->_addUsernameField( $form ); $this->_addSchoolField( $form ); $this->_addFormField( $form ); $this->_addEmailField( $form ); $this->_addPasswordField( $form ); $form->addElement( 'submit', 'submit', _("Register") ); return $form; } /** * Adds fields for first- and last name to form * * @access private * @param HTML_QuickForm $form */ function _addFirstAndLastNameField( &$form ) { $form->addElement( 'text', 'firstname', _("Firstname") . ':', array( 'id'=>'firstname' ) ); $form->addElement( 'text', 'lastname', _("Lastname") . ':', array( 'id'=>'lastname' ) ); // all these fields are required $form->addRule( 'firstname', _("Every person must have a first name."), 'required' ); $form->addRule( 'lastname', _("Every person must have a last name."), 'required' ); } /** * Adds field for username to form * * @access private * @param HTML_QuickForm $form */ function _addUsernameField( &$form ) { $form->addElement( 'text', 'username', _("Username") . ':', array( 'id'=>'username' ) ); // username is certainly required, has to be unique and // contain only limited set of characters $form->addRule( 'username', _("All users need a username."), 'required' ); $form->addRule( 'username', _("Username may only consist of characters a-z, A-Z, 0-9, _ and -."), 'regex', '/^[a-zA-Z0-9_-]+$/' ); $form->registerRule('uniqueUsername', 'callback', '_checkUniquenessOfUsername', 'Module_Register'); $form->addRule( 'username', _("This username is already in use - choose another."), 'uniqueUsername' ); } /** * Adds field for e-mail to form * * @access private * @param HTML_QuickForm $form */ function _addEmailField( &$form ) { $form->addElement( 'text', 'email', _("E-mail") . ':', array( 'id'=>'email' ) ); // e-mail is not required, but has to be in correct form $form->addRule( 'email', _("This is not a correct e-mail address."), 'email' ); } /** * Adds field for school to form * * This static field will have the value of selected school. * * @access private * @param HTML_QuickForm $form */ function _addSchoolField( &$form ) { $form->addElement( 'static', 'school', _("School") . ':', $this->_school->getHTMLName() ); } /** * Adds field for school form to HTML form * * @access private * @param HTML_QuickForm $form */ function _addFormField( &$form ) { $form_list = FormList::getFormsSelectBox( $this->_school ); $form->addElement( 'select', 'form', _("Form") . ':', $form_list, array( 'id'=>'form' ) ); } /** * Adds fields for password to form * * @access private * @param HTML_QuickForm $form */ function _addPasswordField( &$form ) { $form->addElement( 'password', 'password', _("Password") . ':', array( 'id'=>'password' ) ); $form->addElement( 'password', 'password-repeat', _("Repeat password") . ':', array( 'id'=>'password-repeat' ) ); // both password fields are required $form->addRule( 'password', _("This field is required"), 'required' ); $form->addRule( 'password-repeat', _("This field is required"), 'required' ); // the password must match with repeated new password $form->addRule( array('password', 'password-repeat'), _("The passwords do not match."), 'compare' ); // password must contain at least 5 characters $form->addRule( 'password', _("Password must be at least 5 characters long."), 'minlength', 5 ); // only ASCII characters are allowed $form->addRule( 'password', _("Password may only contain characters from the ASCII range."), 'regex', '/^[\x20-\x7E]+$/' ); } /** * Checks if username is unique (if changed) * * If username was not changed in the form, returns true. * If the change was made, but the username already exists, returns false. * Else returns true. * * @access private * @param string $username username to validate * @return bool */ function _checkUniquenessOfUsername( $username ) { $db = DBInstance::get(); $username_exists = (bool) $db->getOne( "SELECT COUNT(username) FROM Users WHERE username=?", array( $username ) ); return !$username_exists; } } ?>