<com:TContent ID="Main"> <h1>Creating <tt>EditUser</tt> Page</h1> <p> The <tt>EditUser</tt> page is very similar to the <a href="?page=Day3.CreateNewUser">NewUser</a>. The main difference is that when <tt>EditUser</tt> is initially requested, the input fields should be initialized with existing user information. Another slight difference is that <tt>EditUser</tt> can also be accessed by normal users. </p> <p> To determine which user account is to be editted, we use the following policy: </p> <ul> <li>If the current user is an administrator, he can edit any user account by specifying the account's username in a GET variable named 'username'. For example, <tt>http://hostname/blog/index.php?page=users.EditUser&username=demo</tt>.</li> <li>If the current user is an administrator and the URl does not contain 'username', the administrator himself's data is being updated.</li> <li>If the current user is a normal user, he can only edit his own account information, and he cannot modify his role data.</li> </ul> <p> We create two files <tt>protected/pages/users/EditUser.page</tt> and <tt>protected/pages/users/EditUser.php</tt> to save the page template and page class, respectively. </p> <h2>Creating Page Template</h2> <p> As you may have guessed, the page template <tt>EditUser</tt> is largely the same as that of <tt>NewUser</tt>. Besides the difference in page title and the caption of the submit button, there are three main differences. </p> <ul> <li>The "username" text box is replaced by a <a href="http://www.pradosoft.com/demos/quickstart/?page=Controls.Label">TLabel</a> control because we do not allow modifying username;</li> <li>The validator for the "password" input is removed. This is because if the user does not provide a password during editting, it means the user does not want to change the password.</li> <li>The "role" input is surrounded with <tt>TControl</tt> whose visibility is toggled according to the role of the currently logged-in user. If the user is not an administrator, the "role" input will not be displayed because normal users are not allowed to modify their roles.</li> </ul> </p> <com:TTextHighlighter CssClass="source" Language="prado"> <%@ Title="My Blog - Edit User" %> <com:TContent ID="Main"> <h1>Edit User</h1> <span>Username:</span> <com:TLabel ID="Username" /> <br/> <span>Password:</span> <br/> <com:TTextBox ID="Password" TextMode="Password" /> <br/> <span>Re-type Password:</span> <com:TCompareValidator ControlToValidate="Password" ControlToCompare="Password2" ErrorMessage="Your password entries did not match." Display="Dynamic" /> <br/> <com:TTextBox ID="Password2" TextMode="Password" /> <br/> <span>Email Address:</span> <com:TRequiredFieldValidator ControlToValidate="Email" ErrorMessage="Please provide your email address." Display="Dynamic" /> <com:TEmailAddressValidator ControlToValidate="Email" ErrorMessage="You entered an invalid email address." Display="Dynamic" /> <br/> <com:TTextBox ID="Email" /> <com:TControl Visible="<%= $this->User->IsAdmin %>"> <br/> <span>Role:</span> <br/> <com:TDropDownList ID="Role"> <com:TListItem Text="Normal User" Value="0" /> <com:TListItem Text="Administrator" Value="1" /> </com:TDropDownList> </com:TControl> <br/> <span>First Name:</span> <br/> <com:TTextBox ID="FirstName" /> <br/> <span>Last Name:</span> <br/> <com:TTextBox ID="LastName" /> <br/> <com:TButton Text="Save" OnClick="saveButtonClicked" /> </com:TContent> </com:TTextHighlighter> <h2>Creating Page Class</h2> <p> Based on the above description and template, we need to write a page class that initializes the inputs with the existing user information. In addition, the page class also needs to implement the <tt>saveButtonClicked()</tt> method which is attached to the "save" button's <tt>OnClick</tt> event. </p> <com:TTextHighlighter CssClass="source" Language="php"> class EditUser extends TPage { /** * Initializes the inputs with existing user data. * This method is invoked by the framework when the page is being initialized. * @param mixed event parameter */ public function onInit($param) { parent::onInit($param); if(!$this->IsPostBack) // if the page is initially requested { // Retrieves the existing user data. This is equivalent to: // $userRecord=$this->getUserRecord(); $userRecord=$this->UserRecord; // Populates the input controls with the existing user data $this->Username->Text=$userRecord->username; $this->Email->Text=$userRecord->email; $this->Role->SelectedValue=$userRecord->role; $this->FirstName->Text=$userRecord->first_name; $this->LastName->Text=$userRecord->last_name; } } /** * Saves the user account if all inputs are valid. * This method responds to the OnClick event of the "save" button. * @param mixed event sender * @param mixed event parameter */ public function saveButtonClicked($sender,$param) { if($this->IsValid) // when all validations succeed { // Retrieves the existing user data. This is equivalent to: $userRecord=$this->UserRecord; // Fetches the input data $userRecord->username=$this->Username->Text; // update password when the input is not empty if(!empty($this->Password->Text)) $userRecord->password=$this->Password->Text; $userRecord->email=$this->Email->Text; // update the role if the current user is an administrator if($this->User->IsAdmin) $userRecord->role=(int)$this->Role->SelectedValue; $userRecord->first_name=$this->FirstName->Text; $userRecord->last_name=$this->LastName->Text; // saves to the database via Active Record mechanism $userRecord->save(); // redirects the browser to the homepage $url=$this->Service->constructUrl($this->Service->DefaultPage); $this->Response->redirect($url); } } /** * Returns the user data to be editted. * @return UserRecord the user data to be editted. * @throws THttpException if the user data is not found. */ protected function getUserRecord() { // the user to be editted is the currently logged-in user $username=$this->User->Name; // if the 'username' GET var is not empty and the current user // is an administrator, we use the GET var value instead. if($this->User->IsAdmin && $this->Request['username']!==null) $username=$this->Request['username']; // use Active Record to look for the specified username $userRecord=UserRecord::finder()->findByPk($username); if(!($userRecord instanceof UserRecord)) throw new THttpException(500,'Username is invalid.'); return $userRecord; } } </com:TTextHighlighter> <com:TipBox> The <tt>onInit()</tt> method is invoked by PRADO during one of the <a href="http://www.pradosoft.com/demos/quickstart/?page=Fundamentals.Pages">page lifecycles</a>. Other commonly overriden lifecycle methods include <tt>onPreInit()</tt>, <tt>onLoad()</tt> and <tt>onPreRender()</tt>. </com:TipBox> <h2>Testing</h2> <p> To test the <tt>EditUser</tt> page, visit the URL <tt>http://hostname/blog/index.php?page=users.EditUser&username=demo</tt>. You may be required to login first if you have not done so. Try logging in with different accounts (e.g. admin/demo, demo/demo) and see how the page displays differently. </p> </com:TContent>