From 4a9dd5c8513ed96d1e0cf43e370b170dc38fb502 Mon Sep 17 00:00:00 2001 From: xue <> Date: Fri, 29 Jun 2007 17:41:20 +0000 Subject: finished blog-tutorial. --- demos/blog-tutorial/samples/day5/blog/index.php | 22 ++++++ .../samples/day5/blog/protected/.htaccess | 1 + .../day5/blog/protected/BlogErrorHandler.php | 40 ++++++++++ .../samples/day5/blog/protected/BlogException.php | 7 ++ .../samples/day5/blog/protected/BlogUser.php | 59 +++++++++++++++ .../samples/day5/blog/protected/application.xml | 50 +++++++++++++ .../samples/day5/blog/protected/data/blog.db | Bin 0 -> 4096 bytes .../day5/blog/protected/database/PostRecord.php | 28 +++++++ .../day5/blog/protected/database/UserRecord.php | 28 +++++++ .../samples/day5/blog/protected/error.html | 20 +++++ .../day5/blog/protected/layouts/MainLayout.php | 19 +++++ .../day5/blog/protected/layouts/MainLayout.tpl | 43 +++++++++++ .../samples/day5/blog/protected/pages/Contact.page | 47 ++++++++++++ .../samples/day5/blog/protected/pages/Contact.php | 30 ++++++++ .../samples/day5/blog/protected/pages/Home.page | 7 ++ .../day5/blog/protected/pages/posts/EditPost.page | 27 +++++++ .../day5/blog/protected/pages/posts/EditPost.php | 72 ++++++++++++++++++ .../day5/blog/protected/pages/posts/ListPost.page | 14 ++++ .../day5/blog/protected/pages/posts/ListPost.php | 64 ++++++++++++++++ .../day5/blog/protected/pages/posts/NewPost.page | 27 +++++++ .../day5/blog/protected/pages/posts/NewPost.php | 34 +++++++++ .../blog/protected/pages/posts/PostRenderer.php | 7 ++ .../blog/protected/pages/posts/PostRenderer.tpl | 17 +++++ .../day5/blog/protected/pages/posts/ReadPost.page | 25 +++++++ .../day5/blog/protected/pages/posts/ReadPost.php | 59 +++++++++++++++ .../day5/blog/protected/pages/posts/config.xml | 6 ++ .../day5/blog/protected/pages/users/AdminUser.page | 40 ++++++++++ .../day5/blog/protected/pages/users/AdminUser.php | 36 +++++++++ .../day5/blog/protected/pages/users/EditUser.page | 61 +++++++++++++++ .../day5/blog/protected/pages/users/EditUser.php | 83 +++++++++++++++++++++ .../day5/blog/protected/pages/users/LoginUser.page | 28 +++++++ .../day5/blog/protected/pages/users/LoginUser.php | 37 +++++++++ .../day5/blog/protected/pages/users/NewUser.page | 73 ++++++++++++++++++ .../day5/blog/protected/pages/users/NewUser.php | 45 +++++++++++ .../day5/blog/protected/pages/users/config.xml | 7 ++ .../samples/day5/blog/protected/schema.sql | 25 +++++++ .../samples/day5/blog/themes/Basic/button.skin | 1 + .../samples/day5/blog/themes/Basic/style.css | 37 +++++++++ 38 files changed, 1226 insertions(+) create mode 100644 demos/blog-tutorial/samples/day5/blog/index.php create mode 100644 demos/blog-tutorial/samples/day5/blog/protected/.htaccess create mode 100644 demos/blog-tutorial/samples/day5/blog/protected/BlogErrorHandler.php create mode 100644 demos/blog-tutorial/samples/day5/blog/protected/BlogException.php create mode 100644 demos/blog-tutorial/samples/day5/blog/protected/BlogUser.php create mode 100644 demos/blog-tutorial/samples/day5/blog/protected/application.xml create mode 100644 demos/blog-tutorial/samples/day5/blog/protected/data/blog.db create mode 100644 demos/blog-tutorial/samples/day5/blog/protected/database/PostRecord.php create mode 100644 demos/blog-tutorial/samples/day5/blog/protected/database/UserRecord.php create mode 100644 demos/blog-tutorial/samples/day5/blog/protected/error.html create mode 100644 demos/blog-tutorial/samples/day5/blog/protected/layouts/MainLayout.php create mode 100644 demos/blog-tutorial/samples/day5/blog/protected/layouts/MainLayout.tpl create mode 100644 demos/blog-tutorial/samples/day5/blog/protected/pages/Contact.page create mode 100644 demos/blog-tutorial/samples/day5/blog/protected/pages/Contact.php create mode 100644 demos/blog-tutorial/samples/day5/blog/protected/pages/Home.page create mode 100644 demos/blog-tutorial/samples/day5/blog/protected/pages/posts/EditPost.page create mode 100644 demos/blog-tutorial/samples/day5/blog/protected/pages/posts/EditPost.php create mode 100644 demos/blog-tutorial/samples/day5/blog/protected/pages/posts/ListPost.page create mode 100644 demos/blog-tutorial/samples/day5/blog/protected/pages/posts/ListPost.php create mode 100644 demos/blog-tutorial/samples/day5/blog/protected/pages/posts/NewPost.page create mode 100644 demos/blog-tutorial/samples/day5/blog/protected/pages/posts/NewPost.php create mode 100644 demos/blog-tutorial/samples/day5/blog/protected/pages/posts/PostRenderer.php create mode 100644 demos/blog-tutorial/samples/day5/blog/protected/pages/posts/PostRenderer.tpl create mode 100644 demos/blog-tutorial/samples/day5/blog/protected/pages/posts/ReadPost.page create mode 100644 demos/blog-tutorial/samples/day5/blog/protected/pages/posts/ReadPost.php create mode 100644 demos/blog-tutorial/samples/day5/blog/protected/pages/posts/config.xml create mode 100644 demos/blog-tutorial/samples/day5/blog/protected/pages/users/AdminUser.page create mode 100644 demos/blog-tutorial/samples/day5/blog/protected/pages/users/AdminUser.php create mode 100644 demos/blog-tutorial/samples/day5/blog/protected/pages/users/EditUser.page create mode 100644 demos/blog-tutorial/samples/day5/blog/protected/pages/users/EditUser.php create mode 100644 demos/blog-tutorial/samples/day5/blog/protected/pages/users/LoginUser.page create mode 100644 demos/blog-tutorial/samples/day5/blog/protected/pages/users/LoginUser.php create mode 100644 demos/blog-tutorial/samples/day5/blog/protected/pages/users/NewUser.page create mode 100644 demos/blog-tutorial/samples/day5/blog/protected/pages/users/NewUser.php create mode 100644 demos/blog-tutorial/samples/day5/blog/protected/pages/users/config.xml create mode 100644 demos/blog-tutorial/samples/day5/blog/protected/schema.sql create mode 100644 demos/blog-tutorial/samples/day5/blog/themes/Basic/button.skin create mode 100644 demos/blog-tutorial/samples/day5/blog/themes/Basic/style.css (limited to 'demos/blog-tutorial/samples/day5/blog') diff --git a/demos/blog-tutorial/samples/day5/blog/index.php b/demos/blog-tutorial/samples/day5/blog/index.php new file mode 100644 index 00000000..7ccffe49 --- /dev/null +++ b/demos/blog-tutorial/samples/day5/blog/index.php @@ -0,0 +1,22 @@ +run(); + +?> \ No newline at end of file diff --git a/demos/blog-tutorial/samples/day5/blog/protected/.htaccess b/demos/blog-tutorial/samples/day5/blog/protected/.htaccess new file mode 100644 index 00000000..3418e55a --- /dev/null +++ b/demos/blog-tutorial/samples/day5/blog/protected/.htaccess @@ -0,0 +1 @@ +deny from all \ No newline at end of file diff --git a/demos/blog-tutorial/samples/day5/blog/protected/BlogErrorHandler.php b/demos/blog-tutorial/samples/day5/blog/protected/BlogErrorHandler.php new file mode 100644 index 00000000..56b71f8a --- /dev/null +++ b/demos/blog-tutorial/samples/day5/blog/protected/BlogErrorHandler.php @@ -0,0 +1,40 @@ +getErrorMessage(),TLogger::ERROR,'BlogApplication'); + // call parent implementation to display the error + parent::handleExternalError($statusCode,$exception); + } +} + +?> \ No newline at end of file diff --git a/demos/blog-tutorial/samples/day5/blog/protected/BlogException.php b/demos/blog-tutorial/samples/day5/blog/protected/BlogException.php new file mode 100644 index 00000000..fd17fc84 --- /dev/null +++ b/demos/blog-tutorial/samples/day5/blog/protected/BlogException.php @@ -0,0 +1,7 @@ + \ No newline at end of file diff --git a/demos/blog-tutorial/samples/day5/blog/protected/BlogUser.php b/demos/blog-tutorial/samples/day5/blog/protected/BlogUser.php new file mode 100644 index 00000000..6b9e0a23 --- /dev/null +++ b/demos/blog-tutorial/samples/day5/blog/protected/BlogUser.php @@ -0,0 +1,59 @@ +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/day5/blog/protected/application.xml b/demos/blog-tutorial/samples/day5/blog/protected/application.xml new file mode 100644 index 00000000..cd996cb6 --- /dev/null +++ b/demos/blog-tutorial/samples/day5/blog/protected/application.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/demos/blog-tutorial/samples/day5/blog/protected/data/blog.db b/demos/blog-tutorial/samples/day5/blog/protected/data/blog.db new file mode 100644 index 00000000..fa48526a Binary files /dev/null and b/demos/blog-tutorial/samples/day5/blog/protected/data/blog.db differ diff --git a/demos/blog-tutorial/samples/day5/blog/protected/database/PostRecord.php b/demos/blog-tutorial/samples/day5/blog/protected/database/PostRecord.php new file mode 100644 index 00000000..01f84437 --- /dev/null +++ b/demos/blog-tutorial/samples/day5/blog/protected/database/PostRecord.php @@ -0,0 +1,28 @@ + array(self::BELONGS_TO, 'UserRecord'), + ); + + public static function finder($className=__CLASS__) + { + return parent::finder($className); + } +} +?> \ No newline at end of file diff --git a/demos/blog-tutorial/samples/day5/blog/protected/database/UserRecord.php b/demos/blog-tutorial/samples/day5/blog/protected/database/UserRecord.php new file mode 100644 index 00000000..18d5ebbe --- /dev/null +++ b/demos/blog-tutorial/samples/day5/blog/protected/database/UserRecord.php @@ -0,0 +1,28 @@ + array(self::HAS_MANY, 'PostRecord'), + ); + + public static function finder($className=__CLASS__) + { + return parent::finder($className); + } +} +?> \ No newline at end of file diff --git a/demos/blog-tutorial/samples/day5/blog/protected/error.html b/demos/blog-tutorial/samples/day5/blog/protected/error.html new file mode 100644 index 00000000..caf2cdfc --- /dev/null +++ b/demos/blog-tutorial/samples/day5/blog/protected/error.html @@ -0,0 +1,20 @@ + + +%%ErrorMessage%% + + +
+ +
+

%%ErrorMessage%%

+

+The above error happened when the server was processing your request. +

+

+If you think this is a server error, please contact the webmaster. +

+
+ + \ No newline at end of file diff --git a/demos/blog-tutorial/samples/day5/blog/protected/layouts/MainLayout.php b/demos/blog-tutorial/samples/day5/blog/protected/layouts/MainLayout.php new file mode 100644 index 00000000..46c1483d --- /dev/null +++ b/demos/blog-tutorial/samples/day5/blog/protected/layouts/MainLayout.php @@ -0,0 +1,19 @@ +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/day5/blog/protected/layouts/MainLayout.tpl b/demos/blog-tutorial/samples/day5/blog/protected/layouts/MainLayout.tpl new file mode 100644 index 00000000..34723f77 --- /dev/null +++ b/demos/blog-tutorial/samples/day5/blog/protected/layouts/MainLayout.tpl @@ -0,0 +1,43 @@ + + + + +
+ + + +
+ +
+ + + +
+
+ + \ No newline at end of file diff --git a/demos/blog-tutorial/samples/day5/blog/protected/pages/Contact.page b/demos/blog-tutorial/samples/day5/blog/protected/pages/Contact.page new file mode 100644 index 00000000..c36149ca --- /dev/null +++ b/demos/blog-tutorial/samples/day5/blog/protected/pages/Contact.page @@ -0,0 +1,47 @@ +<%@ Title="My Blog - Contact" %> + + + +

Contact

+

Please fill out the following form to let me know your feedback on my blog. Thanks!

+ +Your Name: + +
+ + +
+ +Your Email: + + +
+ + +
+ +Feedback: + +
+ + +
+ + + +
\ No newline at end of file diff --git a/demos/blog-tutorial/samples/day5/blog/protected/pages/Contact.php b/demos/blog-tutorial/samples/day5/blog/protected/pages/Contact.php new file mode 100644 index 00000000..b6ce575e --- /dev/null +++ b/demos/blog-tutorial/samples/day5/blog/protected/pages/Contact.php @@ -0,0 +1,30 @@ +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/day5/blog/protected/pages/Home.page b/demos/blog-tutorial/samples/day5/blog/protected/pages/Home.page new file mode 100644 index 00000000..7a9c4a7d --- /dev/null +++ b/demos/blog-tutorial/samples/day5/blog/protected/pages/Home.page @@ -0,0 +1,7 @@ +<%@ Title="Welcome to PRADO" %> + + + +

Welcome to PRADO!

+ +
\ No newline at end of file diff --git a/demos/blog-tutorial/samples/day5/blog/protected/pages/posts/EditPost.page b/demos/blog-tutorial/samples/day5/blog/protected/pages/posts/EditPost.page new file mode 100644 index 00000000..579d833e --- /dev/null +++ b/demos/blog-tutorial/samples/day5/blog/protected/pages/posts/EditPost.page @@ -0,0 +1,27 @@ +<%@ Title="My Blog - Edit Post" %> + + + +

Edit Post

+ +Title: + +
+ + +
+Content: + +
+ + +
+ + +
\ No newline at end of file diff --git a/demos/blog-tutorial/samples/day5/blog/protected/pages/posts/EditPost.php b/demos/blog-tutorial/samples/day5/blog/protected/pages/posts/EditPost.php new file mode 100644 index 00000000..e137b85e --- /dev/null +++ b/demos/blog-tutorial/samples/day5/blog/protected/pages/posts/EditPost.php @@ -0,0 +1,72 @@ +getPost(); + $postRecord=$this->Post; + // Authorization check: only the author or the administrator can edit the post + if($postRecord->author_id!==$this->User->Name && !$this->User->IsAdmin) + throw new THttpException(500,'You are not allowed to edit this post.'); + + if(!$this->IsPostBack) // if the page is initially requested + { + // Populates the input controls with the existing post data + $this->TitleEdit->Text=$postRecord->title; + $this->ContentEdit->Text=$postRecord->content; + } + } + + /** + * Saves the post 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: + // $postRecord=$this->getPost(); + $postRecord=$this->Post; + + // Fetches the input data + $postRecord->title=$this->TitleEdit->SafeText; + $postRecord->content=$this->ContentEdit->SafeText; + + // saves to the database via Active Record mechanism + $postRecord->save(); + + // redirects the browser to the ReadPost page + $url=$this->Service->constructUrl('posts.ReadPost',array('id'=>$postRecord->post_id)); + $this->Response->redirect($url); + } + } + + /** + * Returns the post data to be editted. + * @return PostRecord the post data to be editted. + * @throws THttpException if the post data is not found. + */ + protected function getPost() + { + // the ID of the post to be editted is passed via GET parameter 'id' + $postID=(int)$this->Request['id']; + // use Active Record to look for the specified post ID + $postRecord=PostRecord::finder()->findByPk($postID); + if($postRecord===null) + throw new THttpException(500,'Post is not found.'); + return $postRecord; + } +} + +?> \ No newline at end of file diff --git a/demos/blog-tutorial/samples/day5/blog/protected/pages/posts/ListPost.page b/demos/blog-tutorial/samples/day5/blog/protected/pages/posts/ListPost.page new file mode 100644 index 00000000..e26bc2f5 --- /dev/null +++ b/demos/blog-tutorial/samples/day5/blog/protected/pages/posts/ListPost.page @@ -0,0 +1,14 @@ +<%@ Title="My Blog" %> + + + + + + + + \ No newline at end of file diff --git a/demos/blog-tutorial/samples/day5/blog/protected/pages/posts/ListPost.php b/demos/blog-tutorial/samples/day5/blog/protected/pages/posts/ListPost.php new file mode 100644 index 00000000..7402dace --- /dev/null +++ b/demos/blog-tutorial/samples/day5/blog/protected/pages/posts/ListPost.php @@ -0,0 +1,64 @@ +IsPostBack) // if the page is requested the first time + { + // get the total number of posts available + $this->Repeater->VirtualItemCount=PostRecord::finder()->count(); + // populates post data into the repeater + $this->populateData(); + } + } + + /** + * Event handler to the OnPageIndexChanged event of the pager. + * This method is invoked when the user clicks on a page button + * and thus changes the page of posts to display. + */ + public function pageChanged($sender,$param) + { + // change the current page index to the new one + $this->Repeater->CurrentPageIndex=$param->NewPageIndex; + // re-populate data into the repeater + $this->populateData(); + } + + /** + * Determines which page of posts to be displayed and + * populates the repeater with the fetched data. + */ + protected function populateData() + { + $offset=$this->Repeater->CurrentPageIndex*$this->Repeater->PageSize; + $limit=$this->Repeater->PageSize; + if($offset+$limit>$this->Repeater->VirtualItemCount) + $limit=$this->Repeater->VirtualItemCount-$offset; + $this->Repeater->DataSource=$this->getPosts($offset,$limit); + $this->Repeater->dataBind(); + } + + /** + * Fetches posts from database with offset and limit. + */ + protected function getPosts($offset, $limit) + { + // Construts a query criteria + $criteria=new TActiveRecordCriteria; + $criteria->OrdersBy['create_time']='desc'; + $criteria->Limit=$limit; + $criteria->Offset=$offset; + // query for the posts with the above criteria and with author information + return PostRecord::finder()->withAuthor()->findAll($criteria); + } +} + +?> \ No newline at end of file diff --git a/demos/blog-tutorial/samples/day5/blog/protected/pages/posts/NewPost.page b/demos/blog-tutorial/samples/day5/blog/protected/pages/posts/NewPost.page new file mode 100644 index 00000000..bd46dfbb --- /dev/null +++ b/demos/blog-tutorial/samples/day5/blog/protected/pages/posts/NewPost.page @@ -0,0 +1,27 @@ +<%@ Title="My Blog - New Post" %> + + + +

Create New Post

+ +Title: + +
+ + +
+Content: + +
+ + +
+ + +
\ No newline at end of file diff --git a/demos/blog-tutorial/samples/day5/blog/protected/pages/posts/NewPost.php b/demos/blog-tutorial/samples/day5/blog/protected/pages/posts/NewPost.php new file mode 100644 index 00000000..a5e3ea4d --- /dev/null +++ b/demos/blog-tutorial/samples/day5/blog/protected/pages/posts/NewPost.php @@ -0,0 +1,34 @@ +IsValid) // when all validations succeed + { + // populates a PostRecord object with user inputs + $postRecord=new PostRecord; + // using SafeText instead of Text avoids Cross Site Scripting attack + $postRecord->title=$this->TitleEdit->SafeText; + $postRecord->content=$this->ContentEdit->SafeText; + $postRecord->author_id=$this->User->Name; + $postRecord->create_time=time(); + $postRecord->status=0; + + // saves to the database via Active Record mechanism + $postRecord->save(); + + // redirects the browser to the newly created post page + $url=$this->Service->constructUrl('posts.ReadPost',array('id'=>$postRecord->post_id)); + $this->Response->redirect($url); + } + } +} + +?> \ No newline at end of file diff --git a/demos/blog-tutorial/samples/day5/blog/protected/pages/posts/PostRenderer.php b/demos/blog-tutorial/samples/day5/blog/protected/pages/posts/PostRenderer.php new file mode 100644 index 00000000..cf0539a1 --- /dev/null +++ b/demos/blog-tutorial/samples/day5/blog/protected/pages/posts/PostRenderer.php @@ -0,0 +1,7 @@ + \ No newline at end of file diff --git a/demos/blog-tutorial/samples/day5/blog/protected/pages/posts/PostRenderer.tpl b/demos/blog-tutorial/samples/day5/blog/protected/pages/posts/PostRenderer.tpl new file mode 100644 index 00000000..8f4a0502 --- /dev/null +++ b/demos/blog-tutorial/samples/day5/blog/protected/pages/posts/PostRenderer.tpl @@ -0,0 +1,17 @@ +
+

+ +

+ +

+Author: +
+Time: + +

+ +

+ +

+
\ No newline at end of file diff --git a/demos/blog-tutorial/samples/day5/blog/protected/pages/posts/ReadPost.page b/demos/blog-tutorial/samples/day5/blog/protected/pages/posts/ReadPost.page new file mode 100644 index 00000000..60a8cf1e --- /dev/null +++ b/demos/blog-tutorial/samples/day5/blog/protected/pages/posts/ReadPost.page @@ -0,0 +1,25 @@ + + +

+ +

+ + + Edit | + + + +

+Author: +
+Time: + +

+ +

+ +

+ +
\ No newline at end of file diff --git a/demos/blog-tutorial/samples/day5/blog/protected/pages/posts/ReadPost.php b/demos/blog-tutorial/samples/day5/blog/protected/pages/posts/ReadPost.php new file mode 100644 index 00000000..0c120824 --- /dev/null +++ b/demos/blog-tutorial/samples/day5/blog/protected/pages/posts/ReadPost.php @@ -0,0 +1,59 @@ +Request['id']; + // retrieves PostRecord with author information filled in + $this->_post=PostRecord::finder()->withAuthor()->findByPk($postID); + if($this->_post===null) // if post id is invalid + throw new BlogException(500,'Unable to find the specified post.'); + // set the page title as the post title + $this->Title=$this->_post->title; + } + + /** + * @return PostRecord the PostRecord currently being viewed + */ + public function getPost() + { + return $this->_post; + } + + /** + * Deletes the post currently being viewed + * This method is invoked when the user clicks on the "Delete" button + */ + public function deletePost($sender,$param) + { + // only the author or the administrator can delete a post + if(!$this->canEdit()) + throw new THttpException('You are not allowed to perform this action.'); + // delete it from DB + $this->_post->delete(); + // redirect the browser to the homepage + $this->Response->redirect($this->Service->DefaultPageUrl); + } + + /** + * @return boolean whether the current user can edit/delete the post being viewed + */ + public function canEdit() + { + // only the author or the administrator can edit/delete a post + return $this->User->Name===$this->Post->author_id || $this->User->IsAdmin; + } +} + +?> \ No newline at end of file diff --git a/demos/blog-tutorial/samples/day5/blog/protected/pages/posts/config.xml b/demos/blog-tutorial/samples/day5/blog/protected/pages/posts/config.xml new file mode 100644 index 00000000..64065ed5 --- /dev/null +++ b/demos/blog-tutorial/samples/day5/blog/protected/pages/posts/config.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/demos/blog-tutorial/samples/day5/blog/protected/pages/users/AdminUser.page b/demos/blog-tutorial/samples/day5/blog/protected/pages/users/AdminUser.page new file mode 100644 index 00000000..af03b858 --- /dev/null +++ b/demos/blog-tutorial/samples/day5/blog/protected/pages/users/AdminUser.page @@ -0,0 +1,40 @@ +<%@ Title="My Blog - Manage User Accounts" %> + + + +

Manage User Accounts

+ +Create New User +
+ + + + + # + $this->Service->constructUrl('users.EditUser',array('username'=>{0})) + + + + + + + + + + + +
\ No newline at end of file diff --git a/demos/blog-tutorial/samples/day5/blog/protected/pages/users/AdminUser.php b/demos/blog-tutorial/samples/day5/blog/protected/pages/users/AdminUser.php new file mode 100644 index 00000000..ad8f6e3d --- /dev/null +++ b/demos/blog-tutorial/samples/day5/blog/protected/pages/users/AdminUser.php @@ -0,0 +1,36 @@ +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/day5/blog/protected/pages/users/EditUser.page b/demos/blog-tutorial/samples/day5/blog/protected/pages/users/EditUser.page new file mode 100644 index 00000000..8aa3670e --- /dev/null +++ b/demos/blog-tutorial/samples/day5/blog/protected/pages/users/EditUser.page @@ -0,0 +1,61 @@ +<%@ Title="My Blog - Edit User" %> + + + +

Edit User

+ +Username: + + +
+Password: +
+ + +
+Re-type Password: + +
+ + +
+Email Address: + + +
+ + + +
+Role: +
+ + + + +
+ +
+First Name: +
+ + +
+Last Name: +
+ + +
+ + +
\ No newline at end of file diff --git a/demos/blog-tutorial/samples/day5/blog/protected/pages/users/EditUser.php b/demos/blog-tutorial/samples/day5/blog/protected/pages/users/EditUser.php new file mode 100644 index 00000000..81538c33 --- /dev/null +++ b/demos/blog-tutorial/samples/day5/blog/protected/pages/users/EditUser.php @@ -0,0 +1,83 @@ +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->DefaultPageUrl); + } + } + + /** + * 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/day5/blog/protected/pages/users/LoginUser.page b/demos/blog-tutorial/samples/day5/blog/protected/pages/users/LoginUser.page new file mode 100644 index 00000000..f7fc7367 --- /dev/null +++ b/demos/blog-tutorial/samples/day5/blog/protected/pages/users/LoginUser.page @@ -0,0 +1,28 @@ +<%@ Title="My Blog - Login" %> + + + +

Login

+ +Username: + +
+ + +
+Password: + +
+ + +
+ + +
\ No newline at end of file diff --git a/demos/blog-tutorial/samples/day5/blog/protected/pages/users/LoginUser.php b/demos/blog-tutorial/samples/day5/blog/protected/pages/users/LoginUser.php new file mode 100644 index 00000000..a0955490 --- /dev/null +++ b/demos/blog-tutorial/samples/day5/blog/protected/pages/users/LoginUser.php @@ -0,0 +1,37 @@ +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->DefaultPageUrl; + $this->Response->redirect($url); + } + } +} + +?> \ No newline at end of file diff --git a/demos/blog-tutorial/samples/day5/blog/protected/pages/users/NewUser.page b/demos/blog-tutorial/samples/day5/blog/protected/pages/users/NewUser.page new file mode 100644 index 00000000..d1547a9a --- /dev/null +++ b/demos/blog-tutorial/samples/day5/blog/protected/pages/users/NewUser.page @@ -0,0 +1,73 @@ +<%@ Title="My Blog - New User" %> + + + +

Create New User

+ +Username: + + +
+ + +
+Password: + +
+ + +
+Re-type Password: + +
+ + +
+Email Address: + + +
+ + +
+Role: +
+ + + + + +
+First Name: +
+ + +
+Last Name: +
+ + +
+ + +
\ No newline at end of file diff --git a/demos/blog-tutorial/samples/day5/blog/protected/pages/users/NewUser.php b/demos/blog-tutorial/samples/day5/blog/protected/pages/users/NewUser.php new file mode 100644 index 00000000..76e8cb88 --- /dev/null +++ b/demos/blog-tutorial/samples/day5/blog/protected/pages/users/NewUser.php @@ -0,0 +1,45 @@ +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->DefaultPageUrl); + } + } +} + +?> \ No newline at end of file diff --git a/demos/blog-tutorial/samples/day5/blog/protected/pages/users/config.xml b/demos/blog-tutorial/samples/day5/blog/protected/pages/users/config.xml new file mode 100644 index 00000000..56554441 --- /dev/null +++ b/demos/blog-tutorial/samples/day5/blog/protected/pages/users/config.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/demos/blog-tutorial/samples/day5/blog/protected/schema.sql b/demos/blog-tutorial/samples/day5/blog/protected/schema.sql new file mode 100644 index 00000000..89f7388e --- /dev/null +++ b/demos/blog-tutorial/samples/day5/blog/protected/schema.sql @@ -0,0 +1,25 @@ +/* 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_id VARCHAR(128) NOT NULL + CONSTRAINT fk_author REFERENCES users(username), + create_time INTEGER NOT NULL, /* UNIX timestamp */ + title VARCHAR(256) NOT NULL, /* title of the post */ + content TEXT, /* post body */ + 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); diff --git a/demos/blog-tutorial/samples/day5/blog/themes/Basic/button.skin b/demos/blog-tutorial/samples/day5/blog/themes/Basic/button.skin new file mode 100644 index 00000000..886aa7a5 --- /dev/null +++ b/demos/blog-tutorial/samples/day5/blog/themes/Basic/button.skin @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/demos/blog-tutorial/samples/day5/blog/themes/Basic/style.css b/demos/blog-tutorial/samples/day5/blog/themes/Basic/style.css new file mode 100644 index 00000000..a6738366 --- /dev/null +++ b/demos/blog-tutorial/samples/day5/blog/themes/Basic/style.css @@ -0,0 +1,37 @@ +body { + font-family: verdana, 'trebuchet ms', sans-serif; + font-size: 10pt; + background: white; +} + +#page { + margin: 0 auto 0 auto; + width: 600px; +} + +#footer { + text-align: center; + margin-top: 10px; + padding: 10px; + border-top: 1px solid silver; +} + +.post-box { + margin-bottom: 10px; + padding: 5px; +} + +.post-box h3 { + padding: 5px; + font-size: 13pt; + background: lightgray; +} + +.post-box a { + color: black; + text-decoration: none; +} + +.post-box a:hover { + color: red; +} \ No newline at end of file -- cgit v1.2.3