summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitattributes2
-rw-r--r--HISTORY5
-rw-r--r--demos/blog/index.php5
-rw-r--r--demos/blog/protected/Common/BlogDataModule.php15
-rw-r--r--demos/blog/protected/Common/schema.sql6
-rw-r--r--demos/blog/protected/Data/Settings.xml1
-rw-r--r--demos/blog/protected/Layouts/MainLayout.tpl2
-rw-r--r--demos/blog/protected/Pages/Admin/ConfigMan.page10
-rw-r--r--demos/blog/protected/Pages/Admin/ConfigMan.php2
-rw-r--r--demos/blog/protected/Pages/Posts/ListPost.page6
-rw-r--r--demos/blog/protected/Pages/Posts/ViewPost.page1
-rw-r--r--demos/blog/protected/Pages/Posts/ViewPost.php2
-rw-r--r--demos/blog/protected/Portlets/CommentPortlet.php39
-rw-r--r--demos/blog/protected/Portlets/CommentPortlet.tpl15
-rw-r--r--demos/blog/themes/Fall/style.css2
-rw-r--r--demos/blog/themes/Spring/style.css2
-rw-r--r--demos/blog/themes/Summer/style.css2
-rw-r--r--demos/blog/themes/Winter/style.css2
-rw-r--r--framework/Security/TUserManager.php24
-rw-r--r--framework/Web/UI/WebControls/TCheckBox.php15
-rw-r--r--framework/Web/UI/WebControls/TDataGrid.php4
-rw-r--r--framework/Web/UI/WebControls/TListControlValidator.php4
-rw-r--r--framework/Web/UI/WebControls/TRadioButton.php5
-rw-r--r--index.html3
24 files changed, 157 insertions, 17 deletions
diff --git a/.gitattributes b/.gitattributes
index d046e8ab..08cd6622 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -78,6 +78,8 @@ demos/blog/protected/Portlets/ArchivePortlet.php -text
demos/blog/protected/Portlets/ArchivePortlet.tpl -text
demos/blog/protected/Portlets/CategoryPortlet.php -text
demos/blog/protected/Portlets/CategoryPortlet.tpl -text
+demos/blog/protected/Portlets/CommentPortlet.php -text
+demos/blog/protected/Portlets/CommentPortlet.tpl -text
demos/blog/protected/Portlets/LoginPortlet.php -text
demos/blog/protected/Portlets/LoginPortlet.tpl -text
demos/blog/protected/Portlets/Portlet.php -text
diff --git a/HISTORY b/HISTORY
index be5af858..5f4fc7d0 100644
--- a/HISTORY
+++ b/HISTORY
@@ -7,7 +7,7 @@ NEW: TQueue (Qiang)
NEW: TSessionPageStatePersister (Qiang)
NEW: SQLMap (Wei)
-Version 3.0.1 June 1, 2006
+Version 3.0.1 June 4, 2006
==========================
BUG: Ticket#28 - OnClick does not work with Safari/KHTML (Wei)
BUG: Ticket#37 - Changes of config files do not trigger cache update (Qiang)
@@ -17,8 +17,11 @@ BUG: Ticket#167 - TSecurityManager issues warning when trying to encrypt/decrypt
BUG: Ticket#169 - Validation of subclass of THtmlArea/TDatePicker fails (Wei)
BUG: Ticket#179 - CGI incompatibility causing clientscripts.php failure (Qiang)
BUG: Ticket#181 - Unable to change Content-Type in response header if charset is not set (Qiang)
+BUG: Ticket#200 - onClick javascript event triggered twice on CheckBox label (Qiang)
ENH: Ticket#150 - TDataGrid and TDataList now render table section tags (Qiang)
ENH: Ticket#152 - constituent parts of TWizard are exposed (Qiang)
+ENH: Ticket#184 - added TUserManager.Users and Roles properties (Qiang)
+ENH: Ticket#197 - sanity check for datagrid header and footer (Qiang)
ENH: added sanity check to calling event handlers (Qiang)
ENH: added search for quickstart tutorials (Wei)
ENH: added support to property tags for template owner control (Qiang)
diff --git a/demos/blog/index.php b/demos/blog/index.php
index 43c0b436..88f798db 100644
--- a/demos/blog/index.php
+++ b/demos/blog/index.php
@@ -4,11 +4,16 @@ $basePath=dirname(__FILE__);
$frameworkPath=$basePath.'/../../framework/prado.php';
$assetsPath=$basePath.'/assets';
$runtimePath=$basePath.'/protected/runtime';
+$dataPath=$basePath.'/protected/Data';
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.");
+if(!is_writable($dataPath))
+ die("Please make sure that the directory $dataPath is writable by Web server process.");
+if(!extension_loaded("sqlite"))
+ die("SQLite PHP extension is required.");
require_once($frameworkPath);
diff --git a/demos/blog/protected/Common/BlogDataModule.php b/demos/blog/protected/Common/BlogDataModule.php
index a15701ab..3dc71989 100644
--- a/demos/blog/protected/Common/BlogDataModule.php
+++ b/demos/blog/protected/Common/BlogDataModule.php
@@ -341,9 +341,22 @@ class BlogDataModule extends TModule
return $commentRecord;
}
+ public function queryComments($filter,$orderBy,$limit)
+ {
+ if($filter!=='')
+ $filter='WHERE '.$filter;
+ $sql="SELECT * FROM tblComments $filter $orderBy $limit";
+ $result=$this->query($sql);
+ $rows=sqlite_fetch_all($result,SQLITE_ASSOC);
+ $comments=array();
+ foreach($rows as $row)
+ $comments[]=$this->populateCommentRecord($row);
+ return $comments;
+ }
+
public function queryCommentsByPostID($id)
{
- $sql="SELECT * FROM tblComments WHERE post_id=$id";
+ $sql="SELECT * FROM tblComments WHERE post_id=$id ORDER BY create_time DESC";
$result=$this->query($sql);
$rows=sqlite_fetch_all($result,SQLITE_ASSOC);
$comments=array();
diff --git a/demos/blog/protected/Common/schema.sql b/demos/blog/protected/Common/schema.sql
index a93512df..9c111f0c 100644
--- a/demos/blog/protected/Common/schema.sql
+++ b/demos/blog/protected/Common/schema.sql
@@ -66,5 +66,11 @@ INSERT INTO tblPosts (id,author_id,create_time,title,content,status)
INSERT INTO tblCategories (name,description,post_count)
VALUES ('Miscellaneous','This category holds posts on any topic.',1);
+INSERT INTO tblCategories (name,description,post_count)
+ VALUES ('PRADO','Topics related with the PRADO framework.',0);
+
+INSERT INTO tblCategories (name,description,post_count)
+ VALUES ('PHP','Topics related with PHP.',0);
+
INSERT INTO tblPost2Category (post_id,category_id)
VALUES (1,1);
diff --git a/demos/blog/protected/Data/Settings.xml b/demos/blog/protected/Data/Settings.xml
index b097f22f..69f55370 100644
--- a/demos/blog/protected/Data/Settings.xml
+++ b/demos/blog/protected/Data/Settings.xml
@@ -7,6 +7,7 @@
<parameter id="MultipleUser" value="false" />
<parameter id="AccountApproval" value="false" />
<parameter id="PostPerPage" value="6" />
+ <parameter id="RecentComments" value="6" />
<parameter id="PostApproval" value="false" />
<parameter id="ThemeName" value="Winter" />
</parameters> \ No newline at end of file
diff --git a/demos/blog/protected/Layouts/MainLayout.tpl b/demos/blog/protected/Layouts/MainLayout.tpl
index 87313f38..f3a77adc 100644
--- a/demos/blog/protected/Layouts/MainLayout.tpl
+++ b/demos/blog/protected/Layouts/MainLayout.tpl
@@ -34,6 +34,8 @@
<com:Application.Portlets.ArchivePortlet />
+<com:Application.Portlets.CommentPortlet />
+
</div><!-- end of sidebar -->
<div id="footer">
diff --git a/demos/blog/protected/Pages/Admin/ConfigMan.page b/demos/blog/protected/Pages/Admin/ConfigMan.page
index 69ee0899..5c6cd53d 100644
--- a/demos/blog/protected/Pages/Admin/ConfigMan.page
+++ b/demos/blog/protected/Pages/Admin/ConfigMan.page
@@ -56,6 +56,16 @@
Text="Please enter a number." />
<br/>
+<span class="input-label">Number of recent comments shown</span>
+<com:TTextBox ID="RecentComments" Columns="8"/>
+<com:TRegularExpressionValidator
+ ControlToValidate="RecentComments"
+ ValidationGroup="settings"
+ Display="Dynamic"
+ RegularExpression="[1-9]\d*"
+ Text="Please enter a number." />
+<br/>
+
<com:TCheckBox ID="PostApproval" Text="New posts need approval" />
<br/>
diff --git a/demos/blog/protected/Pages/Admin/ConfigMan.php b/demos/blog/protected/Pages/Admin/ConfigMan.php
index 6443e5a0..e4b89b3c 100644
--- a/demos/blog/protected/Pages/Admin/ConfigMan.php
+++ b/demos/blog/protected/Pages/Admin/ConfigMan.php
@@ -34,6 +34,7 @@ class ConfigMan extends BlogPage
$this->MultipleUser->Checked=TPropertyValue::ensureBoolean($parameters['MultipleUser']);
$this->AccountApproval->Checked=TPropertyValue::ensureBoolean($parameters['AccountApproval']);
$this->PostPerPage->Text=$parameters['PostPerPage'];
+ $this->RecentComments->Text=$parameters['RecentComments'];
$this->PostApproval->Checked=TPropertyValue::ensureBoolean($parameters['PostApproval']);
$themes=$this->Service->ThemeManager->AvailableThemes;
$this->ThemeName->DataSource=$themes;
@@ -55,6 +56,7 @@ class ConfigMan extends BlogPage
$elements[]=$this->createParameter('MultipleUser',$this->MultipleUser->Checked);
$elements[]=$this->createParameter('AccountApproval',$this->AccountApproval->Checked);
$elements[]=$this->createParameter('PostPerPage',$this->PostPerPage->Text);
+ $elements[]=$this->createParameter('RecentComments',$this->RecentComments->Text);
$elements[]=$this->createParameter('PostApproval',$this->PostApproval->Checked);
$themeName=$this->ThemeName->SelectedItem->Text;
$elements[]=$this->createParameter('ThemeName',$themeName);
diff --git a/demos/blog/protected/Pages/Posts/ListPost.page b/demos/blog/protected/Pages/Posts/ListPost.page
index 4c96d6fb..1371a5ab 100644
--- a/demos/blog/protected/Pages/Posts/ListPost.page
+++ b/demos/blog/protected/Pages/Posts/ListPost.page
@@ -3,6 +3,12 @@
<com:TPanel ID="CategoryPanel" Visible="false" CssClass="category">
<div class="category-name">
<%= $this->Category->Name %>
+<com:THyperLink
+ Text="[#]"
+ Tooltip="Edit this category"
+ Visible=<%= $this->User->IsAdmin %>
+ NavigateUrl=<%= $this->Service->constructUrl('Posts.EditCategory',array('id'=>$this->Category->ID)) %>
+ />
<com:TLinkButton
Text="[-]"
Tooltip="Delete this category"
diff --git a/demos/blog/protected/Pages/Posts/ViewPost.page b/demos/blog/protected/Pages/Posts/ViewPost.page
index 5bd80a52..c48b8537 100644
--- a/demos/blog/protected/Pages/Posts/ViewPost.page
+++ b/demos/blog/protected/Pages/Posts/ViewPost.page
@@ -43,6 +43,7 @@ by
<prop:ItemTemplate>
<div class="comment">
<div class="comment-header">
+<a name="c<%# $this->DataItem->ID %>"></a>
<com:TLinkButton
Text="Delete"
Attributes.onclick="if(!confirm('Are you sure to delete this comment?')) return false;"
diff --git a/demos/blog/protected/Pages/Posts/ViewPost.php b/demos/blog/protected/Pages/Posts/ViewPost.php
index 84f33cff..8d0a7124 100644
--- a/demos/blog/protected/Pages/Posts/ViewPost.php
+++ b/demos/blog/protected/Pages/Posts/ViewPost.php
@@ -75,7 +75,7 @@ class ViewPost extends BlogPage
public function deleteButtonClicked($sender,$param)
{
- $this->DataAccess->deletePost($this->PostID);
+ $this->DataAccess->deletePost($this->CurrentPost->ID);
$this->gotoDefaultPage();
}
diff --git a/demos/blog/protected/Portlets/CommentPortlet.php b/demos/blog/protected/Portlets/CommentPortlet.php
new file mode 100644
index 00000000..4147d6d3
--- /dev/null
+++ b/demos/blog/protected/Portlets/CommentPortlet.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ * CommentPortlet class file
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @link http://www.pradosoft.com/
+ * @copyright Copyright &copy; 2006 PradoSoft
+ * @license http://www.pradosoft.com/license/
+ * @version $Revision: $ $Date: $
+ */
+
+Prado::using('Application.Portlets.Portlet');
+
+/**
+ * CommentPortlet class
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @link http://www.pradosoft.com/
+ * @copyright Copyright &copy; 2006 PradoSoft
+ * @license http://www.pradosoft.com/license/
+ */
+class CommentPortlet extends Portlet
+{
+ public function onLoad($param)
+ {
+ parent::onLoad($param);
+ $comments=$this->Application->getModule('data')->queryComments('','ORDER BY create_time DESC','LIMIT 10');
+ foreach($comments as $comment)
+ {
+ $comment->ID=$this->Service->constructUrl('Posts.ViewPost',array('id'=>$comment->PostID)).'#c'.$comment->ID;
+ if(strlen($comment->Content)>40)
+ $comment->Content=substr($comment->Content,0,40).' ...';
+ }
+ $this->CommentList->DataSource=$comments;
+ $this->CommentList->dataBind();
+ }
+}
+
+?> \ No newline at end of file
diff --git a/demos/blog/protected/Portlets/CommentPortlet.tpl b/demos/blog/protected/Portlets/CommentPortlet.tpl
new file mode 100644
index 00000000..cebdabc6
--- /dev/null
+++ b/demos/blog/protected/Portlets/CommentPortlet.tpl
@@ -0,0 +1,15 @@
+<div class="portlet">
+
+<h2 class="portlet-title">Latest comments</h2>
+
+<div class="portlet-content">
+<com:TBulletedList
+ ID="CommentList"
+ DisplayMode="HyperLink"
+ DataTextField="Content"
+ DataValueField="ID"
+ EnableViewState="false"
+ />
+</div><!-- end of portlet-content -->
+
+</div><!-- end of portlet -->
diff --git a/demos/blog/themes/Fall/style.css b/demos/blog/themes/Fall/style.css
index 27975b05..9b18b151 100644
--- a/demos/blog/themes/Fall/style.css
+++ b/demos/blog/themes/Fall/style.css
@@ -132,7 +132,7 @@ a img {
.portlet-content {
margin: 0 0 10px 0;
- padding: 10px 10px 0 10px;
+ padding: 10px 0 0 10px;
font-size: 10px;
}
diff --git a/demos/blog/themes/Spring/style.css b/demos/blog/themes/Spring/style.css
index 7066669c..6a675c0f 100644
--- a/demos/blog/themes/Spring/style.css
+++ b/demos/blog/themes/Spring/style.css
@@ -132,7 +132,7 @@ a img {
.portlet-content {
margin: 0 0 10px 0;
- padding: 10px 10px 0 10px;
+ padding: 10px 0 0 10px;
font-size: 10px;
}
diff --git a/demos/blog/themes/Summer/style.css b/demos/blog/themes/Summer/style.css
index 068860d1..d7218f7d 100644
--- a/demos/blog/themes/Summer/style.css
+++ b/demos/blog/themes/Summer/style.css
@@ -132,7 +132,7 @@ a img {
.portlet-content {
margin: 0 0 10px 0;
- padding: 10px 10px 0 10px;
+ padding: 10px 0 0 10px;
font-size: 10px;
}
diff --git a/demos/blog/themes/Winter/style.css b/demos/blog/themes/Winter/style.css
index 4eadd18e..bfa488fa 100644
--- a/demos/blog/themes/Winter/style.css
+++ b/demos/blog/themes/Winter/style.css
@@ -133,7 +133,7 @@ a img {
.portlet-content {
margin: 0 0 10px 0;
border-top: 1px solid #cfd4d9;
- padding: 10px 10px 0 10px;
+ padding: 10px 0 0 10px;
font-size: 10px;
}
diff --git a/framework/Security/TUserManager.php b/framework/Security/TUserManager.php
index 45e55bd7..6b10fa8b 100644
--- a/framework/Security/TUserManager.php
+++ b/framework/Security/TUserManager.php
@@ -124,6 +124,30 @@ class TUserManager extends TModule implements IUserManager
}
/**
+ * Returns an array of all users.
+ * Each array element represents a single user.
+ * The array key is the username in lower case, and the array value is the
+ * corresponding user password.
+ * @return array list of users
+ */
+ public function getUsers()
+ {
+ return $this->_users;
+ }
+
+ /**
+ * Returns an array of user role information.
+ * Each array element represents the roles for a single user.
+ * The array key is the username in lower case, and the array value is
+ * the roles (represented as an array) that the user is in.
+ * @return array list of user role information
+ */
+ public function getRoles()
+ {
+ return $this->_roles;
+ }
+
+ /**
* @return string the full path to the file storing user/role information
*/
public function getUserFile()
diff --git a/framework/Web/UI/WebControls/TCheckBox.php b/framework/Web/UI/WebControls/TCheckBox.php
index cb8fb30d..fda0480d 100644
--- a/framework/Web/UI/WebControls/TCheckBox.php
+++ b/framework/Web/UI/WebControls/TCheckBox.php
@@ -240,6 +240,8 @@ class TCheckBox extends TWebControl implements IPostBackDataHandler, IValidatabl
{
$attributes=$this->getAttributes();
$value=$attributes->remove('value');
+ // onclick js should only be added to input tag
+ $onclick=$attributes->remove('onclick');
if($attributes->getCount())
{
$writer->addAttributes($attributes);
@@ -248,6 +250,8 @@ class TCheckBox extends TWebControl implements IPostBackDataHandler, IValidatabl
if($value!==null)
$attributes->add('value',$value);
}
+ else
+ $onclick='';
if($needSpan)
$writer->renderBeginTag('span');
$clientID=$this->getClientID();
@@ -256,16 +260,16 @@ class TCheckBox extends TWebControl implements IPostBackDataHandler, IValidatabl
if($this->getTextAlign()==='Left')
{
$this->renderLabel($writer,$clientID,$text);
- $this->renderInputTag($writer,$clientID);
+ $this->renderInputTag($writer,$clientID,$onclick);
}
else
{
- $this->renderInputTag($writer,$clientID);
+ $this->renderInputTag($writer,$clientID,$onclick);
$this->renderLabel($writer,$clientID,$text);
}
}
else
- $this->renderInputTag($writer,$clientID);
+ $this->renderInputTag($writer,$clientID,$onclick);
if($needSpan)
$writer->renderEndTag();
}
@@ -334,14 +338,17 @@ class TCheckBox extends TWebControl implements IPostBackDataHandler, IValidatabl
* Renders a checkbox input element.
* @param THtmlWriter the writer for the rendering purpose
* @param string checkbox id
+ * @param string onclick js
*/
- protected function renderInputTag($writer,$clientID)
+ protected function renderInputTag($writer,$clientID,$onclick)
{
if($clientID!=='')
$writer->addAttribute('id',$clientID);
$writer->addAttribute('type','checkbox');
if(($value = $this->getValueAttribute()) !== '')
$writer->addAttribute('value',$value);
+ if($onclick!=='')
+ $writer->addAttribute('onclick',$onclick);
if(($uniqueID=$this->getUniqueID())!=='')
$writer->addAttribute('name',$uniqueID);
if($this->getChecked())
diff --git a/framework/Web/UI/WebControls/TDataGrid.php b/framework/Web/UI/WebControls/TDataGrid.php
index 6ff6faba..82c243ca 100644
--- a/framework/Web/UI/WebControls/TDataGrid.php
+++ b/framework/Web/UI/WebControls/TDataGrid.php
@@ -1523,7 +1523,7 @@ class TDataGrid extends TBaseDataList implements INamingContainer
protected function renderTable($writer)
{
$this->renderBeginTag($writer);
- if($this->_header->getVisible())
+ if($this->_header && $this->_header->getVisible())
{
$writer->writeLine();
$writer->renderBeginTag('thead');
@@ -1536,7 +1536,7 @@ class TDataGrid extends TBaseDataList implements INamingContainer
$item->renderControl($writer);
$writer->renderEndTag();
- if($this->_footer->getVisible())
+ if($this->_footer && $this->_footer->getVisible())
{
$writer->writeLine();
$writer->renderBeginTag('tfoot');
diff --git a/framework/Web/UI/WebControls/TListControlValidator.php b/framework/Web/UI/WebControls/TListControlValidator.php
index 0d0940ab..be69085d 100644
--- a/framework/Web/UI/WebControls/TListControlValidator.php
+++ b/framework/Web/UI/WebControls/TListControlValidator.php
@@ -36,7 +36,7 @@ Prado::using('System.Web.UI.WebControls.TBaseValidator');
* <com:TListItem Text="item3" Value="value3" />
* </com:TListBox>
*
- * <com:TRequiredListValidator
+ * <com:TListControlValidator
* ControlToValidate="listbox"
* MinSelection="2"
* ErrorMessage="Please select at least 2" />
@@ -49,7 +49,7 @@ Prado::using('System.Web.UI.WebControls.TBaseValidator');
* <com:TListItem Text="item3" Value="value3" />
* </com:TCheckBoxList>
*
- * <com:TRequiredListValidator
+ * <com:TListControlValidator
* ControlToValidate="checkboxes"
* RequiredSelections="value1"
* MinSelection="2"
diff --git a/framework/Web/UI/WebControls/TRadioButton.php b/framework/Web/UI/WebControls/TRadioButton.php
index 6a5ade4d..dc7ba057 100644
--- a/framework/Web/UI/WebControls/TRadioButton.php
+++ b/framework/Web/UI/WebControls/TRadioButton.php
@@ -139,14 +139,17 @@ class TRadioButton extends TCheckBox
* Renders a radiobutton input element.
* @param THtmlWriter the writer for the rendering purpose
* @param string checkbox id
+ * @param string onclick js
*/
- protected function renderInputTag($writer,$clientID)
+ protected function renderInputTag($writer,$clientID,$onclick)
{
if($clientID!=='')
$writer->addAttribute('id',$clientID);
$writer->addAttribute('type','radio');
$writer->addAttribute('name',$this->getUniqueGroupName());
$writer->addAttribute('value',$this->getValueAttribute());
+ if($onclick!=='')
+ $writer->addAttribute('onclick',$onclick);
if($this->getChecked())
$writer->addAttribute('checked','checked');
if(!$this->getEnabled(true))
diff --git a/index.html b/index.html
index eeb0e53b..f1513ff1 100644
--- a/index.html
+++ b/index.html
@@ -7,7 +7,7 @@
<body>
<h1>PRADO Framework for PHP 5 </h1>
-<p>Version 3.0.0, May 1, 2006<br>
+<p>Version 3.0.1, June 4, 2006<br>
Copyright&copy; 2004-2006 by <a href="http://www.pradosoft.com/">PradoSoft</a><br>
All Rights Reserved.
</p>
@@ -54,6 +54,7 @@ The installation is done! You will see the following subdirectories,
<ul>
<li><a href="demos/helloworld/index.php">Hello World</a></li>
<li><a href="demos/quickstart/index.php">Prado QuickStart Tutorial</a> (contains many small demos)</li>
+ <li><a href="demos/blog/index.php">Prado Weblog</a> (requires sqlite extension)
<li><a href="demos/composer/index.php">Prado Component Writer</a></li>
<li><a href="demos/peronsal/index.php">Personal Website</a> (incomplete)</li>
</ul>