[Solar-svn] Revision 3114

pmjones at solarphp.com pmjones at solarphp.com
Sun Apr 13 09:33:59 CDT 2008


Solar_Model_Nodes
-----------------

* [DEL] Method _newSelectByTags() is now entirely unnecessary, because the
  new Solar_Sql_Model::newSelect() method now adds all types of eager joins
  for us via $params.

* [REF] Refactored method fetchAllByTags() to use only fetchAll($params),
  instead of building a custom SELECT and running it through the previous
  model _fetchAll() support method.



Modified: trunk/Solar/Model/Nodes.php
===================================================================
--- trunk/Solar/Model/Nodes.php	2008-04-13 14:30:39 UTC (rev 3113)
+++ trunk/Solar/Model/Nodes.php	2008-04-13 14:33:59 UTC (rev 3114)
@@ -172,7 +172,8 @@
      * 
      * Fetches a collection of nodes with certain tags.
      * 
-     * @param array $tag_list Fetch only nodes with all of these tags.
+     * @param array $tag_list Fetch only nodes with all of these tags. If
+     * empty, will fetch all nodes.
      * 
      * @param array $params Added parameters for the SELECT.
      * 
@@ -181,16 +182,26 @@
      */
     public function fetchAllByTags($tag_list, $params = null)
     {
-        // no tags? fetch all to pre-empt errors related to "IN()" not
-        // having a list to work with.
         $tag_list = $this->_fixTagList($tag_list);
-        if (! $tag_list) {
-            return $this->fetchAll($params);
+        if ($tag_list) {
+            // use this so we can inherit different model names
+            $native_primary = "{$this->_model_name}.{$this->_primary_col}";
+            
+            // eager-join to tags
+            $params['eager'][] = 'tags';
+            
+            // find tags in this list
+            $params['where']['tags.name in (?)'] = $tag_list;
+            
+            // group by the model primary key so that multiple tag matches
+            // only return one row
+            $params['group'][] = $native_primary;
+            
+            // make sure that all tags match
+            $params['having']["COUNT($native_primary) = ?"] = count($tag_list);
         }
         
-        // fetch
-        $select = $this->_newSelectByTags($tag_list, $params);
-        return $this->_fetchAll($select, $params);
+        return $this->fetchAll($params);
     }
     
     /**
@@ -212,106 +223,13 @@
         // no duplicates allowed
         $tag_list = array_unique($tag_list);
         
-        // if the string tag-list is empty, the preg-split leaves one empty
+        // if the string tag-list was empty, the preg-split leaves one empty
         // element in the array.
-        if ($tag_list[0] == '') {
+        if (count($tag_list) == 1 && reset($tag_list) == '') {
             $tag_list = array();
         }
         
         // done!
         return $tag_list;
     }
-    
-    /**
-     * 
-     * Support method to create a new selection tool based on tag lists.
-     * 
-     * @param array $tag_list The list of tags to select by.
-     * 
-     * @param array &$params A reference to added parameters for the SELECT.
-     * 
-     * @return Solar_Sql_Select
-     * 
-     */
-    protected function _newSelectByTags($tag_list, &$params)
-    {
-        // setup
-        $params = $this->fixSelectParams($params);
-        $select = $this->newSelect($params['eager']);
-        
-        // catalog entries for joining
-        $taggings = $this->_related['taggings'];
-        $tags     = $this->_related['tags'];
-        
-        // primary key on the nodes table as an alias; e.g., "nodes.id"
-        $native_primary = "{$this->_model_name}.{$this->_primary_col}";
-        
-        // http://forge.mysql.com/wiki/TagSchema
-        // build the select differently from other fetchAll() statements
-        $select->distinct($params['distinct'])
-               ->from("{$this->_table_name} AS {$this->_model_name}", $params['cols'])
-               // join taggings on nodes
-               ->join(
-                   "{$taggings->foreign_table} AS {$taggings->foreign_alias}",
-                   "{$taggings->foreign_alias}.node_id = $native_primary"
-               )
-               // join tags on taggings
-               ->join(
-                   "{$tags->foreign_table} AS {$tags->foreign_alias}",
-                   "{$tags->foreign_alias}.id = {$taggings->foreign_alias}.tag_id"
-               )
-               // select for the listed tags
-               ->where("{$tags->foreign_alias}.name IN (?)", $tag_list)
-               // user-provided WHERE
-               ->multiWhere($params['where'])
-               // group by nodes.id to collapse multiple nodes (1 for each tag)
-               ->group($native_primary)
-               // make sure the tag-count matches
-               ->having("COUNT($native_primary) = ?", count($tag_list))
-               // user-provided ORDER, paging, etc
-               ->order($params['order'])
-               ->setPaging($params['paging'])
-               ->limitPage($params['page'])
-               ->bind($params['bind']);
-        
-        // done!
-        return $select;
-    }
-    
-    /**
-     * 
-     * Gets a count of nodes and pages-of-nodes with certain tags.
-     * 
-     * @param array $tag_list Count only nodes with all of these tags.
-     * 
-     * @param array $params Added parameters for the SELECT.
-     * 
-     * @return array An array with elemets 'count' (the number of nodes) and
-     * 'pages' (the number of pages-of-nodes).
-     * 
-     */
-    public function countPagesByTags($tag_list, $params = null)
-    {
-        $tag_list = $this->_fixTagList($tag_list);
-        if (! $tag_list) {
-            return $this->countPages($params);
-        }
-        
-        // we need to select the nodes + tags as an "inner" sub-select;
-        // clear any limits on it.
-        $inner = $this->_newSelectByTags($tag_list, $params);
-        $inner->clear('limit');
-        
-        // set up the outer select, which will wrap the inner sub-select
-        $outer = Solar::factory($this->_select_class, array(
-            'sql' => $this->_sql
-        ));
-        
-        // wrap the sub-select and make sure paging is correct
-        $outer->fromSelect($inner, $this->_model_name);
-        $outer->setPaging($this->_paging);
-        
-        // *now* get the count of pages with the tags requested
-        return $outer->countPages("{$this->_model_name}.{$this->_primary_col}");
-    }
 }




More information about the Solar-svn mailing list