1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47:
48: class ArticleObject extends AlphaDAO {
49: 50: 51: 52: 53: 54:
55: protected $title;
56:
57: 58: 59: 60: 61: 62:
63: protected $section;
64:
65: 66: 67: 68: 69: 70:
71: protected $description;
72:
73: 74: 75: 76: 77: 78:
79: protected $bodyOnload;
80:
81: 82: 83: 84: 85: 86:
87: protected ;
88:
89: 90: 91: 92: 93: 94:
95: protected $content;
96:
97: 98: 99: 100: 101: 102:
103: protected $author;
104:
105: 106: 107: 108: 109: 110:
111: protected $published;
112:
113: 114: 115: 116: 117: 118:
119: protected ;
120:
121: 122: 123: 124: 125: 126:
127: protected $votes;
128:
129: 130: 131: 132: 133: 134:
135: protected $tags;
136:
137: 138: 139: 140: 141: 142:
143: protected $taggedAttributes = array('title', 'description', 'content');
144:
145: 146: 147: 148: 149: 150:
151: private $filePath;
152:
153: 154: 155: 156: 157: 158:
159: protected $dataLabels = array("OID"=>"Article ID#","title"=>"Title","section"=>"Site Section","description"=>"Description","bodyOnload"=>"Body onload Javascript","content"=>"Content","headerContent"=>"HTML Header Content","author"=>"Author","created_ts"=>"Date Added","updated_ts"=>"Date of last Update","published"=>"Published","URL"=>"URL","printURL"=>"Printer version URL","comments"=>"Comments","votes"=>"Votes","tags"=>"Tags");
160:
161: 162: 163: 164: 165: 166:
167: const TABLE_NAME = 'Article';
168:
169: 170: 171: 172: 173: 174:
175: protected $URL;
176:
177: 178: 179: 180: 181: 182:
183: protected $printURL;
184:
185: 186: 187: 188: 189: 190:
191: private static $logger = null;
192:
193: 194: 195: 196: 197:
198: public function __construct() {
199: self::$logger = new Logger('ArticleObject');
200:
201:
202: parent::__construct();
203:
204: $this->title = new String();
205: $this->title->setHelper('Please provide a title for the article.');
206: $this->title->setSize(100);
207: $this->title->setRule("/\w+/");
208:
209: $this->section = new DEnum('ArticleObject::section');
210:
211: $this->description = new String();
212: $this->description->setHelper('Please provide a brief description of the article.');
213: $this->description->setSize(200);
214: $this->description->setRule("/\w+/");
215: $this->bodyOnload = new String();
216: $this->content = new Text();
217: $this->content->setHelper('Please provide some content for the article.');
218: $this->content->setRule("/\w+/");
219: $this->headerContent = new Text();
220: $this->author = new String();
221: $this->author->setHelper('Please state the name of the author of this article');
222: $this->author->setSize(70);
223: $this->author->setRule("/\w+/");
224: $this->published = new Boolean(0);
225:
226: $this->comments = new Relation();
227: $this->markTransient('comments');
228: $this->comments->setValue($this->OID);
229: $this->comments->setRelatedClass('ArticleCommentObject');
230: $this->comments->setRelatedClassField('articleOID');
231: $this->comments->setRelatedClassDisplayField('content');
232: $this->comments->setRelationType('ONE-TO-MANY');
233:
234: $this->votes = new Relation();
235: $this->markTransient('votes');
236: $this->votes->setValue($this->OID);
237: $this->votes->setRelatedClass('ArticleVoteObject');
238: $this->votes->setRelatedClassField('articleOID');
239: $this->votes->setRelatedClassDisplayField('score');
240: $this->votes->setRelationType('ONE-TO-MANY');
241:
242: $this->tags = new Relation();
243: $this->markTransient('tags');
244: $this->tags->setRelatedClass('TagObject');
245: $this->tags->setRelatedClassField('taggedOID');
246: $this->tags->setRelatedClassDisplayField('content');
247: $this->tags->setRelationType('ONE-TO-MANY');
248: $this->tags->setTaggedClass(get_class($this));
249: $this->tags->setValue($this->OID);
250:
251: $this->URL = '';
252: $this->printURL = '';
253:
254: $this->markTransient('URL');
255: $this->markTransient('printURL');
256:
257:
258: $this->markUnique('title');
259:
260: $this->markTransient('filePath');
261: $this->markTransient('taggedAttributes');
262: }
263:
264: 265: 266: 267: 268: 269:
270: protected function after_save_callback() {
271: if($this->getVersion() == 1 && $this->tags instanceof Relation) {
272:
273: $this->tags->setValue($this->OID);
274:
275: foreach($this->taggedAttributes as $tagged) {
276: $tags = TagObject::tokenize($this->get($tagged), get_class($this), $this->getOID());
277: foreach($tags as $tag) {
278: try {
279: $tag->save();
280: }catch(ValidationException $e){
281: 282: 283: 284:
285: }
286: }
287: }
288: }
289: }
290:
291: 292: 293: 294: 295:
296: protected function after_loadByAttribute_callback() {
297: $this->after_load_callback();
298: }
299:
300: 301: 302: 303: 304:
305: protected function after_load_callback() {
306: global $config;
307: global $front;
308:
309:
310: if($config->get('app.use.mod.rewrite')) {
311:
312: if(isset($front) && $front->hasAlias('ViewArticleTitle')) {
313: $alias = $front->getControllerAlias('ViewArticleTitle');
314:
315: $this->URL = $config->get('app.url').$alias.'/'.str_replace(' ', '-', $this->title->getValue());
316: }else{
317: $this->URL = $config->get('app.url').'ViewArticleTitle/title/'.str_replace(' ', $config->get('cms.url.title.separator'), $this->title->getValue());
318: }
319: }else{
320: $this->URL = $config->get('app.url').'alpha/controller/ViewArticle.php?oid='.$this->getID();
321: }
322:
323:
324: if($config->get('app.use.mod.rewrite')) {
325:
326: if(isset($front) && $front->hasAlias('ViewArticlePrint')) {
327: $alias = $front->getControllerAlias('ViewArticlePrint');
328:
329: $this->printURL = $config->get('app.url').$alias.'/'.str_replace(' ', '-', $this->title->getValue());
330: }else{
331: $this->printURL = $config->get('app.url').'ViewArticlePrint/title/'.str_replace(' ', $config->get('cms.url.title.separator'), $this->title->getValue());
332: }
333: }else{
334: $this->printURL = $config->get('app.url').'alpha/controller/ViewArticlePrint.php?title='.$this->title->getValue();
335: }
336:
337: $this->comments->setValue($this->OID);
338: $this->votes->setValue($this->OID);
339: }
340:
341: 342: 343: 344: 345: 346: 347: 348: 349: 350:
351: public function loadRecentWithLimit($limit, $excludeID = ''){
352:
353: if($excludeID != '') {
354: $denum = new DEnum('ArticleObject::section');
355: $excludeID = $denum->getOptionID($excludeID);
356: }
357:
358: $sqlQuery = "SELECT OID FROM ".$this->getTableName()." WHERE published='1' AND section!='$excludeID' ORDER BY created_ts DESC LIMIT 0, $limit;";
359:
360: $result = $this->query($sqlQuery);
361:
362: $OIDs = array();
363:
364: foreach($result as $row)
365: array_push($OIDs, $row['OID']);
366:
367: return $OIDs;
368: }
369:
370: 371: 372: 373: 374: 375:
376: public function getAttachmentsLocation() {
377: global $config;
378:
379: return $config->get('app.file.store.dir').'attachments/article_'.$this->getID();
380: }
381:
382: 383: 384: 385: 386: 387:
388: public function getAttachmentsURL() {
389: global $config;
390:
391: return $config->get('app.url').'attachments/article_'.$this->getID();
392: }
393:
394: 395: 396: 397: 398: 399:
400: public function getAttachmentSecureURL($filename) {
401: global $config;
402:
403: return FrontController::generateSecureURL('act=ViewAttachment&dir='.$this->getAttachmentsLocation().'&filename='.$filename);
404: }
405:
406: 407: 408: 409: 410: 411:
412: public function createAttachmentsFolder() {
413:
414: try{
415: mkdir($this->getAttachmentsLocation());
416: }catch (Exception $e) {
417: throw new AlphaException('Unable to create the folder ['.$this->getAttachmentsLocation().'] for the article.');
418: }
419:
420:
421: try{
422: chmod($this->getAttachmentsLocation(), 0777);
423: }catch (Exception $e) {
424: throw new AlphaException('Unable to set write permissions on the folder ['.$this->getAttachmentsLocation().'].');
425: }
426: }
427:
428: 429: 430: 431: 432: 433:
434: public function getArticleScore() {
435: $votes = $this->getArticleVotes();
436:
437: $score = 0;
438: $total_score = 0;
439: $vote_count = count($votes);
440:
441: for($i = 0; $i < $vote_count; $i++){
442: $total_score += $votes[$i]->get('score');
443: }
444:
445: if($vote_count > 0)
446: $score = $total_score/$vote_count;
447:
448: return sprintf("%01.2f", $score);
449: }
450:
451: 452: 453: 454: 455: 456:
457: public function getArticleVotes() {
458: $votes = $this->votes->getRelatedObjects();
459:
460: return $votes;
461: }
462:
463: 464: 465: 466: 467: 468: 469:
470: public function checkUserVoted() {
471:
472: if (!isset($_SESSION['currentUser']))
473: return true;
474:
475: $userID = $_SESSION['currentUser']->getID();
476:
477: $vote = new ArticleVoteObject();
478:
479: $sqlQuery = "SELECT COUNT(*) AS usersVote FROM ".$vote->getTableName()." WHERE articleOID='".$this->OID."' AND personOID='".$userID."';";
480:
481: $result = $this->query($sqlQuery);
482:
483: if(!isset($result[0])) {
484: throw new AlphaException('Failed to check if the current user voted for the article ['.$this->OID.'], query ['.$sqlQuery.']');
485: return false;
486: }
487:
488: $row = $result[0];
489:
490: if($row['usersVote'] == "0")
491: return false;
492: else
493: return true;
494: }
495:
496: 497: 498: 499: 500: 501:
502: public function getArticleComments() {
503: $comments = $this->comments->getRelatedObjects();
504:
505: return $comments;
506: }
507:
508: 509: 510: 511: 512: 513: 514:
515: public function loadContentFromFile($filePath) {
516: try{
517: $this->content->setValue(file_get_contents($filePath));
518: $this->filePath = $filePath;
519: }catch (Exception $e) {
520: throw new FileNotFoundException($e->getMessage());
521: }
522: }
523:
524: 525: 526: 527: 528: 529:
530: public function isLoadedFromFile() {
531: return ($this->filePath == '' ? false: true);
532: }
533:
534: 535: 536: 537: 538: 539: 540: 541:
542: public function getContentFileDate() {
543: if($this->filePath != '') {
544: try{
545: return date("Y-m-d H:i:s", filemtime($this->filePath));
546: }catch (Exception $e) {
547: throw new FileNotFoundException($e->getMessage());
548: }
549: }else{
550: throw new FileNotFoundException('Error trying to access an article content file when none is set!');
551: }
552: }
553: }
554:
555: ?>