Element.class.php (16242B)
1 <?php 2 namespace cms\model; 3 4 5 use ArrayUtils; 6 use Logger; 7 8 /** 9 * Diese Objektklasse stellt ein Element das. 10 * 11 * Ein Element ist ein Platzhalter in einem Template und kann verschiedenen 12 * Typs sein, z.B. Text oder ein Bild. 13 * 14 * @author Jan Dankert 15 * @package openrat.objects 16 */ 17 class Element extends ModelBase 18 { 19 const ELEMENT_TYPE_DATE = 1; 20 const ELEMENT_TYPE_NUMBER = 2; 21 const ELEMENT_TYPE_TEXT = 3; 22 const ELEMENT_TYPE_INFO = 4; 23 const ELEMENT_TYPE_INFODATE = 5; 24 const ELEMENT_TYPE_LINK = 6; 25 const ELEMENT_TYPE_LONGTEXT = 7; 26 const ELEMENT_TYPE_CODE = 8; 27 const ELEMENT_TYPE_DYNAMIC = 9; 28 const ELEMENT_TYPE_SELECT = 10; 29 const ELEMENT_TYPE_COPY = 11; 30 const ELEMENT_TYPE_LINKINFO = 12; 31 const ELEMENT_TYPE_LINKDATE = 13; 32 const ELEMENT_TYPE_INSERT = 14; 33 34 const ELEMENT_FORMAT_TEXT = 0; 35 const ELEMENT_FORMAT_HTML = 1; 36 const ELEMENT_FORMAT_WIKI = 2; 37 const ELEMENT_FORMAT_MARKDOWN = 3; 38 39 const ELEMENT_FLAG_HTML_ALLOWED = 1; 40 const ELEMENT_FLAG_ALL_LANGUAGES = 2; 41 const ELEMENT_FLAG_WRITABLE = 4; 42 const ELEMENT_FLAG_WITH_ICON = 8; 43 const ELEMENT_FLAG_INHERIT = 16; 44 45 /** 46 * Eindeutige ID dieses Elementes 47 * @type Integer 48 */ 49 var $elementid; 50 51 /** 52 * Template-ID zu der dieses Elementes geh?rt 53 * @type Integer 54 */ 55 var $templateid; 56 57 /** 58 * Typ des Elementes 59 * Folgende Typen sind moeglich: 60 * <ul> 61 * <li>text</li> 62 * <li>longtext</li> 63 * <li>select</li> 64 * <li>number</li> 65 * <li>link</li> 66 * <li>date</li> 67 * <li>insert</li> 68 * <li>linkinfo</li> 69 * <li>linkdate</li> 70 * <li>code</li> 71 * <li>info</li> 72 * <li>infodate</li> 73 * </ul> 74 * 75 * @type String 76 * @deprecated use #typeid 77 */ 78 var $type; 79 80 /** 81 * 82 * Type of the element. Must be a constant value of ELEMENT_TYPE_*. 83 * @var integer Type of element 84 */ 85 public $typeid; 86 87 /** 88 * Logischer Name dieses Elementes 89 * @type String 90 */ 91 var $name; 92 93 /** 94 * Eingabefeld-Bezeichnung für dieses Element. 95 * @type String 96 */ 97 var $label; 98 99 /** 100 * Beschreibung zu diesem Element 101 * Zu jedem Element kann eine Beschreibung hinterlegt werden, die dem Redakteur bei der Bearbeitung 102 * der Inhalte als Bearbeitungshilfe dienen kann. 103 * @type String 104 */ 105 var $desc; 106 107 /** 108 * Objekt-ID eines Ordners, aus diesem Ordner (samt Unterordner) 109 * k?nnen zu verlinkende Objekte ausgew?hlt werden 110 * @type Integer 111 */ 112 var $folderObjectId = 0; 113 114 /** 115 * Vorausgew�hltes Objekt. 116 * @type Integer 117 */ 118 var $defaultObjectId = 0; 119 120 /** 121 * Schalter ob dieses Element von Redakteuren bearbeiten werden kann 122 * @type bool 123 */ 124 public $writable; 125 126 /** 127 * values are inherited from parent nodes. 128 * @var bool 129 */ 130 public $inherit; 131 132 /** 133 * Schalter, ob dieses Element in allen Sprachen den gleichen Inhalt haben soll 134 * @type bool 135 */ 136 public $allLanguages; 137 138 public static $readonlyElementTypeIds = array( 139 self::ELEMENT_TYPE_COPY,self::ELEMENT_TYPE_LINKINFO,self::ELEMENT_TYPE_LINKDATE,self::ELEMENT_TYPE_INFO,self::ELEMENT_TYPE_INFODATE,self::ELEMENT_TYPE_CODE,self::ELEMENT_TYPE_DYNAMIC 140 ); 141 142 143 /** 144 * Untertyp. 145 * 146 * @var String 147 */ 148 var $subtype = ''; 149 150 /** 151 * @var bool 152 */ 153 var $withIcon = false; 154 var $dateformat = 'r'; 155 156 /* 157 * @deprecated use format. 158 */ 159 public $wiki = false; 160 161 public $format = self::ELEMENT_FORMAT_TEXT; 162 163 /** 164 * @var bool 165 */ 166 public $html = false; 167 168 var $decimals = 0; 169 var $decPoint = '.'; 170 var $thousandSep = ''; 171 var $code = ''; 172 var $defaultText = ''; 173 174 175 /** 176 * Im Konstruktor wird die Element-Id gesetzt 177 * @param Integer Element-Id 178 */ 179 function __construct( $elementid=0 ) 180 { 181 if ( intval($elementid)!=0 ) 182 $this->elementid = $elementid; 183 } 184 185 186 /** 187 * Hinzuf?gen eines Elementes 188 * Das aktuelle Element wird in die Datenbank geschrieben. 189 */ 190 function add() 191 { 192 $sql = db()->sql('SELECT MAX(id) FROM {{element}}'); 193 $this->elementid = intval($sql->getOne())+1; 194 195 $sql = db()->sql( 'INSERT INTO {{element}}'. 196 ' (id,templateid,name,label,descr,typeid,flags) '. 197 " VALUES ( {elementid},{templateid},{name},{label},{description},{typeid},{flags} ) " ); 198 199 $flags = 0; 200 $flags += self::ELEMENT_FLAG_WRITABLE * intval($this->writable); 201 202 $sql->setInt ( 'elementid' ,$this->elementid ); 203 $sql->setString ( 'name' ,$this->name ); 204 $sql->setString ( 'label' ,$this->label ); 205 $sql->setInt ( 'typeid' ,$this->typeid ); 206 $sql->setInt ( 'templateid' ,$this->templateid ); 207 $sql->setInt ( 'flags' ,$flags ); 208 $sql->setString ( 'description',$this->desc ); 209 210 $sql->query(); 211 } 212 213 214 /** 215 * Lesen des Elementes aus der Datenbank 216 * Alle Eigenschaften des Elementes werden aus der Datenbank gelesen 217 * @throws \ObjectNotFoundException 218 */ 219 function load() 220 { 221 if ( intval($this->elementid) != 0 ) 222 { 223 $db = db_connection(); 224 $sql = $db->sql( <<<SQL 225 SELECT * FROM {{element}} 226 WHERE id={elementid} 227 SQL 228 ); 229 $sql->setInt( 'elementid',$this->elementid ); 230 $this->setDatabaseRow( $sql->getRow() ); 231 } 232 } 233 234 235 /** 236 * @param $prop 237 * @throws \ObjectNotFoundException 238 */ 239 function setDatabaseRow($prop ) 240 { 241 if ( count($prop) <= 0 ) 242 throw new \ObjectNotFoundException("Element not found"); 243 244 $this->elementid = $prop['id' ]; 245 $this->templateid = $prop['templateid']; 246 $this->name = $prop['name' ]; 247 $this->label = $prop['label' ]; 248 $this->desc = $prop['descr' ]; 249 $this->typeid = $prop['typeid' ]; 250 $this->type = Element::getAvailableTypes()[ $this->typeid ]; // name of type 251 $this->subtype = $prop['subtype' ]; 252 253 $this->dateformat = $prop['dateformat']; 254 $this->wiki = $prop['format'] == self::ELEMENT_FORMAT_WIKI; 255 $this->format = $prop['format']; 256 $this->withIcon = (boolean) ($prop['flags'] & self::ELEMENT_FLAG_WITH_ICON ); 257 $this->html = (boolean) ($prop['flags'] & self::ELEMENT_FLAG_HTML_ALLOWED ); 258 $this->allLanguages = (boolean) ($prop['flags'] & self::ELEMENT_FLAG_ALL_LANGUAGES); 259 $this->writable = (boolean) ($prop['flags'] & self::ELEMENT_FLAG_WRITABLE ); 260 $this->inherit = (boolean) ($prop['flags'] & self::ELEMENT_FLAG_INHERIT ); 261 262 if ( !$this->writable) 263 $this->withIcon = false; 264 265 $this->decimals = intval( $prop['decimals' ] ); 266 $this->decPoint = strval( $prop['dec_point' ] ); 267 $this->thousandSep = strval( $prop['thousand_sep' ] ); 268 $this->code = strval( $prop['code' ] ); 269 $this->defaultText = strval( $prop['default_text' ] ); 270 $this->folderObjectId = intval( $prop['folderobjectid' ] ); 271 $this->defaultObjectId = intval( $prop['default_objectid'] ); 272 } 273 274 275 /** 276 * Abspeichern des Elementes 277 * Das aktuelle Element wird in der Datenbank gespeichert 278 */ 279 function save() 280 { 281 $db = db_connection(); 282 283 $sql = $db->sql( 'UPDATE {{element}}'. 284 ' SET templateid = {templateid},'. 285 ' name = {name},'. 286 ' label = {label},'. 287 ' descr = {desc},'. 288 ' typeid = {typeid},'. 289 ' subtype = {subtype},'. 290 ' dateformat = {dateformat},'. 291 ' flags = {flags},'. 292 ' format = {format},'. 293 ' decimals = {decimals},'. 294 ' dec_point = {decPoint},'. 295 ' thousand_sep = {thousandSep},'. 296 ' code = {code},'. 297 ' default_text = {defaultText},'. 298 ' folderobjectid = {folderObjectId},'. 299 ' default_objectid= {defaultObjectId}'. 300 ' WHERE id={elementid}' ); 301 302 $flags = 0; 303 $flags += self::ELEMENT_FLAG_WITH_ICON * intval($this->withIcon ); 304 $flags += self::ELEMENT_FLAG_HTML_ALLOWED * intval($this->html ); 305 $flags += self::ELEMENT_FLAG_ALL_LANGUAGES * intval($this->allLanguages); 306 $flags += self::ELEMENT_FLAG_WRITABLE * intval($this->writable ); 307 $flags += self::ELEMENT_FLAG_INHERIT * intval($this->inherit ); 308 309 $sql->setInt ( 'elementid' ,$this->elementid ); 310 $sql->setInt ( 'templateid' ,$this->templateid ); 311 $sql->setString ( 'name' ,$this->name ); 312 $sql->setString ( 'label' ,$this->label ); 313 $sql->setString ( 'desc' ,$this->desc ); 314 $sql->setInt ( 'typeid' ,$this->typeid ); 315 $sql->setString ( 'subtype' ,$this->subtype ); 316 $sql->setString ( 'dateformat' ,$this->dateformat ); 317 $sql->setInt ( 'flags' ,$flags ); 318 $sql->setInt ( 'format' ,$this->format ); 319 $sql->setInt ( 'decimals' ,$this->decimals ); 320 $sql->setString ( 'decPoint' ,$this->decPoint ); 321 $sql->setString ( 'thousandSep' ,$this->thousandSep ); 322 $sql->setString ( 'code' ,$this->code ); 323 $sql->setString ( 'defaultText' ,$this->defaultText ); 324 325 if ( intval($this->folderObjectId)==0 ) 326 $sql->setNull( 'folderObjectId' ); 327 else $sql->setInt ( 'folderObjectId' ,$this->folderObjectId ); 328 329 if ( intval($this->defaultObjectId)==0 ) 330 $sql->setNull( 'defaultObjectId' ); 331 else $sql->setInt ( 'defaultObjectId' ,$this->defaultObjectId ); 332 333 $sql->query(); 334 } 335 336 337 338 /** 339 * Setzt ein Prefix vor den Elementnamen. 340 * @param String Prefix 341 */ 342 function setPrefix( $prefix ) 343 { 344 if ( strrpos($this->name,'%') === FALSE ) 345 $name = $this->name; 346 else 347 list( $oldprefix,$name ) = explode('%',$this->name.'%'); 348 349 $this->name = $prefix.'%'.$name; 350 } 351 352 353 /** 354 * Loeschen des Elementes und aller Inhalte 355 */ 356 public function delete() 357 { 358 $db = db_connection(); 359 360 // Inhalte loeschen. 361 // notwendig, damit die Fremdschlüsselbeziehungen auf diesen Element aufgehoben werden. 362 $this->deleteValues(); 363 364 // Element loeschen 365 $sql = $db->sql('DELETE FROM {{element}} '. 366 ' WHERE id={elementid}' ); 367 $sql->setInt( 'elementid',$this->elementid ); 368 369 $sql->query(); 370 } 371 372 373 /** 374 * L?schen aller Seiteninhalte mit diesem Element 375 * Das Element wird nicht gel?scht. 376 */ 377 public function deleteValues() 378 { 379 $db = db_connection(); 380 381 // Alle Inhalte mit diesem Element l?schen 382 $sql = $db->sql('DELETE FROM {{value}} '. 383 ' WHERE elementid={elementid}' ); 384 $sql->setInt( 'elementid',$this->elementid ); 385 $sql->query(); 386 } 387 388 389 /** 390 * Abhaengig vom Element-Typ werden die zur Darstellung notwendigen Eigenschaften ermittelt. 391 * @return array 392 */ 393 function getRelatedProperties() 394 { 395 $prp = array('text' =>array('inherit','withIcon','allLanguages','writable','html','defaultText','format'), 396 'longtext'=>array('inherit','withIcon','allLanguages','writable','html','defaultText','format'), 397 'select' =>array('inherit','withIcon','allLanguages','writable','defaultText','code'), 398 'number' =>array('inherit','withIcon','allLanguages','writable','decPoint','decimals','thousandSep'), 399 'link' =>array('inherit','subtype','withIcon','allLanguages','writable','linktype','folderObjectId','defaultObjectId'), 400 'date' =>array('inherit','withIcon','allLanguages','writable','dateformat','defaultText'), 401 'list' =>array('inherit','subtype','withIcon','allLanguages','writable','folderObjectId','defaultObjectId'), 402 'insert' =>array('inherit','subtype','withIcon','allLanguages','writable','folderObjectId','defaultObjectId'), 403 'copy' =>array('inherit','prefix','name','defaultText'), 404 'linkinfo'=>array('prefix','subtype','defaultText'), 405 'linkdate'=>array('prefix','subtype','dateformat'), 406 'code' =>array('code'), 407 'dynamic' =>array('subtype','code'), 408 'info' =>array('subtype'), 409 'infodate'=>array('subtype','dateformat') ); 410 return $prp[ $this->getTypeName() ]; 411 } 412 413 414 415 function getDefaultValue() 416 { 417 switch( $this->type ) 418 { 419 case 'text': 420 case 'longtext': 421 return $this->defaultText; 422 423 case 'number'; 424 return '0'; 425 426 default: 427 } 428 429 return lang('EL_TYPE_'.$this->type); 430 431 } 432 433 /** 434 * Ermitteln aller benutzbaren Elementtypen. 435 * 436 * @return array id->name 437 */ 438 public static function getAvailableTypes() 439 { 440 return array( 441 self::ELEMENT_TYPE_TEXT => 'text', 442 self::ELEMENT_TYPE_LONGTEXT => 'longtext', 443 self::ELEMENT_TYPE_SELECT => 'select', 444 self::ELEMENT_TYPE_NUMBER => 'number', 445 self::ELEMENT_TYPE_LINK => 'link', 446 self::ELEMENT_TYPE_DATE => 'date', 447 self::ELEMENT_TYPE_INSERT => 'insert', 448 self::ELEMENT_TYPE_COPY => 'copy', 449 self::ELEMENT_TYPE_LINKINFO => 'linkinfo', 450 self::ELEMENT_TYPE_LINKDATE => 'linkdate', 451 self::ELEMENT_TYPE_CODE => 'code', 452 self::ELEMENT_TYPE_DYNAMIC => 'dynamic', 453 self::ELEMENT_TYPE_INFO => 'info', 454 self::ELEMENT_TYPE_INFODATE => 'infodate' 455 ); 456 } 457 458 459 /** 460 * Ermitteln aller benutzbaren Elementtypen. 461 * 462 * @return array id->name 463 */ 464 public static function getAvailableFormats() 465 { 466 return array( 467 self::ELEMENT_FORMAT_TEXT => 'text', 468 self::ELEMENT_FORMAT_WIKI => 'wiki', 469 self::ELEMENT_FORMAT_HTML => 'html', 470 self::ELEMENT_FORMAT_MARKDOWN => 'markdown' 471 ); 472 } 473 474 475 /** 476 * Ermittelt die Klasse des Element-Typs.<br> 477 * Entweder "info", "text" oder "dynamic". 478 * 479 * @return String 480 */ 481 function getTypeClass() 482 { 483 switch( $this->type ) 484 { 485 case 'text': 486 case 'longtext': 487 case 'select': 488 case 'number': 489 case 'link': 490 case 'date': 491 case 'list': 492 case 'insert': 493 return 'text'; 494 495 case 'code': 496 case 'dynamic': 497 return 'dynamic'; 498 499 case 'copy': 500 case 'info': 501 case 'infodate': 502 case 'linkinfo': 503 case 'linkdate': 504 default: 505 return 'info'; 506 } 507 } 508 509 510 function getSelectItems() 511 { 512 $parameters = explode( "\n",$this->code ); 513 $items = array(); 514 515 foreach( $parameters as $it ) 516 { 517 $paar = explode( ":",$it,2 ); 518 $param_name = trim($paar[0]); 519 520 if ( count($paar) > 1 ) 521 $param_value = trim($paar[1]); 522 else 523 $param_value = trim($paar[0]); 524 525 // Wenn Inhalt mit "'" beginnt und mit "'" aufhoert, dann diese Zeichen abschneiden 526 if ( substr($param_value,0,1) == "'" && substr($param_value,strlen($param_value)-1,1) == "'" ) 527 $param_value = substr($param_value,1,strlen($param_value)-2); 528 529 $items[$param_name] = $param_value; 530 } 531 return $items; 532 } 533 534 535 function getDynamicParameters() 536 { 537 // Fixing old syntax ("key:value") to valid YAML syntax. 538 $this->code = preg_replace( '/^(\w+)\:(.+)$/m','${1}: ${2}', $this->code ); 539 540 $items = \YAML::parse( $this->code ); 541 542 Logger::trace('dynamic-parameters: '.print_r($items,true)); 543 544 return (array) $items; 545 } 546 547 548 /** 549 * Ermittelt, ob das Element beschreibbar ist. 550 * Bestimmte Typen (z.B. Info-Felder) sind nie beschreibbar, dann wird immer false zur?ckgegeben. 551 * Ansonsten wird ermittelt, ob dieses Element als beschreibbar markiert ist. 552 */ 553 function isWritable() 554 { 555 // Bei bestimmten Feldern immer false zurueckgeben 556 if ( in_array($this->typeid,Element::$readonlyElementTypeIds) ) 557 return false; 558 559 return $this->writable; 560 } 561 562 563 /** 564 * The technical name of this element type. 565 * 566 * @return String 567 */ 568 public function getTypeName() { 569 return Element::getAvailableTypes()[ $this->typeid ]; // name of type 570 571 } 572 573 public function getName() 574 { 575 return $this->name; 576 } 577 578 } 579 580 ?>