Value.class.php (19803B)
1 <?php 2 namespace cms\model; 3 use cms\base\Configuration; 4 use cms\base\DB; 5 use cms\base\Startup; 6 use util\ArrayUtils; 7 use cms\generator\Publish; 8 use cms\macros\MacroRunner; 9 use \util\exception\ObjectNotFoundException; 10 use logger\Logger; 11 use util\exception\GeneratorException; 12 use util\Text; 13 use util\Html; 14 use util\Http; 15 use util\Transformer; 16 use util\Code; 17 use util\cache\FileCache; 18 19 // OpenRat Content Management System 20 // Copyright (C) 2002-2012 Jan Dankert, cms@jandankert.de 21 // 22 // This program is free software; you can redistribute it and/or 23 // modify it under the terms of the GNU General Public License 24 // as published by the Free Software Foundation; either version 2 25 // of the License, or (at your option) any later version. 26 // 27 // This program is distributed in the hope that it will be useful, 28 // but WITHOUT ANY WARRANTY; without even the implied warranty of 29 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 30 // GNU General Public License for more details. 31 // 32 // You should have received a copy of the GNU General Public License 33 // along with this program; if not, write to the Free Software 34 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 35 36 37 38 /** 39 * Darstellen einer Inhaltes 40 * 41 * @version $Revision$ 42 * @author $Author$ 43 * @package openrat.objects 44 */ 45 46 class Value extends ModelBase 47 { 48 /** 49 * ID dieser Inhaltes 50 * @type Integer 51 */ 52 var $valueid=0; 53 54 /** 55 * Seiten-Objekt der ?bergeordneten Seite 56 * @type Page 57 */ 58 var $page; 59 60 /** 61 * Seiten-Id der uebergeordneten Seite 62 * @type Integer 63 */ 64 var $pageid; 65 66 /** 67 * Objekt-ID, auf die verlinkt wird 68 * @type Integer 69 */ 70 var $linkToObjectId=0; 71 72 /** 73 * Text-Inhalt 74 * @type String 75 */ 76 var $text=''; 77 78 /** 79 * Zahl. Auch Flie?kommazahlen werden als Ganzzahl gespeichert 80 * @type Integer 81 */ 82 var $number=0; 83 84 85 /** 86 * Datum als Unix-Timestamp 87 * @type Integer 88 */ 89 var $date=0; 90 91 /** 92 * Element-Objekt 93 * @type Element 94 */ 95 var $element; 96 97 /** 98 * Element-Id 99 * @type Integer 100 */ 101 var $elementid; 102 103 /** 104 * Der eigentliche Inhalt des Elementes 105 * @type String 106 */ 107 var $value; 108 109 /** 110 * TimeStamp der letzten Aenderung 111 * @type Integer 112 */ 113 var $lastchangeTimeStamp; 114 115 /** 116 * Benutzer-ID der letzten Aenderung 117 * @type Integer 118 */ 119 var $lastchangeUserId; 120 121 /** 122 * Benutzername der letzten Aenderung 123 * @type Integer 124 */ 125 var $lastchangeUserName; 126 127 /** 128 * Schalter, ob dieser Inhalt der aktive Inhalt ist 129 * @type Boolean 130 */ 131 var $active; 132 133 /** 134 * @type Publish 135 */ 136 public $publisher; 137 138 /** 139 * @type boolean 140 */ 141 var $publish = false; 142 143 /** 144 * @type Boolean 145 * @deprecated 146 */ 147 public $simple; 148 149 150 /** 151 * Sprach-Id. 152 * @var int 153 */ 154 public $languageid; 155 156 /** 157 * Format 158 * 159 * @var int 160 */ 161 public $format = null; 162 163 /** 164 * Konstruktor 165 */ 166 function __construct() 167 { 168 $this->lastchangeUserId = 0; 169 $this->lastchangeTimeStamp = 0; 170 171 } 172 173 174 175 /** 176 * Laden des aktuellen Inhaltes aus der Datenbank 177 */ 178 function loadForPublic() 179 { 180 $stmt = Db::sql( <<<SQL 181 SELECT * FROM {{value}} 182 WHERE elementid ={elementid} 183 AND pageid ={pageid} 184 AND languageid={languageid} 185 AND publish =1 186 SQL 187 ); 188 $stmt->setInt( 'elementid' ,$this->elementid ); 189 $stmt->setInt( 'pageid' ,$this->pageid ); 190 $stmt->setInt( 'languageid',$this->languageid); 191 $row = $stmt->getRow(); 192 193 if ( count($row) > 0 ) // Wenn Inhalt gefunden 194 { 195 $this->text = $row['text' ]; 196 $this->format = $row['format']; 197 $this->valueid = intval($row['id'] ); 198 $this->linkToObjectId = intval($row['linkobjectid']); 199 $this->number = intval($row['number' ]); 200 $this->date = intval($row['date' ]); 201 202 $this->active = ( $row['active' ]=='1' ); 203 $this->publish = ( $row['publish']=='1' ); 204 205 $this->lastchangeTimeStamp = intval($row['lastchange_date' ]); 206 $this->lastchangeUserId = intval($row['lastchange_userid']); 207 } 208 } 209 210 /** 211 * Laden des aktuellen Inhaltes aus der Datenbank 212 */ 213 function load() 214 { 215 $stmt = Db::sql( <<<SQL 216 SELECT * FROM {{value}} 217 WHERE elementid ={elementid} 218 AND pageid ={pageid} 219 AND languageid={languageid} 220 AND active=1 221 SQL 222 ); 223 $stmt->setInt( 'elementid' ,$this->elementid ); 224 $stmt->setInt( 'pageid' ,$this->pageid ); 225 $stmt->setInt( 'languageid',$this->languageid); 226 $row = $stmt->getRow(); 227 228 if ( count($row) > 0 ) // Wenn Inhalt gefunden 229 { 230 $this->text = $row['text' ]; 231 $this->format = $row['format']; 232 $this->valueid = intval($row['id'] ); 233 $this->linkToObjectId = intval($row['linkobjectid']); 234 $this->number = intval($row['number' ]); 235 $this->date = intval($row['date' ]); 236 237 $this->active = ( $row['active' ]=='1' ); 238 $this->publish = ( $row['publish']=='1' ); 239 240 $this->lastchangeTimeStamp = intval($row['lastchange_date' ]); 241 $this->lastchangeUserId = intval($row['lastchange_userid']); 242 } 243 } 244 245 246 /** 247 * Laden eines bestimmten Inhaltes aus der Datenbank 248 */ 249 function loadWithId( $valueid = null ) 250 { 251 if ( $valueid ) 252 $this->valueid = $valueid; 253 254 $sql = DB::sql( <<<SQL 255 SELECT {{value}}.*,{{user}}.name as lastchange_username 256 FROM {{value}} 257 LEFT JOIN {{user}} ON {{user}}.id={{value}}.lastchange_userid 258 WHERE {{value}}.id={valueid} 259 SQL 260 ); 261 $sql->setInt( 'valueid',$this->valueid); 262 $row = $sql->getRow(); 263 264 $this->text = $row['text' ]; 265 $this->format = $row['format' ]; 266 $this->pageid = intval($row['pageid' ]); 267 $this->elementid = intval($row['elementid' ]); 268 $this->languageid = intval($row['languageid' ]); 269 $this->valueid = intval($row['id' ]); 270 $this->linkToObjectId = intval($row['linkobjectid']); 271 $this->number = intval($row['number' ]); 272 $this->date = intval($row['date' ]); 273 274 $this->active = ( $row['active' ]=='1' ); 275 $this->publish = ( $row['publish']=='1' ); 276 277 $this->lastchangeTimeStamp = intval($row['lastchange_date' ]); 278 $this->lastchangeUserId = intval($row['lastchange_userid' ]); 279 $this->lastchangeUserName = $row['lastchange_username']; 280 } 281 282 283 /** 284 * Alle Versionen des aktuellen Inhaltes werden ermittelt 285 * @return array 286 */ 287 function getVersionList() 288 { 289 $stmt = DB::sql( <<<SQL 290 SELECT {{value}}.*,{{user}}.name as lastchange_username 291 FROM {{value}} 292 LEFT JOIN {{user}} ON {{user}}.id={{value}}.lastchange_userid 293 WHERE elementid ={elementid} 294 AND pageid ={pageid} 295 AND languageid={languageid} 296 ORDER BY lastchange_date 297 SQL 298 ); 299 $stmt->setInt( 'elementid' ,$this->element->elementid ); 300 $stmt->setInt( 'pageid' ,$this->pageid ); 301 $stmt->setInt( 'languageid',$this->languageid); 302 303 $list = array(); 304 foreach($stmt->getAll() as $row ) 305 { 306 $val = new Value(); 307 $val->valueid = $row['id']; 308 309 $val->text = $row['text']; 310 $val->format = $row['format']; 311 $val->valueid = intval($row['id'] ); 312 $val->linkToObjectId = intval($row['linkobjectid']); 313 $val->number = intval($row['number' ]); 314 $val->date = intval($row['date' ]); 315 $val->element = $this->element; 316 $val->elementid = $this->elementid; 317 $val->languageid = $this->languageid; 318 319 $val->active = ( $row['active' ]=='1' ); 320 $val->publish = ( $row['publish']=='1' ); 321 322 $val->lastchangeTimeStamp = intval($row['lastchange_date' ]); 323 $val->lastchangeUserId = intval($row['lastchange_userid' ]); 324 $val->lastchangeUserName = $row['lastchange_username']; 325 326 $list[] = $val; 327 } 328 return $list; 329 } 330 331 332 /** 333 * Die Anzahl der Versionen des aktuellen Inhaltes wird ermittelt 334 * @return array 335 */ 336 function getCountVersions() 337 { 338 $sql = DB::sql( <<<SQL 339 SELECT COUNT(*) FROM {{value}} 340 WHERE elementid ={elementid} 341 AND pageid ={pageid} 342 AND languageid={languageid} 343 SQL 344 ); 345 $sql->setInt( 'elementid' ,$this->element->elementid ); 346 $sql->setInt( 'pageid' ,$this->pageid ); 347 $sql->setInt( 'languageid',$this->languageid); 348 349 return $sql->getOne(); 350 } 351 352 353 function getLastChangeTime() 354 { 355 $sql = DB::sql( <<<SQL 356 SELECT lastchange_date FROM {{value}} 357 WHERE elementid ={elementid} 358 AND pageid ={pageid} 359 AND languageid={languageid} 360 ORDER BY id DESC 361 SQL 362 ); 363 $sql->setInt( 'elementid' ,$this->element->elementid ); 364 $sql->setInt( 'pageid' ,$this->pageid ); 365 $sql->setInt( 'languageid',$this->languageid); 366 367 return $sql->getOne(); 368 } 369 370 371 /** 372 * Gets the last change date by another user since a specific date. 373 * @param $date 374 * @param $userid 375 * @return String 376 */ 377 public function getLastChangeSinceByAnotherUser( $date, $userid ) 378 { 379 $sql = Db::sql( <<<SQL 380 SELECT lastchange_date FROM {{value}} 381 WHERE elementid ={elementid} 382 AND pageid ={pageid} 383 AND languageid={languageid} 384 AND lastchange_date > {date} 385 AND lastchange_userid != {userid} 386 ORDER BY id DESC 387 SQL 388 ); 389 $sql->setInt( 'elementid' ,$this->element->elementid ); 390 $sql->setInt( 'pageid' ,$this->pageid ); 391 $sql->setInt( 'languageid',$this->languageid); 392 $sql->setInt( 'date' ,$date ); 393 $sql->setInt( 'userid' ,$userid); 394 395 return $sql->getOne(); 396 } 397 398 399 400 /** 401 * Inhalt freigeben 402 */ 403 function release() 404 { 405 $sql = DB::sql( <<<SQL 406 UPDATE {{value}} 407 SET publish = 0 408 WHERE elementid ={elementid} 409 AND pageid ={pageid} 410 AND languageid={languageid} 411 SQL 412 ); 413 $sql->setInt( 'elementid' ,$this->elementid ); 414 $sql->setInt( 'pageid' ,$this->pageid ); 415 $sql->setInt( 'languageid',$this->languageid); 416 417 $sql->execute(); 418 419 $sql = Db::sql( <<<SQL 420 UPDATE {{value}} 421 SET publish = 1 422 WHERE active = 1 423 AND elementid ={elementid} 424 AND pageid ={pageid} 425 AND languageid={languageid} 426 SQL 427 ); 428 $sql->setInt( 'elementid' ,$this->elementid ); 429 $sql->setInt( 'pageid' ,$this->pageid ); 430 $sql->setInt( 'languageid',$this->languageid); 431 432 $sql->execute(); 433 } 434 435 436 /** 437 * No function, values are NOT updated, values are only added. 438 * @return name|void 439 */ 440 protected function save() 441 { 442 // not implemented, values are only added ("copy on write") 443 } 444 445 /** 446 * Inhalt speichern 447 */ 448 public function add() 449 { 450 $stmt = Db::sql( <<<SQL 451 UPDATE {{value}} 452 SET active=0 453 WHERE elementid ={elementid} 454 AND pageid ={pageid} 455 AND languageid={languageid} 456 SQL 457 ); 458 $stmt->setInt( 'elementid' ,$this->element->elementid ); 459 $stmt->setInt( 'pageid' ,$this->pageid ); 460 $stmt->setInt( 'languageid',$this->languageid); 461 462 $stmt->execute(); 463 464 if ( $this->publish ) 465 { 466 // Wenn Inhalt sofort veroeffentlicht werden kann, dann 467 // alle anderen Inhalte auf nicht-veroeffentlichen stellen 468 $stmt = DB::sql( <<<SQL 469 UPDATE {{value}} 470 SET publish=0 471 WHERE elementid ={elementid} 472 AND pageid ={pageid} 473 AND languageid={languageid} 474 SQL 475 ); 476 $stmt->setInt( 'elementid' ,$this->element->elementid ); 477 $stmt->setInt( 'pageid' ,$this->pageid ); 478 $stmt->setInt( 'languageid',$this->languageid); 479 480 $stmt->execute(); 481 } 482 483 // Naechste ID aus Datenbank besorgen 484 $stmt = DB::sql('SELECT MAX(id) FROM {{value}}'); 485 $this->valueid = intval($stmt->getOne())+1; 486 487 $stmt = DB::sql( <<<SQL 488 INSERT INTO {{value}} 489 (id ,linkobjectid ,text ,number ,date ,elementid ,format ,pageid ,languageid ,active,publish ,lastchange_date ,lastchange_userid ) 490 VALUES ({valueid},{linkobjectid},{text},{number},{date},{elementid},{format},{pageid},{languageid},1 ,{publish},{lastchange_date},{lastchange_userid}) 491 SQL 492 ); 493 $stmt->setInt( 'valueid' ,$this->valueid ); 494 $stmt->setInt( 'format' ,$this->format ); 495 $stmt->setInt( 'elementid' ,$this->element->elementid ); 496 $stmt->setInt( 'pageid' ,$this->pageid ); 497 $stmt->setInt( 'languageid',$this->languageid ); 498 499 if ( intval($this->linkToObjectId)==0) 500 $stmt->setNull ( 'linkobjectid' ); 501 else $stmt->setInt ( 'linkobjectid',$this->linkToObjectId ); 502 503 if ( $this->text == '' ) 504 $stmt->setNull ( 'text' ); 505 else $stmt->setString( 'text',$this->text ); 506 507 if ( intval($this->number)==0) 508 $stmt->setNull ( 'number' ); 509 else $stmt->setInt ( 'number',$this->number ); 510 511 if ( intval($this->date)==0) 512 $stmt->setNull ( 'date' ); 513 else $stmt->setInt ( 'date',$this->date ); 514 515 $stmt->setBoolean( 'publish' ,$this->publish ); 516 $stmt->setInt ( 'lastchange_date' ,Startup::now() ); 517 $user = \util\Session::getUser(); 518 $stmt->setInt ( 'lastchange_userid',$user->userid ); 519 520 $stmt->execute(); 521 522 // Nur ausfuehren, wenn in Konfiguration aktiviert. 523 $limit = Configuration::subset(['content','revision-limit'] ); 524 if ( $limit->is('enabled',false) ) 525 $this->checkLimit(); 526 } 527 528 529 /** 530 * Pruefen, ob maximale Anzahl von Versionen erreicht. 531 * In diesem Fall die zu alten Versionen l�schen. 532 */ 533 function checkLimit() 534 { 535 $limitConfig = Configuration::subset(['content','revision-limit']); 536 537 $sql = DB::sql( <<<SQL 538 SELECT id FROM {{value}} 539 WHERE elementid = {elementid} 540 AND pageid = {pageid} 541 AND languageid = {languageid} 542 AND active = 0 543 AND publish = 0 544 ORDER BY id 545 SQL 546 ); 547 $sql->setInt( 'elementid' ,$this->element->elementid ); 548 $sql->setInt( 'pageid' ,$this->pageid ); 549 $sql->setInt( 'languageid',$this->languageid ); 550 $values = $sql->getCol(); 551 552 if ( count($values) > $limitConfig->get('min-revisions',3) ) 553 { 554 $sql = DB::sql( <<<SQL 555 DELETE FROM {{value}} 556 WHERE elementid = {elementid} 557 AND pageid = {pageid} 558 AND languageid = {languageid} 559 AND active = 0 560 AND publish = 0 561 AND lastchange_date < {min_date} 562 AND id < {min_id} 563 SQL 564 ); 565 $sql->setInt( 'elementid' ,$this->element->elementid ); 566 $sql->setInt( 'pageid' ,$this->pageid ); 567 $sql->setInt( 'languageid',$this->languageid ); 568 $sql->setInt( 'min_date' ,$limitConfig['max-age']*24*60*60); 569 $sql->setInt( 'min_id' ,$values[count($values)-$limitConfig['min-revisions']]); 570 $sql->execute(); 571 } 572 573 if ( count($values) > $limitConfig->get('max-revisions',100 ) ) 574 { 575 $sql = Db::sql( <<<SQL 576 DELETE FROM {{value}} 577 WHERE elementid = {elementid} 578 AND pageid = {pageid} 579 AND languageid = {languageid} 580 AND active = 0 581 AND publish = 0 582 AND lastchange_date < {min_date} 583 AND id < {min_id} 584 SQL 585 ); 586 $sql->setInt( 'elementid' ,$this->element->elementid ); 587 $sql->setInt( 'pageid' ,$this->pageid ); 588 $sql->setInt( 'languageid',$this->languageid ); 589 $sql->setInt( 'min_date' ,$limitConfig['min-age']*24*60*60); 590 $sql->setInt( 'min_id' ,$values[count($values)-$limitConfig['max-revisions']]); 591 $sql->execute(); 592 } 593 } 594 595 596 597 /** 598 * Diesen Inhalt loeschen 599 */ 600 function delete() 601 { 602 $stmt = DB::sql( <<<SQL 603 DELETE * FROM {{value}} 604 WHERE elementid ={elementid} 605 AND pageid ={pageid} 606 AND languageid={languageid} 607 SQL 608 ); 609 $stmt->setInt( 'elementid' ,$this->element->elementid ); 610 $stmt->setInt( 'pageid' ,$this->pageid ); 611 $stmt->setInt( 'languageid',$this->languageid); 612 613 $stmt->execute(); 614 } 615 616 617 618 /** 619 * Es werden Objekte mit einem Inhalt gesucht. 620 * @param String Suchbegriff 621 * @return array Liste der gefundenen Objekt-IDs 622 */ 623 function getObjectIdsByValue( $text ) 624 { 625 $sql = DB::sql( <<<SQL 626 SELECT {{object}}.id FROM {{value}} 627 LEFT JOIN {{page}} 628 ON {{page}}.id={{value}}.pageid 629 LEFT JOIN {{object}} 630 ON {{object}}.id={{page}}.objectid 631 WHERE {{value}}.text LIKE {text} 632 AND {{value}}.languageid={languageid} 633 ORDER BY {{object}}.lastchange_date DESC 634 SQL 635 ); 636 637 $sql->setInt ( 'languageid',$this->languageid ); 638 $sql->setString( 'text' ,'%'.$text.'%' ); 639 640 return $sql->getCol(); 641 } 642 643 644 /** 645 * Es werden Objekte mit einer UserId ermittelt 646 * @param Integer Benutzer-Id der letzten ?nderung 647 * @return array Liste der gefundenen Objekt-IDs 648 */ 649 function getObjectIdsByLastChangeUserId( $userid ) 650 { 651 $sql = DB::sql( <<<SQL 652 SELECT {{object}}.id FROM {{value}} 653 LEFT JOIN {{page}} 654 ON {{page}}.id={{value}}.pageid 655 LEFT JOIN {{object}} 656 ON {{object}}.id={{page}}.objectid 657 WHERE {{value}}.lastchange_userid={userid} 658 AND {{value}}.languageid={languageid} 659 ORDER BY {{object}}.lastchange_date DESC 660 SQL 661 ); 662 $sql->setInt ( 'languageid',$this->languageid ); 663 $sql->setInt ( 'userid' ,$userid ); 664 665 return $sql->getCol(); 666 } 667 668 669 670 /** 671 * Es wird das Objekt ermittelt, welches der Benutzer zuletzt ge�ndert hat. 672 * 673 * @return Integer Objekt-Id 674 */ 675 public static function getLastChangedObjectByUserId( $userid ) 676 { 677 $sql = DB::sql( <<<SQL 678 SELECT {{object}}.id 679 FROM {{value}} 680 LEFT JOIN {{page}} 681 ON {{page}}.id={{value}}.pageid 682 LEFT JOIN {{object}} 683 ON {{object}}.id={{page}}.objectid 684 WHERE {{value}}.lastchange_userid={userid} 685 ORDER BY {{value}}.lastchange_date DESC 686 SQL 687 ); 688 $sql->setInt ( 'userid' ,$userid ); 689 return $sql->getOne(); 690 } 691 692 693 /** 694 * Es wird das Objekt ermittelt, welches der Benutzer zuletzt ge�ndert hat. 695 * 696 * @return Integer Objekt-Id 697 */ 698 public static function getLastChangedObjectInProjectByUserId( $projectid, $userid ) 699 { 700 $sql = DB::sql( <<<SQL 701 SELECT {{object}}.id 702 FROM {{value}} 703 LEFT JOIN {{page}} 704 ON {{page}}.id={{value}}.pageid 705 LEFT JOIN {{object}} 706 ON {{object}}.id={{page}}.objectid 707 WHERE {{value}}.lastchange_userid={userid} 708 AND {{object}}.projectid = {projectid} 709 ORDER BY {{value}}.lastchange_date DESC 710 SQL 711 ); 712 $sql->setInt ( 'userid' ,$userid ); 713 $sql->setInt ( 'projectid' ,$projectid ); 714 return $sql->getOne(); 715 } 716 717 718 /** 719 * Ermittelt den unbearbeiteten, "rohen" Inhalt. 720 * 721 * @return mixed Inhalt 722 */ 723 public function getRawValue() 724 { 725 switch( $this->element->typeid ) 726 { 727 case Element::ELEMENT_TYPE_LINK: 728 return $this->linkToObjectId; 729 730 case Element::ELEMENT_TYPE_DATE; 731 return $this->date; 732 733 default: 734 return $this->text; 735 } 736 } 737 738 739 public function getName() 740 { 741 return $this->element->label; 742 } 743 744 745 public function __toString() 746 { 747 return "Value: ".print_r($this,true); 748 } 749 750 751 752 public function getId() 753 { 754 return $this->valueid; 755 } 756 757 758 }