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 = "Archive of " + res.handlers.site.getTitle();
 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