EGOCMS  18.0
EGOTEC Content-Managament-System
Ego_Output.php
gehe zur Dokumentation dieser Datei
1 <?php
7 require_once('base/Ego_System.php');
8 require_once('base/functions.php');
9 
28 class Ego_Output {
34  private $page = null;
35 
41  private $site = null;
42 
48  private $file = '';
49 
55  private $info = array();
56 
62  private $pool = '';
63 
69  private $mime_type = '';
70 
76  private $cache = '';
77 
83  private $generator = 'Server-File';
84 
90  private $etag = '';
91 
97  private $name = '';
98 
104  private $is_image = false;
105 
111  private $is_valid = false;
112 
118  private $web_format = false;
119 
125  private $temporary = false;
126 
132  private $quality = 100;
133 
139  private $multipart_support = false;
140 
146  private $error = false;
147 
154  public function __construct($source = null, $pool = '') {
155  if (is_a($source, 'Page')) {
156  // Datei einer Seite
157  $this->page = $source;
158  $this->site = $this->page->getSite();
159 
160  // Mediapool Unterverzeichnis erkennen
161  $dir = '';
162  if ($_REQUEST['dir'] || $_REQUEST['c_date']) {
163  $dir = $_REQUEST['dir'] ? $_REQUEST['dir'] : $_REQUEST['c_date'];
164  if ($_REQUEST['c_date'] && !is_numeric($dir) && strpos($dir, DIRECTORY_SEPARATOR) === false) {
165  // Mediapool Archive erwarten immer Zeitstempel
166  $dir = strtotime($dir);
167  }
168  }
169 
170  if ($_REQUEST['thumbnail']) {
171  // Ein Thumbnail über die URL generieren
172  list($width, $height, $index) = explode('x', $_REQUEST['thumbnail'], 3);
173  $this->file = $this->getThumbnail((int) $width, (int) ($height ?? $width), $pool, $dir, [
174  'index' => (int) $index
175  ]);
176  $this->detectMimeType();
177  $this->is_image = true;
178  if ($pool) {
179  $this->pool = $pool;
180  }
181  } elseif ($pool) {
182  $this->pool = $pool;
183  $file = $this->page->getMediapool()->get($this->pool, $dir);
184  $this->info = $file;
185  $this->file = $file['file'];
186 
187  $this->detectMimeType();
188  $type = $file['suffix'];
189  } else {
190  // Bei der Ausgabe eines Multimedia Ausschnitts wird die Originalseite referenziert
191  if ($this->page->field['type'] == 'multimedia/image' && $this->page->extra['crop_image']) {
192  $extra = array(
193  'edit' => $this->page->extra['edit'],
194  'crop_image' => true
195  );
196  $this->page = $this->page->getParents()->nextPage();
197  $this->page->extra = array_merge($this->page->extra, $extra);
198  }
199 
200  $this->file = $GLOBALS['egotec_conf']['var_dir'].'media/'.$this->site->name.'/';
201  if ($_REQUEST['c_date']) {
202  // Als "c_date" das vom Page Konstruktor ermittelte Datum verwenden
203  $archive_file = $this->file . $this->page->getMediaFilename(
204  false,
205  '_'.Ego_System::dateEncode($this->page->field['c_date'])
206  );
207  if (Ego_System::file_exists($archive_file)) {
208  $this->file = $archive_file;
209  } else {
210  // Gibt es keine passende Version, wird das Original verwendet
211  $this->file .= $this->page->getMediaFilename();
212  }
213  } else {
214  $this->file .= $this->page->getMediaFilename();
215  }
216  $this->mime_type = $this->page->extra['mime_type'];
217  $type = $this->page->extra['image_type'];
218 
219  // Automatisch zur passenden Datei für das Endgerät wechseln
220  if ($this->site->admin['video']['compress'] && !$GLOBALS['is_index']) {
221  require_once 'base/Ego_Mobile.php';
222  $mobile = new Ego_Mobile();
223  $files = [
224  '360p' => $this->page->getMediapool()->get('360p.mp4'),
225  '720p' => $this->page->getMediapool()->get('720p.mp4'),
226  '1080p' => $this->page->getMediapool()->get('1080p.mp4')
227  ];
228  $is_mobile = $mobile->isMobile();
229  $is_tablet = $mobile->isTablet();
230  if (
231  ($is_mobile && !$is_tablet && ($data = $files['360p'])) // 360p nur für Mobile
232  || ($is_tablet && ($data = $files['720p'])) // 720p nur für Tablets
233  || ($data = $files['1080p']) // 1080p nur für Desktops
234  ) {
235  $this->file = $data['file'];
236  $this->mime_type = $data['mime'];
237  } else {
238  // Wenn nichts zutrifft, dann die höhste verfügbare Auflösung verwenden (ansonsten die Originaldatei)
239  $existing_files = array_filter($files);
240  if ($data = array_pop($existing_files)) {
241  $this->file = $data['file'];
242  $this->mime_type = $data['mime'];
243  }
244  }
245  }
246  }
247 
248  // Bestimmte MimeTypes setzen
249  if (!empty($type)) {
250  $formats = array(
251  'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
252  'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
253  'pptm' => 'application/vnd.ms-powerpoint.presentation.macroEnabled.12',
254  'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
255  'xlsm' => 'application/vnd.ms-excel.sheet.macroEnabled.12',
256  'xps' => 'application/vnd.ms-xpsdocument',
257  'svg' => 'image/svg+xml'
258  );
259  if (array_key_exists($type, $formats)) {
260  $this->mime_type = $formats[$type];
261  }
262  }
263  } elseif (is_string($source)) {
264  if (strpos($source, 'string:') === 0) {
265  // Übergebenen String in eine temporäre Datei speichern
266  $file = tempnam($GLOBALS['egotec_conf']['tmp_dir'], 'output');
267  Ego_System::file_put_contents($file, substr($source, 7));
268  $this->setFile($file);
269  $this->setTemporary(true);
270  } else {
271  // Existierende Datei verwenden
272  $this->setFile($source);
273  }
274  if (!empty($GLOBALS['site']) && is_a($GLOBALS['site'], 'Site')) {
275  $this->site = $GLOBALS['site'];
276  } elseif (class_exists('Site')) {
277  $this->site = new Site();
278  }
279  }
280 
281  // Erkennen, ob die auszugebende Datei ein Bild (außer SVG und ICO: diese werden immer direkt und ohne ImageMagick Transformation ausgegeben)
282  $ignore_image_mimes = array('image/svg+xml', 'image/x-icon', 'image/vnd.microsoft.icon');
283  $ignore_image_types = array('svg', 'ico');
284 
285  if (!$this->is_image) {
286  if ($this->page && $this->page->field['type'] == 'multimedia/image') {
287  $this->is_image = !in_array($this->page->extra['mime_type'], $ignore_image_mimes);
288  } elseif ($pool) {
289  $this->is_image = preg_match(
290  '/\.(' . implode(
291  '|',
292  array_filter(
293  Ego_System::getFormats('image'),
294  function ($type) use ($ignore_image_types) {
295  return !in_array($type, $ignore_image_types);
296  }
297  )
298  ) . ')$/ims',
299  $pool
300  );
301  } elseif ($this->file) {
302  $this->is_image = !(strpos($this->mime_type, 'image') === false || in_array($this->mime_type, $ignore_image_mimes));
303  if ($this->page && $this->page->extra['mime_type'] && $this->page->extra['image_type']) {
304  $this->is_valid = true; // Kopierte Multimedia Seitentypen unterstützen
305  }
306  }
307  }
308 
309  if ($this->is_image) {
310  $this->web_format = in_array(
311  $this->mime_type,
313  );
314  if (is_numeric($_REQUEST['quality'])) {
315  // In der URL gesetzt
316  $this->quality = $_REQUEST['quality'];
317  } else if (is_numeric($GLOBALS['quality'])) {
318  // Vom Template gesetzt
319  $this->quality = $GLOBALS['quality'];
320  } elseif (is_numeric($GLOBALS['egotec_conf']['image']['quality'])) {
321  // Aus den Einstellungen des Mandanten auslesen
322  $this->quality = $GLOBALS['egotec_conf']['image']['quality'];
323  }
324  }
325  }
326 
333  private function isValid($download = false) {
334  return (
335  $this->is_valid
336  || (
337  (
338  in_array($this->page->field['type'], array('multimedia/file', 'multimedia/image', 'multimedia/category'))
339  || $this->pool
340  )
341  && (
342  (
343  $download
344  && $this->page->field['type'] == 'multimedia/category'
345  )
346  || Ego_System::file_exists($this->file)
347  )
348  && $this->page->hasRights('view')
349  )
350  );
351  }
352 
358  private function detectMimeType() {
359  require_once('base/Ego_MimeType.php');
360  $mime = new Ego_MimeType();
361  $this->mime_type = $mime->autoDetect($this->file);
362  }
363 
370  public function error($image = false) {
371  Ego_System::header(404);
372  if (($this->is_image || $image) && !$this->error) {
373  $error_image = true;
374  if (class_exists('Imagick')) {
375  $width = $this->page ? $this->page->extra['origImgWidth'] : 0;
376  if (!is_numeric($width) || $_REQUEST['width']) {
377  $width = (int) $_REQUEST['width'];
378  }
379  $height = $this->page ? $this->page->extra['origImgHeight'] : 0;
380  if (!is_numeric($height) || $_REQUEST['height']) {
381  $height = (int) $_REQUEST['height'];
382  }
383 
384  if ($width && $height) {
385  $this->file = tempnam($GLOBALS['egotec_conf']['tmp_dir'], 'transform');
386 
387  $image = new Imagick();
388  $draw = new ImagickDraw();
389  $image->newImage($width, $height, new ImagickPixel('grey'));
390 
391  $font_size = ceil(min(array($width, $height)) / 6);
392  $draw->setFillColor('lightgrey');
393  $draw->setFontSize($font_size);
394  $draw->setTextAlignment(Imagick::ALIGN_CENTER);
395  $image->annotateImage(
396  $draw,
397  ceil($width / 2),
398  ceil($height / 2) + ceil($font_size / 2),
399  0,
400  Ego_System::isDevMode() ? "{$width} x {$height}" : 404
401  );
402  $image->setFormat('png');
403 
404  Ego_System::file_put_contents($this->file, $image);
405  $this->setTemporary(true);
406 
407  $error_image = false;
408  }
409  }
410  if ($error_image) {
411  $this->file = $GLOBALS['egotec_conf']['egotec_dir'] . 'pub' .
412  DIRECTORY_SEPARATOR . 'missing_file.gif';
413  }
414  $this->detectMimeType();
415  $this->is_valid = true;
416  $this->error = true;
417  $error = $this->read();
418  } elseif ($this->site) {
419  $error = $this->site->getErrorPage();
420  } else {
421  $site = new Site();
422  $error = $site->getErrorPage();
423  }
424  return $error;
425  }
426 
436  private function prepend(&$page, &$site, &$auth, &$smarty) {
437  if (
438  !$this->pool
439  && $page
440  && $site
441  && ($file = $site->getSiteFile($page->field['type'].DIRECTORY_SEPARATOR.'index.php'))
442  ) {
443  require_once($file);
444  }
445  }
446 
453  public function setName($name) {
454  $this->name = $name;
455  }
456 
462  private function getName() {
463  if ($this->name != '') {
464  return $this->name;
465  } elseif ($this->pool) {
466  return $this->pool;
467  } elseif ($this->page) {
468  $suffix = '.'.$this->page->extra['image_type'];
469  return preg_replace(
470  '/'.preg_quote($suffix, '/').'$/i',
471  '',
472  strtr($this->page->field['name'], '/\:*?"<>|', '_________')
473  ).$suffix;
474  } else {
475  return basename($this->file);
476  }
477  }
478 
485  private function setDefaultHeaders($length = 0) {
486  if (!empty($this->etag)) {
487  Ego_System::header('ETag: "'.$this->etag.'"');
488  }
489  Ego_System::header('Content-Type: '.$this->mime_type.'; charset=UTF-8');
490  $t = $this->page ? $this->site->getCacheExpire() : 0;
491  if (!$t) { // Keiner darf cachen
493  } else {
494  /* Bei Bildern ist das Feld cache immer 0. Es wird trotzdem immer ein Header gesendet,
495  * so dass Browser und Proxy cachen dürfen. */
496  Ego_System::header("Expires: ". gmdate("D, d M Y H:i:s", time() + $t) . " GMT");
497 
498  /* Bei HTTPS und PDF muss für IE8 (unter kleiner) immer "Pragma: public" stehen
499  * ansonsten gibt es komische Probleme bei "Ziel speichern unter"
500  * und Seitenaufruf von PDFs bei HTTPS */
501  if (
502  $_SERVER['HTTPS'] == 'on'
503  && in_array(
504  mb_strtolower($this->page->extra['image_type']),
505  array('pdf', 'doc', 'docx', 'dot')
506  )
507  ) {
508  Ego_System::header("Pragma: public");
509  }
510  if (
511  $this->page->field['cache']&2
512  && $GLOBALS['auth']->isNobody()
513  ) {
514  // Proxy und/oder Browser darf cachen
515  Ego_System::header('Cache-Control: public');
516  } else {
517  // Nur Browser darf cachen
518  Ego_System::header('Cache-Control: private');
519  }
520  }
521  if (!$GLOBALS['egotec_conf']['no_content_length_header']) {
522  if (!$length) {
523  $length = $this->getFilesize($this->file);
524  }
525  Ego_System::header('Content-Length: '.$length);
526  }
527  if ($this->page) {
528  Ego_System::header("Last-Modified: ".gmdate("D, d M Y H:i:s", Ego_System::dateEncode($this->page->field['c_date']))." GMT");
529  if ($this->page->extra['meta_robots'] && $this->page->extra['meta_robots'] != 'index') {
530  Ego_System::header('X-Robots-Tag: '.$this->page->extra['meta_robots']);
531  }
532  }
533  }
534 
540  private function setSingleHeaders() {
541  Ego_System::header('Content-Disposition: inline; filename="'.$this->getName().'";');
542  Ego_System::header('Content-Transfer-Encoding: binary');
543  Ego_System::header('Accept-Ranges: bytes');
544  Ego_System::header('Content-Size: '.$this->getFilesize($this->file));
545  Ego_System::header('Connection: Keep-Alive');
546  $this->setDefaultHeaders();
547  ob_clean();
548  flush();
549  readfile_chunked($this->file);
550  }
551 
557  private function setRangeHeaders() {
558  $fp = @fopen($this->file, 'rb');
559  $size = $this->getFilesize($this->file);
560  $length = $size;
561  $start = 0;
562  $end = $size - 1;
563  if (isset($_SERVER['HTTP_RANGE'])) {
564  $c_end = $end;
565  list(, $range) = explode('=', $_SERVER['HTTP_RANGE'], 2);
566  if (strpos($range, ',') !== false) {
567  // Multiple Range
568  if ($this->multipart_support) {
569  $boundary = md5('multipart_byteranges');
570  Ego_System::header(206);
571  Ego_System::header("Content-Length: $size");
572  Ego_System::header('Content-Type: multipart/byteranges; boundary=' . $boundary);
573  foreach (explode(',', $range) as $multi_range) {
574  $multi_range = explode('-', trim($multi_range));
575  if ($multi_range[0] == '-') {
576  $start = $size - substr($multi_range, 1);
577  $end = $c_end;
578  } else {
579  $start = $multi_range[0];
580  $end = (isset($multi_range[1]) && is_numeric($multi_range[1])) ? $multi_range[1] : $size;
581  }
582  fseek($fp, $start);
583  $buffer = 1024 * 8;
584  echo "--{$boundary}\r\n";
585  echo "Content-Type: {$this->mime_type}\r\n";
586  echo "Content-Range: bytes $start-$end/$size\r\n\r\n";
587  while (!feof($fp) && ($p = ftell($fp)) <= $end) {
588  if ($p + $buffer > $end) {
589  $buffer = $end - $p + 1;
590  }
591  set_time_limit(0);
592  echo fread($fp, $buffer);
593  }
594  echo "\r\n";
595  flush();
596  }
597  echo "--{$boundary}--\r\n\r\n";
598  fclose($fp);
599  } else {
600  // Multiple Range nicht unterstützen und stattdessen als Download behandeln
601  $this->setDownloadHeaders();
602  }
603  return;
604  } else {
605  // Single Range
606  if ($range[0] == '-') {
607  $c_start = $size - substr($range, 1);
608  } else {
609  $range = explode('-', $range);
610  $c_start = $range[0];
611  $c_end = (isset($range[1]) && is_numeric($range[1])) ? $range[1] : $size;
612  }
613  $c_end = $c_end > $end ? $end : $c_end;
614  if ($c_start > $c_end || $c_start > $size - 1 || $c_end >= $size) {
615  Ego_System::header(416);
616  Ego_System::header("Content-Range: bytes $start-$end/$size");
617  exit;
618  }
619  $start = $c_start;
620  $end = $c_end;
621  $length = $end - $start + 1;
622  fseek($fp, $start);
623  Ego_System::header(206);
624  }
625  }
626  Ego_System::header("Content-Range: bytes $start-$end/$size");
627  $this->setDefaultHeaders($length);
628  $buffer = 1024 * 8;
629  while (!feof($fp) && ($p = ftell($fp)) <= $end) {
630  if ($p + $buffer > $end) {
631  $buffer = $end - $p + 1;
632  }
633  set_time_limit(0);
634  echo fread($fp, $buffer);
635  flush();
636  }
637  fclose($fp);
638  }
639 
645  private function setDownloadHeaders() {
646  Ego_System::header('Content-Description: File Transfer');
647  Ego_System::header('Content-Disposition: attachment; filename="'.$this->getName().'";');
648  Ego_System::header('Content-Transfer-Encoding: binary');
649  Ego_System::header('Connection: close');
650  $this->setDefaultHeaders();
651  ob_clean();
652  flush();
653  readfile_chunked($this->file);
654  }
655 
662  public function read($download = false) {
663  // Datei aus dem Cache ermitteln
664  if (
665  !empty($this->etag)
666  && $_SERVER['HTTP_IF_NONE_MATCH'] == '"' . $this->etag . '"'
667  && $GLOBALS['auth']->isNobody()
668  ) {
669  Ego_System::header('Cache-Control: private');
670  Ego_System::header(304);
671  exit;
672  }
673 
674  if ($this->isValid($download)) {
675  $this->prepend($this->page, $this->site, $GLOBALS['auth'], $GLOBALS['smarty']);
676 
677  // In der Entwicklungsumgebung immer Platzhalter Bilder anzeigen
678  if (
679  $GLOBALS['egotec_conf']['dev']['images']
680  && $this->is_image
681  && !$download
682  ) {
683  $this->error(true);
684  }
685 
686  // Parameter für die Modifizierung ermitteln
687  $modify = array();
688  $modify_keys = array('clip', 'rotation', 'mirror');
689  if ($_REQUEST['original'] && !$GLOBALS['auth']->isNobody()) {
690  // Angemeldete Benutzer dürfen das Original sehen
691  unset($_REQUEST['width'], $_REQUEST['height']);
692 
693  // Im Original wird die Rotation beibehalten
694  $modify_keys = array('rotation', 'mirror');
695  }
696 
697  foreach ($modify_keys as $param) {
698  if (isset($_REQUEST[$param])) {
699  $modify[$param] = $_REQUEST[$param];
700  } else {
701  if ($this->pool) {
702  if (isset($this->info[$param])) {
703  $modify[$param] = $this->info[$param];
704  }
705  } elseif ($this->page->field['type'] == 'multimedia/image') {
706  if (isset($this->page->extra['edit'][$param])) {
707  $modify[$param] = $this->page->extra['edit'][$param];
708  }
709  }
710  }
711  }
712 
713  if (
714  (!$download || !empty($modify))
715  && $this->is_image
716  && ($_REQUEST['width']
717  || $_REQUEST['height']
718  || $this->quality != 100
719  || !$this->web_format
720  || !empty($modify))
721  ) {
722  // Bild transformieren
723  $this->transform((int) $_REQUEST['width'], (int) $_REQUEST['height'], $modify);
724  }
725  if ($download) {
726  if (
727  !$this->page
728  && @is_dir($this->file)
729  ) {
730  // Bei einem Verzeichnis wird automatisch ein Archiv erzeugt
731  $this->setTemporary(true);
732  $this->setFile($this->createArchive($this->file));
733  } elseif (
734  $this->page
735  && $this->page->field['type'] == 'multimedia/category'
736  && !empty($this->site->admin['allow_download'])
737  && !empty($this->page->extra['allow_download'])
738  ) {
739  // Archiv erstellen
740  $this->file = $this->page->export();
741  $this->detectMimeType();
742  $this->setTemporary(true);
743  $this->page->extra['image_type'] = 'tar.gz';
744  }
745  // Datei herunterladen
746  $this->setDownloadHeaders();
747  } else {
748  // Datei ausgeben
749  $partial = false;
750  if (
751  (
752  isset($_SERVER['HTTP_RANGE']) // Range Header werden angefordert
753  || strpos($this->mime_type, 'video/') === 0 // Videos immer mit Range Header übertragen
754  )
755  && (
756  !preg_match('/MSIE (.*?);/', $_SERVER['HTTP_USER_AGENT'], $matches)
757  || $matches[1] > 8 // Range Header nicht für MSIE 8 und kleiner
758  )
759  ) {
760  // teilweise
761  $this->setRangeHeaders();
762  $partial = true;
763  } else {
764  // direkt
765  $this->setSingleHeaders();
766  }
767  if (
768  !$partial
769  && $this->site
770  && !empty($this->cache)
771  && ($this->page->field['cache']&3) != 0
772  && !$GLOBALS['no_cache']
773  ) {
774  // Ausgabe cachen
775  $info = array(
776  'headers' => $GLOBALS['egotec']['response_headers'],
777  'stats' => $GLOBALS['stats'],
778  'type' => $this->page->field['type']
779  );
780  $this->site->setCacheEntry($this->cache . '.info', $info);
781  $this->site->setCacheEntry($this->cache, $this->file);
782  }
783  }
784  if ($this->temporary) {
785  @unlink($this->file);
786  }
787  exit;
788  }
789  return $this->error($this->page && strpos($this->page->extra['mime_type'], 'image/') === 0);
790  }
791 
797  public function download() {
798 
799  return $this->read(true);
800  }
801 
813  public function pdf($name = '', $temporary = true, $cookie = true, $return = 1) {
814  if ($this->isValid()) {
815  // Einstellungen
816  $smarty = $GLOBALS['smarty'];
817  $site = $this->site;
818  $page = $this->page;
819  $context = null;
820  if ($cookie && !empty($_COOKIE[EGOTEC])) {
821  $context = stream_context_create(array(
822  'http' => array(
823  'method' => 'GET',
824  'header' => "Cookie: ".EGOTEC."=".$_COOKIE[EGOTEC]."\r\n"
825  )
826  ));
827  }
828  $s = Ego_System::file_get_contents($this->file, true, $context);
829  if (!empty($name)) {
830  $this->setName($name);
831  }
832  $_REQUEST['title'] = $this->getName();
833 
834  // Generierung durchführen
835  $no_pdf_header = true;
836  include('pdf/pdf_create.php');
837 
838  // Datei übernehmen
839  $pdf_file = $GLOBALS['egotec_conf']['tmp_dir'].'output'.md5(microtime()).'.pdf';
840  Ego_System::file_put_contents($pdf_file, $s);
841  if ($temporary) {
842  $this->removeFile();
843  }
844  $this->setTemporary($return !== 3);
845  $this->setFile($pdf_file);
846 
847  // Datei ausgeben
848  switch ($return) {
849  case 1:
850  // Download
851  return $this->download();
852  case 2:
853  // Ausgabe
854  return $this->read();
855  case 3:
856  // Pfad zur generierten PDF Datei
857  return $this->file;
858  }
859  }
860  return $this->error();
861  }
862 
871  public function transform($width, $height, $modify = array()) {
872  if ($this->is_image) {
873  // Hook für eigene Transformationen erkennen
874  $output_transform = $this->page && method_exists($this->page, 'outputTransform');
875 
876  // Wasserzeichen erkennen
877  $output_watermark = '';
878  if ($this->pool) {
879  // Mediapool (ohne Vererbung)
880  $list = md5($_REQUEST['dir']);
881  $key = md5($this->pool);
882  if ($this->page->extra['mediapool'][$list][$key]['watermark']) {
883  $output_watermark = $this->page->extra['mediapool'][$list][$key]['watermark'];
884  }
885  } elseif ($this->page) {
886  // Multimedia (mit Vererbung)
887  $inherit = $this->page->inheritExtra(array('watermark'));
888  if ($inherit['watermark']) {
889  $output_watermark = $inherit['watermark'];
890  }
891  }
892 
893  // Kompressionen sind nur mit JPG Dateien möglich
894  $quality = in_array($this->mime_type, array('image/jpeg', 'image/jpg')) ? $this->quality : 0;
895 
896  if ($width > 0 || $height > 0 || !empty($modify) || $output_transform || $output_watermark || $quality) {
897  $size = getimagesize($this->file);
898 
899  // Breite und Höhe dürfen nicht größer sein als das Original
900  if ($width > $size[0] || $height > $size[1]) {
901  $width = $size[0];
902  $height = $size[1];
903  }
904 
905  if (!$_REQUEST['max'] || $size[0] > $width || $size[1] > $height || !empty($modify)) {
906  $dir = $GLOBALS['egotec_conf']['cachemedia_dir'];
907  if ($this->page) {
908  $dir .= $this->site->name . DIRECTORY_SEPARATOR . $this->site->language . DIRECTORY_SEPARATOR . $this->page->field['id'] . DIRECTORY_SEPARATOR;
909  $dir .= Ego_System::dateEncode($_REQUEST['c_date'] ? $_REQUEST['c_date'] : $this->page->field['c_date']) .
910  DIRECTORY_SEPARATOR;
911  } else {
912  $dir .= '_output' . DIRECTORY_SEPARATOR;
913  }
914  if (!file_exists($dir)) {
915  Ego_System::mkdir($dir);
916  }
917  $file = $dir . $width . 'x' . $height . 'x' . $this->quality . ($this->web_format ? '' : '_jpg');
918  if ($this->pool) {
919  $file .= '_' . str_replace('.', '_', base64_encode($this->pool));
920  } elseif (!$this->page) {
921  $file .= '_' . md5($this->file);
922  }
923  if ($output_watermark) {
924  $file .= '_' . md5($output_watermark);
925  }
926  if (!empty($modify)) {
927  $file .= '_' . md5(serialize($modify));
928  }
929 
930  // Hook um abzufragen ob die Cache verwendet werden soll
931  $output_cache = $this->page && method_exists($this->page, 'outputCache');
932 
933  if (
935  && !$_REQUEST['c_date']
936  && !$this->error
937  && (!$output_cache || $this->page->outputCache($width, $height))
938  ) {
939  // Datei aus dem Cache verwenden
940  $this->file = $file;
941  Ego_System::header("X-Cache: CMS");
942  } else {
943  // Keine unnötige Skalierung bei Originalgröße und voller Qualität
944  if (
945  !$_REQUEST['c_date']
946  && $size[0] == $width
947  && $size[1] == $height
948  && empty($modify)
949  && (!in_array($this->mime_type, array('image/jpeg', 'image/jpg'))
950  || $this->quality == 100)
951  && !$output_transform
952  && !$output_watermark
953  ) {
954  return false;
955  }
956 
957  // Datei neu generieren
958  require_once('base/Ego_Image.php');
959  $imageTransform = new Ego_Image();
960  $tmp = tempnam($GLOBALS['egotec_conf']['tmp_dir'], 'transform');
961 
962  if (Ego_System::copy($this->file, $tmp)) {
963  $imageTransform->load($tmp);
964 
965  // Ausgabe modifizieren
966  if (!empty($modify)) {
967  // Bild spiegeln
968  if ($modify['mirror']) {
969  if (strpos($modify['mirror'], 'v') !== false) {
970  $imageTransform->mirror(true, false);
971  }
972  if (strpos($modify['mirror'], 'h') !== false) {
973  $imageTransform->mirror(false, true);
974  }
975  }
976 
977  // Bild rotieren
978  if ($modify['rotation']) {
979  $imageTransform->rotate((int) $modify['rotation']);
980  }
981 
982  // Bildausschnitt verwenden
983  if ($modify['clip']) {
984  list($x1, $y1, $x2, $y2) = explode(',', $modify['clip'], 4);
985  $cwidth = $x2 - $x1;
986  $cheight = $y2 - $y1;
987 
988  $imageTransform->crop($x1, $y1, $x2, $y2);
989 
990  $size[0] = $cwidth;
991  $size[1] = $cheight;
992 
993  // Breite und Höhe dürfen nicht größer sein als der Ausschnitt
994  if ($width > $cwidth) {
995  $width = $cwidth;
996  } elseif (!$width) {
997  $width = (int)round($cwidth * ($height / $cheight));
998  }
999  if ($height > $cheight) {
1000  $height = $cheight;
1001  } elseif (!$height) {
1002  $height = (int)round($cheight * ($width / $cwidth));
1003  }
1004  }
1005  }
1006 
1007  if ($_REQUEST['max']) {
1008  if ($width) {
1009  // Breite ändern, Seitenverhältnis beibehalten
1010  $w = $width;
1011  $h = (int)round($size[1] * ($width / $size[0]));
1012  }
1013  if ($height && $h > $height) {
1014  // Höhe ändern, Seitenverhältnis beibehalten
1015  $w = (int)round($w * ($height / $h));
1016  $h = $height;
1017  }
1018  $imageTransform->resize($w, $h);
1019  } else {
1020  if ($width && $height) {
1021  // Höhe und Breite ändern
1022  $imageTransform->resize($width, $height);
1023  } else if ($width) {
1024  // Breite ändern, Seitenverhältnis beibehalten
1025  $imageTransform->scaleByX($width);
1026  } else if ($height) {
1027  // Höhe ändern, Seitenverhältnis beibehalten
1028  $imageTransform->scaleByY($height);
1029  }
1030  }
1031 
1032  // Hook für eigene Transformationen anwenden
1033  if ($output_transform) {
1034  $this->page->outputTransform($imageTransform, $tmp, $width, $height, $modify);
1035  }
1036 
1037  // Wasserzeichen einfügen
1038  if ($output_watermark) {
1039  $imageTransform->watermark($output_watermark);
1040  }
1041 
1042  if (
1043  !$this->error
1044  && $imageTransform->save($file, ($this->web_format ? '' : 'jpeg'), $quality)
1045  ) {
1046  $imageTransform->free();
1047  $this->file = $file;
1048  }
1049  }
1050  @unlink($tmp);
1051  }
1052  } else {
1053  return false;
1054  }
1055  }
1056  }
1057  return true;
1058  }
1059 
1066  public function setFile($file) {
1067  $this->file = $file;
1068  $this->detectMimeType();
1069  $this->is_valid = true;
1070  }
1071 
1077  public function removeFile() {
1078  @unlink($this->file);
1079  $this->file = '';
1080  $this->is_valid = false;
1081  }
1082 
1090  public function setCache($cache, $etag = '') {
1091  $this->cache = $cache;
1092  $this->etag = $etag;
1093  }
1094 
1101  public function setTemporary($temporary) {
1102  $this->temporary = $temporary;
1103  }
1104 
1111  public function createArchive($path) {
1112  if (@is_dir($path)) {
1113  $dir = $GLOBALS['egotec_conf']['tmp_dir'];
1114  $name = basename($path);
1115  $file = $name.'.tar.gz';
1116 
1117  // Archiv erstellen
1118  require_once('Archive/Tar.php');
1119  $cwd = getcwd();
1120  chdir($dir);
1121  $zip = new Archive_Tar($file, 'gz');
1122  $zip->_separator = ',';
1123  $zip->setIgnoreList(array($dir));
1124  $zip->createModify(rtrim($path, DIRECTORY_SEPARATOR), '', $name);
1125  chdir($cwd);
1126  return $dir.$file;
1127  }
1128  return null;
1129  }
1130 
1138  public static function export($key, $type) {
1139  $source = '';
1140  switch ($type) {
1141  case 'workflow':
1142  require_once('workflow/Ego_Workflow.php');
1143  $workflow = new Ego_Workflow($key);
1144  $source = $workflow->export();
1145  break;
1146  case 'template':
1147  require_once('base/template/Ego_Template.php');
1148  $template = new Ego_Template($key);
1149  $source = $template->export();
1150  }
1151  if (!empty($source)) {
1152  $output = new Ego_Output($source);
1153  $output->setTemporary(true);
1154  $output->download();
1155  }
1156  }
1157 
1168  private function getThumbnail($width, $height = 0, $pool = '', $dir = '', $params = []) {
1169  if ($this->page) {
1170  return $this->page->getThumbnail($width, $height, $pool, $dir, $params);
1171  } else {
1172  // TODO Thumbnail für Dateien, die keinem Page Objekt zugeordnet sind
1173  }
1174  return null;
1175  }
1176 
1183  private function getFilesize($file) {
1184  return (int) @filesize($file);
1185  }
1186 }
1187 ?>
static getFormats($type)
static export($key, $type)
static isDevMode()
static file_put_contents($filename, $data, $flags=0, $context=null)
setName($name)
Definition: Ego_Output.php:453
setCache($cache, $etag='')
read($download=false)
Definition: Ego_Output.php:662
static noCache()
Definition: Ego_System.php:929
static file_exists($file)
transform($width, $height, $modify=array())
Definition: Ego_Output.php:871
setTemporary($temporary)
static mkdir($dir, $mode=0755, $recursive=true)
Definition: Ego_System.php:497
setFile($file)
static file_get_contents($filename, $utf8=true, $context=null)
static copy($src, $dest, $except='', $useLinks=false)
static dateEncode($string)
Definition: Ego_System.php:484
createArchive($path)
static header($header, $replace=true)
Definition: Ego_System.php:833
__construct($source=null, $pool='')
Definition: Ego_Output.php:154
pdf($name='', $temporary=true, $cookie=true, $return=1)
Definition: Ego_Output.php:813
error($image=false)
Definition: Ego_Output.php:370
Definition: Site.php:29