diff options
Diffstat (limited to 'demos/blog-tutorial/samples')
28 files changed, 769 insertions, 8 deletions
diff --git a/demos/blog-tutorial/samples/day1/blog/protected/layouts/MainLayout.tpl b/demos/blog-tutorial/samples/day1/blog/protected/layouts/MainLayout.tpl index 5218b98d..6e264936 100644 --- a/demos/blog-tutorial/samples/day1/blog/protected/layouts/MainLayout.tpl +++ b/demos/blog-tutorial/samples/day1/blog/protected/layouts/MainLayout.tpl @@ -12,7 +12,7 @@  </div>
  <div id="footer">
 -Powered by <%= PRADO::poweredByPrado() %>
 +<%= PRADO::poweredByPrado() %>
  </div>
  </com:TForm>
 diff --git a/demos/blog-tutorial/samples/day2/blog/protected/data/blog.db b/demos/blog-tutorial/samples/day2/blog/protected/data/blog.db Binary files differindex 37449fd3..46e82bfb 100644 --- a/demos/blog-tutorial/samples/day2/blog/protected/data/blog.db +++ b/demos/blog-tutorial/samples/day2/blog/protected/data/blog.db diff --git a/demos/blog-tutorial/samples/day2/blog/protected/database/PostRecord.php b/demos/blog-tutorial/samples/day2/blog/protected/database/PostRecord.php index 31451b30..a761286a 100644 --- a/demos/blog-tutorial/samples/day2/blog/protected/database/PostRecord.php +++ b/demos/blog-tutorial/samples/day2/blog/protected/database/PostRecord.php @@ -1,6 +1,6 @@  <?php
  /**
 - * Auto generated by prado-cli.php on 2007-04-06 08:42:12.
 + * Auto generated by prado-cli.php on 2007-04-07 10:44:20.
   */
  class PostRecord extends TActiveRecord
  {
 @@ -15,6 +15,8 @@ class PostRecord extends TActiveRecord  	public $title;  	public $content; + +	public $status;  	public static function finder($className=__CLASS__)
 diff --git a/demos/blog-tutorial/samples/day2/blog/protected/database/UserRecord.php b/demos/blog-tutorial/samples/day2/blog/protected/database/UserRecord.php index 2f657cd8..87043894 100644 --- a/demos/blog-tutorial/samples/day2/blog/protected/database/UserRecord.php +++ b/demos/blog-tutorial/samples/day2/blog/protected/database/UserRecord.php @@ -1,6 +1,6 @@  <?php
  /**
 - * Auto generated by prado-cli.php on 2007-04-06 08:42:08.
 + * Auto generated by prado-cli.php on 2007-04-07 10:44:25.
   */
  class UserRecord extends TActiveRecord
  {
 diff --git a/demos/blog-tutorial/samples/day2/blog/protected/layouts/MainLayout.tpl b/demos/blog-tutorial/samples/day2/blog/protected/layouts/MainLayout.tpl index 5218b98d..6e264936 100644 --- a/demos/blog-tutorial/samples/day2/blog/protected/layouts/MainLayout.tpl +++ b/demos/blog-tutorial/samples/day2/blog/protected/layouts/MainLayout.tpl @@ -12,7 +12,7 @@  </div>
  <div id="footer">
 -Powered by <%= PRADO::poweredByPrado() %>
 +<%= PRADO::poweredByPrado() %>
  </div>
  </com:TForm>
 diff --git a/demos/blog-tutorial/samples/day2/blog/protected/schema.sql b/demos/blog-tutorial/samples/day2/blog/protected/schema.sql index 085e47c3..d3189b40 100644 --- a/demos/blog-tutorial/samples/day2/blog/protected/schema.sql +++ b/demos/blog-tutorial/samples/day2/blog/protected/schema.sql @@ -1,8 +1,8 @@  /* create users table */
  CREATE TABLE users (
    username      VARCHAR(128) NOT NULL PRIMARY KEY,
 -  email         VARCHAR(128) NOT NULL UNIQUE,
 -  password      VARCHAR(128) NOT NULL,  /* plain text password */
 +  email         VARCHAR(128) NOT NULL,
 +  password      VARCHAR(128) NOT NULL,  /* in plain text */
    role          INTEGER NOT NULL,       /* 0: normal user, 1: administrator */
    first_name    VARCHAR(128),
    last_name     VARCHAR(128)
 @@ -14,10 +14,11 @@ CREATE TABLE posts (    author        VARCHAR(128) NOT NULL,  /* references users.username */
    create_time   INTEGER NOT NULL,       /* UNIX timestamp */
    title         VARCHAR(256) NOT NULL,  /* title of the post */
 -  content       TEXT NOT NULL           /* content of the post */
 +  content       TEXT NOT NULL,          /* content of the post */
 +  status		INTEGER NOT NULL		/* 0: published; 1: draft; 2: pending; 2: denied */
  );
  /* insert some initial data records for testing */
  INSERT INTO users VALUES ('admin', 'admin@example.com', 'demo', 1, 'Qiang', 'Xue');
  INSERT INTO users VALUES ('demo', 'demo@example.com', 'demo', 0, 'Wei', 'Zhuo');
 -INSERT INTO posts VALUES (NULL, 'admin', 1175708482, 'first post', 'this is my first post');
 +INSERT INTO posts VALUES (NULL, 'admin', 1175708482, 'first post', 'this is my first post', 0);
 diff --git a/demos/blog-tutorial/samples/day3/blog/index.php b/demos/blog-tutorial/samples/day3/blog/index.php new file mode 100644 index 00000000..8132899e --- /dev/null +++ b/demos/blog-tutorial/samples/day3/blog/index.php @@ -0,0 +1,23 @@ +<?php
 +
 +$frameworkPath='D:\wwwroot\prado3\framework\prado.php';
 +
 +// The following directory checks may be removed if performance is required
 +$basePath=dirname(__FILE__);
 +$assetsPath=$basePath.'/assets';
 +$runtimePath=$basePath.'/protected/runtime';
 +
 +if(!is_file($frameworkPath))
 +	die("Unable to find prado framework path $frameworkPath.");
 +if(!is_writable($assetsPath))
 +	die("Please make sure that the directory $assetsPath is writable by Web server process.");
 +if(!is_writable($runtimePath))
 +	die("Please make sure that the directory $runtimePath is writable by Web server process.");
 +
 +
 +require_once($frameworkPath);
 +
 +$application=new TApplication;
 +$application->run();
 +
 +?>
\ No newline at end of file diff --git a/demos/blog-tutorial/samples/day3/blog/protected/.htaccess b/demos/blog-tutorial/samples/day3/blog/protected/.htaccess new file mode 100644 index 00000000..3418e55a --- /dev/null +++ b/demos/blog-tutorial/samples/day3/blog/protected/.htaccess @@ -0,0 +1 @@ +deny from all
\ No newline at end of file diff --git a/demos/blog-tutorial/samples/day3/blog/protected/BlogUser.php b/demos/blog-tutorial/samples/day3/blog/protected/BlogUser.php new file mode 100644 index 00000000..6b9e0a23 --- /dev/null +++ b/demos/blog-tutorial/samples/day3/blog/protected/BlogUser.php @@ -0,0 +1,59 @@ +<?php
 +
 +// Include TDbUserManager.php file which defines TDbUser
 +Prado::using('System.Security.TDbUserManager');
 +
 +/**
 + * BlogUser Class.
 + * BlogUser represents the user data that needs to be kept in session.
 + * Default implementation keeps username and role information.
 + */
 +class BlogUser extends TDbUser
 +{
 +	/**
 +	 * Creates a BlogUser object based on the specified username.
 +	 * This method is required by TDbUser. It checks the database
 +	 * to see if the specified username is there. If so, a BlogUser
 +	 * object is created and initialized.
 +	 * @param string the specified username
 +	 * @return BlogUser the user object, null if username is invalid.
 +	 */
 +	public function createUser($username)
 +	{
 +		// use UserRecord Active Record to look for the specified username
 +		$userRecord=UserRecord::finder()->findByPk($username);
 +		if($userRecord instanceof UserRecord) // if found
 +		{
 +			$user=new BlogUser($this->Manager);
 +			$user->Name=$username;  // set username
 +			$user->Roles=($userRecord->role==1?'admin':'user'); // set role
 +			$user->IsGuest=false;   // the user is not a guest
 +			return $user;
 +		}
 +		else
 +			return null;
 +	}
 +
 +	/**
 +	 * Checks if the specified (username, password) is valid.
 +	 * This method is required by TDbUser.
 +	 * @param string username
 +	 * @param string password
 +	 * @return boolean whether the username and password are valid.
 +	 */
 +	public function validateUser($username,$password)
 +	{
 +		// use UserRecord Active Record to look for the (username, password) pair.
 +		return UserRecord::finder()->findBy_username_AND_password($username,$password)!==null;
 +	}
 +
 +	/**
 +	 * @return boolean whether this user is an administrator.
 +	 */
 +	public function getIsAdmin()
 +	{
 +		return $this->isInRole('admin');
 +	}
 +}
 +
 +?>
\ No newline at end of file diff --git a/demos/blog-tutorial/samples/day3/blog/protected/application.xml b/demos/blog-tutorial/samples/day3/blog/protected/application.xml new file mode 100644 index 00000000..785f3608 --- /dev/null +++ b/demos/blog-tutorial/samples/day3/blog/protected/application.xml @@ -0,0 +1,55 @@ +<?xml version="1.0" encoding="utf-8"?>
 +
 +<application id="blog" mode="Debug">
 +  <paths>
 +    <using namespace="Application.database.*" />
 +  </paths>
 +
 +  <!-- configurations for modules -->
 +  <modules>
 +    <!-- Remove this comment mark to enable caching
 +    <module id="cache" class="System.Caching.TDbCache" />
 +    -->
 +
 +    <!-- Remove this comment mark to enable PATH url format
 +    <module id="request" class="THttpRequest" UrlFormat="Path" />
 +    -->
 +
 +    <!-- Remove this comment mark to enable logging
 +    <module id="log" class="System.Util.TLogRouter">
 +      <route class="TBrowserLogRoute" Categories="System" />
 +    </module>
 +    -->
 +    <module id="db" class="System.Data.TDataSourceConfig">
 +      <database ConnectionString="sqlite:protected/data/blog.db" />
 +    </module>
 +    
 +    <module 
 +      class="System.Data.ActiveRecord.TActiveRecordConfig" 
 +      ConnectionID="db" />
 + 
 +    <module id="auth"
 +      class="System.Security.TAuthManager"
 +      UserManager="users" 
 +      LoginPage="users.LoginUser" />
 +
 +    <module id="users"
 +      class="System.Security.TDbUserManager"
 +      UserClass="Application.BlogUser" />
 +
 +  </modules>
 +
 +  <!-- configuration for available services -->
 +  <services>
 +    <service id="page" class="TPageService" DefaultPage="Home">
 +      <pages MasterClass="Application.layouts.MainLayout" />
 +    </service>
 +  </services>
 +
 +  <!-- application parameters
 +  <parameters>
 +    <parameter id="param1" value="value1" />
 +    <parameter id="param2" value="value2" />
 +  </parameters>
 +  -->
 +</application>
\ No newline at end of file diff --git a/demos/blog-tutorial/samples/day3/blog/protected/data/blog.db b/demos/blog-tutorial/samples/day3/blog/protected/data/blog.db Binary files differnew file mode 100644 index 00000000..37449fd3 --- /dev/null +++ b/demos/blog-tutorial/samples/day3/blog/protected/data/blog.db diff --git a/demos/blog-tutorial/samples/day3/blog/protected/database/PostRecord.php b/demos/blog-tutorial/samples/day3/blog/protected/database/PostRecord.php new file mode 100644 index 00000000..a761286a --- /dev/null +++ b/demos/blog-tutorial/samples/day3/blog/protected/database/PostRecord.php @@ -0,0 +1,27 @@ +<?php
 +/**
 + * Auto generated by prado-cli.php on 2007-04-07 10:44:20.
 + */
 +class PostRecord extends TActiveRecord
 +{
 +	const TABLE='posts';
 +
 +	public $post_id; + +	public $author; + +	public $create_time; + +	public $title; + +	public $content; + +	public $status; +
 +
 +	public static function finder($className=__CLASS__)
 +	{
 +		return parent::finder($className);
 +	}
 +}
 +?>
\ No newline at end of file diff --git a/demos/blog-tutorial/samples/day3/blog/protected/database/UserRecord.php b/demos/blog-tutorial/samples/day3/blog/protected/database/UserRecord.php new file mode 100644 index 00000000..87043894 --- /dev/null +++ b/demos/blog-tutorial/samples/day3/blog/protected/database/UserRecord.php @@ -0,0 +1,27 @@ +<?php
 +/**
 + * Auto generated by prado-cli.php on 2007-04-07 10:44:25.
 + */
 +class UserRecord extends TActiveRecord
 +{
 +	const TABLE='users';
 +
 +	public $username; + +	public $email; + +	public $password; + +	public $role; + +	public $first_name; + +	public $last_name; +
 +
 +	public static function finder($className=__CLASS__)
 +	{
 +		return parent::finder($className);
 +	}
 +}
 +?>
\ No newline at end of file diff --git a/demos/blog-tutorial/samples/day3/blog/protected/layouts/MainLayout.php b/demos/blog-tutorial/samples/day3/blog/protected/layouts/MainLayout.php new file mode 100644 index 00000000..46c1483d --- /dev/null +++ b/demos/blog-tutorial/samples/day3/blog/protected/layouts/MainLayout.php @@ -0,0 +1,19 @@ +<?php
 +
 +class MainLayout extends TTemplateControl
 +{
 +	/**
 +	 * Logs out a user.
 +	 * This method responds to the "logout" button's OnClick event.
 +	 * @param mixed event sender
 +	 * @param mixed event parameter
 +	 */
 +	public function logoutButtonClicked($sender,$param)
 +	{
 +		$this->Application->getModule('auth')->logout();
 +		$url=$this->Service->constructUrl($this->Service->DefaultPage);
 +		$this->Response->redirect($url);
 +	}
 +}
 +
 +?>
\ No newline at end of file diff --git a/demos/blog-tutorial/samples/day3/blog/protected/layouts/MainLayout.tpl b/demos/blog-tutorial/samples/day3/blog/protected/layouts/MainLayout.tpl new file mode 100644 index 00000000..89538ab2 --- /dev/null +++ b/demos/blog-tutorial/samples/day3/blog/protected/layouts/MainLayout.tpl @@ -0,0 +1,29 @@ +<html>
 +<com:THead />
 +<body>
 +<com:TForm>
 + 
 +<div id="header">
 +<h1>My PRADO Blog</h1>
 +</div>
 + 
 +<div id="main">
 +<com:TContentPlaceHolder ID="Main" />
 +</div>
 + 
 +<div id="footer">
 +<com:THyperLink Text="Login" 
 +	NavigateUrl="<%= $this->Service->constructUrl('users.LoginUser') %>"
 +	Visible="<%= $this->User->IsGuest %>" />
 +
 +<com:TLinkButton Text="Logout" 
 +	OnClick="logoutButtonClicked"
 +	Visible="<%= !$this->User->IsGuest %>" />
 +
 +<br/>
 +<%= PRADO::poweredByPrado() %>
 +</div>
 + 
 +</com:TForm>
 +</body>
 +</html>
\ No newline at end of file diff --git a/demos/blog-tutorial/samples/day3/blog/protected/pages/Contact.page b/demos/blog-tutorial/samples/day3/blog/protected/pages/Contact.page new file mode 100644 index 00000000..c36149ca --- /dev/null +++ b/demos/blog-tutorial/samples/day3/blog/protected/pages/Contact.page @@ -0,0 +1,47 @@ +<%@ Title="My Blog - Contact" %>
 + 
 +<com:TContent ID="Main">
 + 
 +<h1>Contact</h1>
 +<p>Please fill out the following form to let me know your feedback on my blog. Thanks!</p>
 +
 +<span>Your Name:</span>
 +<com:TRequiredFieldValidator ControlToValidate="Name"
 +	ErrorMessage="Please provide your name." 
 +	Display="Dynamic"
 +	/>
 +<br/>
 +<com:TTextBox ID="Name" />
 +
 +<br/>
 +
 +<span>Your Email:</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" />
 +
 +<br/>
 +
 +<span>Feedback:</span>
 +<com:TRequiredFieldValidator ControlToValidate="Feedback"
 +	ErrorMessage="Please provide your feedback." 
 +	Display="Dynamic"
 +	/>
 +<br/>
 +<com:TTextBox ID="Feedback" 
 +	TextMode="MultiLine" 
 +	Rows="10"
 +	Columns="40" />
 +
 +<br/>
 +
 +<com:TButton Text="Submit" OnClick="submitButtonClicked" />
 +
 +</com:TContent>
\ No newline at end of file diff --git a/demos/blog-tutorial/samples/day3/blog/protected/pages/Contact.php b/demos/blog-tutorial/samples/day3/blog/protected/pages/Contact.php new file mode 100644 index 00000000..b6ce575e --- /dev/null +++ b/demos/blog-tutorial/samples/day3/blog/protected/pages/Contact.php @@ -0,0 +1,30 @@ +<?php
 +
 +class Contact extends TPage
 +{
 +	/**
 +	 * Event handler for the OnClick event of the submit button.
 +	 * @param TButton the button triggering the event
 +	 * @param TEventParameter event parameter (null here)
 +	 */
 +	public function submitButtonClicked($sender, $param)
 +	{
 +		if ($this->IsValid)  // check if input validation is successful
 +		{
 +			// obtain the user name, email, feedback from the textboxes
 +			$name = $this->Name->Text;
 +			$email = $this->Email->Text;
 +			$feedback = $this->Feedback->Text;
 +
 +			// send an email to administrator with the above information
 +			$this->mailFeedback($name, $email, $feedback);
 +		}
 +	}
 +
 +	protected function mailFeedback($name, $email, $feedback)
 +	{
 +		// implementation of sending the feedback email
 +	}
 +}
 +
 +?>
\ No newline at end of file diff --git a/demos/blog-tutorial/samples/day3/blog/protected/pages/Home.page b/demos/blog-tutorial/samples/day3/blog/protected/pages/Home.page new file mode 100644 index 00000000..7a9c4a7d --- /dev/null +++ b/demos/blog-tutorial/samples/day3/blog/protected/pages/Home.page @@ -0,0 +1,7 @@ +<%@ Title="Welcome to PRADO" %>
 +
 +<com:TContent ID="Main">
 +
 +<h1>Welcome to PRADO!</h1>
 +
 +</com:TContent>
\ No newline at end of file diff --git a/demos/blog-tutorial/samples/day3/blog/protected/pages/users/AdminUser.page b/demos/blog-tutorial/samples/day3/blog/protected/pages/users/AdminUser.page new file mode 100644 index 00000000..af03b858 --- /dev/null +++ b/demos/blog-tutorial/samples/day3/blog/protected/pages/users/AdminUser.page @@ -0,0 +1,40 @@ +<%@ Title="My Blog - Manage User Accounts" %>
 +
 +<com:TContent ID="Main">
 + 
 +<h1>Manage User Accounts</h1>
 +
 +<a href="<%= $this->Service->constructUrl('users.NewUser')%>">Create New User</a>
 +<br/>
 +
 +<com:TDataGrid ID="UserGrid"
 +    DataKeyField="username"
 +    AutoGenerateColumns="false"
 +    OnDeleteCommand="deleteButtonClicked">
 +
 +    <com:THyperLinkColumn
 +        HeaderText="Username"
 +        DataTextField="username"
 +        DataNavigateUrlField="username">
 +        <prop:DataNavigateUrlFormatString>#
 +          $this->Service->constructUrl('users.EditUser',array('username'=>{0}))
 +        </prop:DataNavigateUrlFormatString>
 +    </com:THyperLinkColumn>
 +
 +    <com:TBoundColumn
 +        HeaderText="Email"
 +        DataField="email" />
 +    
 +    <com:TCheckBoxColumn
 +        HeaderText="Administrator"
 +        DataField="role" />
 +    
 +    <com:TButtonColumn
 +        HeaderText="Command"
 +        Text="Delete" 
 +        ButtonType="PushButton"
 +        CommandName="delete" />
 +
 +</com:TDataGrid>
 +
 +</com:TContent>
\ No newline at end of file diff --git a/demos/blog-tutorial/samples/day3/blog/protected/pages/users/AdminUser.php b/demos/blog-tutorial/samples/day3/blog/protected/pages/users/AdminUser.php new file mode 100644 index 00000000..ad8f6e3d --- /dev/null +++ b/demos/blog-tutorial/samples/day3/blog/protected/pages/users/AdminUser.php @@ -0,0 +1,36 @@ +<?php
 +
 +class AdminUser extends TPage
 +{
 +	/**
 +	 * Populates the datagrid with user lists.
 +	 * This method is invoked by the framework when initializing the page
 +	 * @param mixed event parameter
 +	 */
 +	public function onInit($param)
 +	{
 +		parent::onInit($param);
 +		// fetches all data account information
 +		$this->UserGrid->DataSource=UserRecord::finder()->findAll();
 +		// binds the data to interface components
 +		$this->UserGrid->dataBind();
 +	}
 +
 +	/**
 +	 * Deletes a specified user record.
 +	 * This method responds to the datagrid's OnDeleteCommand event.
 +	 * @param TDataGrid the event sender
 +	 * @param TDataGridCommandEventParameter the event parameter
 +	 */
 +	public function deleteButtonClicked($sender,$param)
 +	{
 +		// obtains the datagrid item that contains the clicked delete button
 +		$item=$param->Item;
 +		// obtains the primary key corresponding to the datagrid item
 +		$username=$this->UserGrid->DataKeys[$item->ItemIndex];
 +		// deletes the user record with the specified username primary key
 +		UserRecord::finder()->deleteByPk($username);
 +	}
 +}
 +
 +?>
\ No newline at end of file diff --git a/demos/blog-tutorial/samples/day3/blog/protected/pages/users/EditUser.page b/demos/blog-tutorial/samples/day3/blog/protected/pages/users/EditUser.page new file mode 100644 index 00000000..8aa3670e --- /dev/null +++ b/demos/blog-tutorial/samples/day3/blog/protected/pages/users/EditUser.page @@ -0,0 +1,61 @@ +<%@ 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>
\ No newline at end of file diff --git a/demos/blog-tutorial/samples/day3/blog/protected/pages/users/EditUser.php b/demos/blog-tutorial/samples/day3/blog/protected/pages/users/EditUser.php new file mode 100644 index 00000000..cb69b9d5 --- /dev/null +++ b/demos/blog-tutorial/samples/day3/blog/protected/pages/users/EditUser.php @@ -0,0 +1,83 @@ +<?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
 +			$this->Response->redirect($this->Service->constructUrl($this->Service->DefaultPage));
 +		}
 +	}
 +
 +	/**
 +	 * 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;
 +	}
 +}
 +
 +?>
\ No newline at end of file diff --git a/demos/blog-tutorial/samples/day3/blog/protected/pages/users/LoginUser.page b/demos/blog-tutorial/samples/day3/blog/protected/pages/users/LoginUser.page new file mode 100644 index 00000000..f7fc7367 --- /dev/null +++ b/demos/blog-tutorial/samples/day3/blog/protected/pages/users/LoginUser.page @@ -0,0 +1,28 @@ +<%@ Title="My Blog - Login" %>
 +
 +<com:TContent ID="Main">
 + 
 +<h1>Login</h1>
 +
 +<span>Username:</span>
 +<com:TRequiredFieldValidator 
 +	ControlToValidate="Username"
 +	ErrorMessage="Please provide your username." 
 +	Display="Dynamic" />
 +<br/>
 +<com:TTextBox ID="Username" />
 +
 +<br/>
 +<span>Password:</span>
 +<com:TCustomValidator
 +	ControlToValidate="Password"
 +	ErrorMessage="Your entered an invalid password."
 +	Display="Dynamic"
 +	OnServerValidate="validateUser" />
 +<br/>
 +<com:TTextBox ID="Password" TextMode="Password" />
 +
 +<br/>
 +<com:TButton Text="Login" OnClick="loginButtonClicked" />
 +
 +</com:TContent>
\ No newline at end of file diff --git a/demos/blog-tutorial/samples/day3/blog/protected/pages/users/LoginUser.php b/demos/blog-tutorial/samples/day3/blog/protected/pages/users/LoginUser.php new file mode 100644 index 00000000..dff8f2f0 --- /dev/null +++ b/demos/blog-tutorial/samples/day3/blog/protected/pages/users/LoginUser.php @@ -0,0 +1,37 @@ +<?php
 +
 +class LoginUser extends TPage
 +{
 +	/**
 +	 * Validates whether the username and password are correct.
 +	 * This method responds to the TCustomValidator's OnServerValidate event.
 +	 * @param mixed event sender
 +	 * @param mixed event parameter
 +	 */
 +	public function validateUser($sender,$param)
 +	{
 +		$authManager=$this->Application->getModule('auth');
 +		if(!$authManager->login($this->Username->Text,$this->Password->Text))
 +			$param->IsValid=false;  // tell the validator that validation fails
 +	}
 +
 +	/**
 +	 * Redirects the user's browser to appropriate URL if login succeeds.
 +	 * This method responds to the login button's OnClick event.
 +	 * @param mixed event sender
 +	 * @param mixed event parameter
 +	 */
 +	public function loginButtonClicked($sender,$param)
 +	{
 +		if($this->Page->IsValid)  // all validations succeed
 +		{
 +			// obtain the URL of the privileged page that the user wanted to visit originally
 +			$url=$this->Application->getModule('auth')->ReturnUrl;
 +			if(empty($url))  // the user accesses the login page directly
 +				$url=$this->Service->constructUrl($this->Service->DefaultPage);
 +			$this->Response->redirect($url);
 +		}
 +	}
 +}
 +
 +?>
\ No newline at end of file diff --git a/demos/blog-tutorial/samples/day3/blog/protected/pages/users/NewUser.page b/demos/blog-tutorial/samples/day3/blog/protected/pages/users/NewUser.page new file mode 100644 index 00000000..d1547a9a --- /dev/null +++ b/demos/blog-tutorial/samples/day3/blog/protected/pages/users/NewUser.page @@ -0,0 +1,73 @@ +<%@ Title="My Blog - New User" %>
 +
 +<com:TContent ID="Main">
 + 
 +<h1>Create New User</h1>
 +
 +<span>Username:</span>
 +<com:TRequiredFieldValidator 
 +	ControlToValidate="Username"
 +	ErrorMessage="Please provide a username." 
 +	Display="Dynamic" />
 +<com:TCustomValidator
 +	ControlToValidate="Username"
 +	ErrorMessage="Sorry, your username is taken by someone else. Please choose another username."
 +	OnServerValidate="checkUsername"
 +	Display="Dynamic" />
 +<br/>
 +<com:TTextBox ID="Username" />
 +
 +<br/>
 +<span>Password:</span>
 +<com:TRequiredFieldValidator 
 +	ControlToValidate="Password"
 +	ErrorMessage="Please provide a password." 
 +	Display="Dynamic" />
 +<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" />
 +
 +<br/>
 +<span>Role:</span>
 +<br/>
 +<com:TDropDownList ID="Role">
 +	<com:TListItem Text="Normal User" Value="0" />
 +	<com:TListItem Text="Administrator" Value="1" />
 +</com:TDropDownList>
 +
 +<br/>
 +<span>First Name:</span>
 +<br/>
 +<com:TTextBox ID="FirstName" />
 +
 +<br/>
 +<span>Last Name:</span>
 +<br/>
 +<com:TTextBox ID="LastName" />
 +
 +<br/>
 +<com:TButton Text="Create" OnClick="createButtonClicked" />
 +
 +</com:TContent>
\ No newline at end of file diff --git a/demos/blog-tutorial/samples/day3/blog/protected/pages/users/NewUser.php b/demos/blog-tutorial/samples/day3/blog/protected/pages/users/NewUser.php new file mode 100644 index 00000000..005fb7d2 --- /dev/null +++ b/demos/blog-tutorial/samples/day3/blog/protected/pages/users/NewUser.php @@ -0,0 +1,45 @@ +<?php
 +
 +class NewUser extends TPage
 +{
 +	/**
 +	 * Checks whether the username exists in the database.
 +	 * This method responds to the OnServerValidate event of username's custom validator.
 +	 * @param mixed event sender
 +	 * @param mixed event parameter
 +	 */
 +	public function checkUsername($sender,$param)
 +	{
 +		// valid if the username is not found in the database
 +		$param->IsValid=UserRecord::finder()->findByPk($this->Username->Text)===null;
 +	}
 +
 +	/**
 +	 * Creates a new user account if all inputs are valid.
 +	 * This method responds to the OnClick event of the "create" button.
 +	 * @param mixed event sender
 +	 * @param mixed event parameter
 +	 */
 +	public function createButtonClicked($sender,$param)
 +	{
 +		if($this->IsValid)  // when all validations succeed
 +		{
 +			// populates a UserRecord object with user inputs
 +			$userRecord=new UserRecord;
 +			$userRecord->username=$this->Username->Text;
 +			$userRecord->password=$this->Password->Text;
 +			$userRecord->email=$this->Email->Text;
 +			$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
 +			$this->Response->redirect($this->Service->constructUrl($this->Service->DefaultPage));
 +		}
 +	}
 +}
 +
 +?>
\ No newline at end of file diff --git a/demos/blog-tutorial/samples/day3/blog/protected/pages/users/config.xml b/demos/blog-tutorial/samples/day3/blog/protected/pages/users/config.xml new file mode 100644 index 00000000..56554441 --- /dev/null +++ b/demos/blog-tutorial/samples/day3/blog/protected/pages/users/config.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="utf-8"?>
 +<configuration>
 +  <authorization>
 +    <allow pages="NewUser,AdminUser" roles="admin" />
 +    <deny users="?" />
 +  </authorization>
 +</configuration>
\ No newline at end of file diff --git a/demos/blog-tutorial/samples/day3/blog/protected/schema.sql b/demos/blog-tutorial/samples/day3/blog/protected/schema.sql new file mode 100644 index 00000000..d3189b40 --- /dev/null +++ b/demos/blog-tutorial/samples/day3/blog/protected/schema.sql @@ -0,0 +1,24 @@ +/* create users table */
 +CREATE TABLE users (
 +  username      VARCHAR(128) NOT NULL PRIMARY KEY,
 +  email         VARCHAR(128) NOT NULL,
 +  password      VARCHAR(128) NOT NULL,  /* in plain text */
 +  role          INTEGER NOT NULL,       /* 0: normal user, 1: administrator */
 +  first_name    VARCHAR(128),
 +  last_name     VARCHAR(128)
 +);
 +
 +/* create posts table */
 +CREATE TABLE posts (
 +  post_id       INTEGER NOT NULL PRIMARY KEY,
 +  author        VARCHAR(128) NOT NULL,  /* references users.username */
 +  create_time   INTEGER NOT NULL,       /* UNIX timestamp */
 +  title         VARCHAR(256) NOT NULL,  /* title of the post */
 +  content       TEXT NOT NULL,          /* content of the post */
 +  status		INTEGER NOT NULL		/* 0: published; 1: draft; 2: pending; 2: denied */
 +);
 +
 +/* insert some initial data records for testing */
 +INSERT INTO users VALUES ('admin', 'admin@example.com', 'demo', 1, 'Qiang', 'Xue');
 +INSERT INTO users VALUES ('demo', 'demo@example.com', 'demo', 0, 'Wei', 'Zhuo');
 +INSERT INTO posts VALUES (NULL, 'admin', 1175708482, 'first post', 'this is my first post', 0);
  | 
