File modules/cms/model/File.class.php

Last commit: Sun Jan 29 00:20:21 2023 +0100	Jan Dankert	New node type "Script".
1 <?php 2 namespace cms\model; 3 // OpenRat Content Management System 4 // Copyright (C) 2002-2012 Jan Dankert, cms@jandankert.de 5 // 6 // This program is free software; you can redistribute it and/or 7 // modify it under the terms of the GNU General Public License 8 // as published by the Free Software Foundation; either version 2 9 // of the License, or (at your option) any later version. 10 // 11 // This program is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 // 16 // You should have received a copy of the GNU General Public License 17 // along with this program; if not, write to the Free Software 18 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 19 20 21 // Standard Mime-Type 22 use cms\base\Configuration; 23 use cms\base\DB as Db; 24 use util\cache\FileCache; 25 26 27 /** 28 * File. 29 * 30 * @author Jan Dankert 31 */ 32 class File extends BaseObject 33 { 34 const DEFAULT_MIMETYPE = 'application/octet-stream'; 35 36 const FORMAT_BLOB_RAW = 1; 37 const FORMAT_BLOB_BASE64 = 2; 38 const FILE_FORMAT_TEXT = 3; 39 40 public $fileid; 41 42 public $contentid = null; 43 44 public $size = 0; 45 public $value = ''; 46 public $extension = ''; 47 public $log_filenames = array(); 48 public $fullFilename = ''; 49 50 public $mime_type = ''; 51 52 public $tmpfile; 53 54 55 public static $MIME_TYPES = [ 56 'ez' => 'application/andrew-inset', 57 'csm' => 'application/cu-seeme', 58 'cu' => 'application/cu-seeme', 59 'tsp' => 'application/dsptype', 60 'spl' => 'application/x-futuresplash ', 61 'cpt' => 'image/x-corelphotopaint', 62 'hqx' => 'application/mac-binhex40', 63 'nb' => 'application/mathematica', 64 'mdb' => 'application/msaccess', 65 'doc' => 'application/msword', 66 'dot' => 'application/msword', 67 'bin' => 'application/octet-stream', 68 'oda' => 'application/oda', 69 'pdf' => 'application/pdf', 70 'pgp' => 'application/pgp-signature', 71 'ps' => 'application/postscript', 72 'ai' => 'application/postscript', 73 'eps' => 'application/postscript', 74 'rtf' => 'text/rtf', 75 'smi' => 'application/smil', 76 'smil' => 'application/smil', 77 'xls' => 'application/vnd.ms-excel', 78 'xlb' => 'application/vnd.ms-excel', 79 'ppt' => 'application/vnd.ms-powerpoint', 80 'pps' => 'application/vnd.ms-powerpoint', 81 'pot' => 'application/vnd.ms-powerpoint', 82 'sdw' => 'application/vnd.stardivision.writer', 83 'sgl' => 'application/vnd.stardivision.writer-global', 84 'vor' => 'application/vnd.stardivision.writer', 85 'sdc' => 'application/vnd.stardivision.calc', 86 'sda' => 'application/vnd.stardivision.draw', 87 'sdd' => 'application/vnd.stardivision.impress', 88 'sdp' => 'application/vnd.stardivision.impress-packed', 89 'smf' => 'application/vnd.stardivision.math', 90 'sds' => 'application/vnd.stardivision.chart', 91 'smd' => 'application/vnd.stardivision.mail', 92 'wbxml' => 'application/vnd.wap.wbxml ', 93 'wmlc' => 'application/vnd.wap.wmlc', 94 'wmlsc' => 'application/vnd.wap.wmlscriptc', 95 'wp5' => 'application/wordperfect5.1', 96 'zip' => 'application/zip', 97 'wk' => 'application/x-123', 98 'bcpio' => 'application/x-bcpio', 99 'vcd' => 'application/x-cdlink ', 100 'pgn' => 'application/x-chess-pgn', 101 'cpio' => 'application/x-cpio', 102 'csh' => 'text/x-csh', 103 'deb' => 'application/x-debian-package', 104 'dcr' => 'application/x-director', 105 'dir' => 'application/x-director', 106 'dxr' => 'application/x-director', 107 'wad' => 'application/x-doom', 108 'dms' => 'application/x-dms', 109 'dvi' => 'application/x-dvi', 110 'pfa' => 'application/x-font', 111 'pfb' => 'application/x-font', 112 'gsf' => 'application/x-font', 113 'pcf' => 'application/x-font', 114 'gnumeric' => 'application/x-gnumeric', 115 'gtar' => 'application/x-gtar', 116 'tgz' => 'application/x-gtar', 117 'taz' => 'application/x-gtar', 118 'hdf' => 'application/x-hdf', 119 'phtml' => 'text/html', 120 'pht' => 'text/html', 121 'php' => 'text/html', 122 'phps' => 'text/html', 123 'php3' => 'text/html', 124 'php3p' => 'text/html ', 125 'php4' => 'text/html', 126 'docbook' => 'application/docbook+xml', 127 'ica' => 'application/x-ica', 128 'jar' => 'application/x-java-archive', 129 'jnlp' => 'application/x-java-jnlp-file', 130 'ser' => 'application/x-java-serialized-object', 131 'class' => 'application/x-java-vm', 132 'js' => 'application/x-javascript', 133 'chrt' => 'application/x-kchart', 134 'kil' => 'application/x-killustrator', 135 'kpr' => 'application/x-kpresenter', 136 'kpt' => 'application/x-kpresenter', 137 'skp' => 'application/x-koan ', 138 'skd' => 'application/x-koan ', 139 'skt' => 'application/x-koan ', 140 'skm' => 'application/x-koan ', 141 'ksp' => 'application/x-kspread', 142 'kwd' => 'application/x-kword', 143 ' kwt' => 'application/x-kword', 144 'latex' => 'application/x-latex', 145 'lha' => 'application/x-lha', 146 'lzh' => 'application/x-lzh', 147 'lzx' => 'application/x-lzx', 148 'frm' => 'fbdocapplication/x-maker', 149 'maker' => 'fbdocapplication/x-maker', 150 'frame' => 'fbdocapplication/x-maker', 151 'fm' => 'fbdocapplication/x-maker', 152 'fb' => 'fbdocapplication/x-maker', 153 'book' => 'fbdocapplication/x-maker', 154 'mif' => 'application/x-mif', 155 'com' => 'application/x-msdos-program', 156 'exe' => 'application/x-msdos-program', 157 'bat' => 'application/x-msdos-program', 158 'dll' => 'application/x-msdos-program', 159 'msi' => 'application/x-msi', 160 'nc' => 'application/x-netcdf', 161 'cdf' => 'application/x-netcdf', 162 'pac' => 'application/x-ns-proxy-autoconfig', 163 'o' => 'application/x-object', 164 'ogg' => 'application/x-ogg', 165 'oza' => 'application/x-oz-application', 166 'pl' => 'application/x-perl', 167 'pm' => 'application/x-perl', 168 'crl' => 'application/x-pkcs7-crl', 169 'rpm' => 'audio/x-pn-realaudio-plugin ', 170 'shar' => 'application/x-shar', 171 'swf' => 'application/x-shockwave-flash', 172 'swfl' => 'application/x-shockwave-flash', 173 'sh' => 'text/x-sh', 174 'sit' => 'application/x-stuffit', 175 'sv4cpio' => 'application/x-sv4cpio', 176 'sv4crc' => 'application/x-sv4crc', 177 'tar' => 'application/x-tar', 178 'tcl' => 'text/x-tcl', 179 'tex' => 'text/x-tex', 180 'gf' => 'application/x-tex-gf', 181 'pk' => 'application/x-tex-pk', 182 'texinfo' => 'application/x-texinfo', 183 'texi' => 'application/x-texinfo', 184 '; "~"' => 'application/x-trash', 185 ';"%"' => 'application/x-trash', 186 'bak' => 'application/x-trash', 187 'old' => 'application/x-trash', 188 'sik' => 'application/x-trash', 189 't' => 'application/x-troff', 190 'tr' => 'application/x-troff', 191 'roff' => 'application/x-troff', 192 'man' => 'application/x-troff-man', 193 'me' => 'application/x-troff-me', 194 'ms' => 'application/x-troff-ms', 195 'ustar' => 'application/x-ustar', 196 'src' => 'application/x-wais-source', 197 'wz' => 'application/x-wingz', 198 'crt' => 'application/x-x509-ca-cert', 199 'fig' => 'application/x-xfig', 200 'au' => 'audio/basic', 201 'snd' => 'audio/basic', 202 'mid' => 'audio/midi', 203 'midi' => 'audio/midi', 204 'kar' => 'audio/midi', 205 'mpga' => 'audio/mpeg', 206 'mpega' => 'audio/mpeg', 207 'mp2' => 'audio/mpeg', 208 'mp3' => 'audio/mpeg', 209 'm3u' => 'audio/x-mpegurl', 210 'sid' => 'audio/prs.sid', 211 'aif' => 'audio/x-aiff', 212 'aiff' => 'audio/x-aiff', 213 'aifc' => 'audio/x-aiff', 214 'gsm' => 'audio/x-gsm', 215 'ra' => 'audio/x-realaudio ', 216 'rm' => 'audio/x-pn-realaudio', 217 'ram' => 'audio/x-pn-realaudio', 218 'pls' => 'audio/x-scpls', 219 'wav' => 'audio/x-wav', 220 'pdb' => 'chemical/x-pdb', 221 'xyz' => 'chemical/x-xyz ', 222 'bmp' => 'image/x-ms-bmp', 223 'gif' => 'image/gif', 224 'ief' => 'image/ief', 225 'jpeg' => 'image/jpeg', 226 'jpg' => 'image/jpeg', 227 'jpe' => 'image/jpeg', 228 'pcx' => 'image/pcx', 229 'png' => 'image/png', 230 'svg' => 'image/svg+xml', 231 'svgz' => 'image/svg+xml', 232 'tiff' => 'image/tiff', 233 'tif' => 'image/tiff', 234 'wbmp' => 'image/vnd.wap.wbmp', 235 'ras' => 'image/x-cmu-raster', 236 'cdr' => 'image/x-coreldraw', 237 'pat' => 'image/x-coreldrawpattern', 238 'cdt' => 'image/x-coreldrawtemplate', 239 'djvu' => 'image/x-djvu', 240 'djv' => 'image/x-djvu', 241 'jng' => 'image/x-jng', 242 'pnm' => 'image/x-portable-anymap', 243 'pbm' => 'image/x-portable-bitmap', 244 'pgm' => 'image/x-portable-graymap', 245 'ppm' => 'image/x-portable-pixmap', 246 'rgb' => 'image/x-rgb', 247 'xbm' => 'image/x-xbitmap', 248 'xpm' => 'image/x-xpixmap', 249 'xwd' => 'image/x-xwindowdump', 250 'igs' => 'model/iges', 251 'iges' => 'model/iges', 252 'msh' => 'model/mesh', 253 'mesh' => 'model/mesh', 254 'silo' => 'model/mesh', 255 'wrl' => 'x-world/x-vrml', 256 'vrml' => 'x-world/x-vrml', 257 'csv' => 'text/comma-separated-values', 258 'css' => 'text/css', 259 'htm' => 'text/html', 260 'html' => 'text/html', 261 'xhtml' => 'text/html', 262 'mml' => 'text/mathml', 263 'asc' => 'text/plain', 264 'txt' => 'text/plain', 265 'text' => 'text/plain', 266 'diff' => 'text/plain', 267 'rtx' => 'text/richtext', 268 'tsv' => 'text/tab-separated-values', 269 'wml' => 'text/vnd.wap.wml', 270 'wmls' => 'text/vnd.wap.wmlscript', 271 'xml' => 'text/xml', 272 'xsl' => 'text/xml', 273 'hpp' => 'text/x-c++hdr', 274 'hxx' => 'text/x-c++hdr', 275 'hh' => 'text/x-c++hdr', 276 'cpp' => 'text/x-c++src', 277 'cxx' => 'text/x-c++src', 278 'cc' => 'text/x-c++src', 279 'h' => 'text/x-chdr', 280 'c' => 'text/x-csrc', 281 'java' => 'text/x-java', 282 'moc' => 'text/x-moc', 283 'p' => 'text/x-pascal', 284 'pas' => 'text/x-pascal', 285 'etx' => 'text/x-setext', 286 'tk' => 'text/x-tcl', 287 'ltx' => 'text/x-tex', 288 'sty' => 'text/x-tex', 289 'cls' => 'text/x-tex', 290 'vcs' => 'text/x-vcalendar', 291 'vcf' => 'text/x-vcard', 292 'dl' => 'video/dl', 293 'fli' => 'video/fli', 294 'gl' => 'video/gl', 295 'mpeg' => 'video/mpeg', 296 'mpg' => 'video/mpeg', 297 'mpe' => 'video/mpeg', 298 'qt' => 'video/quicktime', 299 'mov' => 'video/quicktime', 300 'mxu' => 'video/vnd.mpegurl', 301 'mng' => 'video/x-mng', 302 'asf' => 'video/x-ms-asf', 303 'asx' => 'video/x-ms-asf', 304 'avi' => 'video/x-msvideo', 305 'movie' => 'video/x-sgi-movie', 306 'ice' => 'x-conference/x-cooltalk', 307 'vrm' => 'x-world/x-vrml', 308 ]; 309 310 public $filterid; 311 312 public $public; 313 314 /** 315 * @var mixed 316 */ 317 public $format; 318 319 /** 320 * Konstruktor 321 * 322 * @param Objekt-Id 323 */ 324 function __construct( $objectid='' ) 325 { 326 parent::__construct( $objectid ); 327 $this->isFile = true; 328 $this->typeid = BaseObject::TYPEID_FILE; 329 } 330 331 332 /** 333 * @return FileCache 334 */ 335 public function getCache() { 336 $cacheKey = array('db'=>DB::get()->id,'file'=>$this->objectid,'publish'=> \util\ClassUtils::getSimpleClassName($this->publisher)); 337 338 return new FileCache( $cacheKey,function() { 339 return $this->loadValueFromDatabase(); 340 }, $this->lastchangeDate ); 341 } 342 343 344 345 /** 346 * Ermitteln aller Eigenschaften. 347 * 348 * @return array 349 */ 350 function getProperties() 351 { 352 return array_merge( parent::getProperties(), 353 array('full_filename'=>$this->fullFilename, 354 'extension' =>$this->extension, 355 'size' =>$this->size, 356 'filterid' =>$this->filterid ) ); 357 } 358 359 360 361 /** 362 * Es werden Objekte zu einer Dateierweiterung ermittelt 363 * 364 * @param String Dateierweiterung ohne fuehrenden Punkt (z.B. 'jpeg') 365 * @return array Liste der gefundenen Objekt-IDs 366 */ 367 public static function getObjectIdsByExtension( $extension ) 368 { 369 $db = \cms\base\DB::get(); 370 371 $sql = $db->sql( 'SELECT {{file}}.objectid FROM {{file}} '. 372 ' LEFT JOIN {{object}} '. 373 ' ON {{object}}.id={{file}}.objectid'. 374 ' WHERE {{file}}.extension={extension}' ); 375 $sql->setString( 'extension',$extension ); 376 377 return $sql->getCol(); 378 } 379 380 381 382 /** 383 * Ermittelt den Mime-Type zu dieser Datei 384 * 385 * @return String Mime-Type 386 * @deprecated use FileGenerator for this. 387 */ 388 public function mimeType() 389 { 390 if ( $this->mime_type ) 391 return $this->mime_type; 392 393 $ext = strtolower( $this->getRealExtension() ); 394 395 $this->mime_type = self::getMimeType( $ext ); 396 397 return( $this->mime_type ); 398 } 399 400 401 402 public static function getMimeType( $extension ) { 403 404 $mime_types = Configuration::subset('mime_types')->getConfig() + self::$MIME_TYPES; 405 406 $mimeType = @$mime_types[$extension]; 407 408 if ( $mimeType ) 409 return $mimeType; 410 else 411 // Fallback to default mime type 412 return self::DEFAULT_MIMETYPE; 413 } 414 415 416 /** 417 * Lesen der Datei aus der Datenbank. 418 * 419 * Es werden nur die Meta-Daten (Erweiterung, Gr��e) gelesen. Zum Lesen des 420 * Datei-Inhaltes muss #loadValue() aufgerufen werden. 421 */ 422 public function load() 423 { 424 $db = \cms\base\DB::get(); 425 426 $sql = $db->sql( 'SELECT id,contentid,extension,size,filterid'. 427 ' FROM {{file}}'. 428 ' WHERE objectid={objectid}' ); 429 $sql->setInt( 'objectid',$this->objectid ); 430 $row = $sql->getRow(); 431 432 if ( count($row)!=0 ) 433 { 434 $this->fileid = $row['id' ]; 435 $this->extension = $row['extension']; 436 $this->size = $row['size' ]; 437 $this->filterid = $row['filterid' ]; 438 $this->contentid = $row['contentid']; 439 } 440 441 $this->objectLoad(); 442 443 return $this; 444 } 445 446 447 448 /** 449 * Unwiderrufliches L�schen der Datei aus der Datenbank. 450 */ 451 function delete() 452 { 453 // Delete file 454 $sql = DB::sql( <<<SQL 455 DELETE FROM {{file}} 456 WHERE objectid={objectid} 457 SQL 458 ); 459 $sql->setInt( 'objectid',$this->objectid ); 460 $sql->execute(); 461 462 // Content must be deleted after the file (because the file is referencing the content) 463 $content = new Content( $this->contentid ); 464 $content->delete(); 465 466 parent::delete(); 467 } 468 469 470 471 /** 472 * Ermittelt die Datei-Endung. 473 * 474 * @return String Datei-Endung 475 */ 476 function extension() 477 { 478 if ($this->extension != '') 479 return $this->extension; 480 481 $this->load(); 482 return $this->extension; 483 } 484 485 486 /** 487 * Einen Dateinamen in Dateiname und Extension aufteilen. 488 * @param string filename Dateiname 489 */ 490 function parse_filename($filename) 491 { 492 $filename = basename($filename); 493 494 $p = strrpos($filename, '.'); 495 if ($p !== false) 496 { 497 $this->extension = substr($filename, $p +1); 498 $this->filename = substr($filename, 0, $p); 499 } 500 else 501 { 502 $this->extension = ''; 503 $this->filename = $filename; 504 } 505 } 506 507 508 /** 509 * Speichert die Datei-Informationen in der Datenbank. 510 */ 511 public function save() 512 { 513 $db = \cms\base\DB::get(); 514 515 $sql = $db->sql( <<<EOF 516 UPDATE {{file}} SET 517 size = {size}, 518 filterid = {filterid}, 519 extension = {extension} 520 WHERE objectid={objectid} 521 EOF 522 ); 523 $sql->setString('size' ,$this->size ); 524 $sql->setString('extension',$this->extension ); 525 $sql->setString('objectid' ,$this->objectid ); 526 $sql->setInt ('filterid' ,$this->filterid ); 527 $sql->execute(); 528 529 parent::save(); 530 } 531 532 533 /** 534 * Kopieren des Inhaltes von einer anderen Datei 535 * @param int ID der Datei, von der der Inhalt kopiert werden soll 536 */ 537 function copyValueFromFile( $otherfileid ) 538 { 539 $of = new File( $otherfileid ); 540 $this->value = $of->loadValue(); 541 $this->saveValue(); 542 } 543 544 545 public function loadValue() 546 { 547 return $this->loadValueFromDatabase(); 548 } 549 550 551 /** 552 * Lesen des Inhaltes der Datei aus der Datenbank. 553 * 554 * @return String Inhalt der Datei 555 */ 556 private function loadValueFromDatabase() 557 { 558 $sql = Db::sql( <<<SQL 559 SELECT {{file}}.size,{{value}}.file,{{value}}.format 560 FROM {{file}} 561 LEFT JOIN {{content}} 562 ON {{file}}.contentid = {{content}}.id 563 LEFT JOIN {{value}} 564 ON {{value}}.contentid = {{content}}.id AND {{value}}.active = 1 565 WHERE objectid={objectid} 566 SQL 567 ); 568 $sql->setInt( 'objectid', $this->objectid); 569 $row = $sql->getRow(); 570 571 if ( count($row) != 0 ) 572 { 573 $this->value = $row['file']; 574 $this->size = $row['size']; 575 $this->format = $row['format']; 576 } 577 578 // If the value is stored in BASE64 we must decode it now. 579 $valueIsStoredAsBase64 = DB::get()->conf['base64']; 580 581 if ( $valueIsStoredAsBase64 ) 582 $this->value = base64_decode( $this->value ); 583 584 return $this->value; 585 } 586 587 588 /** 589 * Speichert den Inhalt in der Datenbank. 590 */ 591 function saveValue() 592 { 593 $this->getCache()->invalidate(); 594 595 $db = \cms\base\DB::get(); 596 597 $sql = $db->sql( 'UPDATE {{file}}'. 598 ' SET size={size} '. 599 ' WHERE objectid={objectid}' ); 600 $sql->setInt( 'objectid' ,$this->objectid ); 601 $sql->setInt( 'size' ,strlen($this->value) ); 602 603 $sql->execute(); 604 605 $value = new Value(); 606 $value->contentid = $this->contentid; 607 608 // Base64-encoding is done in the Value. 609 $value->file = $this->value; 610 611 $value->publish = $this->public; 612 613 $value->persist(); 614 } 615 616 617 /** 618 * Lesen der Datei aus der Datenbank und schreiben in temporaere Datei 619 */ 620 function write() 621 { 622 $this->getCache()->load(); 623 } 624 625 626 /** 627 * F�gt die Datei der Datenbank hinzu. 628 */ 629 function add() 630 { 631 parent::add(); 632 633 // Getting the content id 634 $content = new Content(); 635 $content->persist(); 636 $this->contentid = $content->getId(); 637 638 $sql = Db::sql('SELECT MAX(id) FROM {{file}}'); 639 $this->fileid = intval($sql->getOne())+1; 640 641 $sql = Db::sql('INSERT INTO {{file}}'. 642 ' (id,contentid,objectid,extension,size)'. 643 " VALUES( {fileid},{contentid},{objectid},{extension},0 )" ); 644 $sql->setInt ('fileid' ,$this->fileid ); 645 $sql->setInt ('contentid',$this->contentid ); 646 $sql->setInt ('objectid' ,$this->objectid ); 647 $sql->setString('extension',$this->extension ); 648 649 $sql->execute(); 650 651 $this->saveValue(); 652 } 653 654 655 /** 656 * Setzt den Zeitstempel der Datei auf die aktuelle Zeit. 657 * 658 * @see objectClasses/Object#setTimestamp() 659 */ 660 661 function setTimestamp() 662 { 663 $this->getCache()->invalidate(); 664 665 parent::setTimestamp(); 666 } 667 668 669 670 671 /** 672 * Change type. 673 * 674 * This is only allowed for files, because it is only allowed to switch between the following types: file,image,text. 675 */ 676 public function updateType() 677 { 678 679 $stmt = Db::sql(<<<SQL 680 UPDATE {{object}} SET 681 typeid = {typeid} 682 WHERE id={objectid} 683 SQL 684 ); 685 686 $stmt->setInt('typeid' , $this->typeid ); 687 $stmt->setInt('objectid', $this->objectid); 688 $stmt->execute(); 689 } 690 691 692 693 694 /** 695 * Ermittelt die wirksame Datei-Endung. Diese kann sich 696 * in der Extra-Dateiendung, aber auch direkt im Dateiname 697 * befinden. 698 * 699 * @return Dateiendung 700 */ 701 function getRealExtension() 702 { 703 if ( $this->extension ) 704 { 705 return $this->extension; 706 } 707 else 708 { 709 $pos = strrpos($this->filename,'.'); 710 if ( $pos === false ) 711 return ''; 712 else 713 return substr($this->filename,$pos+1); 714 } 715 } 716 717 718 719 720 public function getSize() 721 { 722 return $this->size; 723 } 724 725 } 726
Download modules/cms/model/File.class.php
History Sun, 29 Jan 2023 00:20:21 +0100 Jan Dankert New node type "Script". Mon, 25 Apr 2022 03:26:21 +0200 Jan Dankert New: New Project may be created with sample data. Sun, 13 Feb 2022 20:14:39 +0100 dankert Refactoring: removed duplicate code, use inheritance ;) Mon, 6 Dec 2021 01:38:41 +0100 dankert Fixed the file/image upload. Mon, 6 Dec 2021 01:00:00 +0100 dankert New: Show a version from file history; New: Text history. Tue, 9 Nov 2021 23:52:56 +0100 Jan Dankert Some fixes for reading content from the new content table. Tue, 9 Nov 2021 01:22:31 +0100 Jan Dankert Fix: Creating and reading files. Mon, 8 Nov 2021 01:05:19 +0100 Jan Dankert Refactoring: Reading values from the new content table. Sun, 7 Mar 2021 00:10:20 +0100 Jan Dankert Refactoring: Hopefully more performance while accessing the database resultsets. Thu, 4 Mar 2021 03:39:25 +0100 Jan Dankert New: Separate edit action for images and texts. Thu, 4 Mar 2021 02:24:45 +0100 Jan Dankert New: The calculation of the mime types should be done in the generators. Sat, 27 Feb 2021 00:01:45 +0100 Jan Dankert Fix: File-filtering. Wed, 18 Nov 2020 01:46:36 +0100 Jan Dankert Refactoring of model classes: New method persist() and some other cleanups. Tue, 17 Nov 2020 23:51:00 +0100 Jan Dankert Refactoring: Every Actionmethod has now its own class. Fri, 23 Oct 2020 23:09:52 +0200 Jan Dankert Refactoring: Using the new config classes. Fri, 2 Oct 2020 23:11:48 +0200 Jan Dankert Cleanup: No '.inputholder' any more, notices with links to objects. Thu, 1 Oct 2020 20:55:07 +0200 Jan Dankert Fix: Import RequestParams (for using their constants) Tue, 29 Sep 2020 22:17:11 +0200 Jan Dankert Refactoring: Do not use global constants. Sat, 26 Sep 2020 12:20:43 +0200 Jan Dankert Refactoring: No global variables like $SESS any more. All constants are capsulated by classes. Sat, 26 Sep 2020 10:32:02 +0200 Jan Dankert Refactoring: No global $conf array any more. Sat, 26 Sep 2020 05:02:20 +0200 Jan Dankert Fix: The file filtering must be done in the file generator. Sat, 26 Sep 2020 02:26:39 +0200 Jan Dankert Refactoring: No global functions any more, the database object is read from the Db class. Wed, 23 Sep 2020 01:04:05 +0200 Jan Dankert Cleanup of deprecated methods and deprecated class attributes. Mon, 21 Sep 2020 22:48:59 +0200 Jan Dankert Complexe refactoring: Moving all generation logic from the model (Value,Page,File) to generators classes. Fri, 18 Sep 2020 23:04:13 +0200 Jan Dankert Refactoring: Renaming module "cms/publish" to "cms/generator" Fri, 18 Sep 2020 22:48:46 +0200 Jan Dankert Refactoring: Every project has 1 publishing target. Sun, 23 Feb 2020 04:01:30 +0100 Jan Dankert Refactoring with Namespaces for the cms modules, part 1: moving.