summaryrefslogtreecommitdiff
path: root/demos/blog/protected/Pages/Posts
diff options
context:
space:
mode:
authorxue <>2006-05-29 03:08:07 +0000
committerxue <>2006-05-29 03:08:07 +0000
commit2ea02214b2fb6bedb58dbbd318ef171a9e146524 (patch)
tree16b12d9f68986fe204900d1cee4914a0a4035a7b /demos/blog/protected/Pages/Posts
parent8c1edb7f4eced999c9704ec9ff7ba11d88248bbd (diff)
Merge from 3.0 branch till 1099.
Diffstat (limited to 'demos/blog/protected/Pages/Posts')
-rw-r--r--demos/blog/protected/Pages/Posts/EditCategory.page36
-rw-r--r--demos/blog/protected/Pages/Posts/EditCategory.php44
-rw-r--r--demos/blog/protected/Pages/Posts/EditPost.page41
-rw-r--r--demos/blog/protected/Pages/Posts/EditPost.php51
-rw-r--r--demos/blog/protected/Pages/Posts/ListPost.page27
-rw-r--r--demos/blog/protected/Pages/Posts/ListPost.php44
-rw-r--r--demos/blog/protected/Pages/Posts/MyPost.page46
-rw-r--r--demos/blog/protected/Pages/Posts/MyPost.php34
-rw-r--r--demos/blog/protected/Pages/Posts/NewCategory.page36
-rw-r--r--demos/blog/protected/Pages/Posts/NewCategory.php24
-rw-r--r--demos/blog/protected/Pages/Posts/NewPost.page41
-rw-r--r--demos/blog/protected/Pages/Posts/NewPost.php34
-rw-r--r--demos/blog/protected/Pages/Posts/ViewPost.page113
-rw-r--r--demos/blog/protected/Pages/Posts/ViewPost.php73
-rw-r--r--demos/blog/protected/Pages/Posts/config.xml7
15 files changed, 651 insertions, 0 deletions
diff --git a/demos/blog/protected/Pages/Posts/EditCategory.page b/demos/blog/protected/Pages/Posts/EditCategory.page
new file mode 100644
index 00000000..fdde2648
--- /dev/null
+++ b/demos/blog/protected/Pages/Posts/EditCategory.page
@@ -0,0 +1,36 @@
+<com:TContent ID="Main">
+
+<h2>Update Post Category</h2>
+
+<span class="input-label">Category name</span>
+<com:TRequiredFieldValidator
+ Display="Dynamic"
+ ControlToValidate="CategoryName"
+ ErrorMessage="...is required"
+ ValidationGroup="category" />
+<com:TCustomValidator
+ ControlToValidate="CategoryName"
+ ValidationGroup="category"
+ Display="Dynamic"
+ OnServerValidate="checkCategoryName"
+ Text="...must be unique"
+ ControlCssClass="inputerror" />
+<br/>
+<com:TTextBox ID="CategoryName" Columns="50" MaxLength="128" />
+<br/>
+
+<span class="input-label">Description</span>
+<br/>
+<com:TTextBox
+ ID="CategoryDescription"
+ TextMode="MultiLine"
+ Columns="50"
+ Rows="5" />
+<br/>
+
+<com:TLinkButton
+ Text="Save"
+ OnClick="saveButtonClicked"
+ ValidationGroup="category" />
+
+</com:TContent> \ No newline at end of file
diff --git a/demos/blog/protected/Pages/Posts/EditCategory.php b/demos/blog/protected/Pages/Posts/EditCategory.php
new file mode 100644
index 00000000..fd2d0707
--- /dev/null
+++ b/demos/blog/protected/Pages/Posts/EditCategory.php
@@ -0,0 +1,44 @@
+<?php
+
+class EditCategory extends BlogPage
+{
+ public function getCurrentCategory()
+ {
+ $id=TPropertyValue::ensureInteger($this->Request['id']);
+ if(($cat=$this->DataAccess->queryCategoryByID($id))!==null)
+ return $cat;
+ else
+ throw new BlogException('xxx');
+ }
+
+ public function onLoad($param)
+ {
+ parent::onLoad($param);
+ if(!$this->IsPostBack)
+ {
+ $catRecord=$this->getCurrentCategory();
+ $this->CategoryName->Text=$catRecord->Name;
+ $this->CategoryDescription->Text=$catRecord->Description;
+ }
+ }
+
+ public function saveButtonClicked($sender,$param)
+ {
+ if($this->IsValid)
+ {
+ $categoryRecord=$this->getCurrentCategory();
+ $categoryRecord->Name=$this->CategoryName->Text;
+ $categoryRecord->Description=$this->CategoryDescription->Text;
+ $this->DataAccess->updateCategory($categoryRecord);
+ $this->gotoPage('Posts.ListPost',array('cat'=>$categoryRecord->ID));
+ }
+ }
+
+ public function checkCategoryName($sender,$param)
+ {
+ $name=$this->CategoryName->Text;
+ $param->IsValid=$this->DataAccess->queryCategoryByName($name)===null;
+ }
+}
+
+?> \ No newline at end of file
diff --git a/demos/blog/protected/Pages/Posts/EditPost.page b/demos/blog/protected/Pages/Posts/EditPost.page
new file mode 100644
index 00000000..591f5945
--- /dev/null
+++ b/demos/blog/protected/Pages/Posts/EditPost.page
@@ -0,0 +1,41 @@
+<com:TContent ID="Main">
+
+<h2>Update Post</h2>
+
+Title
+<com:TRequiredFieldValidator
+Display="Dynamic"
+ ControlToValidate="Title"
+ ErrorMessage="...is required"
+ ValidationGroup="post" />
+<br/>
+<com:TTextBox ID="Title" Columns="70" MaxLength="256" />
+<br/>
+
+Content
+<com:TRequiredFieldValidator
+Display="Dynamic"
+ ControlToValidate="Content"
+ ErrorMessage="...is required"
+ ValidationGroup="post" />
+<br/>
+<com:THtmlArea ID="Content" Width="450px" />
+<br/>
+
+Categories<br/>
+<com:TListBox
+ ID="Categories"
+ SelectionMode="Multiple"
+ DataTextField="Name"
+ DataValueField="ID" />
+<br/>
+
+<com:TCheckBox ID="DraftMode" Text="in draft mode (the post will not be published)" />
+<br/>
+
+<com:TLinkButton
+ Text="Save"
+ OnClick="saveButtonClicked"
+ ValidationGroup="post" />
+
+</com:TContent> \ No newline at end of file
diff --git a/demos/blog/protected/Pages/Posts/EditPost.php b/demos/blog/protected/Pages/Posts/EditPost.php
new file mode 100644
index 00000000..57e92b1c
--- /dev/null
+++ b/demos/blog/protected/Pages/Posts/EditPost.php
@@ -0,0 +1,51 @@
+<?php
+
+class EditPost extends BlogPage
+{
+ public function getCurrentPost()
+ {
+ $id=TPropertyValue::ensureInteger($this->Request['id']);
+ if(($post=$this->DataAccess->queryPostByID($id))!==null)
+ return $post;
+ else
+ throw new BlogException('xxx');
+ }
+
+ public function onLoad($param)
+ {
+ parent::onLoad($param);
+ if(!$this->IsPostBack)
+ {
+ $postRecord=$this->getCurrentPost();
+ $this->Title->Text=$postRecord->Title;
+ $this->Content->Text=$postRecord->Content;
+ $this->DraftMode->Checked=$postRecord->Status===0;
+ $this->Categories->DataSource=$this->DataAccess->queryCategories();
+ $this->Categories->dataBind();
+ $cats=$this->DataAccess->queryCategoriesByPostID($postRecord->ID);
+ $catIDs=array();
+ foreach($cats as $cat)
+ $catIDs[]=$cat->ID;
+ $this->Categories->SelectedValues=$catIDs;
+ }
+ }
+
+ public function saveButtonClicked($sender,$param)
+ {
+ if($this->IsValid)
+ {
+ $postRecord=$this->getCurrentPost();
+ $postRecord->Title=$this->Title->Text;
+ $postRecord->Content=$this->Content->Text;
+ $postRecord->Status=$this->DraftMode->Checked?0:1;
+ $postRecord->ModifyTime=time();
+ $cats=array();
+ foreach($this->Categories->SelectedValues as $value)
+ $cats[]=TPropertyValue::ensureInteger($value);
+ $this->DataAccess->updatePost($postRecord,$cats);
+ $this->gotoPage('Posts.ViewPost',array('id'=>$postRecord->ID));
+ }
+ }
+}
+
+?> \ No newline at end of file
diff --git a/demos/blog/protected/Pages/Posts/ListPost.page b/demos/blog/protected/Pages/Posts/ListPost.page
new file mode 100644
index 00000000..15fc3d0c
--- /dev/null
+++ b/demos/blog/protected/Pages/Posts/ListPost.page
@@ -0,0 +1,27 @@
+<com:TContent ID="Main">
+
+<com:TRepeater ID="PostList" EnableViewState="false">
+ <prop:ItemTemplate>
+<div class="post">
+<div class="post-title">
+<%# $this->DataItem->Title %>
+</div>
+<div class="post-time">
+<%# date('l, F j, Y \a\t h:i:s a',$this->DataItem->CreateTime) %>
+</div>
+<div class="post-content">
+<%# $this->DataItem->Content %>
+</div>
+<div class="post-footer">
+posted by
+<%# '<a href="' . $this->Service->constructUrl('Users.ViewUser',array('id'=>$this->DataItem->AuthorID)) . '">' . $this->DataItem->AuthorName . '</a>' %>
+|
+<%# '<a href="' . $this->Service->constructUrl('Posts.ViewPost',array('id'=>$this->DataItem->ID)) . '">PermaLink</a>' %>
+|
+<%# '<a href="' . $this->Service->constructUrl('Posts.ViewPost',array('id'=>$this->DataItem->ID)) . '#comments">Comments (' . $this->DataItem->CommentCount . ')</a>' %>
+</div>
+</div>
+ </prop:ItemTemplate>
+</com:TRepeater>
+
+</com:TContent> \ No newline at end of file
diff --git a/demos/blog/protected/Pages/Posts/ListPost.php b/demos/blog/protected/Pages/Posts/ListPost.php
new file mode 100644
index 00000000..6d56b543
--- /dev/null
+++ b/demos/blog/protected/Pages/Posts/ListPost.php
@@ -0,0 +1,44 @@
+<?php
+
+class ListPost extends BlogPage
+{
+ const DEFAULT_LIMIT=10;
+
+ public function getPosts()
+ {
+ $timeFilter='';
+ $catFilter='';
+ if(($time=TPropertyValue::ensureInteger($this->Request['time']))>0)
+ {
+ $year=(integer)($time/100);
+ $month=$time%100;
+ $startTime=mktime(0,0,0,$month,1,$year);
+ if(++$month>12)
+ {
+ $month=1;
+ $year++;
+ }
+ $endTime=mktime(0,0,0,$month,1,$year);
+ $timeFilter="create_time>=$startTime AND create_time<$endTime";
+ }
+ if(($catID=$this->Request['cat'])!==null)
+ {
+ $catID=TPropertyValue::ensureInteger($catID);
+ $catFilter="category_id=$catID";
+ }
+ if(($offset=TPropertyValue::ensureInteger($this->Request['offset']))<=0)
+ $offset=0;
+ if(($limit=TPropertyValue::ensureInteger($this->Request['limit']))<=0)
+ $limit=self::DEFAULT_LIMIT;
+ return $this->DataAccess->queryPosts('',$timeFilter,$catFilter,'ORDER BY create_time DESC',"LIMIT $offset,$limit");
+ }
+
+ public function onLoad($param)
+ {
+ parent::onLoad($param);
+ $this->PostList->DataSource=$this->getPosts();
+ $this->PostList->dataBind();
+ }
+}
+
+?> \ No newline at end of file
diff --git a/demos/blog/protected/Pages/Posts/MyPost.page b/demos/blog/protected/Pages/Posts/MyPost.page
new file mode 100644
index 00000000..95a32ac9
--- /dev/null
+++ b/demos/blog/protected/Pages/Posts/MyPost.page
@@ -0,0 +1,46 @@
+<com:TContent ID="Main">
+
+<h2>My Posts</h2>
+
+<com:TDataGrid ID="PostGrid"
+ AutoGenerateColumns="false"
+ CssClass="grid"
+ HeaderStyle.CssClass="grid-header"
+ ItemStyle.CssClass="grid-row1"
+ AlternatingItemStyle.CssClass="grid-row2"
+ AllowPaging="true"
+ AllowCustomPaging="true"
+ PageSize="20"
+ PagerStyle.CssClass="grid-pager"
+ PagerStyle.Mode="Numeric"
+ OnPageIndexChanged="changePage"
+ OnPagerCreated="pagerCreated"
+ >
+ <com:THyperLinkColumn
+ HeaderText="Title"
+ DataNavigateUrlField="ID"
+ DataNavigateUrlFormatString="#$this->Service->constructUrl('Posts.ViewPost',array('id'=>{0}))"
+ DataTextField="Title"
+ />
+ <com:TBoundColumn
+ HeaderText="Status"
+ DataField="Status"
+ DataFormatString="#{0}?'Published':'Draft'"
+ ItemStyle.Width="70px"
+ />
+ <com:TBoundColumn
+ HeaderText="Comments"
+ DataField="CommentCount"
+ ItemStyle.HorizontalAlign="Center"
+ ItemStyle.Width="80px"
+ />
+ <com:TBoundColumn
+ HeaderText="Time"
+ DataField="CreateTime"
+ DataFormatString="#date('M j, Y',{0})"
+ ItemStyle.Wrap="false"
+ ItemStyle.Width="90px"
+ />
+</com:TDataGrid>
+
+</com:TContent> \ No newline at end of file
diff --git a/demos/blog/protected/Pages/Posts/MyPost.php b/demos/blog/protected/Pages/Posts/MyPost.php
new file mode 100644
index 00000000..be03ca63
--- /dev/null
+++ b/demos/blog/protected/Pages/Posts/MyPost.php
@@ -0,0 +1,34 @@
+<?php
+
+class MyPost extends BlogPage
+{
+ protected function bindData()
+ {
+ $author=$this->User->ID;
+ $offset=$this->PostGrid->CurrentPageIndex*$this->PostGrid->PageSize;
+ $limit=$this->PostGrid->PageSize;
+ $this->PostGrid->DataSource=$this->DataAccess->queryPosts("author_id=$author",'','','ORDER BY a.status ASC, create_time DESC',"LIMIT $offset,$limit");
+ $this->PostGrid->VirtualItemCount=$this->DataAccess->queryPostCount("author_id=$author",'','');
+ $this->PostGrid->dataBind();
+ }
+
+ public function onLoad($param)
+ {
+ parent::onLoad($param);
+ if(!$this->IsPostBack)
+ $this->bindData();
+ }
+
+ public function changePage($sender,$param)
+ {
+ $this->PostGrid->CurrentPageIndex=$param->NewPageIndex;
+ $this->bindData();
+ }
+
+ public function pagerCreated($sender,$param)
+ {
+ $param->Pager->Controls->insertAt(0,'Page: ');
+ }
+}
+
+?> \ No newline at end of file
diff --git a/demos/blog/protected/Pages/Posts/NewCategory.page b/demos/blog/protected/Pages/Posts/NewCategory.page
new file mode 100644
index 00000000..92fe1468
--- /dev/null
+++ b/demos/blog/protected/Pages/Posts/NewCategory.page
@@ -0,0 +1,36 @@
+<com:TContent ID="Main">
+
+<h2>New Post Category</h2>
+
+<span class="input-label">Category name</span>
+<com:TRequiredFieldValidator
+ Display="Dynamic"
+ ControlToValidate="CategoryName"
+ ErrorMessage="...is required"
+ ValidationGroup="category" />
+<com:TCustomValidator
+ ControlToValidate="CategoryName"
+ ValidationGroup="category"
+ Display="Dynamic"
+ OnServerValidate="checkCategoryName"
+ Text="...must be unique"
+ ControlCssClass="inputerror" />
+<br/>
+<com:TTextBox ID="CategoryName" Columns="50" MaxLength="128" />
+<br/>
+
+<span class="input-label">Description</span>
+<br/>
+<com:TTextBox
+ ID="CategoryDescription"
+ TextMode="MultiLine"
+ Columns="50"
+ Rows="5" />
+<br/>
+
+<com:TLinkButton
+ Text="Save"
+ OnClick="saveButtonClicked"
+ ValidationGroup="category" />
+
+</com:TContent> \ No newline at end of file
diff --git a/demos/blog/protected/Pages/Posts/NewCategory.php b/demos/blog/protected/Pages/Posts/NewCategory.php
new file mode 100644
index 00000000..d36f6af1
--- /dev/null
+++ b/demos/blog/protected/Pages/Posts/NewCategory.php
@@ -0,0 +1,24 @@
+<?php
+
+class NewCategory extends BlogPage
+{
+ public function saveButtonClicked($sender,$param)
+ {
+ if($this->IsValid)
+ {
+ $categoryRecord=new CategoryRecord;
+ $categoryRecord->Name=$this->CategoryName->Text;
+ $categoryRecord->Description=$this->CategoryDescription->Text;
+ $this->DataAccess->insertCategory($categoryRecord);
+ $this->gotoPage('Posts.ListPost',array('cat'=>$categoryRecord->ID));
+ }
+ }
+
+ public function checkCategoryName($sender,$param)
+ {
+ $name=$this->CategoryName->Text;
+ $param->IsValid=$this->DataAccess->queryCategoryByName($name)===null;
+ }
+}
+
+?> \ No newline at end of file
diff --git a/demos/blog/protected/Pages/Posts/NewPost.page b/demos/blog/protected/Pages/Posts/NewPost.page
new file mode 100644
index 00000000..a49188f6
--- /dev/null
+++ b/demos/blog/protected/Pages/Posts/NewPost.page
@@ -0,0 +1,41 @@
+<com:TContent ID="Main">
+
+<h2>Write a New Post</h2>
+
+Title
+<com:TRequiredFieldValidator
+Display="Dynamic"
+ ControlToValidate="Title"
+ ErrorMessage="...is required"
+ ValidationGroup="post" />
+<br/>
+<com:TTextBox ID="Title" Columns="70" MaxLength="256" />
+<br/>
+
+Content
+<com:TRequiredFieldValidator
+Display="Dynamic"
+ ControlToValidate="Content"
+ ErrorMessage="...is required"
+ ValidationGroup="post" />
+<br/>
+<com:THtmlArea ID="Content" Width="450px" />
+<br/>
+
+Categories<br/>
+<com:TListBox
+ ID="Categories"
+ SelectionMode="Multiple"
+ DataTextField="Name"
+ DataValueField="ID" />
+<br/>
+
+<com:TCheckBox ID="DraftMode" Text="in draft mode (the post will not be published)" />
+<br/>
+
+<com:TLinkButton
+ Text="Save"
+ OnClick="saveButtonClicked"
+ ValidationGroup="post" />
+
+</com:TContent> \ No newline at end of file
diff --git a/demos/blog/protected/Pages/Posts/NewPost.php b/demos/blog/protected/Pages/Posts/NewPost.php
new file mode 100644
index 00000000..055c7f92
--- /dev/null
+++ b/demos/blog/protected/Pages/Posts/NewPost.php
@@ -0,0 +1,34 @@
+<?php
+
+class NewPost extends BlogPage
+{
+ public function onLoad($param)
+ {
+ parent::onLoad($param);
+ if(!$this->IsPostBack)
+ {
+ $this->Categories->DataSource=$this->DataAccess->queryCategories();
+ $this->Categories->dataBind();
+ }
+ }
+
+ public function saveButtonClicked($sender,$param)
+ {
+ if($this->IsValid)
+ {
+ $postRecord=new PostRecord;
+ $postRecord->Title=$this->Title->Text;
+ $postRecord->Content=$this->Content->Text;
+ $postRecord->Status=$this->DraftMode->Checked?0:1;
+ $postRecord->CreateTime=time();
+ $postRecord->AuthorID=$this->User->ID;
+ $cats=array();
+ foreach($this->Categories->SelectedValues as $value)
+ $cats[]=TPropertyValue::ensureInteger($value);
+ $this->DataAccess->insertPost($postRecord,$cats);
+ $this->gotoPage('Posts.ViewPost',array('id'=>$postRecord->ID));
+ }
+ }
+}
+
+?> \ No newline at end of file
diff --git a/demos/blog/protected/Pages/Posts/ViewPost.page b/demos/blog/protected/Pages/Posts/ViewPost.page
new file mode 100644
index 00000000..4b233615
--- /dev/null
+++ b/demos/blog/protected/Pages/Posts/ViewPost.page
@@ -0,0 +1,113 @@
+<com:TContent ID="Main">
+
+<div class="post">
+<div class="post-title">
+<%= $this->CurrentPost->Title %>
+</div>
+<div class="post-time">
+<%= date('l, F j, Y \a\t h:i:s a',$this->CurrentPost->CreateTime) %>
+by
+<%= '<a href="' . $this->Service->constructUrl('Users.ViewUser',array('id'=>$this->CurrentPost->AuthorID)) . '">' . $this->CurrentPost->AuthorName . '</a>' %>
+<%= $this->CanEditPost ? '| <a href="' . $this->Service->constructUrl('Posts.EditPost',array('id'=>$this->CurrentPost->ID)) . '">Edit</a> | ' : '';
+%>
+<com:TLinkButton
+ Text="Delete"
+ OnClick="deleteButtonClicked"
+ Visible=<%= $this->CanEditPost %>
+ Attributes.onclick="if(!confirm('Are you sure to delete this post? This will also delete all related comments.')) return false;"
+ />
+</div>
+<div class="post-content">
+<%= $this->CurrentPost->Content %>
+</div>
+<div class="post-footer">
+<com:TRepeater ID="CategoryList" EnableViewState="false">
+ <prop:ItemTemplate>
+ [
+ <a href="<%# $this->Service->constructUrl('Posts.ListPost',array('cat'=>$this->DataItem->ID)) %>"><%# $this->DataItem->Name %></a>
+ ]
+ </prop:ItemTemplate>
+</com:TRepeater>
+</div>
+</div>
+
+<div class="comments">
+<a name="comments"></a>
+<h3>Comments</h3>
+
+<com:TRepeater ID="CommentList" OnItemCommand="repeaterItemCommand">
+ <prop:ItemTemplate>
+<div class="comment">
+<div class="comment-header">
+<com:TLinkButton
+ Text="Delete"
+ Attributes.onclick="if(!confirm('Are you sure to delete this comment?')) return false;"
+ CommandParameter=<%# $this->DataItem->ID %>
+ Visible=<%= $this->Page->CanEditPost %> Style="float:right"/>
+<%# date('F j, Y \a\t h:i:s a',$this->DataItem->CreateTime) %>
+by
+<%# $this->DataItem->AuthorWebsite==='' ?
+ $this->DataItem->AuthorName :
+ '<a href="' . $this->DataItem->AuthorWebsite . '">' . $this->DataItem->AuthorName . '</a>' %>
+</div>
+<div class="comment-content">
+<%# $this->DataItem->Content %>
+</div>
+</div>
+ </prop:ItemTemplate>
+</com:TRepeater>
+
+<h4>Leave your comment</h4>
+
+<span class="input-label">Name</span>
+<com:TRequiredFieldValidator
+ ControlToValidate="CommentAuthor"
+ ValidationGroup="comment""
+ Display="Dynamic"
+ Text="...is required"
+ ControlCssClass="inputerror" />
+<br/>
+<com:TTextBox ID="CommentAuthor" />
+<br/>
+
+<span class="input-label">Email address</span>
+<com:TRequiredFieldValidator
+ ControlToValidate="CommentEmail"
+ ValidationGroup="comment""
+ Display="Dynamic"
+ Text="...is required"
+ ControlCssClass="inputerror" />
+<com:TEmailAddressValidator
+ ControlToValidate="CommentEmail"
+ ValidationGroup="comment"
+ Display="Dynamic"
+ Text="*"
+ ErrorMessage="You entered an invalid email address."
+ ControlCssClass="inputerror" />
+<br/>
+<com:TTextBox ID="CommentEmail" />
+<br/>
+
+<span class="input-label">Personal website</span>
+<br/>
+<com:TTextBox ID="CommentWebsite" Columns="70"/>
+<br/>
+
+<span class="input-label">Comment</span>
+<com:TRequiredFieldValidator
+ ControlToValidate="CommentContent"
+ ValidationGroup="comment"
+ Display="Dynamic"
+ Text="...is required"
+ ControlCssClass="inputerror" />
+<br/>
+<com:TTextBox ID="CommentContent" TextMode="MultiLine" Columns="55" Rows="10"/>
+<br/>
+
+<com:TLinkButton
+ Text="Submit"
+ ValidationGroup="comment"
+ OnClick="submitCommentButtonClicked" />
+
+</div>
+</com:TContent> \ No newline at end of file
diff --git a/demos/blog/protected/Pages/Posts/ViewPost.php b/demos/blog/protected/Pages/Posts/ViewPost.php
new file mode 100644
index 00000000..309bedc1
--- /dev/null
+++ b/demos/blog/protected/Pages/Posts/ViewPost.php
@@ -0,0 +1,73 @@
+<?php
+
+class ViewPost extends BlogPage
+{
+ private $_postID=null;
+ private $_post=null;
+
+ public function getPostID()
+ {
+ if($this->_postID===null)
+ $this->_postID=TPropertyValue::ensureInteger($this->Request['id']);
+ return $this->_postID;
+ }
+
+ public function getCurrentPost()
+ {
+ if($this->_post===null)
+ {
+ if(($this->_post=$this->DataAccess->queryPostByID($this->getPostID()))===null)
+ $this->reportError(BlogErrors::ERROR_POST_NOT_FOUND);
+ }
+ return $this->_post;
+ }
+
+ public function getCanEditPost()
+ {
+ $user=$this->getUser();
+ $authorID=$this->getCurrentPost()->AuthorID;
+ return $authorID===$user->getID() || $user->isInRole('admin');
+ }
+
+ public function onLoad($param)
+ {
+ parent::onLoad($param);
+ $this->CategoryList->DataSource=$this->DataAccess->queryCategoriesByPostID($this->getPostID());
+ $this->CategoryList->dataBind();
+ $this->CommentList->DataSource=$this->DataAccess->queryCommentsByPostID($this->getPostID());
+ $this->CommentList->dataBind();
+ }
+
+ public function submitCommentButtonClicked($sender,$param)
+ {
+ if($this->IsValid)
+ {
+ $commentRecord=new CommentRecord;
+ $commentRecord->PostID=$this->CurrentPost->ID;
+ $commentRecord->AuthorName=$this->CommentAuthor->Text;
+ $commentRecord->AuthorEmail=$this->CommentEmail->Text;
+ $commentRecord->AuthorWebsite=$this->CommentWebsite->Text;
+ $commentRecord->AuthorIP=$this->Request->UserHostAddress;
+ $commentRecord->Content=$this->CommentContent->Text;
+ $commentRecord->CreateTime=time();
+ $commentRecord->Status=0;
+ $this->DataAccess->insertComment($commentRecord);
+ $this->Response->reload();
+ }
+ }
+
+ public function deleteButtonClicked($sender,$param)
+ {
+ $this->DataAccess->deletePost($this->PostID);
+ $this->gotoDefaultPage();
+ }
+
+ public function repeaterItemCommand($sender,$param)
+ {
+ $id=TPropertyValue::ensureInteger($param->CommandParameter);
+ $this->DataAccess->deleteComment($id);
+ $this->Response->reload();
+ }
+}
+
+?> \ No newline at end of file
diff --git a/demos/blog/protected/Pages/Posts/config.xml b/demos/blog/protected/Pages/Posts/config.xml
new file mode 100644
index 00000000..1c04e946
--- /dev/null
+++ b/demos/blog/protected/Pages/Posts/config.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<configuration>
+ <authorization>
+ <deny pages="EditPost,NewPost,MyPost" users="?" />
+ </authorization>
+</configuration> \ No newline at end of file