From 51aa293bdd77fa6a7bc65341c962655ab7ef52e7 Mon Sep 17 00:00:00 2001
From: "ctrlaltca@gmail.com" <>
Date: Wed, 9 Nov 2011 22:12:14 +0000
Subject: fix #370: - deprecated TSqliteCache, use TDbCache instead - reworked
the dataaccess code of demos/blog - other smalll fixes around
---
HISTORY | 1 +
UPGRADE | 6 +-
demos/blog/index.php | 2 -
demos/blog/index_php.php | 2 -
demos/blog/protected/Common/BlogDataModule.php | 391 ++++++++++++++-------
demos/blog/protected/Pages/SearchPost.php | 16 +-
demos/blog/protected/application.php | 2 +-
demos/blog/protected/application.xml | 2 +-
.../PhpShell/PHP/Shell/Extensions/Prototypes.php | 228 ------------
framework/Caching/TSqliteCache.php | 5 +-
framework/Data/TDbCommand.php | 4 +-
requirements/index.php | 2 +-
requirements/messages-bg.txt | 2 +-
requirements/messages-id.txt | 2 +-
requirements/messages-zh.txt | 2 +-
requirements/messages.txt | 74 ++--
16 files changed, 322 insertions(+), 419 deletions(-)
diff --git a/HISTORY b/HISTORY
index 1ad2f77e..9a05be93 100644
--- a/HISTORY
+++ b/HISTORY
@@ -39,6 +39,7 @@ BUG: Issue #371 - Sorting on TActiveDataGrid autogenerated column not work (ctrl
ENH: Performance (micro)optimization in TUrlMapping::loadUrlMappings - invoke `getDefaultMappingClass` outside of loop (Yves)
BUG: TActiveMultiView must update clientside only when necessary to get other active controls work fine inside it (ctrlaltca)
BUG: TListBox doesn't correctly reports selected indices to serverside on callback
+CHG: Deprecated TSqliteCache since it's based on php's sqlite extension (ctrlaltca)
Version 3.1.10 Jul 17, 2011
BUG: Added missing timeout on TCacheHttpSession (ctrlaltca)
diff --git a/UPGRADE b/UPGRADE
index f290c3e0..a9af97a9 100644
--- a/UPGRADE
+++ b/UPGRADE
@@ -30,7 +30,11 @@ Upgrading from v3.1.x
The easist way to understand if a component is broken because of this change is to check if you get a
'Operation invalid when page is already rendering' exception.
- A new "TReCaptcha" control has been added to overcome the limited security offered by TCaptcha. If you
- are currently using TCaptcha, an update to the new control is really adviced.
+ are currently using TCaptcha, an update to the new control is really adviced.
+- Since php 5.2 the "sqlite" extension is not built by default. As a consequence, we deprecated (but kept
+ to mantain backwards compatibility) everything based on that extension.
+ TSqliteCache should be abandoned in favour of TDbCache.
+ The "sqlite" backend for message translation has been deprecated, use "Database" instead.
Upgrading from v3.1.10
diff --git a/demos/blog/index.php b/demos/blog/index.php
index 88f798db..6bec1512 100644
--- a/demos/blog/index.php
+++ b/demos/blog/index.php
@@ -12,8 +12,6 @@ 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/index_php.php b/demos/blog/index_php.php
index a5434860..76c5345c 100644
--- a/demos/blog/index_php.php
+++ b/demos/blog/index_php.php
@@ -12,8 +12,6 @@ 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);
$application=new TApplication('protected',false,TApplication::CONFIG_TYPE_PHP);
diff --git a/demos/blog/protected/Common/BlogDataModule.php b/demos/blog/protected/Common/BlogDataModule.php
index d44d9126..26dfc5cf 100644
--- a/demos/blog/protected/Common/BlogDataModule.php
+++ b/demos/blog/protected/Common/BlogDataModule.php
@@ -50,8 +50,14 @@ class BlogDataModule extends TModule
{
if(trim($statement)!=='')
{
- if(@sqlite_query($this->_db,$statement)===false)
- throw new BlogException(500,'blogdatamodule_createdatabase_failed',sqlite_error_string(sqlite_last_error($this->_db)),$statement);
+ try {
+ $command=$this->_db->createCommand($statement);
+ $command->execute();
+ }
+ catch(TDbException $e)
+ {
+ throw new BlogException(500,'blogdatamodule_createdatabase_failed',$e->getErrorMessage(),$statement);
+ }
}
}
}
@@ -60,9 +66,16 @@ class BlogDataModule extends TModule
{
$dbFile=$this->getDbFile();
$newDb=!is_file($dbFile);
- $error='';
- if(($this->_db=sqlite_open($dbFile,0666,$error))===false)
- throw new BlogException(500,'blogdatamodule_dbconnect_failed',$error);
+
+ try {
+ $this->_db=new TDbConnection("sqlite:".$dbFile);
+ $this->_db->Active=true;
+ }
+ catch(TDbException $e)
+ {
+ throw new BlogException(500,'blogdatamodule_dbconnect_failed',$e->getErrorMessage());
+ }
+
if($newDb)
$this->createDatabase();
}
@@ -81,10 +94,14 @@ class BlogDataModule extends TModule
public function query($sql)
{
- if(($result=@sqlite_query($this->_db,$sql))!==false)
- return $result;
- else
- throw new BlogException(500,'blogdatamodule_query_failed',sqlite_error_string(sqlite_last_error($this->_db)),$sql);
+ try {
+ $command=$this->_db->createCommand($sql);
+ return $command->query();
+ }
+ catch(TDbException $e)
+ {
+ throw new BlogException(500,'blogdatamodule_query_failed',$e->getErrorMessage(),$sql);
+ }
}
protected function populateUserRecord($row)
@@ -108,8 +125,7 @@ class BlogDataModule extends TModule
if($filter!=='')
$filter='WHERE '.$filter;
$sql="SELECT * FROM tblUsers $filter $orderBy $limit";
- $result=$this->query($sql);
- $rows=sqlite_fetch_all($result,SQLITE_ASSOC);
+ $rows=$this->query($sql);
$users=array();
foreach($rows as $row)
$users[]=$this->populateUserRecord($row);
@@ -122,7 +138,7 @@ class BlogDataModule extends TModule
$filter='WHERE '.$filter;
$sql="SELECT COUNT(id) AS user_count FROM tblUsers $filter";
$result=$this->query($sql);
- if(($row=sqlite_fetch_array($result,SQLITE_ASSOC))!==false)
+ if(($row=$result->read())!==false)
return $row['user_count'];
else
return 0;
@@ -132,7 +148,7 @@ class BlogDataModule extends TModule
{
$sql="SELECT * FROM tblUsers WHERE id=$id";
$result=$this->query($sql);
- if(($row=sqlite_fetch_array($result,SQLITE_ASSOC))!==false)
+ if(($row=$result->read())!==false)
return $this->populateUserRecord($row);
else
return null;
@@ -140,10 +156,12 @@ class BlogDataModule extends TModule
public function queryUserByName($name)
{
- $name=sqlite_escape_string($name);
- $sql="SELECT * FROM tblUsers WHERE name='$name'";
- $result=$this->query($sql);
- if(($row=sqlite_fetch_array($result,SQLITE_ASSOC))!==false)
+ $command=$this->_db->createCommand("SELECT * FROM tblUsers WHERE name=?");
+ $command->bindValue(1, $name);
+
+ $result=$command->query();
+
+ if(($row=$result->read())!==false)
return $this->populateUserRecord($row);
else
return null;
@@ -151,42 +169,51 @@ class BlogDataModule extends TModule
public function insertUser($user)
{
- $name=sqlite_escape_string($user->Name);
- $fullName=sqlite_escape_string($user->FullName);
- $passwd=sqlite_escape_string($user->Password);
- $email=sqlite_escape_string($user->Email);
- $website=sqlite_escape_string($user->Website);
- $createTime=time();
- $sql="INSERT INTO tblUsers ".
+ $command=$this->_db->createCommand("INSERT INTO tblUsers ".
"(name,full_name,role,passwd,email,reg_time,status,website) ".
- "VALUES ('$name','$fullName',{$user->Role},'$passwd','$email',$createTime,{$user->Status},'$website')";
- $this->query($sql);
- $user->ID=sqlite_last_insert_rowid($this->_db);
+ "VALUES (?,?,?,?,?,?,?,?)");
+ $command->bindValue(1, $user->Name);
+ $command->bindValue(2, $user->FullName);
+ $command->bindValue(3, $user->Role);
+ $command->bindValue(4, $user->Password);
+ $command->bindValue(5, $user->Email);
+ $command->bindValue(6, time());
+ $command->bindValue(7, $user->Status);
+ $command->bindValue(8, $user->Website);
+ $command->execute();
+
+ $user->ID=$this->_db->getLastInsertID();
}
public function updateUser($user)
{
- $name=sqlite_escape_string($user->Name);
- $fullName=sqlite_escape_string($user->FullName);
- $passwd=sqlite_escape_string($user->Password);
- $email=sqlite_escape_string($user->Email);
- $website=sqlite_escape_string($user->Website);
- $sql="UPDATE tblUsers SET
- name='$name',
- full_name='$fullName',
- role={$user->Role},
- passwd='$passwd',
- vcode='{$user->VerifyCode}',
- email='$email',
- status={$user->Status},
- website='$website'
- WHERE id={$user->ID}";
- $this->query($sql);
+ $command=$this->_db->createCommand("UPDATE tblUsers SET
+ name=?,
+ full_name=?,
+ role=?,
+ passwd=?,
+ vcode=?,
+ email=?,
+ status=?,
+ website=?
+ WHERE id=?");
+ $command->bindValue(1, $user->Name);
+ $command->bindValue(2, $user->FullName);
+ $command->bindValue(3, $user->Role);
+ $command->bindValue(4, $user->Password);
+ $command->bindValue(5, $user->VerifyCode);
+ $command->bindValue(6, $user->Email);
+ $command->bindValue(7, $user->Status);
+ $command->bindValue(8, $user->Website);
+ $command->bindValue(9, $user->ID);
+ $command->execute();
}
public function deleteUser($id)
{
- $this->query("DELETE FROM tblUsers WHERE id=$id");
+ $command=$this->_db->createCommand("DELETE FROM tblUsers WHERE id=?");
+ $command->bindValue(1, $id);
+ $command->execute();
}
protected function populatePostRecord($row)
@@ -209,6 +236,7 @@ class BlogDataModule extends TModule
public function queryPosts($postFilter,$categoryFilter,$orderBy,$limit)
{
+ //FIXME this is insecure by design since it misses proper escaping
$filter='';
if($postFilter!=='')
$filter.=" AND $postFilter";
@@ -226,16 +254,54 @@ class BlogDataModule extends TModule
a.comment_count AS comment_count
FROM tblPosts a, tblUsers b
WHERE a.author_id=b.id $filter $orderBy $limit";
- $result=$this->query($sql);
- $rows=sqlite_fetch_all($result,SQLITE_ASSOC);
+ $rows=$this->query($sql);
$posts=array();
foreach($rows as $row)
$posts[]=$this->populatePostRecord($row);
return $posts;
}
+ public function queryPostsSearch($keywords,$orderBy,$limit)
+ {
+ $sql="SELECT a.id AS id,
+ a.author_id AS author_id,
+ b.name AS author_name,
+ b.full_name AS author_full_name,
+ a.create_time AS create_time,
+ a.modify_time AS modify_time,
+ a.title AS title,
+ a.content AS content,
+ a.status AS status,
+ a.comment_count AS comment_count
+ FROM tblPosts a, tblUsers b
+ WHERE a.author_id=b.id AND a.status=0";
+
+ foreach($keywords as $keyword)
+ $sql.=" AND (content LIKE ? OR title LIKE ?)";
+
+ $sql.=" $orderBy $limit";
+
+ $command=$this->_db->createCommand($sql);
+
+ $i=1;
+ foreach($keywords as $keyword)
+ {
+ $command->bindValue($i, "%".$keyword."%");
+ $i++;
+ }
+
+ $rows=$command->query();
+
+ $posts=array();
+ foreach($rows as $row)
+ $posts[]=$this->populatePostRecord($row);
+ return $posts;
+
+ }
+
public function queryPostCount($postFilter,$categoryFilter)
{
+ //FIXME this is insecure by design since it misses proper escaping
$filter='';
if($postFilter!=='')
$filter.=" AND $postFilter";
@@ -245,7 +311,7 @@ class BlogDataModule extends TModule
FROM tblPosts a, tblUsers b
WHERE a.author_id=b.id $filter";
$result=$this->query($sql);
- if(($row=sqlite_fetch_array($result,SQLITE_ASSOC))!==false)
+ if(($row=$result->read())!==false)
return $row['post_count'];
else
return 0;
@@ -264,28 +330,33 @@ class BlogDataModule extends TModule
a.status AS status,
a.comment_count AS comment_count
FROM tblPosts a, tblUsers b
- WHERE a.id=$id AND a.author_id=b.id";
- $result=$this->query($sql);
- if(($row=sqlite_fetch_array($result,SQLITE_ASSOC))!==false)
+ WHERE a.id=? AND a.author_id=b.id";
+
+ $command=$this->_db->createCommand($sql);
+ $command->bindValue(1, $id);
+
+ $result=$command->query();
+
+ if(($row=$result->read())!==false)
return $this->populatePostRecord($row);
else
return null;
}
- public function escapeString($string)
- {
- return sqlite_escape_string($string);
- }
-
public function insertPost($post,$catIDs)
{
- $title=sqlite_escape_string($post->Title);
- $content=sqlite_escape_string($post->Content);
- $sql="INSERT INTO tblPosts
+ $command=$this->_db->createCommand("INSERT INTO tblPosts
(author_id,create_time,modify_time,title,content,status)
- VALUES ({$post->AuthorID},{$post->CreateTime},{$post->ModifyTime},'$title','$content',{$post->Status})";
- $this->query($sql);
- $post->ID=sqlite_last_insert_rowid($this->_db);
+ VALUES (?,?,?,?,?,?)");
+ $command->bindValue(1, $post->AuthorID);
+ $command->bindValue(2, $post->CreateTime);
+ $command->bindValue(3, $post->ModifyTime);
+ $command->bindValue(4, $post->Title);
+ $command->bindValue(5, $post->Content);
+ $command->bindValue(6, $post->Status);
+
+ $command->execute();
+ $post->ID=$this->_db->getLastInsertID();
foreach($catIDs as $catID)
$this->insertPostCategory($post->ID,$catID);
}
@@ -306,15 +377,19 @@ class BlogDataModule extends TModule
$this->insertPostCategory($post->ID,$id);
}
- $title=sqlite_escape_string($post->Title);
- $content=sqlite_escape_string($post->Content);
- $sql="UPDATE tblPosts SET
- modify_time={$post->ModifyTime},
- title='$title',
- content='$content',
- status={$post->Status}
- WHERE id={$post->ID}";
- $this->query($sql);
+ $command=$this->_db->createCommand("UPDATE tblPosts SET
+ modify_time=?,
+ title=?,
+ content=?,
+ status=?
+ WHERE id=?");
+ $command->bindValue(1, $post->ModifyTime);
+ $command->bindValue(2, $post->Title);
+ $command->bindValue(3, $post->Content);
+ $command->bindValue(4, $post->Status);
+ $command->bindValue(5, $post->ID);
+
+ $command->execute();
}
public function deletePost($id)
@@ -322,8 +397,14 @@ class BlogDataModule extends TModule
$cats=$this->queryCategoriesByPostID($id);
foreach($cats as $cat)
$this->deletePostCategory($id,$cat->ID);
- $this->query("DELETE FROM tblComments WHERE post_id=$id");
- $this->query("DELETE FROM tblPosts WHERE id=$id");
+
+ $command=$this->_db->createCommand("DELETE FROM tblComments WHERE post_id=?");
+ $command->bindValue(1, $id);
+ $command->execute();
+
+ $command=$this->_db->createCommand("DELETE FROM tblPosts WHERE id=?");
+ $command->bindValue(1, $id);
+ $command->execute();
}
protected function populateCommentRecord($row)
@@ -343,11 +424,11 @@ class BlogDataModule extends TModule
public function queryComments($filter,$orderBy,$limit)
{
+ //FIXME this is insecure by design since it misses proper escaping
if($filter!=='')
$filter='WHERE '.$filter;
$sql="SELECT * FROM tblComments $filter $orderBy $limit";
- $result=$this->query($sql);
- $rows=sqlite_fetch_all($result,SQLITE_ASSOC);
+ $rows=$this->query($sql);
$comments=array();
foreach($rows as $row)
$comments[]=$this->populateCommentRecord($row);
@@ -356,9 +437,12 @@ class BlogDataModule extends TModule
public function queryCommentsByPostID($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);
+ $sql="SELECT * FROM tblComments WHERE post_id=? ORDER BY create_time DESC";
+ $command=$this->_db->createCommand($sql);
+ $command->bindValue(1, $id);
+
+ $rows=$command->query();
+
$comments=array();
foreach($rows as $row)
$comments[]=$this->populateCommentRecord($row);
@@ -367,35 +451,50 @@ class BlogDataModule extends TModule
public function insertComment($comment)
{
- $authorName=sqlite_escape_string($comment->AuthorName);
- $authorEmail=sqlite_escape_string($comment->AuthorEmail);
- $authorWebsite=sqlite_escape_string($comment->AuthorWebsite);
- $content=sqlite_escape_string($comment->Content);
$sql="INSERT INTO tblComments
(post_id,author_name,author_email,author_website,author_ip,create_time,status,content)
- VALUES ({$comment->PostID},'$authorName','$authorEmail','$authorWebsite','{$comment->AuthorIP}',{$comment->CreateTime},{$comment->Status},'$content')";
- $this->query($sql);
- $comment->ID=sqlite_last_insert_rowid($this->_db);
+ VALUES (?,?,?,?,?,?,?,?)";
+ $command=$this->_db->createCommand($sql);
+ $command->bindValue(1, $comment->PostID);
+ $command->bindValue(2, $comment->AuthorName);
+ $command->bindValue(3, $comment->AuthorEmail);
+ $command->bindValue(4, $comment->AuthorWebsite);
+ $command->bindValue(5, $comment->AuthorIP);
+ $command->bindValue(6, $comment->CreateTime);
+ $command->bindValue(7, $comment->Status);
+ $command->bindValue(8, $comment->Content);
+
+ $command->execute();
+ $comment->ID=$this->_db->getLastInsertID();
$this->query("UPDATE tblPosts SET comment_count=comment_count+1 WHERE id={$comment->PostID}");
}
public function updateComment($comment)
{
- $authorName=sqlite_escape_string($comment->AuthorName);
- $authorEmail=sqlite_escape_string($comment->AuthorEmail);
- $content=sqlite_escape_string($comment->Content);
- $sql="UPDATE tblComments SET status={$comment->Status} WHERE id={$comment->ID}";
- $this->query($sql);
+ $sql="UPDATE tblComments SET status=? WHERE id=?";
+ $command=$this->_db->createCommand($sql);
+ $command->bindValue(1, $comment->Status);
+ $command->bindValue(2, $comment->ID);
+
+ $command->execute();
}
public function deleteComment($id)
{
- $result=$this->query("SELECT post_id FROM tblComments WHERE id=$id");
- if(($row=sqlite_fetch_array($result,SQLITE_ASSOC))!==false)
+ $sql="SELECT post_id FROM tblComments WHERE id=?";
+ $command=$this->_db->createCommand($sql);
+ $command->bindValue(1, $id);
+ $result=$command->query();
+
+ if(($row=$result->read())!==false)
{
- $postID=$row['post_id'];
- $this->query("DELETE FROM tblComments WHERE id=$id");
- $this->query("UPDATE tblPosts SET comment_count=comment_count-1 WHERE id=$postID");
+ $command=$this->_db->createCommand("DELETE FROM tblComments WHERE id=?");
+ $command->bindValue(1, $id);
+ $command->execute();
+
+ $command=$this->_db->createCommand("UPDATE tblPosts SET comment_count=comment_count-1 WHERE id=?");
+ $command->bindValue(1, $row['post_id']);
+ $command->execute();
}
}
@@ -412,8 +511,7 @@ class BlogDataModule extends TModule
public function queryCategories()
{
$sql="SELECT * FROM tblCategories ORDER BY name ASC";
- $result=$this->query($sql);
- $rows=sqlite_fetch_all($result,SQLITE_ASSOC);
+ $rows=$this->query($sql);
$cats=array();
foreach($rows as $row)
$cats[]=$this->populateCategoryRecord($row);
@@ -427,9 +525,12 @@ class BlogDataModule extends TModule
a.description AS description,
a.post_count AS post_count
FROM tblCategories a, tblPost2Category b
- WHERE a.id=b.category_id AND b.post_id=$postID ORDER BY a.name";
- $result=$this->query($sql);
- $rows=sqlite_fetch_all($result,SQLITE_ASSOC);
+ WHERE a.id=b.category_id AND b.post_id=? ORDER BY a.name";
+
+ $command=$this->_db->createCommand($sql);
+ $command->bindValue(1, $postID);
+ $rows=$command->query();
+
$cats=array();
foreach($rows as $row)
$cats[]=$this->populateCategoryRecord($row);
@@ -438,9 +539,13 @@ class BlogDataModule extends TModule
public function queryCategoryByID($id)
{
- $sql="SELECT * FROM tblCategories WHERE id=$id";
- $result=$this->query($sql);
- if(($row=sqlite_fetch_array($result,SQLITE_ASSOC))!==false)
+ $sql="SELECT * FROM tblCategories WHERE id=?";
+
+ $command=$this->_db->createCommand($sql);
+ $command->bindValue(1, $id);
+ $result=$command->query();
+
+ if(($row=$result->read())!==false)
return $this->populateCategoryRecord($row);
else
return null;
@@ -448,10 +553,13 @@ class BlogDataModule extends TModule
public function queryCategoryByName($name)
{
- $name=sqlite_escape_string($name);
- $sql="SELECT * FROM tblCategories WHERE name='$name'";
- $result=$this->query($sql);
- if(($row=sqlite_fetch_array($result,SQLITE_ASSOC))!==false)
+ $sql="SELECT * FROM tblCategories WHERE name=?";
+
+ $command=$this->_db->createCommand($sql);
+ $command->bindValue(1, $name);
+ $result=$command->query();
+
+ if(($row=$result->read())!==false)
return $this->populateCategoryRecord($row);
else
return null;
@@ -459,46 +567,73 @@ class BlogDataModule extends TModule
public function insertCategory($category)
{
- $name=sqlite_escape_string($category->Name);
- $description=sqlite_escape_string($category->Description);
$sql="INSERT INTO tblCategories
(name,description)
- VALUES ('$name','$description')";
- $this->query($sql);
- $category->ID=sqlite_last_insert_rowid($this->_db);
+ VALUES (?,?)";
+
+ $command=$this->_db->createCommand($sql);
+ $command->bindValue(1, $category->Name);
+ $command->bindValue(2, $category->Description);
+ $command->execute();
+
+ $category->ID=$this->_db->getLastInsertID();
}
public function updateCategory($category)
{
- $name=sqlite_escape_string($category->Name);
- $description=sqlite_escape_string($category->Description);
- $sql="UPDATE tblCategories SET name='$name', description='$description', post_count={$category->PostCount} WHERE id={$category->ID}";
- $this->query($sql);
+ $sql="UPDATE tblCategories SET name=?, description=?, post_count=? WHERE id=?";
+
+ $command=$this->_db->createCommand($sql);
+ $command->bindValue(1, $category->Name);
+ $command->bindValue(2, $category->Description);
+ $command->bindValue(3, $category->PostCount);
+ $command->bindValue(4, $category->ID);
+
+ $command->execute();
}
public function deleteCategory($id)
{
- $sql="DELETE FROM tblPost2Category WHERE category_id=$id";
- $this->query($sql);
- $sql="DELETE FROM tblCategories WHERE id=$id";
- $this->query($sql);
+ $sql="DELETE FROM tblPost2Category WHERE category_id=?";
+ $command=$this->_db->createCommand($sql);
+ $command->bindValue(1, $id);
+ $command->execute();
+
+ $sql="DELETE FROM tblCategories WHERE id=?";
+ $command=$this->_db->createCommand($sql);
+ $command->bindValue(1, $id);
+ $command->execute();
}
public function insertPostCategory($postID,$categoryID)
{
- $sql="INSERT INTO tblPost2Category (post_id, category_id) VALUES ($postID, $categoryID)";
- $this->query($sql);
- $sql="UPDATE tblCategories SET post_count=post_count+1 WHERE id=$categoryID";
- $this->query($sql);
+ $sql="INSERT INTO tblPost2Category (post_id, category_id) VALUES (?, ?)";
+ $command=$this->_db->createCommand($sql);
+ $command->bindValue(1, $postID);
+ $command->bindValue(2, $categoryID);
+ $command->execute();
+
+ $sql="UPDATE tblCategories SET post_count=post_count+1 WHERE id=?";
+ $command=$this->_db->createCommand($sql);
+ $command->bindValue(1, $categoryID);
+ $command->execute();
+
}
public function deletePostCategory($postID,$categoryID)
{
- $sql="DELETE FROM tblPost2Category WHERE post_id=$postID AND category_id=$categoryID";
- if($this->query($sql)>0)
+ $sql="DELETE FROM tblPost2Category WHERE post_id=? AND category_id=?";
+ $command=$this->_db->createCommand($sql);
+ $command->bindValue(1, $postID);
+ $command->bindValue(2, $categoryID);
+ $result=$command->query();
+
+ if($result->getRowCount()>0)
{
- $sql="UPDATE tblCategories SET post_count=post_count-1 WHERE id=$categoryID";
- $this->query($sql);
+ $sql="UPDATE tblCategories SET post_count=post_count-1 WHERE id=?";
+ $command=$this->_db->createCommand($sql);
+ $command->bindValue(1, $categoryID);
+ $command->execute();
}
}
@@ -506,7 +641,7 @@ class BlogDataModule extends TModule
{
$sql="SELECT MIN(create_time) AS create_time FROM tblPosts";
$result=$this->query($sql);
- if(($row=sqlite_fetch_array($result,SQLITE_ASSOC))!==false)
+ if(($row=$result->read())!==false)
return $row['create_time'];
else
return time();
diff --git a/demos/blog/protected/Pages/SearchPost.php b/demos/blog/protected/Pages/SearchPost.php
index a824d257..dc483f9a 100644
--- a/demos/blog/protected/Pages/SearchPost.php
+++ b/demos/blog/protected/Pages/SearchPost.php
@@ -7,23 +7,15 @@ class SearchPost extends BlogPage
public function onInit($param)
{
parent::onInit($param);
- $this->_posts=$this->DataAccess->queryPosts(
- $this->getPostFilter(),
- '',
+ $this->_posts=$this->DataAccess->queryPostsSearch(
+ $this->getPostKeywords(),
'ORDER BY create_time DESC',
'LIMIT '.$this->getPageOffset().','.$this->getPageSize());
}
- private function getPostFilter()
+ private function getPostKeywords()
{
- $filter='a.status=0';
- $keywords=explode(' ',$this->Request['keyword']);
- foreach($keywords as $keyword)
- {
- if(($keyword=$this->DataAccess->escapeString(trim($keyword)))!=='')
- $filter.=" AND (content LIKE '%$keyword%' OR title LIKE '%$keyword%')";
- }
- return $filter;
+ return explode(' ',$this->Request['keyword']);
}
private function getPageOffset()
diff --git a/demos/blog/protected/application.php b/demos/blog/protected/application.php
index d7d7c97b..01604c03 100644
--- a/demos/blog/protected/application.php
+++ b/demos/blog/protected/application.php
@@ -20,7 +20,7 @@ return array(
),
'cache' => array(
- 'class' => 'System.Caching.TSqliteCache',
+ 'class' => 'System.Caching.TDbCache',
),
'error' => array(
diff --git a/demos/blog/protected/application.xml b/demos/blog/protected/application.xml
index d28b2dd7..908e3f59 100644
--- a/demos/blog/protected/application.xml
+++ b/demos/blog/protected/application.xml
@@ -9,7 +9,7 @@
-
+
diff --git a/framework/3rdParty/PhpShell/PHP/Shell/Extensions/Prototypes.php b/framework/3rdParty/PhpShell/PHP/Shell/Extensions/Prototypes.php
index 6e228688..618074e5 100644
--- a/framework/3rdParty/PhpShell/PHP/Shell/Extensions/Prototypes.php
+++ b/framework/3rdParty/PhpShell/PHP/Shell/Extensions/Prototypes.php
@@ -2529,234 +2529,6 @@ class PHP_ShellPrototypes {
'params' => 'int id, int variable_key',
'description' => 'Removes variable from shared memory',
),
- 'sqlite_popen' =>
- array (
- 'return' => 'resource',
- 'params' => 'string filename [, int mode [, string &error_message]]',
- 'description' => 'Opens a persistent handle to a SQLite database. Will create the database if it does not exist.',
- ),
- 'sqlite_open' =>
- array (
- 'return' => 'resource',
- 'params' => 'string filename [, int mode [, string &error_message]]',
- 'description' => 'Opens a SQLite database. Will create the database if it does not exist.',
- ),
- 'sqlite_factory' =>
- array (
- 'return' => 'object',
- 'params' => 'string filename [, int mode [, string &error_message]]',
- 'description' => 'Opens a SQLite database and creates an object for it. Will create the database if it does not exist.',
- ),
- 'sqlite_busy_timeout' =>
- array (
- 'return' => 'void',
- 'params' => 'resource db, int ms',
- 'description' => 'Set busy timeout duration. If ms <= 0, all busy handlers are disabled.',
- ),
- 'sqlite_close' =>
- array (
- 'return' => 'void',
- 'params' => 'resource db',
- 'description' => 'Closes an open sqlite database.',
- ),
- 'sqlite_unbuffered_query' =>
- array (
- 'return' => 'resource',
- 'params' => 'string query, resource db [ , int result_type [, string &error_message]]',
- 'description' => 'Executes a query that does not prefetch and buffer all data.',
- ),
- 'sqlite_fetch_column_types' =>
- array (
- 'return' => 'resource',
- 'params' => 'string table_name, resource db [, int result_type]',
- 'description' => 'Return an array of column types from a particular table.',
- ),
- 'sqlite_query' =>
- array (
- 'return' => 'resource',
- 'params' => 'string query, resource db [, int result_type [, string &error_message]]',
- 'description' => 'Executes a query against a given database and returns a result handle.',
- ),
- 'sqlite_exec' =>
- array (
- 'return' => 'boolean',
- 'params' => 'string query, resource db[, string &error_message]',
- 'description' => 'Executes a result-less query against a given database',
- ),
- 'sqlite_fetch_all' =>
- array (
- 'return' => 'array',
- 'params' => 'resource result [, int result_type [, bool decode_binary]]',
- 'description' => 'Fetches all rows from a result set as an array of arrays.',
- ),
- 'sqlite_fetch_array' =>
- array (
- 'return' => 'array',
- 'params' => 'resource result [, int result_type [, bool decode_binary]]',
- 'description' => 'Fetches the next row from a result set as an array.',
- ),
- 'sqlite_fetch_object' =>
- array (
- 'return' => 'object',
- 'params' => 'resource result [, string class_name [, NULL|array ctor_params [, bool decode_binary]]]',
- 'description' => 'Fetches the next row from a result set as an object.',
- ),
- 'sqlite_array_query' =>
- array (
- 'return' => 'array',
- 'params' => 'resource db, string query [ , int result_type [, bool decode_binary]]',
- 'description' => 'Executes a query against a given database and returns an array of arrays.',
- ),
- 'sqlite_single_query' =>
- array (
- 'return' => 'array',
- 'params' => 'resource db, string query [, bool first_row_only [, bool decode_binary]]',
- 'description' => 'Executes a query and returns either an array for one single column or the value of the first row.',
- ),
- 'sqlite_fetch_single' =>
- array (
- 'return' => 'string',
- 'params' => 'resource result [, bool decode_binary]',
- 'description' => 'Fetches the first column of a result set as a string.',
- ),
- 'sqlite_current' =>
- array (
- 'return' => 'array',
- 'params' => 'resource result [, int result_type [, bool decode_binary]]',
- 'description' => 'Fetches the current row from a result set as an array.',
- ),
- 'sqlite_column' =>
- array (
- 'return' => 'mixed',
- 'params' => 'resource result, mixed index_or_name [, bool decode_binary]',
- 'description' => 'Fetches a column from the current row of a result set.',
- ),
- 'sqlite_libversion' =>
- array (
- 'return' => 'string',
- 'params' => '',
- 'description' => 'Returns the version of the linked SQLite library.',
- ),
- 'sqlite_libencoding' =>
- array (
- 'return' => 'string',
- 'params' => '',
- 'description' => 'Returns the encoding (iso8859 or UTF-8) of the linked SQLite library.',
- ),
- 'sqlite_changes' =>
- array (
- 'return' => 'int',
- 'params' => 'resource db',
- 'description' => 'Returns the number of rows that were changed by the most recent SQL statement.',
- ),
- 'sqlite_last_insert_rowid' =>
- array (
- 'return' => 'int',
- 'params' => 'resource db',
- 'description' => 'Returns the rowid of the most recently inserted row.',
- ),
- 'sqlite_num_rows' =>
- array (
- 'return' => 'int',
- 'params' => 'resource result',
- 'description' => 'Returns the number of rows in a buffered result set.',
- ),
- 'sqlite_valid' =>
- array (
- 'return' => 'bool',
- 'params' => 'resource result',
- 'description' => 'Returns whether more rows are available.',
- ),
- 'sqlite_has_prev' =>
- array (
- 'return' => 'bool',
- 'params' => 'resource result',
- 'description' => '* Returns whether a previous row is available.',
- ),
- 'sqlite_num_fields' =>
- array (
- 'return' => 'int',
- 'params' => 'resource result',
- 'description' => 'Returns the number of fields in a result set.',
- ),
- 'sqlite_field_name' =>
- array (
- 'return' => 'string',
- 'params' => 'resource result, int field_index',
- 'description' => 'Returns the name of a particular field of a result set.',
- ),
- 'sqlite_seek' =>
- array (
- 'return' => 'bool',
- 'params' => 'resource result, int row',
- 'description' => 'Seek to a particular row number of a buffered result set.',
- ),
- 'sqlite_rewind' =>
- array (
- 'return' => 'bool',
- 'params' => 'resource result',
- 'description' => 'Seek to the first row number of a buffered result set.',
- ),
- 'sqlite_next' =>
- array (
- 'return' => 'bool',
- 'params' => 'resource result',
- 'description' => 'Seek to the next row number of a result set.',
- ),
- 'sqlite_key' =>
- array (
- 'return' => 'int',
- 'params' => 'resource result',
- 'description' => 'Return the current row index of a buffered result.',
- ),
- 'sqlite_prev' =>
- array (
- 'return' => 'bool',
- 'params' => 'resource result',
- 'description' => '* Seek to the previous row number of a result set.',
- ),
- 'sqlite_escape_string' =>
- array (
- 'return' => 'string',
- 'params' => 'string item',
- 'description' => 'Escapes a string for use as a query parameter.',
- ),
- 'sqlite_last_error' =>
- array (
- 'return' => 'int',
- 'params' => 'resource db',
- 'description' => 'Returns the error code of the last error for a database.',
- ),
- 'sqlite_error_string' =>
- array (
- 'return' => 'string',
- 'params' => 'int error_code',
- 'description' => 'Returns the textual description of an error code.',
- ),
- 'sqlite_create_aggregate' =>
- array (
- 'return' => 'bool',
- 'params' => 'resource db, string funcname, mixed step_func, mixed finalize_func[, long num_args]',
- 'description' => 'Registers an aggregate function for queries.',
- ),
- 'sqlite_create_function' =>
- array (
- 'return' => 'bool',
- 'params' => 'resource db, string funcname, mixed callback[, long num_args]',
- 'description' => 'Registers a "regular" function for queries.',
- ),
- 'sqlite_udf_encode_binary' =>
- array (
- 'return' => 'string',
- 'params' => 'string data',
- 'description' => 'Apply binary encoding (if required) to a string to return from an UDF.',
- ),
- 'sqlite_udf_decode_binary' =>
- array (
- 'return' => 'string',
- 'params' => 'string data',
- 'description' => 'Decode binary encoding on a string parameter passed to an UDF.',
- ),
'socket_select' =>
array (
'return' => 'int',
diff --git a/framework/Caching/TSqliteCache.php b/framework/Caching/TSqliteCache.php
index d4308e64..15314624 100644
--- a/framework/Caching/TSqliteCache.php
+++ b/framework/Caching/TSqliteCache.php
@@ -15,8 +15,9 @@
*
* TSqliteCache implements a cache application module based on SQLite database.
*
- * To use this module, the sqlite PHP extension must be loaded. Note, Sqlite extension
- * is no longer loaded by default since PHP 5.1.
+ * THIS CLASS IS DEPRECATED since it relies on the sqlite PHP extension, that is
+ * no longer loaded by default since PHP 5.1. You are discouraged from using it:
+ * use {@link TDbCache} instead.
*
* Since PRADO v3.1.0, a new DB-based cache module called {@link TDbCache}
* is provided. If you have PDO extension installed, you may consider using
diff --git a/framework/Data/TDbCommand.php b/framework/Data/TDbCommand.php
index 937a44ff..f542a277 100644
--- a/framework/Data/TDbCommand.php
+++ b/framework/Data/TDbCommand.php
@@ -4,7 +4,7 @@
*
* @author Qiang Xue
* @link http://www.pradosoft.com/
- * @copyright Copyright © 2005-2011 PradoSoft
+ * @copyright Copyright © 2005-2011 PradoSoft
* @license http://www.pradosoft.com/license/
* @version $Id$
* @package System.Data
@@ -133,6 +133,8 @@ class TDbCommand extends TComponent
* using named placeholders, this will be a parameter name of
* the form :name. For a prepared statement using question mark
* placeholders, this will be the 1-indexed position of the parameter.
+ * Unlike {@link bindValue}, the variable is bound as a reference and will
+ * only be evaluated at the time that {@link execute} or {@link query} is called.
* @param mixed Name of the PHP variable to bind to the SQL statement parameter
* @param int SQL data type of the parameter
* @param int length of the data type
diff --git a/requirements/index.php b/requirements/index.php
index 21ba2abc..2f222038 100644
--- a/requirements/index.php
+++ b/requirements/index.php
@@ -98,7 +98,7 @@ $requirements = array(
false,
extension_loaded("sqlite"),
'SQLite extension check',
- 'SQLite extension optional'),
+ 'SQLite extension optional deprecated'),
array(
false,
extension_loaded("memcache"),
diff --git a/requirements/messages-bg.txt b/requirements/messages-bg.txt
index 8e38c93d..62de0eed 100644
--- a/requirements/messages-bg.txt
+++ b/requirements/messages-bg.txt
@@ -2,7 +2,7 @@
passed with warnings = Конфигурацията на вашия сървър удовлетворява минималните изисквания на PRADO. Моля, обърнете внимание на предупрежденията по-долу.
failed = За съжаление, вашият сървър не удовлетворява изискванията на PRADO.
PHP version check = Проверка за версията на PHP
-PHP 5.1.0 or higher required = Изисква се PHP 5.1.0 или по-висока версия.
+PHP 5.2.0 or higher required = Изисква се PHP 5.2.0 или по-висока версия.
SQLite extension check = Проверка за SQLite
SQLite extension optional = SQLite разширението е незадължително. Ако не е заредено, няма да можете да ползвате TSqliteCache.
Memcache extension check = Проверка за Memcache
diff --git a/requirements/messages-id.txt b/requirements/messages-id.txt
index 95f767bf..96a74a60 100644
--- a/requirements/messages-id.txt
+++ b/requirements/messages-id.txt
@@ -2,7 +2,7 @@ all passed = Selamat! konfigurasi server anda memenuhi semua persyaratan PRAD
passed with warnings = Konfigurasi server anda memenuhi persyaratan minimum PRADO. Silahkan perhatikan peringatan yang didaftarkan di bawah.
failed = Maaf, konfigurasi server anda tidak memenuhi persyaratan PRADO.
PHP version check = pemeriksaan versi PHP
-PHP 5.1.0 or higher required = PHP versi 5.1.0 atau lebih tinggi diperlukan oleh PRADO.
+PHP 5.2.0 or higher required = PHP versi 5.2.0 atau lebih tinggi diperlukan oleh PRADO.
SQLite extension check = Pemeriksaan ekstensi SQLite
SQLite extension optional = Ekstensi SQLite adalah opsional. Jika tidak ada, anda tidak akan bisa menggunakan TSqliteCache.
Memcache extension check = Pemeriksaan ekstensi Memcache
diff --git a/requirements/messages-zh.txt b/requirements/messages-zh.txt
index d483440d..6151da17 100644
--- a/requirements/messages-zh.txt
+++ b/requirements/messages-zh.txt
@@ -2,7 +2,7 @@
passed with warnings = 您的服务器配置符合PRADO的最低要求。请关注以下的警告信息。
failed = 对不起,您的服务器配置不符合PRADO的要求。
PHP version check = PHP版本检查
-PHP 5.1.0 or higher required = PRADO需要PHP 5.1.0或更高版本。
+PHP 5.2.0 or higher required = PRADO需要PHP 5.2.0或更高版本。
SQLite extension check = SQLite模块检查
SQLite extension optional = SQLite模块是可选的。如果它不存在,您将无法使用TSQLiteCache。
Memcache extension check = Memcache模块检查
diff --git a/requirements/messages.txt b/requirements/messages.txt
index 5c60b8bc..9e9c595e 100644
--- a/requirements/messages.txt
+++ b/requirements/messages.txt
@@ -1,41 +1,41 @@
-all passed = Congratulations! Your server configuration satisfies all requirements by PRADO.
-passed with warnings = Your server configuration satisfies minimum requirements by PRADO. Please pay attention to the warnings listed below.
-failed = Sorry, your server configuration does not satisfy the requirements by PRADO.
-PHP version check = PHP version check
-PHP 5.1.0 or higher required = PHP version 5.1.0 or higher is required by PRADO.
-SQLite extension check = SQLite extension check
-SQLite extension optional = SQLite extension is optional. If it is absent, you will not be able to use TSqliteCache.
-Memcache extension check = Memcache extension check
-Memcache extension optional = Memcache extension is optional. If it is absent, you will not be able to use TMemCache.
-APC extension check = APC extension check
-APC extension optional = APC extension is optional. If it is absent, you will not be able to use TAPCCache.
-Zlib extension check = Zlib extension check
-Zlib extension optional = Zlib extension is optional. If it is absent, page state will not be compressed and your page size may increase.
-Reflection extension check = Reflection extension check
+all passed = Congratulations! Your server configuration satisfies all requirements by PRADO.
+passed with warnings = Your server configuration satisfies minimum requirements by PRADO. Please pay attention to the warnings listed below.
+failed = Sorry, your server configuration does not satisfy the requirements by PRADO.
+PHP version check = PHP version check
+PHP 5.2.0 or higher required = PHP version 5.2.0 or higher is required by PRADO.
+SQLite extension check = SQLite extension check
+SQLite extension optional deprecated = SQLite extension is deprecated, but can still be used optionally to support old code.
+Memcache extension check = Memcache extension check
+Memcache extension optional = Memcache extension is optional. If it is absent, you will not be able to use TMemCache.
+APC extension check = APC extension check
+APC extension optional = APC extension is optional. If it is absent, you will not be able to use TAPCCache.
+Zlib extension check = Zlib extension check
+Zlib extension optional = Zlib extension is optional. If it is absent, page state will not be compressed and your page size may increase.
+Reflection extension check = Reflection extension check
Reflection extension required = Reflection extension is required by PRADO. It is used in by PRADO to check the validity of page templates.
-DOM extension check = DOM extension check
-DOM extension required = DOM extension is required by PRADO. It is used in TXmlDocument to parse all sorts of XML-based configurations.
-ICONV extension check = ICONV extension check
-ICONV extension optional = ICONV extension is optional. If it is absent, some internationalization components may not work properly.
-Mcrypt extension check = Mcrypt extension check
-Mcrypt extension optional = Mcrypt extension is optional. If it is absent, sensitive data, such as viewstate, cannot be encrypted.
-XSL extension check = XSL extension check
-XSL extension optional = XSL extension is optional. If it is absent, you will not be able to use TXmlTransform.
+DOM extension check = DOM extension check
+DOM extension required = DOM extension is required by PRADO. It is used in TXmlDocument to parse all sorts of XML-based configurations.
+ICONV extension check = ICONV extension check
+ICONV extension optional = ICONV extension is optional. If it is absent, some internationalization components may not work properly.
+Mcrypt extension check = Mcrypt extension check
+Mcrypt extension optional = Mcrypt extension is optional. If it is absent, sensitive data, such as viewstate, cannot be encrypted.
+XSL extension check = XSL extension check
+XSL extension optional = XSL extension is optional. If it is absent, you will not be able to use TXmlTransform.
$_SERVER["HTTP_ACCEPT"] check = $_SERVER["HTTP_ACCEPT"] check
-HTTP_ACCEPT required = $_SERVER["HTTP_ACCEPT"] is required by multilanguage support.
+HTTP_ACCEPT required = $_SERVER["HTTP_ACCEPT"] is required by multilanguage support.
$_SERVER["SCRIPT_FILENAME"] check = $_SERVER["SCRIPT_FILENAME"] check
-SCRIPT_FILENAME required = $_SERVER["SCRIPT_FILENAME"] must point to the file path of this checker script.
+SCRIPT_FILENAME required = $_SERVER["SCRIPT_FILENAME"] must point to the file path of this checker script.
$_SERVER["REQUEST_URI"] check = $_SERVER["REQUEST_URI"] check
-REQUEST_URI required = Either $_SERVER["REQUEST_URI"] or $_SERVER["QUERY_STRING"] must be available for resolving user requests.
-$_SERVER["PATH_INFO"] check = $_SERVER["PATH_INFO"] check
-PATH_INFO required = $_SERVER["PATH_INFO"] or $_SERVER["PHP_SELF"] and $_SERVER["SCRIPT_NAME"] are required for determining URL pathinfo.
-SPL extension check = SPL extension check
-SPL extension required = SPL extension is required by PRADO.
-CType extension check = CType extension check
-CType extension required = CType extension is required by PRADO.
-PCRE extension check = PCRE extension check
-PCRE extension required = PCRE extension is required by PRADO.
-PDO extension check = PDO extension check
-PDO extension optional = PDO extension is optional. If it is absent, you will not be able to use System.Data.* components.
-SOAP extension check = SOAP extension check
-SOAP extension optional = SOAP extension is optional. If it is absent, you will not be able to use TSoapService.
\ No newline at end of file
+REQUEST_URI required = Either $_SERVER["REQUEST_URI"] or $_SERVER["QUERY_STRING"] must be available for resolving user requests.
+$_SERVER["PATH_INFO"] check = $_SERVER["PATH_INFO"] check
+PATH_INFO required = $_SERVER["PATH_INFO"] or $_SERVER["PHP_SELF"] and $_SERVER["SCRIPT_NAME"] are required for determining URL pathinfo.
+SPL extension check = SPL extension check
+SPL extension required = SPL extension is required by PRADO.
+CType extension check = CType extension check
+CType extension required = CType extension is required by PRADO.
+PCRE extension check = PCRE extension check
+PCRE extension required = PCRE extension is required by PRADO.
+PDO extension check = PDO extension check
+PDO extension optional = PDO extension is optional. If it is absent, you will not be able to use System.Data.* components.
+SOAP extension check = SOAP extension check
+SOAP extension optional = SOAP extension is optional. If it is absent, you will not be able to use TSoapService.
\ No newline at end of file
--
cgit v1.2.3