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