1<?php 2// (c) Copyright by authors of the Tiki Wiki CMS Groupware Project 3// 4// All Rights Reserved. See copyright.txt for details and a complete list of authors. 5// Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details. 6// $Id$ 7 8//this script may only be included - so its better to die if called directly. 9if (strpos($_SERVER['SCRIPT_NAME'], basename(__FILE__)) !== false) { 10 header('location: index.php'); 11 exit; 12} 13 14class ArtLib extends TikiLib 15{ 16 //Special parsing for multipage articles 17 function get_number_of_pages($data) 18 { 19 $parts = explode('...page...', $data); 20 return count($parts); 21 } 22 23 function get_page($data, $i) 24 { 25 // Get slides 26 $parts = explode('...page...', $data); 27 28 if (! isset($parts[$i - 1])) { 29 $i = 1; 30 } 31 $ret = $parts[$i - 1]; 32 if (substr($parts[$i - 1], 1, 5) == '<br/>') { 33 $ret = substr($parts[$i - 1], 6); 34 } 35 36 if (substr($parts[$i - 1], 1, 6) == '<br />') { 37 $ret = substr($parts[$i - 1], 7); 38 } 39 40 return $ret; 41 } 42 43 function approve_submission($subId) 44 { 45 $data = $this->get_submission($subId); 46 47 if (! $data) { 48 return false; 49 } 50 51 if (! $data['image_x']) { 52 $data['image_x'] = 0; 53 } 54 55 if (! $data['image_y']) { 56 $data['image_y'] = 0; 57 } 58 59 $articleId = $this->replace_article( 60 $data['title'], 61 $data['authorName'], 62 $data['topicId'], 63 $data['useImage'], 64 $data['image_name'], 65 $data['image_size'], 66 $data['image_type'], 67 $data['image_data'], 68 $data['heading'], 69 $data['body'], 70 $data['publishDate'], 71 $data['expireDate'], 72 $data['author'], 73 0, 74 $data['image_x'], 75 $data['image_y'], 76 $data['type'], 77 $data['topline'], 78 $data['subtitle'], 79 $data['linkto'], 80 $data['image_caption'], 81 $data['lang'], 82 $data['rating'], 83 $data['isfloat'] 84 ); 85 $this->transfer_attributes_from_submission($subId, $articleId); 86 87 $query = "update `tiki_objects` set `type`= ?, `itemId`= ?, `href`=? where `itemId` = ? and `type`= ?"; 88 $this->query($query, ['article', (int)$articleId, "tiki-read_article.php?articleId=$articleId", (int)$subId, 'submission']); 89 $query = 'update `tiki_objects` set `href`=?, `type`=? where `href`=?'; 90 $this->query($query, ["'tiki-read_article.php?articleId=$articleId", 'article', "tiki-edit_submission.php?subId=$subId"]); 91 92 $this->remove_submission($subId); 93 } 94 95 function add_article_hit($articleId) 96 { 97 if (StatsLib::is_stats_hit()) { 98 $query = "update `tiki_articles` set `nbreads`=`nbreads`+1 where `articleId`=?"; 99 $this->query($query, [$articleId]); 100 } 101 } 102 103 function remove_article($articleId, $article_data = '') 104 { 105 global $user, $prefs; 106 $smarty = TikiLib::lib('smarty'); 107 $tikilib = TikiLib::lib('tiki'); 108 109 if ($articleId) { 110 if (empty($article_data)) { 111 $article_data = $this->get_article($articleId); 112 } 113 $query = 'delete from `tiki_articles` where `articleId`=?'; 114 115 $result = $this->query($query, [$articleId]); 116 $this->remove_object('article', $articleId); 117 118 $multilinguallib = TikiLib::lib('multilingual'); 119 $multilinguallib->detachTranslation('article', $articleId); 120 121 TikiLib::events()->trigger( 122 'tiki.article.delete', 123 [ 124 'type' => 'article', 125 'object' => $articleId, 126 'user' => $user, 127 ] 128 ); 129 130 // TODO refactor 131 $nots = $tikilib->get_event_watches('article_deleted', '*'); 132 if (! empty($article_data['topicId'])) { 133 $nots2 = $tikilib->get_event_watches('topic_article_deleted', $article_data['topicId']); 134 } else { 135 $nots2 = []; 136 } 137 $smarty->assign('mail_action', 'Delete'); 138 139 $nots3 = []; 140 foreach ($nots as $n) { 141 $nots3[] = $n['email']; 142 } 143 foreach ($nots2 as $n) { 144 if (! in_array($n['email'], $nots3)) { 145 $nots[] = $n; 146 } 147 } 148 149 if ($prefs['user_article_watch_editor'] != "y") { 150 for ($i = count($nots) - 1; $i >= 0; --$i) { 151 if ($nots[$i]['user'] == $user) { 152 unset($nots[$i]); 153 break; 154 } 155 } 156 } 157 158 if (! isset($_SERVER['SERVER_NAME'])) { 159 $_SERVER['SERVER_NAME'] = $_SERVER["HTTP_HOST"]; 160 } 161 162 if ($prefs['feature_user_watches'] == 'y' && $prefs['feature_daily_report_watches'] == 'y') { 163 $reportsManager = Reports_Factory::build('Reports_Manager'); 164 $reportsManager->addToCache( 165 $nots, 166 [ 167 'event' => 'article_deleted', 168 'articleId' => $articleId, 169 'articleTitle' => $article_data['title'], 170 'authorName' => $article_data['authorName'], 171 'user' => $user 172 ] 173 ); 174 } 175 176 if (count($nots) || (! empty($emails) && is_array($emails))) { 177 include_once('lib/notifications/notificationemaillib.php'); 178 179 $smarty->assign('mail_site', $_SERVER['SERVER_NAME']); 180 $smarty->assign('mail_title', 'articleId=' . $articleId); 181 $smarty->assign('mail_postid', $articleId); 182 $smarty->assign('mail_user', $user); 183 $smarty->assign('mail_current_data', $article_data['heading'] . "\n----------------------\n" . $article_data['body']); 184 185 // the strings below are used to localize messages in the template file 186 //get_strings tr('New article post:') tr('Edited article post:') tr('Deleted article post:') 187 sendEmailNotification($nots, 'watch', 'user_watch_article_post_subject.tpl', $_SERVER['SERVER_NAME'], 'user_watch_article_post.tpl'); 188 } 189 190 return true; 191 } 192 } 193 194 function remove_submission($subId) 195 { 196 if ($subId) { 197 $query = 'delete from `tiki_submissions` where `subId`=?'; 198 $result = $this->query($query, [(int) $subId]); 199 $this->remove_object('submission', $subId); 200 return true; 201 } 202 } 203 204 function delete_expired_submissions($maxrows = 1000) 205 { 206 $tiki_submissions = TikiDb::get()->table('tiki_submissions'); 207 208 $expired = $tiki_submissions->fetchColumn( 209 'subId', 210 ['expireDate' => $tiki_submissions->lesserThan($this->now)], 211 $maxrows 212 ); 213 214 $transaction = $this->begin(); 215 216 foreach ($expired as $subId) { 217 $tiki_submissions->delete(['subId' => $subId]); 218 219 $this->remove_object('submission', $subId); 220 } 221 222 $transaction->commit(); 223 224 225 return true; 226 } 227 228 function replace_submission($title, $authorName, $topicId, $useImage, $imgname, $imgsize, $imgtype, $imgdata, $heading, $body, $publishDate, $expireDate, $user, $subId, $image_x, $image_y, $type, $topline, $subtitle, $linkto, $image_caption, $lang, $rating = 0, $isfloat = 'n' 229 ) 230 { 231 global $tiki_p_autoapprove_submission, $prefs; 232 $smarty = TikiLib::lib('smarty'); 233 $tikilib = TikiLib::lib('tiki'); 234 235 if ($expireDate < $publishDate) { 236 $expireDate = $publishDate; 237 } 238 239 if (empty($imgdata)) { 240 $imgdata = ''; 241 } 242 243 $notificationlib = TikiLib::lib('notification'); 244 $query = 'select `name` from `tiki_topics` where `topicId` = ?'; 245 $topicName = $this->getOne($query, [(int) $topicId]); 246 $size = strlen($body); 247 248 $info = [ 249 'title' => $title, 250 'authorName' => $authorName, 251 'topicId' => (int) $topicId, 252 'topicName' => $topicName, 253 'size' => (int) $size, 254 'useImage' => $useImage, 255 'image_name' => $imgname, 256 'image_type' => $imgtype, 257 'image_size' => (int) $imgsize, 258 'image_data' => $imgdata, 259 'isfloat' => $isfloat, 260 'image_x' => (int) $image_x, 261 'image_y' => (int) $image_y, 262 'heading' => $heading, 263 'body' => $body, 264 'publishDate' => (int) $publishDate, 265 'expireDate' => (int) $expireDate, 266 'author' => $user, 267 'type' => $type, 268 'rating' => (float) $rating, 269 'topline' => $topline, 270 'subtitle' => $subtitle, 271 'linkto' => $linkto, 272 'image_caption' => $image_caption, 273 'lang' => $lang, 274 ]; 275 276 $article_table = $this->table('tiki_submissions'); 277 if ($subId) { 278 $article_table->update($info, [ 279 'subId' => (int) $subId, 280 ]); 281 } else { 282 $info['created'] = (int) $this->now; 283 $info['nbreads'] = 0; 284 $info['votes'] = 0; 285 $info['points'] = 0; 286 $id = $article_table->insert($info); 287 } 288 289 if ($tiki_p_autoapprove_submission != 'y') { 290 $nots = $tikilib->get_event_watches('article_submitted', '*'); 291 $nots2 = $tikilib->get_event_watches('topic_article_created', $topicId); 292 $nots3 = []; 293 foreach ($nots as $n) { 294 $nots3[] = $n['email']; 295 } 296 foreach ($nots2 as $n) { 297 if (! in_array($n['emails'], $nots3)) { 298 $nots[] = $n; 299 } 300 } 301 if (! isset($_SERVER['SERVER_NAME'])) { 302 $_SERVER['SERVER_NAME'] = $_SERVER['HTTP_HOST']; 303 } 304 305 if ($prefs['user_article_watch_editor'] != "y") { 306 for ($i = count($nots) - 1; $i >= 0; --$i) { 307 if ($nots[$i]['user'] == $user) { 308 unset($nots[$i]); 309 break; 310 } 311 } 312 } 313 314 if (count($nots)) { 315 include_once('lib/notifications/notificationemaillib.php'); 316 $smarty->assign('mail_site', $_SERVER['SERVER_NAME']); 317 $smarty->assign('mail_user', $user); 318 $smarty->assign('mail_title', $title); 319 $smarty->assign('mail_heading', $heading); 320 $smarty->assign('mail_body', $body); 321 $smarty->assign('mail_subId', $id); 322 sendEmailNotification($nots, 'watch', 'submission_notification_subject.tpl', $_SERVER['SERVER_NAME'], 'submission_notification.tpl'); 323 } 324 } 325 $tikilib = TikiLib::lib('tiki'); 326 $tikilib->object_post_save( 327 [ 328 'type' => 'submission', 329 'object' => $id, 330 'description' => substr($heading, 0, 200), 331 'name' => $title, 332 'href' => "tiki-edit_submission.php?subId=$id", 333 ], 334 [ 'content' => $heading . "\n" . $body ] 335 ); 336 337 return $id; 338 } 339 340 function replace_article( $title, $authorName, $topicId, $useImage, $imgname, $imgsize, $imgtype, $imgdata, $heading, $body, $publishDate, $expireDate, $user, $articleId, $image_x, $image_y, $type, $topline, $subtitle, $linkto, $image_caption, $lang, $rating = 0, $isfloat = 'n', $emails = '', $from = '', $list_image_x = '', $list_image_y = '', $ispublished = 'y', $fromurl = false 341 ) 342 { 343 344 $tikilib = TikiLib::lib('tiki'); 345 $smarty = TikiLib::lib('smarty'); 346 347 if ($expireDate < $publishDate) { 348 $expireDate = $publishDate; 349 } 350 if (empty($imgdata) || $useImage === 'n') { // remove image data if not using it 351 $imgdata = ''; 352 } 353 354 $query = 'select `name` from `tiki_topics` where `topicId` = ?'; 355 $topicName = $this->getOne($query, [$topicId]); 356 $size = $body ? mb_strlen($body) : mb_strlen($heading); 357 358 $info = [ 359 'title' => $title, 360 'authorName' => $authorName, 361 'topicId' => (int) $topicId, 362 'topicName' => $topicName, 363 'size' => (int) $size, 364 'useImage' => $useImage, 365 'image_name' => $imgname, 366 'image_type' => $imgtype, 367 'image_size' => (int) $imgsize, 368 'image_data' => $imgdata, 369 'isfloat' => $isfloat, 370 'image_x' => (int) $image_x, 371 'image_y' => (int) $image_y, 372 'list_image_x' => (int) $list_image_x, 373 'list_image_y' => (int) $list_image_y, 374 'heading' => $heading, 375 'body' => $body, 376 'publishDate' => (int) $publishDate, 377 'expireDate' => (int) $expireDate, 378 'author' => $user, 379 'type' => $type, 380 'rating' => (float) $rating, 381 'topline' => $topline, 382 'subtitle' => $subtitle, 383 'linkto' => $linkto, 384 'image_caption' => $image_caption, 385 'lang' => $lang, 386 'ispublished' => $ispublished, 387 ]; 388 389 $article_table = $this->table('tiki_articles'); 390 if ($articleId) { 391 $oldArticle = $this->get_article($articleId); 392 $article_table->update($info, [ 393 'articleId' => (int) $articleId, 394 ]); 395 // Clear article image cache because image may just have been changed 396 $this->delete_image_cache('article', $articleId); 397 398 $event = 'article_edited'; 399 $nots = $tikilib->get_event_watches('article_edited', $articleId); 400 $nots2 = $tikilib->get_event_watches('topic_article_edited', $topicId); 401 $smarty->assign('mail_action', 'Edit'); 402 $smarty->assign('mail_old_title', $oldArticle['title']); 403 $smarty->assign('mail_old_publish_date', $oldArticle['publishDate']); 404 $smarty->assign('mail_old_expiration_date', $oldArticle['expireDate']); 405 $smarty->assign('mail_old_data', $oldArticle['heading'] . "\n----------------------\n" . $oldArticle['body']); 406 } else { 407 $info['created'] = (int) $this->now; 408 $info['nbreads'] = 0; 409 $info['votes'] = 0; 410 $info['points'] = 0; 411 412 $articleId = $article_table->insert($info); 413 414 global $prefs; 415 TikiLib::events()->trigger( 416 'tiki.article.create', 417 [ 418 'type' => 'article', 419 'object' => $articleId, 420 'user' => $user, 421 ] 422 ); 423 $event = 'article_submitted'; 424 $nots = $tikilib->get_event_watches('article_submitted', $articleId); 425 $nots2 = $tikilib->get_event_watches('topic_article_created', $topicId); 426 $smarty->assign('mail_action', 'New'); 427 428 // Create tracker item as well if feature is enabled 429 if (! $fromurl && $prefs['tracker_article_tracker'] == 'y' && $trackerId = $prefs['tracker_article_trackerId']) { 430 $trklib = TikiLib::lib('trk'); 431 $definition = Tracker_Definition::get($trackerId); 432 if ($fieldId = $definition->getArticleField()) { 433 $addit = []; 434 $addit[] = [ 435 'fieldId' => $fieldId, 436 'type' => 'articles', 437 'value' => $articleId, 438 ]; 439 $itemId = $trklib->replace_item($trackerId, 0, ['data' => $addit]); 440 TikiLib::lib('relation')->add_relation('tiki.article.attach', 'trackeritem', $itemId, 'article', $articleId); 441 } 442 } 443 } 444 445 $wikilib = TikiLib::lib('wiki'); 446 $wikilib->update_wikicontent_relations( 447 $heading . "\n" . $body, 448 'article', 449 (int)$articleId 450 ); 451 $wikilib->update_wikicontent_links( 452 $heading . "\n" . $body, 453 'article', 454 (int)$articleId 455 ); 456 457 $nots3 = []; 458 foreach ($nots as $n) { 459 $nots3[] = $n['email']; 460 } 461 foreach ($nots2 as $n) { 462 if (! in_array($n['email'], $nots3)) { 463 $nots[] = $n; 464 } 465 } 466 if (is_array($emails) && (empty($from) || $from == $prefs['sender_email'])) { 467 foreach ($emails as $n) { 468 if (! in_array($n, $nots3)) { 469 $nots[] = ['email' => $n, 'language' => $prefs['site_language']]; 470 } 471 } 472 } 473 global $prefs; 474 475 if ($prefs['user_article_watch_editor'] != "y") { 476 for ($i = count($nots) - 1; $i >= 0; --$i) { 477 if ($nots[$i]['user'] == $user) { 478 unset($nots[$i]); 479 break; 480 } 481 } 482 } 483 484 if (! isset($_SERVER['SERVER_NAME'])) { 485 $_SERVER['SERVER_NAME'] = $_SERVER['HTTP_HOST']; 486 } 487 488 if ($prefs['feature_user_watches'] == 'y' && $prefs['feature_daily_report_watches'] == 'y') { 489 $reportsManager = Reports_Factory::build('Reports_Manager'); 490 $reportsManager->addToCache( 491 $nots, 492 [ 493 'event' => $event, 494 'articleId' => $articleId, 495 'articleTitle' => $title, 496 'authorName' => $authorName, 497 'user' => $user 498 ] 499 ); 500 } 501 502 if (count($nots) || is_array($emails)) { 503 include_once('lib/notifications/notificationemaillib.php'); 504 505 $smarty->assign('mail_site', $_SERVER['SERVER_NAME']); 506 $smarty->assign('mail_title', $title); 507 $smarty->assign('mail_postid', $articleId); 508 $smarty->assign('mail_user', $user); 509 $smarty->assign('mail_current_publish_date', $publishDate); 510 $smarty->assign('mail_current_expiration_date', $expireDate); 511 $smarty->assign('mail_current_data', $heading . "\n----------------------\n" . $body); 512 sendEmailNotification($nots, 'watch', 'user_watch_article_post_subject.tpl', $_SERVER['SERVER_NAME'], 'user_watch_article_post.tpl'); 513 if (is_array($emails) && ! empty($from) && $from != $prefs['sender_email']) { 514 $nots = []; 515 foreach ($emails as $n) { 516 $nots[] = ['email' => $n, 'language' => $prefs['site_language']]; 517 } 518 sendEmailNotification($nots, 'watch', 'user_watch_article_post_subject.tpl', $_SERVER['SERVER_NAME'], 'user_watch_article_post.tpl', $from); 519 } 520 } 521 522 523 require_once('lib/search/refresh-functions.php'); 524 refresh_index('articles', $articleId); 525 526 $tikilib = TikiLib::lib('tiki'); 527 $tikilib->object_post_save( 528 [ 529 'type' => 'article', 530 'object' => $articleId, 531 'description' => substr($heading, 0, 200), 532 'name' => $title, 533 'href' => "tiki-read_article.php?articleId=$articleId" 534 ], 535 [ 'content' => $body . "\n" . $heading ] 536 ); 537 538 return $articleId; 539 } 540 541 function add_topic($name, $imagename, $imagetype, $imagesize, $imagedata) 542 { 543 $query = 'insert into `tiki_topics`(`name`,`image_name`,`image_type`,`image_size`,`image_data`,`active`,`created`) values(?,?,?,?,?,?,?)'; 544 $result = $this->query($query, [$name, $imagename, $imagetype, (int) $imagesize, $imagedata, 'y', (int) $this->now]); 545 546 $query = 'select max(`topicId`) from `tiki_topics` where `created`=? and `name`=?'; 547 $topicId = $this->getOne($query, [(int) $this->now, $name]); 548 return $topicId; 549 } 550 551 function remove_topic($topicId, $all = 0) 552 { 553 $query = 'delete from `tiki_topics` where `topicId`=?'; 554 555 $result = $this->query($query, [$topicId]); 556 557 if ($all == 1) { 558 $query = 'delete from `tiki_articles` where `topicId`=?'; 559 $result = $this->query($query, [$topicId]); 560 } else { 561 $query = 'update `tiki_articles` set `topicId`=?, `topicName`=? where `topicId`=?'; 562 $result = $this->query($query, [null, null, $topicId]); 563 } 564 565 return true; 566 } 567 568 function replace_topic_name($topicId, $name) 569 { 570 $query = 'update `tiki_topics` set `name` = ? where `topicId` = ?'; 571 $result = $this->query($query, [$name, (int)$topicId]); 572 573 $query = 'update `tiki_articles` set `topicName` = ? where `topicId`= ?'; 574 $result = $this->query($query, [$name, (int)$topicId]); 575 return true; 576 } 577 578 function replace_topic_image($topicId, $imagename, $imagetype, $imagesize, $imagedata) 579 { 580 $topicId = (int)$topicId; 581 $query = 'update `tiki_topics` set `image_name` = ?, `image_type` = ?, `image_size` = ?, `image_data` = ? where `topicId` = ?'; 582 $result = $this->query($query, [$imagename, $imagetype, $imagesize, $imagedata, $topicId]); 583 584 return true; 585 } 586 587 function activate_topic($topicId) 588 { 589 $query = 'update `tiki_topics` set `active`=? where `topicId`=?'; 590 591 $result = $this->query($query, ['y', $topicId]); 592 } 593 594 function deactivate_topic($topicId) 595 { 596 $query = 'update `tiki_topics` set `active`=? where `topicId`=?'; 597 598 $result = $this->query($query, ['n', $topicId]); 599 } 600 601 function get_topic($topicId) 602 { 603 $query = 'select `topicId`,`name`,`image_name`,`image_size`,`image_type` from `tiki_topics` where `topicId`=?'; 604 605 $result = $this->query($query, [$topicId]); 606 607 $res = $result->fetchRow(); 608 return $res; 609 } 610 611 function get_topicId($name) 612 { 613 $query = 'select `topicId` from `tiki_topics` where `name`=?'; 614 return $this->getOne($query, [$name]); 615 } 616 617 function list_topics() 618 { 619 $query = 'select `topicId`,`name`,`image_name`,`image_size`,`image_type`,`active` from `tiki_topics` order by `name`'; 620 621 $result = $this->query($query, []); 622 623 $ret = []; 624 625 while ($res = $result->fetchRow()) { 626 $res['subs'] = $this->getOne('select count(*) from `tiki_submissions` where `topicId`=?', [$res['topicId']]); 627 628 $res['arts'] = $this->getOne('select count(*) from `tiki_articles` where `topicId`=?', [$res['topicId']]); 629 $ret[$res['topicId']] = $res; 630 } 631 632 return $ret; 633 } 634 635 function list_active_topics() 636 { 637 $query = 'select * from `tiki_topics` where `active`=?'; 638 639 $result = $this->query($query, ['y']); 640 641 $ret = []; 642 643 while ($res = $result->fetchRow()) { 644 $ret[] = $res; 645 } 646 647 return $ret; 648 } 649 650 // Article Type functions 651 function add_type($type) 652 { 653 $result = $this->query('insert into `tiki_article_types`(`type`) values(?)', [$type]); 654 655 return true; 656 } 657 658 function edit_type( $type, $use_ratings, $show_pre_publ, $show_post_expire, $heading_only, $allow_comments, $comment_can_rate_article, $show_image, $show_avatar, $show_author, $show_pubdate, $show_expdate, $show_reads, $show_size, $show_topline, $show_subtitle, $show_linkto, $show_image_caption, $creator_edit 659 ) 660 { 661 if ($use_ratings == 'on') { 662 $use_ratings = 'y'; 663 } else { 664 $use_ratings = 'n'; 665 } 666 667 if ($show_pre_publ == 'on') { 668 $show_pre_publ = 'y'; 669 } else { 670 $show_pre_publ = 'n'; 671 } 672 673 if ($show_post_expire == 'on') { 674 $show_post_expire = 'y'; 675 } else { 676 $show_post_expire = 'n'; 677 } 678 679 if ($heading_only == 'on') { 680 $heading_only = 'y'; 681 } else { 682 $heading_only = 'n'; 683 } 684 685 if ($allow_comments == 'on') { 686 $allow_comments = 'y'; 687 } else { 688 $allow_comments = 'n'; 689 } 690 691 if ($comment_can_rate_article == 'on') { 692 $comment_can_rate_article = 'y'; 693 } else { 694 $comment_can_rate_article = 'n'; 695 } 696 697 if ($show_image == 'on') { 698 $show_image = 'y'; 699 } else { 700 $show_image = 'n'; 701 } 702 703 if ($show_avatar == 'on') { 704 $show_avatar = 'y'; 705 } else { 706 $show_avatar = 'n'; 707 } 708 709 if ($show_author == 'on') { 710 $show_author = 'y'; 711 } else { 712 $show_author = 'n'; 713 } 714 715 if ($show_pubdate == 'on') { 716 $show_pubdate = 'y'; 717 } else { 718 $show_pubdate = 'n'; 719 } 720 721 if ($show_expdate == 'on') { 722 $show_expdate = 'y'; 723 } else { 724 $show_expdate = 'n'; 725 } 726 727 if ($show_reads == 'on') { 728 $show_reads = 'y'; 729 } else { 730 $show_reads = 'n'; 731 } 732 733 if ($show_size == 'on') { 734 $show_size = 'y'; 735 } else { 736 $show_size = 'n'; 737 } 738 739 if ($show_topline == 'on') { 740 $show_topline = 'y'; 741 } else { 742 $show_topline = 'n'; 743 } 744 if ($show_subtitle == 'on') { 745 $show_subtitle = 'y'; 746 } else { 747 $show_subtitle = 'n'; 748 } 749 750 if ($show_linkto == 'on') { 751 $show_linkto = 'y'; 752 } else { 753 $show_linkto = 'n'; 754 } 755 756 if ($show_image_caption == 'on') { 757 $show_image_caption = 'y'; 758 } else { 759 $show_image_caption = 'n'; 760 } 761 762 if ($creator_edit == 'on') { 763 $creator_edit = 'y'; 764 } else { 765 $creator_edit = 'n'; 766 } 767 $query = "update `tiki_article_types` set 768 `use_ratings` = ?, 769 `show_pre_publ` = ?, 770 `show_post_expire` = ?, 771 `heading_only` = ?, 772 `allow_comments` = ?, 773 `comment_can_rate_article` = ?, 774 `show_image` = ?, 775 `show_avatar` = ?, 776 `show_author` = ?, 777 `show_pubdate` = ?, 778 `show_expdate` = ?, 779 `show_reads` = ?, 780 `show_size` = ?, 781 `show_topline` = ?, 782 `show_subtitle` = ?, 783 `show_linkto` = ?, 784 `show_image_caption` = ?, 785 `creator_edit` = ? 786 where `type` = ?"; 787 788 $result = $this->query( 789 $query, 790 [ 791 $use_ratings, 792 $show_pre_publ, 793 $show_post_expire, 794 $heading_only, 795 $allow_comments, 796 $comment_can_rate_article, 797 $show_image, 798 $show_avatar, 799 $show_author, 800 $show_pubdate, 801 $show_expdate, 802 $show_reads, 803 $show_size, 804 $show_topline, 805 $show_subtitle, 806 $show_linkto, 807 $show_image_caption, 808 $creator_edit, 809 $type 810 ] 811 ); 812 } 813 814 function remove_type($type) 815 { 816 $query = 'delete from `tiki_article_types` where `type`=?'; 817 $result = $this->query($query, [$type]); 818 // remove attributes set for this type too 819 $query = "delete from `tiki_object_relations` where `source_type` = 'articletype' and `source_itemId`=?"; 820 $result = $this->query($query, [$type]); 821 } 822 823 function get_type($type) 824 { 825 $query = 'select * from `tiki_article_types` where `type`=?'; 826 827 $result = $this->query($query, [$type]); 828 829 $res = $result->fetchRow(); 830 return $res; 831 } 832 833 function list_types() 834 { 835 $query = 'select * from `tiki_article_types`'; 836 $result = $this->query($query, []); 837 $ret = []; 838 839 while ($res = $result->fetchRow()) { 840 $res['article_cnt'] = $this->getOne('select count(*) from `tiki_articles` where `type` = ?', [$res['type']]); 841 $ret[] = $res; 842 } 843 844 return $ret; 845 } 846 847 function list_types_byname() 848 { 849 $query = "select * from `tiki_article_types` order by `type` asc"; 850 $result = $this->query($query, []); 851 $ret = []; 852 853 while ($res = $result->fetchRow()) { 854 $ret[$res['type']] = $res; 855 } 856 857 return $ret; 858 } 859 860 function get_user_articles($user, $max) 861 { 862 $query = 'select `articleId` ,`title` from `tiki_articles` where `author`=? order by `publishDate` desc'; 863 864 $articles = $this->fetchAll($query, [$user], $max); 865 866 return Perms::filter(['type' => 'article'], 'object', $articles, ['object' => 'articleId'], 'read_article'); 867 } 868 869 function import_csv($fileName, &$msgs, $csvDelimiter = ',') 870 { 871 global $user, $prefs, $tikilib; 872 $fhandle = fopen($fileName, 'r'); 873 if (($fds = fgetcsv($fhandle, 4096, $csvDelimiter)) === false || empty($fds[0])) { 874 $msgs[] = tra('The file has incorrect syntax or is not a CSV file'); 875 return false; 876 } 877 for ($i = 0, $icount_fds = count($fds); $i < $icount_fds; $i++) { 878 $fields[trim($fds[$i])] = $i; 879 } 880 if (! isset($fields['title'])) { 881 $fields['title'] = $i++; 882 } 883 if (! isset($fields['authorName'])) { 884 $fields['authorName'] = $i++; 885 } 886 if (! isset($fields['topicId'])) { 887 $fields['topicId'] = $i++; 888 } 889 if (! isset($fields['useImage'])) { 890 $fields['useImage'] = $i++; 891 } 892 if (! isset($fields['imgname'])) { 893 $fields['imgname'] = $i++; 894 } 895 if (! isset($fields['imgsize'])) { 896 $fields['imgsize'] = $i++; 897 } 898 if (! isset($fields['imgtype'])) { 899 $fields['imgtype'] = $i++; 900 } 901 if (! isset($fields['imgdata'])) { 902 $fields['imgdata'] = $i++; 903 } 904 if (! isset($fields['heading'])) { 905 $fields['heading'] = $i++; 906 } 907 if (! isset($fields['body'])) { 908 $fields['body'] = $i++; 909 } 910 if (! isset($fields['publishDate'])) { 911 $fields['publishDate'] = $i++; 912 } 913 if (! isset($fields['expireDate'])) { 914 $fields['expireDate'] = $i++; 915 } 916 if (! isset($fields['user'])) { 917 $fields['user'] = $i++; 918 } 919 if (! isset($fields['image_x'])) { 920 $fields['image_x'] = $i++; 921 } 922 if (! isset($fields['image_y'])) { 923 $fields['image_y'] = $i++; 924 } 925 if (! isset($fields['type'])) { 926 $fields['type'] = $i++; 927 } 928 if (! isset($fields['topline'])) { 929 $fields['topline'] = $i++; 930 } 931 if (! isset($fields['subtitle'])) { 932 $fields['subtitle'] = $i++; 933 } 934 if (! isset($fields['linkto'])) { 935 $fields['linkto'] = $i++; 936 } 937 if (! isset($fields['image_caption'])) { 938 $fields['image_caption'] = $i++; 939 } 940 if (! isset($fields['lang'])) { 941 $fields['lang'] = $i++; 942 } 943 if (! isset($fields['rating'])) { 944 $fields['rating'] = $i++; 945 } 946 if (! isset($fields['isfloat'])) { 947 $fields['isfloat'] = $i++; 948 } 949 if (! isset($fields['emails'])) { 950 $fields['emails'] = $i++; 951 } 952 $line = 1; 953 while (($data = fgetcsv($fhandle, 4096, $csvDelimiter)) !== false) { 954 ++$line; 955 if (! isset($data[$fields['title']])) { 956 $data[$fields['title']] = ''; 957 } 958 if (! isset($data[$fields['authorName']])) { 959 $data[$fields['authorName']] = ''; 960 } 961 if (! isset($data[$fields['topicId']])) { 962 $data[$fields['topicId']] = 0; 963 } 964 if (! isset($data[$fields['useImage']])) { 965 $data[$fields['useImage']] = 'n'; 966 } 967 if (! isset($data[$fields['imgname']])) { 968 $data[$fields['imgname']] = ''; 969 } 970 if (! isset($data[$fields['imgsize']])) { 971 $data[$fields['imgsize']] = ''; 972 } 973 if (! isset($data[$fields['imgtype']])) { 974 $data[$fields['imgtype']] = ''; 975 } 976 if (! isset($data[$fields['imgdata']])) { 977 $data[$fields['imgdata']] = ''; 978 } 979 if (! isset($data[$fields['heading']])) { 980 $data[$fields['heading']] = ''; 981 } 982 if (! isset($data[$fields['body']])) { 983 $data[$fields['body']] = ''; 984 } 985 if (! isset($data[$fields['publishDate']])) { 986 $data[$fields['publishDate']] = $tikilib->now; 987 } 988 if (! isset($data[$fields['expireDate']])) { 989 $data[$fields['expireDate']] = $tikilib->now + 365 * 24 * 60 * 60; 990 } 991 if (! isset($data[$fields['user']])) { 992 $data[$fields['user']] = $user; 993 } 994 if (! isset($data[$fields['image_x']])) { 995 $data[$fields['image_x']] = 0; 996 } 997 if (! isset($data[$fields['image_y']])) { 998 $data[$fields['image_y']] = 0; 999 } 1000 if (! isset($data[$fields['type']])) { 1001 $data[$fields['type']] = 'Article'; 1002 } 1003 if (! isset($data[$fields['topline']])) { 1004 $data[$fields['topline']] = ''; 1005 } 1006 if (! isset($data[$fields['subtitle']])) { 1007 $data[$fields['subtitle']] = ''; 1008 } 1009 if (! isset($data[$fields['linkto']])) { 1010 $data[$fields['linkto']] = ''; 1011 } 1012 if (! isset($data[$fields['image_caption']])) { 1013 $data[$fields['image_caption']] = ''; 1014 } 1015 if (! isset($data[$fields['lang']])) { 1016 $data[$fields['lang']] = $prefs['language']; 1017 } 1018 if (! isset($data[$fields['rating']])) { 1019 $data[$fields['rating']] = 7; 1020 } 1021 if (! isset($data[$fields['isfloat']])) { 1022 $data[$fields['isfloat']] = 'n'; 1023 } 1024 if (! isset($data[$fields['emails']])) { 1025 $data[$fields['emails']] = ''; 1026 } 1027 1028 $articleId = $this->replace_article( 1029 $data[$fields['title']], 1030 $data[$fields['authorName']], 1031 $data[$fields['topicId']], 1032 $data[$fields['useImage']], 1033 $data[$fields['imgname']], 1034 $data[$fields['imgsize']], 1035 $data[$fields['imgtype']], 1036 $data[$fields['imgdata']], 1037 $data[$fields['heading']], 1038 $data[$fields['body']], 1039 $data[$fields['publishDate']], 1040 $data[$fields['expireDate']], 1041 $data[$fields['user']], 1042 0, 1043 $data[$fields['image_x']], 1044 $data[$fields['image_y']], 1045 $data[$fields['type']], 1046 $data[$fields['topline']], 1047 $data[$fields['subtitle']], 1048 $data[$fields['linkto']], 1049 $data[$fields['image_caption']], 1050 $data[$fields['lang']], 1051 $data[$fields['rating']], 1052 $data[$fields['isfloat']], 1053 $data[$fields['emails']] 1054 ); 1055 if (empty($articleId)) { 1056 $msgs[] = sprintf(tr('Error line: %d'), $line); 1057 return false; 1058 } 1059 } 1060 if (isset($articleId) && $articleId) { 1061 return true; 1062 } else { 1063 $msgs[] = tr('Import failed due to data format. Make sure the file has Unix-style line breaks.'); 1064 return false; 1065 } 1066 } 1067 1068 function delete_image_cache($image_type, $imageId) 1069 { 1070 global $prefs, $tikidomain; 1071 // Input validation: imageId must be a number, and not 0 1072 if (! ctype_digit("$imageId") || ! ($imageId > 0)) { 1073 return false; 1074 } 1075 switch ($image_type) { 1076 case 'article': 1077 $image_cache_prefix = 'article'; 1078 break; 1079 case 'submission': 1080 $image_cache_prefix = 'article_submission'; 1081 break; 1082 case 'preview': 1083 $image_cache_prefix = 'article_preview'; 1084 break; 1085 default: 1086 return false; 1087 } 1088 $article_image_cache = $prefs['tmpDir']; 1089 if ($tikidomain) { 1090 $article_image_cache .= "/$tikidomain"; 1091 } 1092 $article_image_cache .= "/$image_cache_prefix." . $imageId; 1093 if (@unlink($article_image_cache)) { 1094 return true; 1095 } else { 1096 return false; 1097 } 1098 } 1099 1100 function get_title($articleId) 1101 { 1102 $query = 'select `title` from `tiki_articles` where `articleId`=?'; 1103 return $this->getOne($query, [(int)$articleId]); 1104 } 1105 1106 function fetchtopicId($topic) 1107 { 1108 $topicId = ''; 1109 $query = 'select `topicId` from `tiki_topics` where `name` = ?'; 1110 $topicId = $this->getOne($query, [$topic]); 1111 return $topicId; 1112 } 1113 1114 function get_most_recent_article_id() 1115 { 1116 $maxRecords = 1; 1117 $sort_mode = 'publishDate_desc'; 1118 $date_min = 0; 1119 $date_max = $this->now; 1120 $query = 'SELECT `tiki_articles`.`articleId` FROM `tiki_articles` INNER JOIN `tiki_article_types` on `tiki_articles`.`type` = `tiki_article_types`.`type` ' . 1121 'WHERE `tiki_articles`.`publishDate`>=\'0\' AND (`tiki_articles`.`publishDate`<=? OR `tiki_article_types`.`show_pre_publ`=\'y\') AND ' . 1122 '(`tiki_articles`.`expireDate`>? OR `tiki_article_types`.`show_post_expire`=\'y\') AND `tiki_articles`.`ispublished`=\'y\' ' . 1123 'ORDER BY `publishDate` DESC'; 1124 $bindvars = [ $date_max, $date_max ]; 1125 $id = $this->getOne($query, $bindvars); 1126 return $id; 1127 } 1128 1129 function list_articles( $offset = 0, $maxRecords = -1, $sort_mode = 'publishDate_desc', $find = '', $date_min = 0, $date_max = 0, $user = false, $type = '', $topicId = '', $visible_only = 'y', $topic = '', $categId = '', $creator = '', $group = '', $lang = '', $min_rating = '', $max_rating = '', $override_dates = false, $ispublished = '', $filter = '' 1130 ) 1131 { 1132 1133 global $user, $prefs; 1134 $userlib = TikiLib::lib('user'); 1135 1136 $mid = $join = ''; 1137 $bindvars = []; 1138 $fromSql = ''; 1139 1140 if (! empty($filter)) { 1141 foreach ($filter as $typeF => $val) { 1142 if ($typeF == 'translationOrphan') { 1143 $multilinguallib = TikiLib::lib('multilingual'); 1144 $multilinguallib->sqlTranslationOrphan('article', '`tiki_articles`', 'articleId', $val, $join, $mid, $bindvars); 1145 $mid = ' where ' . $mid; 1146 } 1147 if ($typeF == 'articleId' || $typeF == 'notArticleId') { 1148 $mid .= empty($mid) ? ' where ' : ' and '; 1149 $mid .= '`articleId` ' . ($typeF == 'notArticleId' ? 'not in ' : 'in') . ' (' . implode(',', array_fill(0, count($val), '?')) . ')'; 1150 $bindvars = array_merge($bindvars, $val); 1151 } 1152 } 1153 } 1154 1155 if ($find) { 1156 $findesc = '%' . $find . '%'; 1157 $mid .= empty($mid) ? ' where ' : ' and '; 1158 $mid .= " (`title` like ? or `heading` like ? or `body` like ? or `author` like ? or `authorName` like ?) "; 1159 $bindvars = [$findesc, $findesc, $findesc, $findesc, $findesc]; 1160 } 1161 1162 // type=>[!]a+b+c+d+... 1163 if ($type) { 1164 $invert = ''; 1165 $connect = ' or '; 1166 // parameter list negated? 1167 if (substr($type, 0, 1) == '!') { 1168 $type = substr($type, 1); 1169 $invert = '!'; 1170 $connect = ' and '; 1171 } 1172 $add = ''; 1173 $rest = explode('+', $type); 1174 foreach ($rest as $type) { 1175 if ($add == '') { 1176 if ($mid) { 1177 $mid .= ' and '; 1178 } else { 1179 $mid = ' where '; 1180 } 1181 } else { 1182 $add .= $connect; 1183 } 1184 $add .= " `tiki_articles`.`type`$invert=? "; 1185 $bindvars[] = $type; 1186 } 1187 if ($add <> '') { 1188 $mid .= ' ( ' . $add . ' ) '; 1189 } 1190 } 1191 1192 // topicId=>[!]a+b+c+d+... 1193 if (($topicId) || ($topicId == '0')) { 1194 $invert = ''; 1195 $connect = ' or '; 1196 // parameter list negated? 1197 if (substr($topicId, 0, 1) == '!') { 1198 $topicId = substr($topicId, 1); 1199 $invert = '!'; 1200 $connect = ' and '; 1201 } 1202 $add = ''; 1203 $rest = explode('+', $topicId); 1204 foreach ($rest as $topicId) { 1205 if ($add == '') { 1206 if ($mid) { 1207 $mid .= ' and '; 1208 } else { 1209 $mid = ' where '; 1210 } 1211 } else { 1212 $add .= $connect; 1213 } 1214 $add .= " `tiki_articles`.`topicId`$invert=? "; 1215 $bindvars[] = $topicId; 1216 } 1217 if ($add <> '') { 1218 $mid .= ' ( ' . $add . ' ) '; 1219 } 1220 } 1221 1222 // topic=>[!]a+b+c+d+... 1223 if ($topic) { 1224 $invert = ''; 1225 // parameter list negated? 1226 if (substr($topic, 0, 1) == '!') { 1227 $topic = substr($topic, 1); 1228 $invert = '!'; 1229 } 1230 $rest = explode('\+', $topic); 1231 1232 if ($mid) { 1233 $mid .= ' and '; 1234 } else { 1235 $mid = ' where '; 1236 } 1237 $add = $this->in('tiki_articles.topicName', $rest, $bindvars); 1238 if ($add <> '') { 1239 $add = ($invert ? ' NOT' : '') . ' ( ' . $add . ' ) '; 1240 if ($invert) { 1241 $add = 'COALESCE(' . $add . ', TRUE)'; 1242 } 1243 $mid .= $add; 1244 } 1245 } 1246 if (($visible_only) && ($visible_only <> 'n')) { 1247 if ($date_max <= 0) { 1248 // show articles published today 1249 $date_max = $this->now; 1250 } 1251 $bindvars[] = (int)$date_min; 1252 $bindvars[] = (int)$date_max; 1253 if ($override_dates) { 1254 $condition = "`tiki_articles`.`publishDate`>=? and `tiki_articles`.`publishDate`<=?"; 1255 } else { 1256 $bindvars[] = (int)$this->now; 1257 $condition = "`tiki_articles`.`publishDate`>=? and (`tiki_articles`.`publishDate`<=? or `tiki_article_types`.`show_pre_publ`='y')" 1258 . " and (`tiki_articles`.`expireDate`>? or `tiki_article_types`.`show_post_expire`='y')" 1259 ; 1260 } 1261 $mid .= ( $mid ? ' and ' : ' where ' ) . $condition; 1262 } 1263 if (! empty($lang)) { 1264 $condition = '`tiki_articles`.`lang`=?'; 1265 $mid .= ($mid) ? ' and ' : ' where '; 1266 $mid .= $condition . ' '; 1267 $bindvars[] = $lang; 1268 } 1269 if (! empty($ispublished)) { 1270 $condition = '`tiki_articles`.`ispublished`=?'; 1271 $mid .= ($mid) ? ' and ' : ' where '; 1272 $mid .= $condition . ' '; 1273 $bindvars[] = $ispublished; 1274 } 1275 if ($mid) { 1276 $mid2 = ' and 1 = 1 '; 1277 } else { 1278 $mid2 = ' where 1 = 1 '; 1279 } 1280 1281 if ($creator != '') { 1282 $mid2 .= ' and `tiki_articles`.`author` like ? '; 1283 $bindvars[] = "%$creator%"; 1284 } 1285 1286 if ($min_rating || $max_rating) { 1287 $min_rating = isset($min_rating) ? $min_rating : '0.0'; 1288 $max_rating = isset($max_rating) ? $max_rating : '10.0'; 1289 $mid2 .= ' and (`tiki_articles`.`rating` >= ? and `tiki_articles`.`rating` <= ? )'; 1290 $bindvars[] = $min_rating; 1291 $bindvars[] = $max_rating; 1292 } 1293 1294 $categlib = TikiLib::lib('categ'); 1295 if ($categId) { 1296 $jail = $categId; 1297 } else { 1298 $jail = $categlib->get_jail(); 1299 } 1300 if ($jail) { 1301 $categlib->getSqlJoin($jail, 'article', '`tiki_articles`.`articleId`', $fromSql, $mid2, $bindvars); 1302 } 1303 1304 if (empty($sort_mode)) { 1305 $sort_mode = 'publishDate_desc'; 1306 } 1307 1308 if ($prefs['rating_advanced'] == 'y') { 1309 $ratinglib = TikiLib::lib('rating'); 1310 $fromSql .= $ratinglib->convert_rating_sort($sort_mode, 'article', '`articleId`'); 1311 } 1312 1313 $fromSql .= ' inner join `tiki_article_types` on `tiki_articles`.`type` = `tiki_article_types`.`type` '; 1314 1315 $query = "select distinct `tiki_articles`.*, 1316 `tiki_article_types`.`use_ratings`, 1317 `tiki_article_types`.`show_pre_publ`, 1318 `tiki_article_types`.`show_post_expire`, 1319 `tiki_article_types`.`heading_only`, 1320 `tiki_article_types`.`allow_comments`, 1321 `tiki_article_types`.`comment_can_rate_article`, 1322 `tiki_article_types`.`show_image`, 1323 `tiki_article_types`.`show_avatar`, 1324 `tiki_article_types`.`show_author`, 1325 `tiki_article_types`.`show_pubdate`, 1326 `tiki_article_types`.`show_expdate`, 1327 `tiki_article_types`.`show_reads`, 1328 `tiki_article_types`.`show_size`, 1329 `tiki_article_types`.`show_topline`, 1330 `tiki_article_types`.`show_subtitle`, 1331 `tiki_article_types`.`show_linkto`, 1332 `tiki_article_types`.`show_image_caption`, 1333 `tiki_article_types`.`creator_edit` 1334 from `tiki_articles` 1335 $fromSql 1336 $join 1337 $mid $mid2 order by " . 1338 $this->convertSortMode( 1339 $sort_mode, 1340 [ 1341 'title', 1342 'state', 1343 'authorName', 1344 'topicId', 1345 'topicName', 1346 'publishDate', 1347 'expireDate', 1348 'created', 1349 'author', 1350 'rating', 1351 'nbreads', 1352 ] 1353 ); 1354 1355 $result = $this->fetchAll($query, $bindvars, $maxRecords, $offset); 1356 $query_cant = "select distinct count(*) from `tiki_articles` $fromSql $join $mid $mid2"; 1357 $cant = $this->getOne($query_cant, $bindvars); 1358 $ret = []; 1359 $articleIds = array_map( 1360 function($res){ 1361 return $res['articleId']; 1362 }, $result 1363 ); 1364 Perms::bulk(['type' => 'article'], 'object', $articleIds); 1365 foreach ($result as $res) { 1366 $res['perms'] = $this->get_perm_object($res['articleId'], 'article', [], false); 1367 // Determine if unpublished article should be listed 1368 if ($res['ispublished'] != 'y' && $res['perms']['tiki_p_edit_article'] != 'y') { 1369 $res['disp_article'] = 'n'; 1370 } else { 1371 // no need to do all of the following if we are not adding this article to the array 1372 if ($res['perms']['tiki_p_read_article'] == 'y' || $res['perms']['tiki_p_articles_read_heading'] == 'y') { 1373 $res['entrating'] = floor($res['rating']); 1374 if (empty($res['body'])) { 1375 $res['isEmpty'] = 'y'; 1376 } else { 1377 $res['isEmpty'] = 'n'; 1378 } 1379 if (strlen($res['image_data']) > 0) { 1380 $res['hasImage'] = 'y'; 1381 } else { 1382 $res['hasImage'] = 'n'; 1383 } 1384 $res['count_comments'] = 0; 1385 1386 // Determine if the article would be displayed in the view page 1387 $res['disp_article'] = 'y'; 1388 if (($res['show_pre_publ'] != 'y') and ($this->now < $res['publishDate']) && ! $override_dates) { 1389 $res['disp_article'] = 'n'; 1390 } 1391 if (($res['show_post_expire'] != 'y') and ($this->now > $res['expireDate']) && ! $override_dates) { 1392 $res['disp_article'] = 'n'; 1393 } 1394 $ret[] = $res; 1395 } 1396 } 1397 } 1398 $retval = []; 1399 $retval['data'] = $ret; 1400 $retval['cant'] = $cant; 1401 return $retval; 1402 } 1403 1404 /** 1405 * Work out if body (or heading) should be parsed as html or not 1406 * Currently (tiki 11) tries the prefs but also checks for html in body in case wysiwyg_htmltowiki wasn't enabled previously 1407 * 1408 * @param array $article of article data 1409 * @param bool $check_heading use heading or (default) body 1410 * @return bool 1411 */ 1412 function is_html($article, $check_heading = false) 1413 { 1414 global $prefs; 1415 1416 $text = $check_heading ? $article['heading'] : $article['body']; 1417 1418 return ($prefs['feature_wysiwyg'] === 'y' || $prefs['mobile_mode'] === 'y') && // this now assumes that if in mobile mode any html in articles should not be encoded 1419 $prefs['wysiwyg_htmltowiki'] !== 'y' || 1420 preg_match('/(<\/p>|<\/span>|<\/div>|<\/?br>)/', $text); 1421 } 1422 1423 function list_submissions($offset = 0, $maxRecords = -1, $sort_mode = 'publishDate_desc', $find = '', $date = '', $type = '', $topicId = '', $lang = '') 1424 { 1425 if ($find) { 1426 $findPattern = '%' . $find . '%'; 1427 $mid = " where (`title` like ? or `heading` like ? or `body` like ? or `author` like ? or `authorName` like ?) "; 1428 $bindvars = [$findPattern, $findPattern, $findPattern, $findPattern, $findPattern]; 1429 } else { 1430 $mid = ''; 1431 $bindvars = []; 1432 } 1433 1434 if ($date) { 1435 if ($mid) { 1436 $mid .= ' and `publishDate` <= ? '; 1437 } else { 1438 $mid = ' where `publishDate` <= ? '; 1439 } 1440 $bindvars[] = $date; 1441 } 1442 1443 if ($type) { 1444 $mid .= $mid ? ' AND ' : ' WHERE '; 1445 $mid .= ' `type` = ? '; 1446 $bindvars[] = $type; 1447 } 1448 1449 if ($topicId) { 1450 $mid .= $mid ? ' AND ' : ' WHERE '; 1451 $mid .= ' `topicId` = ? '; 1452 $bindvars[] = $topicId; 1453 } 1454 1455 if ($lang) { 1456 $mid .= $mid ? ' AND ' : ' WHERE '; 1457 $mid .= ' `lang` = ? '; 1458 $bindvars[] = $lang; 1459 } 1460 1461 $query = "select * from `tiki_submissions` $mid order by " . $this->convertSortMode($sort_mode); 1462 $query_cant = "select count(*) from `tiki_submissions` $mid"; 1463 $result = $this->query($query, $bindvars, $maxRecords, $offset); 1464 $cant = $this->getOne($query_cant, $bindvars); 1465 $ret = []; 1466 1467 while ($res = $result->fetchRow()) { 1468 $res['entrating'] = floor($res['rating']); 1469 1470 if (empty($res['body'])) { 1471 $res['isEmpty'] = 'y'; 1472 } else { 1473 $res['isEmpty'] = 'n'; 1474 } 1475 1476 if (strlen($res['image_data']) > 0) { 1477 $res['hasImage'] = 'y'; 1478 } else { 1479 $res['hasImage'] = 'n'; 1480 } 1481 1482 $ret[] = $res; 1483 } 1484 1485 $retval = []; 1486 $retval['data'] = $ret; 1487 $retval['cant'] = $cant; 1488 return $retval; 1489 } 1490 1491 function get_article($articleId, $checkPerms = true) 1492 { 1493 global $user, $prefs; 1494 $query = "select `tiki_articles`.*, 1495 `users_users`.`avatarLibName`, 1496 `tiki_article_types`.`use_ratings`, 1497 `tiki_article_types`.`show_pre_publ`, 1498 `tiki_article_types`.`show_post_expire`, 1499 `tiki_article_types`.`heading_only`, 1500 `tiki_article_types`.`allow_comments`, 1501 `tiki_article_types`.`comment_can_rate_article`, 1502 `tiki_article_types`.`show_image`, 1503 `tiki_article_types`.`show_avatar`, 1504 `tiki_article_types`.`show_author`, 1505 `tiki_article_types`.`show_pubdate`, 1506 `tiki_article_types`.`show_expdate`, 1507 `tiki_article_types`.`show_reads`, 1508 `tiki_article_types`.`show_size`, 1509 `tiki_article_types`.`show_topline`, 1510 `tiki_article_types`.`show_subtitle`, 1511 `tiki_article_types`.`show_linkto`, 1512 `tiki_article_types`.`show_image_caption`, 1513 `tiki_article_types`.`creator_edit` 1514 from `tiki_articles` 1515 left join `tiki_article_types` ON `tiki_articles`.`type` = `tiki_article_types`.`type` 1516 left join `users_users` on `tiki_articles`.`author` = `users_users`.`login` 1517 where `tiki_articles`.`articleId`=?" 1518 ; 1519 1520 $result = $this->query($query, [(int)$articleId]); 1521 if ($result->numRows()) { 1522 $res = $result->fetchRow(); 1523 $res['entrating'] = floor($res['rating']); 1524 } else { 1525 return ''; 1526 } 1527 if ($checkPerms) { 1528 $perms = Perms::get('article', $articleId); 1529 1530 $permsok = $perms->admin_cms || $perms->read_article || $perms->articles_read_heading; 1531 1532 if (! $permsok) { 1533 return false; 1534 } 1535 } 1536 1537 if ($res['author'] != $user) { 1538 TikiLib::events()->trigger( 1539 'tiki.article.view', 1540 [ 1541 'type' => 'article', 1542 'object' => $articleId, 1543 'user' => $user, 1544 'author' => $res['author'], 1545 ] 1546 ); 1547 } 1548 1549 return $res; 1550 } 1551 1552 function get_submission($subId) 1553 { 1554 $query = 'select * from `tiki_submissions` where `subId`=?'; 1555 $result = $this->query($query, [(int) $subId]); 1556 if ($result->numRows()) { 1557 $res = $result->fetchRow(); 1558 $res['entrating'] = floor($res['rating']); 1559 } else { 1560 return false; 1561 } 1562 return $res; 1563 } 1564 1565 function get_topic_image($topicId) 1566 { 1567 $query = 'select `image_name` ,`image_size`,`image_type`, `image_data` from `tiki_topics` where `topicId`=?'; 1568 $result = $this->query($query, [(int) $topicId]); 1569 $res = $result->fetchRow(); 1570 return $res; 1571 } 1572 1573 function get_article_image($id) 1574 { 1575 $query = 'select `image_name` ,`image_size`,`image_type`, `image_data` from `tiki_articles` where `articleId`=?'; 1576 $result = $this->query($query, [(int) $id]); 1577 $res = $result->fetchRow(); 1578 return $res; 1579 } 1580 1581 function add_article_type_attribute($artType, $attributeName) 1582 { 1583 $relationlib = TikiLib::lib('relation'); 1584 $attributelib = TikiLib::lib('attribute'); 1585 1586 $fullAttributeName = TikiFilter::get('attribute_type')->filter(trim('tiki.article.' . $attributeName)); 1587 $relationId = $relationlib->add_relation('tiki.article.attribute', 'articletype', $artType, 'attribute', $fullAttributeName); 1588 if (! $relationId) { 1589 return 0; 1590 } else { 1591 $attributelib->set_attribute('relation', $relationId, 'tiki.relation.target', $attributeName); 1592 return $relationId; 1593 } 1594 } 1595 1596 function delete_article_type_attribute($artType, $relationId) 1597 { 1598 $relationlib = TikiLib::lib('relation'); 1599 // double check relation is associated with article type before deleting 1600 $currentAttributes = $relationlib->get_relations_from('articletype', $artType, 'tiki.article.attribute'); 1601 foreach ($currentAttributes as $att) { 1602 if ($att['relationId'] == $relationId) { 1603 $relationlib->remove_relation($att['relationId']); 1604 } 1605 } 1606 return true; 1607 } 1608 1609 function get_article_type_attributes($artType, $orderby = '') 1610 { 1611 $relationlib = TikiLib::lib('relation'); 1612 $attributelib = TikiLib::lib('attribute'); 1613 1614 $attributes = $relationlib->get_relations_from('articletype', $artType, 'tiki.article.attribute', $orderby); 1615 $ret = []; 1616 foreach ($attributes as $att) { 1617 $relationAtt = $attributelib->get_attributes('relation', $att['relationId']); 1618 if (isset($relationAtt['tiki.relation.target'])) { 1619 $ret[$relationAtt['tiki.relation.target']] = $att; 1620 } 1621 } 1622 return $ret; 1623 } 1624 1625 function set_article_attributes($articleId, $attributeArray, $isSubmission = false) 1626 { 1627 // expects attributeArray in the form of $key=>$val where $key is tiki.article.xxxx and $val is value 1628 $attributelib = TikiLib::lib('attribute'); 1629 if ($isSubmission) { 1630 $type = 'submission'; 1631 } else { 1632 $type = 'article'; 1633 } 1634 $currentAtt = $this->get_article_attributes($articleId); 1635 foreach ($attributeArray as $name => $value) { 1636 if (! in_array($name, array_keys($currentAtt)) || $value != $currentAtt[$name]['value']) { 1637 $attributelib->set_attribute($type, $articleId, $name, $value); 1638 } 1639 } 1640 return true; 1641 } 1642 1643 function get_article_attributes($articleId, $isSubmission = false) 1644 { 1645 $attributelib = TikiLib::lib('attribute'); 1646 1647 if ($isSubmission) { 1648 $type = 'submission'; 1649 } else { 1650 $type = 'article'; 1651 } 1652 1653 $allAttributes = $attributelib->get_attributes($type, $articleId); 1654 $ret = []; 1655 foreach ($allAttributes as $k => $att) { 1656 if (substr($k, 0, 13) == 'tiki.article.') { 1657 $ret[$k] = $att; 1658 } 1659 } 1660 return $ret; 1661 } 1662 1663 function transfer_attributes_from_submission($subId, $articleId) 1664 { 1665 $this->query( 1666 'UPDATE `tiki_object_attributes` set `type` = ?, `itemId` = ? where `type` = ? and `itemId` = ?', 1667 [ 'article', $articleId, 'submission', $subId ] 1668 ); 1669 } 1670 1671 /** 1672 * Get related articles using $freetaglib->get_similar() 1673 * 1674 * @param int $articleId 1675 * @param int $maxResults 1676 * @return array 1677 */ 1678 function get_related_articles($articleId, $maxResults = 5) 1679 { 1680 $freetaglib = TikiLib::lib('freetag'); 1681 $relatedArticles = $freetaglib->get_similar('article', $articleId); 1682 1683 foreach ($relatedArticles as $key => $article) { 1684 $relatedArticles[$key]['articleId'] = $relatedId = str_replace('tiki-read_article.php?articleId=', '', $article['href']); 1685 1686 $relatedArticle = $this->get_article($relatedId); 1687 1688 // exclude articles from the list if they are not published or if no permission to view them 1689 if (! $relatedArticle || $relatedArticle['ispublished'] != 'y') { 1690 unset($relatedArticles[$key]); 1691 } 1692 } 1693 1694 $relatedArticles = array_splice($relatedArticles, 0, $maxResults); 1695 1696 return $relatedArticles; 1697 } 1698} 1699 1700$artlib = new ArtLib; 1701