openrat-cms

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

Element.class.php (16795B)


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