| 1 | <?php |
|---|
| 2 | ############################################################################### |
|---|
| 3 | # Gregarius - A PHP based RSS aggregator. |
|---|
| 4 | # Copyright (C) 2003 - 2006 Marco Bonetti |
|---|
| 5 | # |
|---|
| 6 | ############################################################################### |
|---|
| 7 | # This program is free software and open source software; you can redistribute |
|---|
| 8 | # it and/or modify it under the terms of the GNU General Public License as |
|---|
| 9 | # published by the Free Software Foundation; either version 2 of the License, |
|---|
| 10 | # or (at your option) any later version. |
|---|
| 11 | # |
|---|
| 12 | # This program is distributed in the hope that it will be useful, but WITHOUT |
|---|
| 13 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|---|
| 14 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
|---|
| 15 | # more details. |
|---|
| 16 | # |
|---|
| 17 | # You should have received a copy of the GNU General Public License along |
|---|
| 18 | # with this program; if not, write to the Free Software Foundation, Inc., |
|---|
| 19 | # 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA or visit |
|---|
| 20 | # http://www.gnu.org/licenses/gpl.html |
|---|
| 21 | # |
|---|
| 22 | ############################################################################### |
|---|
| 23 | # E-mail: mbonetti at gmail dot com |
|---|
| 24 | # Web page: http://gregarius.net/ |
|---|
| 25 | # |
|---|
| 26 | ############################################################################### |
|---|
| 27 | |
|---|
| 28 | |
|---|
| 29 | // these are the fontsizes on the weighted list at /tag/ |
|---|
| 30 | define ('SMALLEST',9); |
|---|
| 31 | define ('LARGEST',45); |
|---|
| 32 | define ('UNIT','px'); |
|---|
| 33 | |
|---|
| 34 | /** |
|---|
| 35 | * This class handles the weighted list of all tags, |
|---|
| 36 | * accessible at /tag/ |
|---|
| 37 | */ |
|---|
| 38 | class Tags { |
|---|
| 39 | |
|---|
| 40 | /** |
|---|
| 41 | * holds all the tags in the database. |
|---|
| 42 | * Structure: $tag => $count_of_tagged_items |
|---|
| 43 | */ |
|---|
| 44 | var $allTags = array (); |
|---|
| 45 | |
|---|
| 46 | /** Holds a reference to the superglobal RSS object */ |
|---|
| 47 | var $rss; |
|---|
| 48 | |
|---|
| 49 | /** Objects that the tags point to */ |
|---|
| 50 | var $type; |
|---|
| 51 | |
|---|
| 52 | /** |
|---|
| 53 | * holds unread item count of tags |
|---|
| 54 | * Structure: $tag => $unread_items |
|---|
| 55 | */ |
|---|
| 56 | var $unreadItems = array(); |
|---|
| 57 | |
|---|
| 58 | /** |
|---|
| 59 | * Constructor. Gets a reference of the RSS superglobal and fills |
|---|
| 60 | * the instance data |
|---|
| 61 | */ |
|---|
| 62 | function Tags($type = 'item') { |
|---|
| 63 | $this -> rss = $GLOBALS['rss']; |
|---|
| 64 | $this -> type = $type; |
|---|
| 65 | $this -> populate(); |
|---|
| 66 | } |
|---|
| 67 | |
|---|
| 68 | |
|---|
| 69 | |
|---|
| 70 | |
|---|
| 71 | /** |
|---|
| 72 | * Fills the instance data for this object: gets a hold |
|---|
| 73 | * of all tags defined in the system. |
|---|
| 74 | */ |
|---|
| 75 | function populate() { |
|---|
| 76 | // the all tags weighted list |
|---|
| 77 | $sql = "select t.id, tag, count(*) as cnt from " |
|---|
| 78 | .getTable('metatag'); |
|---|
| 79 | if($this -> type == 'channel'){ |
|---|
| 80 | $sql .= " left join " . getTable('channels') . " c on (fid=c.id) " |
|---|
| 81 | ."inner join " . getTable('tag')." t "." on tid=t.id " |
|---|
| 82 | . " where ttype = 'channel'"; |
|---|
| 83 | }else{ |
|---|
| 84 | $sql .= " left join ".getTable('item')." i on (fid=i.id) " |
|---|
| 85 | ."inner join " . getTable('tag')." t "." on tid=t.id " |
|---|
| 86 | ." where ttype = 'item'"; |
|---|
| 87 | } |
|---|
| 88 | |
|---|
| 89 | |
|---|
| 90 | // Don't count tags of private items |
|---|
| 91 | if (hidePrivate()) { |
|---|
| 92 | $sql .= " and not(i.unread & ".RSS_MODE_PRIVATE_STATE.") "; |
|---|
| 93 | } |
|---|
| 94 | $sql .= " and not (i.unread & ".RSS_MODE_DELETED_STATE.") "; |
|---|
| 95 | |
|---|
| 96 | $sql .= " group by tid order by tag"; |
|---|
| 97 | |
|---|
| 98 | |
|---|
| 99 | $res = rss_query($sql); |
|---|
| 100 | $max = 0; |
|---|
| 101 | $min = 100000; |
|---|
| 102 | $cntr = 0; |
|---|
| 103 | while (list ($tid, $tag, $cnt) = rss_fetch_row($res)) { |
|---|
| 104 | $this->allTags[$tag] = $cnt; |
|---|
| 105 | |
|---|
| 106 | // list of unread items |
|---|
| 107 | $cntUnread = 0; |
|---|
| 108 | $sql = "select fid from " . getTable('metatag') . " where tid = $tid"; |
|---|
| 109 | $res2 = rss_query($sql); |
|---|
| 110 | while(list($fid) = rss_fetch_row($res2)){ |
|---|
| 111 | if($this->type == 'channel'){ |
|---|
| 112 | $cntUnread += getUnreadCount($fid,null); |
|---|
| 113 | }else{ |
|---|
| 114 | $sql = "select unread from " . getTable('item') . " where id = $fid" |
|---|
| 115 | . " and (unread & ".RSS_MODE_UNREAD_STATE.") "; |
|---|
| 116 | if (hidePrivate()) { |
|---|
| 117 | $sql .= " and not(unread & ".RSS_MODE_PRIVATE_STATE.") "; |
|---|
| 118 | } |
|---|
| 119 | if(rss_num_rows(rss_query($sql))) $cntUnread++; |
|---|
| 120 | } |
|---|
| 121 | } |
|---|
| 122 | $this->unreadItems[$tag] = $cntUnread; |
|---|
| 123 | |
|---|
| 124 | $cntr ++; |
|---|
| 125 | } |
|---|
| 126 | } |
|---|
| 127 | |
|---|
| 128 | /** |
|---|
| 129 | * Preformats a tag url, depending on whether mod_rewrite is enabled or not |
|---|
| 130 | */ |
|---|
| 131 | function makeTagLink($tag) { |
|---|
| 132 | if($this -> type == 'channel'){ |
|---|
| 133 | return getPath(). (getConfig('rss.output.usemodrewrite') ? "$tag/" : "feed.php?vfolder=$tag"); |
|---|
| 134 | }else{ |
|---|
| 135 | return getPath(). (getConfig('rss.output.usemodrewrite') ? "tag/$tag" : "tags.php?tag=$tag"); |
|---|
| 136 | } |
|---|
| 137 | } |
|---|
| 138 | |
|---|
| 139 | /** |
|---|
| 140 | * Gateway to the RSS superglobal rendering options |
|---|
| 141 | */ |
|---|
| 142 | function setRenderOptions($options) { |
|---|
| 143 | $this-> rss -> renderOptions |= $options; |
|---|
| 144 | } |
|---|
| 145 | |
|---|
| 146 | /** |
|---|
| 147 | * Does the actual rendering. Since this is a rather simple |
|---|
| 148 | * class we don't use a specific template. We'll have to the |
|---|
| 149 | * day we start supporting non-screen themes. (read: RSS output) |
|---|
| 150 | */ |
|---|
| 151 | function render() { |
|---|
| 152 | if (count($this->allTags)) { |
|---|
| 153 | $spread = max($this->allTags) - min($this->allTags); |
|---|
| 154 | if ($spread <= 0) { |
|---|
| 155 | $spread = 1; |
|---|
| 156 | }; |
|---|
| 157 | $fontspread = LARGEST - SMALLEST; |
|---|
| 158 | $fontstep = $spread / $fontspread; |
|---|
| 159 | if ($fontspread <= 0) { |
|---|
| 160 | $fontspread = 1; |
|---|
| 161 | } |
|---|
| 162 | $ret = ""; |
|---|
| 163 | foreach ($this->allTags as $tag => $cnt) { |
|---|
| 164 | $taglink = $this -> makeTagLink($tag); |
|---|
| 165 | $ret .= "\t<a href=\"$taglink\" title=\"$cnt " |
|---|
| 166 | . ($cnt > 1 || $cnt == 0 ? __('items') : __('item'))."\" style=\"font-size: " |
|---|
| 167 | . (SMALLEST + ($cnt / $fontstep)).UNIT.";\">$tag</a> \n"; |
|---|
| 168 | } |
|---|
| 169 | } else { |
|---|
| 170 | $ret = ""; |
|---|
| 171 | } |
|---|
| 172 | // Spit out the markup |
|---|
| 173 | echo "<div id=\"alltags\" class=\"frame\">$ret</div>\n"; |
|---|
| 174 | } |
|---|
| 175 | |
|---|
| 176 | } |
|---|
| 177 | ?> |
|---|