[pLog-svn] r2109 - in plog/branches/plog-1.1-ben/class: dao database

ork at devel.plogworld.net ork at devel.plogworld.net
Sun May 29 23:40:39 GMT 2005


Author: ork
Date: 2005-05-29 23:40:39 +0000 (Sun, 29 May 2005)
New Revision: 2109

Modified:
   plog/branches/plog-1.1-ben/class/dao/articles.class.php
   plog/branches/plog-1.1-ben/class/database/db.class.php
Log:
polished up articles even more, i personally think this is much more readable and better to maintain.
the work here is not done yet, getBlogArticles() and some other methdos are still a mess. 



Modified: plog/branches/plog-1.1-ben/class/dao/articles.class.php
===================================================================
--- plog/branches/plog-1.1-ben/class/dao/articles.class.php	2005-05-29 23:37:38 UTC (rev 2108)
+++ plog/branches/plog-1.1-ben/class/dao/articles.class.php	2005-05-29 23:40:39 UTC (rev 2109)
@@ -1,6 +1,7 @@
 <?php
 
     include_once( PLOG_CLASS_PATH.'class/dao/model.class.php' );
+    include_once( PLOG_CLASS_PATH.'class/dao/article.class.php' );
     include_once( PLOG_CLASS_PATH.'class/config/config.class.php' );
 
     /**
@@ -34,6 +35,13 @@
 			$this->_blogsettings = null;
         }
 
+        /**
+         * Gets an article from the database, given its id. Also manages the
+         * cache for articles.
+         *
+         * @param articleId Identifier of the article we want to fetch
+         * @return Returns an Article object or 'false' otherwise.
+         */
         function getArticle( $articleId )
         {
             $this->log->info('called getArticle with id: ' . $articleId );
@@ -115,35 +123,88 @@
         /**
          * Gets an article from the database, given its slug, this is used
          * with the fancy permalinks
+         * This method will always return the first matching article, so
+         * if there're more than one article with the same title, you will
+         * always get only one of them.
          *
+         * TBD: includeHiddenFields has no meaning, this should be removed
+         * TBD: this method is rather long, maybe we can shorten it somehow.
+         *
          * @param artTitle Identifier of the article we want to fetch
          * @param blogId If set, the article must belong to the given blog
          * @return Returns an Article object or 'false' otherwise.
          */        
-        function getBlogArticleByTitle( $artTitle, $blogId = -1, $includeHiddenFields = true, $date = -1, $categoryId = -1, $userId = -1, $status = POST_STATUS_PUBLISHED )
+        function getBlogArticleByTitle( $articleTitle, 
+                                        $blogId = -1, 
+                                        $includeHiddenFields = true, 
+                                        $date = -1, 
+                                        $categoryId = -1, 
+                                        $userId = -1, 
+                                        $status = POST_STATUS_PUBLISHED )
         {
-			$prefix = $this->getPrefix();
-            $query = "SELECT a.id, a.date,
-			                 a.user_id,a.blog_id,a.status,a.properties,
-							 a.num_reads, a.slug FROM {$prefix}articles a ";
-			// thanks jon once again :)
-			if($categoryId != -1 && $blogId != -1) {
-				$query .= ",{$prefix}articles_categories c, {$prefix}article_categories_link l ";
-			}
-			$query .= "WHERE a.slug = '".Db::qstr($artTitle)."'";
-            if( $blogId != -1 )
-                $query .= " AND a.blog_id = ".Db::qstr($blogId);
-			if( $date != -1 )
-                $query .= " AND a.date+0 LIKE '$date%'";
-			if( $userId != -1 ) 
-				$query .= " AND a.user_id = ".Db::qstr($userId);
-			if( $categoryId != -1 ) {
-				$query .= " AND c.id = ".Db::qstr($categoryId)." AND c.id = l.category_id AND a.id = l.article_id";
-			}
-				
-            $query .= " AND a.status = $status;";
+            $articleIds = $this->_cache->getData( $articleTitle, CACHE_ARTICLETITLES );
 
-            return $this->_getBlogArticleFromQuery( $query, $includeHiddenFields );
+            if( !$articleIds || empty($articleIds) ) {
+                // ArticleIds are not in the cache, we'll fetch the possible ids
+                // from the database.
+                // We will fetch all articles with the given title, to store the
+                // result in the cache and parse each article later on to find
+                // the correct one.
+                $whereConditions = array();
+                $whereConditions['slug'] = $articleTitle;
+
+                $query = Db::buildSelectQuery( ARTICLES_TABLENAME,
+                                               array('id'),
+                                               $whereConditions );
+
+                $result = $this->Execute( $query );
+
+                if( $result->RecordCount() == 0 ) {
+                    return false;
+                } elseif( $result->RecordCount() == 1 ) {
+                    $row        = $result->FetchRow( $result );
+                    $articleId  = $row['id'];
+                    $articles   = array( $this->getArticle($articleId) );
+                    $articleIds = array( $articleId );
+                } else {
+                    // we have more than just one id found, we need to
+                    // check them all.
+                    $articles   = array();
+                    $articleIds = array();
+
+                    while( $row = $result->FetchRow($result) ) {
+                        $articleId     = $row['id'];
+                        $articles[]    = $this->getArticle( $articleId );
+                        $articlesIds[] = $articlesId;
+                    }
+                }
+                $this->_cache->setData( $articleTitle, CACHE_ARTICLETITLES, $articlesIds );
+            } else {
+                foreach( $articleIds as $articleId ) {
+                    $articles[] = $this->getArticle( $articleId );
+                }
+            }
+
+            foreach( $articles as $article ) {
+                if( $blogId != -1 && $blogId != $article->getBlogId() ) {
+                    // wrong blogId, skip to the next article
+                    continue;
+                }
+                if( $categoryId != -1 && !in_array($categoryId, $article->getCategoryIds()) ) {
+                    // wrong category, skip to the next article
+                    continue;
+                }
+                if( $userId != -1 && $userId != $article->getUserId() ) {
+                    // wrong user, skip to the next article
+                    continue;
+                }
+                if( $status != $article->getStatus() ) {
+                    // wrong status, skip to the next article
+                    continue;
+                }
+                return $article;
+            }
+            return false;
         }
         
         /**
@@ -179,14 +240,23 @@
 
 			// we need to keep the timestamp in mind
 			$date = $article->getDateObject();
-			$articleCorrectedDate = Timestamp::getDateWithOffset( $article->getDate(), -($article->getTimeOffset()));
-			$blogId = $article->getBlog();
+			$articleCorrectedDate = Timestamp::getDateWithOffset( $article->getDate(), 
+                                                                 -($article->getTimeOffset()));
 
-            // gets the article that is just next in time
-            $query = "SELECT * FROM ".$this->getPrefix()."articles 
-			                  WHERE date > '".$articleCorrectedDate."' AND status = '".Db::qstr(POST_STATUS_PUBLISHED)."' 
-							        AND blog_id = '".Db::qstr($blogId)."' ORDER BY date ASC LIMIT 1;";
-			
+            $whereConditions = array();
+            // '=' is the default when calculating the where conditions, but to
+            // have this look uniform, lets add the '=' anyway. :)
+            $whereConditions['blog_id'] = '=' . $article->getBlogId();
+            $whereConditions['date']    = '>' . $articleCorrectedDate;
+            $whereConditions['status']  = '=' . POST_STATUS_PUBLISHED;
+
+            $query = Db::buildSelectQuery( ARTICLES_TABLENAME,
+                                           array(),
+                                           $whereConditions,
+                                           null,
+                                           'date',
+                                           1 );
+
 			return( $this->_getBlogArticleFromQuery( $query, false ));
         }
 
@@ -394,6 +464,7 @@
             // of conditions, such as the maximum date, the amount, the category,
             // wether the category has to be shown in the main page or not, etc...
             $postStatus = $status;
+            $prefix = $this->getPrefix();
 		    $where = $this->buildWhere( $blogid, $date, $amount, $categoryId, $status, $userId, $maxDate, $searchTerms, $page );
             $query = "SELECT a.id as id, a.id, a.date,
                              a.user_id,a.blog_id,a.status,a.properties,
@@ -424,7 +495,7 @@
 				$start = (($page - 1) * $amount);		        
 				$query .= " LIMIT $start, $amount";   
             }
-                                                     
+
             $this->log->info('old query: ' . $query );
 				
 			// execute the query
@@ -689,19 +760,21 @@
          */
         function addArticle( &$newArticle )
         {
-            // first, we build up the query
-            include_once( PLOG_CLASS_PATH.'class/data/textfilter.class.php' );
-            $filter = new Textfilter();
+            include_once( PLOG_CLASS_PATH.'class/dao/customfields/customfields.class.php' );
+            require_once( PLOG_CLASS_PATH.'class/database/db.class.php' );
 
-            $query = "INSERT INTO ".$this->getPrefix()."articles( user_id,blog_id,status,date,properties, slug )
-                      VALUES ( ".$newArticle->getUser().",".
-                      $newArticle->getBlog().",'".
-                      $newArticle->getStatus()."','".
-                      $newArticle->getDate()."','".
-                      serialize($newArticle->getProperties())."','".
-					  $newArticle->getPostSlug()."');";
-            // and then we send it to the db
-            //$this->_db->debug=true;
+            $valuesToInsert = array();
+
+            $valuesToInsert['user_id']    = $newArticle->getUser();
+            $valuesToInsert['blog_id']    = $newArticle->getBlogId();
+            $valuesToInsert['status']     = $newArticle->getStatus();
+            $valuesToInsert['date']       = $newArticle->getDate();
+            $valuesToInsert['properties'] = serialize( $newArticle->getProperties() );
+            $valuesToInsert['slug']       = $newArticle->getPostSlug();
+
+            $query = Db::buildInsertQuery( ARTICLES_TABLENAME,
+                                           $valuesToInsert );
+
             $result = $this->Execute( $query );
 
             if( !$result ){
@@ -719,7 +792,6 @@
             $this->addPostCategoriesLink( $postId, $newArticle->getCategoryIds());
 
             // and save the custom fields
-            include_once( PLOG_CLASS_PATH.'class/dao/customfields/customfields.class.php' );
             $this->addArticleCustomFields( $postId, $newArticle->getBlog(), $newArticle->getFields());
 
             return $postId;
@@ -734,16 +806,21 @@
 		 */
 		function addArticleText( $newArticle )
 		{
+            require_once( PLOG_CLASS_PATH . 'class/data/textfilter.class.php' );
+            require_once( PLOG_CLASS_PATH . 'class/database/db.class.php' );
+
 			$filter = new Textfilter();
-			$prefix = $this->getPrefix();
-			$query = "INSERT INTO {$prefix}articles_text
-			                      (article_id, topic, text, normalized_text, normalized_topic)
-					  VALUES( '".Db::qstr( $newArticle->getId())."', '".
-					            Db::qstr($newArticle->getTopic())."','".
-                                Db::qstr($newArticle->getText(false))."','".
-                                $filter->normalizeText(Db::qstr($newArticle->getText(false)))."', '".
-                                $filter->normalizeText(Db::qstr($newArticle->getTopic()))."')";
-								
+
+            $valuesToInsert = array();
+            $valuesToInsert['article_id']       = $newArticle->getId();
+            $valuesToInsert['topic']            = $newArticle->getTopic();
+            $valuesToInsert['text']             = $newArticle->getText(false);
+            $valuesToInsert['normalized_text']  = $filter->normalizeText( $newArticle->getText(false) );
+            $valuesToInsert['normalized_topic'] = $filter->normalizeText( $newArticle->getTopic() );
+
+            $query = Db::buildInsertQuery( ARTICLETEXTS_TABLENAME,
+                                           $valuesToInsert );
+
 			return( $this->Execute( $query ));
 		}
 		
@@ -758,9 +835,10 @@
             $text = $this->_cache->getData( $articleId, CACHE_ARTICLETEXT );
 
             if( !$text ) {
-                $prefix = $this->getPrefix();
-                $query = "SELECT * FROM {$prefix}articles_text
-                          WHERE article_id = '".Db::qstr($articleId)."'";
+                $query = Db::buildSelectQuery( ARTICLETEXTS_TABLENAME,
+                                               array(),
+                                               'article_id',
+                                               $articleId );
 
                 $result = $this->Execute( $query );
                 
@@ -1128,7 +1206,6 @@
         function _fillArticleInformation( $query_result, $includeHiddenFields = true )
         {
             include_once( PLOG_CLASS_PATH.'class/data/timestamp.class.php' );
-            include_once( PLOG_CLASS_PATH.'class/dao/article.class.php' );
             include_once( PLOG_CLASS_PATH.'class/dao/users.class.php' );
             include_once( PLOG_CLASS_PATH.'class/dao/blogs.class.php' );
             include_once( PLOG_CLASS_PATH."class/dao/bloginfo.class.php" );
@@ -1208,7 +1285,6 @@
 		 */
 		function _fillArticleHeaderInformation( $query_result, $includeHiddenFields = true )
         {
-            include_once( PLOG_CLASS_PATH.'class/dao/article.class.php' );
             include_once( PLOG_CLASS_PATH.'class/data/timestamp.class.php' );
             include_once( PLOG_CLASS_PATH.'class/dao/users.class.php' );
             include_once( PLOG_CLASS_PATH.'class/dao/blogs.class.php' );

Modified: plog/branches/plog-1.1-ben/class/database/db.class.php
===================================================================
--- plog/branches/plog-1.1-ben/class/database/db.class.php	2005-05-29 23:37:38 UTC (rev 2108)
+++ plog/branches/plog-1.1-ben/class/database/db.class.php	2005-05-29 23:40:39 UTC (rev 2109)
@@ -82,40 +82,16 @@
             }
 		}
 
-		/**
-		 * Prepares a string for an SQL query by escaping apostrophe
-		 * characters. If the PHP configuration setting 'magic_quotes_gpc'
-		 * is set to ON, it will first strip the added slashes. Apostrophe
-		 * characters are doubled, conforming with the ANSI SQL standard.
-		 * The SQL parser makes sure that the escape token is not entered
-		 * in the database so there is no need to modify the data when it
-		 * is read from the database.
-		 *
-		 * @param  string $string
-		 * @return string
-		 * @access public
-		 */
-		function qstr($string) {
 
-			if (get_magic_quotes_gpc()) {
-				$string = stripslashes($string);
-			}
-
-			$string = str_replace("'", "''", $string);
-
-			return $string;
-		}
-
         function buildSelectQuery( $tableName, 
                                    $fieldsToFetch = array(),
                                    $whereColumn   = null, 
                                    $whereValue    = null,
                                    $orderColumn   = null,
+                                   $limit         = null,
                                    $whereGlue     = ' AND ')
         {
-            if ( !preg_match( "/^" . Db::getPrefix() . "/", $tableName) ) {
-                $tableName = Db::getPrefix() . $tableName;
-            }
+            $tableName = Db::addTablePrefixToTableName( $tableName );
 
             $query = 'SELECT ';
             if( $fieldsToFetch == array() ) {
@@ -139,14 +115,63 @@
             if( $orderColumn != null ) {
                 $query .= ' ORDER BY ' . $orderColumn;
             }
+
+            if( $limit != null ) {
+                $query .= ' LIMIT ' . $limit;
+            }
+
             $query .= ';';
 
             return $query;
         }
 
+        function buildInsertQuery( $tableName,
+                                   $keyValuePairs )
+        {
+            $tableName = Db::addTablePrefixToTableName( $tableName );
+
+            $query  = 'INSERT INTO ' . $tableName;
+
+            foreach( $keyValuePairs as $key => $value ) {
+                $keys[]   = $key;
+                $values[] = Db::quoteValue( $value );
+            }
+            $query .= ' (' . implode( ",", $keys ) . ')';
+            $query .= ' VALUES (';
+            $query .= implode( ",", $values );
+            $query .= ');';
+
+            return $query;
+        }
+
+        function addTablePrefixToTableName( $tableName ) {
+            if ( !preg_match( "/^" . Db::getPrefix() . "/", $tableName) ) {
+                $tableName = Db::getPrefix() . $tableName;
+            }
+            return $tableName;
+        }
+
+
         function _buildWhereCondition( $columnName, $columnValue )
         {
-            $queryPart  = $columnName . ' = ';
+            preg_match( '/^(.)(.*)$/', $columnValue, $matches );
+            $firstValueCharacter = $matches[1];
+            switch( $firstValueCharacter ) {
+                case '>':
+                    $operator = '>';
+                    $columnValue = $matches[2];
+                    break;
+                case '<':
+                    $operator = '<';
+                    $columnValue = $matches[2];
+                    break;
+                case '=':
+                    $columnValue = $matches[2];
+                    // no break, we want to continue to the default
+                default:
+                    $operator = '=';
+                }
+            $queryPart  = $columnName . ' ' . $operator . ' ';
             $queryPart .= Db::quoteValue( $columnValue );
             return $queryPart;
         }
@@ -165,5 +190,29 @@
             else
                 return '\'' . Db::qstr( $value ) . '\'';
         }
+
+		/**
+		 * Prepares a string for an SQL query by escaping apostrophe
+		 * characters. If the PHP configuration setting 'magic_quotes_gpc'
+		 * is set to ON, it will first strip the added slashes. Apostrophe
+		 * characters are doubled, conforming with the ANSI SQL standard.
+		 * The SQL parser makes sure that the escape token is not entered
+		 * in the database so there is no need to modify the data when it
+		 * is read from the database.
+		 *
+		 * @param  string $string
+		 * @return string
+		 * @access public
+		 */
+		function qstr($string) {
+
+			if (get_magic_quotes_gpc()) {
+				$string = stripslashes($string);
+			}
+
+			$string = str_replace("'", "''", $string);
+
+			return $string;
+		}
     }
 ?>




More information about the pLog-svn mailing list