1 // 2 // The Antville Project 3 // http://code.google.com/p/antville 4 // 5 // Copyright 2001-2007 by The Antville People 6 // 7 // Licensed under the Apache License, Version 2.0 (the ``License''); 8 // you may not use this file except in compliance with the License. 9 // You may obtain a copy of the License at 10 // 11 // http://www.apache.org/licenses/LICENSE-2.0 12 // 13 // Unless required by applicable law or agreed to in writing, software 14 // distributed under the License is distributed on an ``AS IS'' BASIS, 15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 // See the License for the specific language governing permissions and 17 // limitations under the License. 18 // 19 // $Revision$ 20 // $LastChangedBy$ 21 // $LastChangedDate$ 22 // $URL$ 23 // 24 25 /** 26 * @fileOverview Defines the Archive prototype. 27 */ 28 29 Archive.PAGER = "page"; 30 Archive.COLLECTION = "collection"; 31 32 /** 33 * @name Archive 34 * @constructor 35 * @param {Object} name 36 * @param {Object} type 37 * @param {Object} parent 38 * @property {Story[]} _children 39 * @property {String} name 40 * @property {String} parent 41 * @property {String} type 42 * @extends HopObject 43 */ 44 Archive.prototype.constructor = function(name, type, parent) { 45 this.name = name; 46 this.type = type; 47 this.parent = parent; 48 return this; 49 } 50 51 /** 52 * 53 * @param {String} name 54 * @returns {HopObject} 55 */ 56 Archive.prototype.getChildElement = function(name) { 57 if (name.startsWith(Archive.PAGER)) { 58 return new Archive(name, Archive.PAGER, this); 59 } else if (!isNaN(name)) { 60 return new Archive(name, Archive.COLLECTION, this); 61 } 62 return this.get(name); 63 } 64 65 /** 66 * 67 * @param {String} action 68 * @returns {Boolean} 69 */ 70 Archive.prototype.getPermission = function(action) { 71 var site = res.handlers.site; 72 if (!site.getPermission("main") || site.archiveMode !== Site.PUBLIC) { 73 return false; 74 } 75 switch (action) { 76 case "main": 77 case "page1": 78 return true; 79 case "previous": 80 return this.getPage() > 1 81 case "next": 82 return this.getPage() < this.getSize() / this.getPageSize(); 83 } 84 return false; 85 } 86 87 Archive.prototype.main_action = function() { 88 res.data.title = gettext("Story Archive"); 89 res.data.body = this.renderSkinAsString("Archive#main"); 90 res.handlers.site.renderSkin("Site#page"); 91 res.handlers.site.log(); 92 return; 93 } 94 95 Archive.prototype.page1_action = function() { 96 return res.redirect(this.href()); 97 } 98 99 /** 100 * 101 * @param {String} action 102 * @returns {String} 103 */ 104 Archive.prototype.href = function(action) { 105 var buffer = []; 106 var archive = this; 107 while (archive.parent) { 108 buffer.push(archive.name); 109 archive = archive.parent; 110 } 111 buffer.push(res.handlers.site.href("archive")); 112 buffer.reverse(); 113 if (action) { 114 if (this.type === Archive.PAGER) { 115 buffer.pop(); 116 } 117 buffer.push(action); 118 } 119 return buffer.join("/"); 120 } 121 122 /** 123 * 124 * @param {Object} param 125 * @param {String} action 126 * @param {String} text 127 * @see renderLink 128 */ 129 Archive.prototype.link_macro = function(param, action, text) { 130 if (!this.getPermission(action)) { 131 return; 132 } 133 switch (action) { 134 case "previous": 135 var page = this.getPage() - 1; break; 136 case "next": 137 var page = this.getPage() + 1; break; 138 } 139 var action = "page" + page; 140 return renderLink.call(global, param, action, text, this); 141 } 142 143 /** 144 * 145 */ 146 Archive.prototype.stories_macro = function() { 147 var day, storyDay; 148 var page = this.getPage(); 149 var pageSize = this.getPageSize(); 150 151 var renderStory = function(story) { 152 storyDay = story.created.getDate(); 153 if (day !== storyDay) { 154 story.renderSkin("Story#date"); 155 day = storyDay; 156 } 157 story.renderSkin("Story#preview"); 158 return; 159 } 160 161 // FIXME: This is a little bit inconsistent and thus needs special care 162 var archive = this.type === Archive.PAGER ? this.parent : this; 163 if (!archive.parent) { 164 var site = res.handlers.site; 165 var offset = (page - 1) * pageSize; 166 var stories = site.stories.featured.list(offset, pageSize); 167 for each (var story in stories) { 168 renderStory(story); 169 }; 170 return; 171 } 172 173 res.push(); 174 res.write("select id from content "); 175 res.write(this.getFilter()); 176 res.write(" limit " + pageSize); 177 res.write(" offset " + (page - 1) * pageSize); 178 var sql = res.pop(); 179 180 var db = getDBConnection("antville"); 181 rows = db.executeRetrieval(sql); 182 var story, storyDay, day; 183 while (rows.next()) { 184 story = Story.getById(rows.getColumnItem("id")); 185 renderStory(story); 186 } 187 rows.release(); 188 return; 189 } 190 191 /** 192 * @returns {Number} 193 */ 194 Archive.prototype.getSize = function() { 195 // FIXME: This is a little bit inconsistent and thus needs special care 196 var archive = this.type === Archive.PAGER ? this.parent : this; 197 if (!archive.parent) { 198 return res.handlers.site.stories.featured.size(); 199 } 200 var db = getDBConnection("antville"); 201 var sql = "select count(*) as max from content " + this.getFilter(); 202 var rows = db.executeRetrieval(sql); 203 rows.next(); 204 return rows.getColumnItem("max"); 205 } 206 207 /** 208 * @returns {String} 209 */ 210 Archive.prototype.getFilter = function() { 211 var buffer = []; 212 var archive = this; 213 do { 214 if (archive.type === Archive.COLLECTION) { 215 buffer.push(Number(archive.name)); 216 } 217 } while (archive = archive.parent); 218 219 if (buffer.length > 0) { 220 buffer.reverse(); 221 //buffer[1] && (buffer[1] += 1); 222 } else { 223 var now = new Date; 224 buffer.push(now.getDate()); 225 buffer.push(now.getMonth() + 1); 226 buffer.push(now.getFullYear()); 227 } 228 229 res.push(); 230 var site = res.handlers.site; 231 res.write("where site_id = "); 232 res.write(site._id); 233 res.write(" and prototype = 'Story' and status <> 'closed'"); 234 235 var keys = ["year", "month", "day"]; 236 for (var i in buffer) { 237 res.write(" and "); 238 res.write(keys[i]); 239 res.write("(created) = "); 240 res.write(buffer[i]); 241 } 242 res.write(" order by created desc"); 243 return res.pop(); 244 } 245 246 /** 247 * @returns {Number} 248 */ 249 Archive.prototype.getPage = function() { 250 if (this.type === Archive.PAGER) { 251 return Number(this.name.substr(4)); 252 } 253 return 1; 254 } 255 256 /** 257 * @returns {Number} 258 */ 259 Archive.prototype.getPageSize = function() { 260 return res.handlers.site.pageSize; 261 } 262 263 /** 264 * @returns {Date} 265 */ 266 Archive.prototype.getDate = function() { 267 var date = new Date; 268 var offset = path.contains(res.handlers.site.archive) + 1; 269 if (offset > -1) { 270 var archive; 271 var buffer = []; 272 for (var i=offset; i<path.length; i+=1) { 273 archive = path[i]; 274 if (archive.type === Archive.COLLECTION) { 275 buffer.push(Number(archive.name)); 276 } 277 } 278 } 279 buffer[0] && date.setYear(buffer[0]); 280 buffer[1] && date.setMonth(buffer[1] - 1); 281 buffer[2] && date.setDate(buffer[2]); 282 return date; 283 } 284