EGOCMS  24.0
EGOTEC Content-Managament-System
Mediapool.php
gehe zur Dokumentation dieser Datei
1 <?php
13 class Mediapool {
14  private $page;
15  private $site;
16  public $currentDir = 'current';
24  public function __construct(Page $page) {
25  $this->page = $page;
26  $this->site = $this->page->getSite();
27  }
28 
46  public function put($source, $name, $dir = '', $extract = false, $replace = true, $types = '', $save = true, $original = true, $source_extra = array(), &$files = array()) {
47  if (!isset($GLOBALS['__egotec_skip_replication'])) {
48  $GLOBALS['__egotec_skip_replication'] = 'pool.put';
49  }
50 
51  if ($original && ($original_page = $this->page->getCloneOriginal())) {
52  return $original_page->getMediapool()->put($source, $name, $dir, $extract, $replace, $types);
53  }
54 
55  $result = null;
56 
57  if ($extract || $this->page->validateFile($source, $name)) {
58  // Prüfen, ob dieser Dateityp hochgeladen werden darf
59  require_once('base/Ego_MimeType.php');
60  $mime = new Ego_MimeType();
61  switch ($types) {
62  case 'image':
63  if (strpos($mime->autoDetect($source), 'image') !== 0) {
64  return null;
65  }
66  break;
67  case 'file':
68  if (strpos($mime->autoDetect($source), 'image') === 0) {
69  return null;
70  }
71  }
72 
73  // Datei hinzufügen
74  $this->create();
75  $dir = $this->getDir($dir);
76  $path = $this->dir()
77  . rtrim($dir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
78  if (!Ego_System::file_exists($path)) {
79  Ego_System::mkdir($path);
80  }
81  $name = strtr(mb_ereg_replace('[^a-zA-Z0-9\-äöüÄÖÜß()\[\]\.,_ ]', '_', $name), '#?&+', '____'); // Zeichen, die im Namen vorkommen dürfen
82  if (!$replace) {
83  // Eine Datei mit dem selben Namen nicht überschreiben
84  $parts = explode('.', $name, 2);
85  $filename = $parts[0];
86  $suffix = $parts[1] ? '.' . $parts[1] : '';
87  $n = 1;
88  while ((bool)$this->file($name, $dir)) {
89  $name = $filename . '_' . ($n++) . $suffix;
90  }
91  }
92  $file = $path . Ego_System::base64Encode($name);
93  if ($source !== $file) {
94  @unlink($file); // Wegen hard links muss vorher gelöscht werden.
95  }
96  if (Ego_System::copy($source, $file)) {
97  if ($extract) {
98  $this->extract($name, $dir, $files);
99  } else {
100  $files[] = $this->get($name, $dir);
101  }
102 
103  // Copyright für Bilder automatisch ermitteln
104  $save_copyright = false;
105  foreach ($files as $data) {
106  if ($data['isImage']) {
107  require_once('base/Ego_Image.php');
108  $imageTransform = new Ego_Image();
109  try {
110  $imageTransform->load($data['file']);
111 
112  $copyright = $imageTransform->getExif(Ego_Image::EXIF_COPYRIGHT);
113  if (trim($copyright) != '') {
114  $data['copyright'] = $copyright;
115 
116  if (
117  $save
118  || $this->site->conf['admin']['mediapool']['upload_copyright']
119  ) {
120  $this->setInfo($dir, $data['name'], 'copyright', $copyright);
121  $save_copyright = true;
122  }
123  }
124  } catch (Ego_Image_Exception $e) {
125  // ignorieren
126  }
127  }
128  }
129 
130  if ($save_copyright) {
131  $this->page->extra['_asis'] = 3;
132  }
133 
134  if (!empty($source_extra)) {
135  foreach ($source_extra as $key => $value) {
136  $this->setInfo($dir, $name, $key, $value);
137  }
138  $this->page->extra['_asis'] = 5; // asis 5 = Extra Feld für Media kopiert
139  }
140 
141  $data['extra'] = $this->page->extra['mediapool'];
142  if ($save_copyright || !empty($source_extra)) {
143  $this->page->update(array(), true, true);
144  }
145 
146  $result = $data;
147  }
148  }
149 
150  $this->page->replicate('pool.put', "@file:$source", $name, $dir, $extract, $replace, $types, $save, $original);
151 
152  return $result;
153  }
154 
162  public function duplicate($name, $dir = '') {
163  $item = $this->get($name, $dir);
164  if (!empty($item)) {
165  return $this->put($item['file'], $name, $dir, false, false, '', true, true, $item['extra']);
166  }
167  return null;
168  }
169 
178  public function extract($name, $dir = '', &$files = []) {
179  if (!isset($GLOBALS['__egotec_skip_replication'])) {
180  $GLOBALS['__egotec_skip_replication'] = 'pool.extract';
181  }
182 
183  if ($original_page = $this->page->getCloneOriginal()) {
184  return $original_page->getMediapool()->extract($name, $dir);
185  }
186  $dir = $this->getDir($dir);
187  $path = $this->dir();
188  $file = $this->file($name, $dir);
189  if ($file) {
190  $tmp_file = tempnam($GLOBALS['egotec_conf']['tmp_dir'], 'ZIP_').'.zip';
191  if (Ego_System::copy($file, $tmp_file)) {
192  require_once('media/functions.php');
193  if (preg_match('/\.gz$/msi', $name)) {
194  require_once('Archive/Tar.php');
195  $zip = new Archive_Tar($tmp_file);
196  } else {
197  require_once('Archive/Zip.php');
198  $zip = new Archive_Zip($tmp_file);
199  }
200  $cwd = getcwd();
201  chdir($path.$dir);
202  @set_time_limit(0);
203  $list = $zip->extract();
204  @unlink($file);
205  @unlink($tmp_file);
206  chdir($cwd);
207  if (is_array($list)) {
208  $main_dir = '';
209  foreach ($list as $info) {
210  $info_dir = $path
211  .rtrim($dir, DIRECTORY_SEPARATOR)
212  .DIRECTORY_SEPARATOR.$info['stored_filename'];
213  if (!is_dir($info_dir)) {
214  if ($this->page->validateFile($info_dir)) {
215  $info_name = Ego_System::base64Encode(basename($info['stored_filename']));
216  @rename(
217  $info_dir,
218  $path
219  . rtrim($dir, DIRECTORY_SEPARATOR)
220  . DIRECTORY_SEPARATOR . $info_name
221  );
222 
223  // Alle Dateien im Archiv merken
224  $files[] = $this->get(basename($info['stored_filename']), $dir);
225  } else {
226  @unlink($info_dir);
227  }
228  } elseif ($main_dir == '' || strlen($info_dir) < strlen($main_dir)) {
229  $main_dir = $info_dir;
230  }
231  }
232  if ($main_dir != '') {
233  Ego_System::deldir($main_dir);
234  }
235 
236  $this->page->replicate("pool.extract", $name, $dir);
237 
238  return true;
239  } elseif ($list === true) {
240  // TODO Tar liefert keine Liste der entpackten Dateien
241  return true;
242  }
243  }
244  }
245 
246  return false;
247  }
248 
259  public function get($name, $dir = '', $params = array(), $decoded = false, $block = '') {
260  $dir = $this->getDir($dir);
261  $params['pool'] = $name;
262  $file = $this->file($name, $dir, $convert);
263  $name_key = md5(!empty($convert) ? $convert['name'] : $name);
264  $sub_dir = $this->subDir($dir);
265  if (!$file) {
266  if (!$decoded) {
267  // Fallback, falls der Name kodiert übergeben, aber nicht kodiert gespeichert wurde
268  return $this->get(urldecode($name), $dir, $params, true);
269  }
270  return array();
271  }
272 
273  $suffix = '';
274  if (preg_match('/\.([^\.]+)$/ims', $name, $match)) {
275  $suffix = strtolower($match[1]);
276  }
277 
278  // Mime-Type der Datei
279  require_once 'base/Ego_MimeType.php';
280  $mime = new Ego_MimeType();
281  $mime_type = !empty($convert)
282  ? $convert['mime']
283  : ($mime->byExtension($suffix) ?? $mime->autoDetect($file));
284 
285  if (
286  (!empty($suffix) && $ext = $suffix)
287  || ($ext = $mime->getExtension($mime_type))
288  ) {
289  $isImage = in_array($ext, Ego_System::getFormats('image'));
290  $isArchive = in_array($ext, Ego_System::getFormats('archive'));
291  $isVideo = in_array($ext, Ego_System::getFormats('video'));
292  }
293  $sub_data = array();
294 
295  $width = $height = null;
296  if ($info = Ego_System::getFileInfo($file)) {
297  $width = $info['width'];
298  $height = $info['height'];
299  if ($isImage) {
300  $params['width'] = $width ?: null;
301  $params['height'] = $height ?: null;
302  }
303  if (isset($info['duration'])) {
304  $sub_data['duration'] = $info['duration'];
305  }
306  }
307  if ((string) $dir != (string) $this->currentDir) {
308  $params['dir'] = $this->subDir($dir);
309  }
310  $params['site'] = $this->site->name;
311  $params['lang'] = $this->site->language;
312  $params['id'] = $this->page->field['id'];
313 
314  // Download URL ohne width und height
315  $download_params = $params;
316  $download_params['download'] = 1;
317  unset($download_params['width'], $download_params['height']);
318 
319  // Titel bestimmen
320  $title = empty($params['no_auto_title']) ? $name : '';
321  if ($extra_title = (string) ($this->page->extra['mediapool'][md5($sub_dir)][$name_key]['title'])) {
322  $title = $extra_title;
323  } elseif ($pos = strrpos($title, '.')) {
324  $title = substr($title, 0, $pos);
325  }
326 
327  // Zusätzliche Eigenschaften
328  $extra = array();
329  if ($block) {
330  $extra_key = 'block.' . $block;
331  } else {
332  $extra_key = ($sub = strrchr($dir, DIRECTORY_SEPARATOR)) ? substr($sub, 1) : 'default';
333  }
334  if ($this->page->conf['mediapool'][$extra_key]['extra']) {
335  foreach ($this->page->conf['mediapool'][$extra_key]['extra'] as $field) {
336  $extra[$field['name']] = $this->page->extra['mediapool'][md5($sub_dir)][$name_key][$field['name']];
337  }
338  }
339 
346  $get_url = function($params) {
347  unset($params['mime_type']);
348  return 'index.php?' . str_replace('%2F', '/', http_build_query($params));
349  };
350 
360  $isUsed = false;
361  if ($dir === '') {
362  $pattern = '/([.?*+^$[\]\\(){}|-])/';
363  $name1 = str_replace($pattern, '\\$1', $name);
364  $name2 = str_replace($pattern, '\\$1', str_replace('/%20/', '+', urlencode($name)));
365  $name3 = str_replace(['/\‍(/', '/\‍)/'], ['%28', '%29'], $name2); // TODO auch andere Zeichen als () berücksichtigen
366  $regex = '/([?&-]pool[=-]|\/_\/)('
367  . preg_quote($name1, '/')
368  . '|' . preg_quote($name2, '/')
369  . '|' . preg_quote($name3, '/')
370  . ')/';
371  foreach (['content', 'short', 'extra'] as $key) {
372  if (preg_match($regex, $this->page->field[$key])) {
373  $isUsed = true;
374  break;
375  }
376  }
377  }
378 
379  // Alle ignorierten Konvertierungen
380  $convert_ignore = array_filter(explode(',', (string) $this->page->extra['mediapool'][md5($sub_dir)][$name_key]['convert_ignore']));
381  sort($convert_ignore);
382 
383  // Alle verfügbaren Konvertierungen
384  if (!empty($params['get_formats']) && $isImage) {
385  unset($params['get_formats'], $download_params['get_formats']);
386  require_once 'base/Ego_Output.php';
387  $output = new Ego_Output($this->page, $name, $dir);
388  $sub_data['converted_files'] = array_filter($output->getConvertedImages(), function($file) use ($convert_ignore) {
389  return !in_array($file['format'], $convert_ignore);
390  });
391  $sub_data['converted_files'] = array_map(function($file) use (&$params, &$get_url) {
392  $file['url'] = $get_url(array_merge($params, ['suffix' => $file['format'], 'inactive' => 1, 'preview' => 1]));
393  return $file;
394  }, $sub_data['converted_files']);
395  }
396 
397  $data = array_merge(array(
398  'identity' => $this->page->getIdentity(),
399  'name' => $name,
400  'key' => md5($name),
401  'file' => $file,
402  'url' => $get_url($params),
403  'download' => $get_url($download_params),
404  'convert' => !empty($convert),
405  'size' => @filesize($file),
406  'mime' => $mime_type,
407  'width' => $width,
408  'height' => $height,
409  'suffix' => $suffix,
410  'isImage' => $isImage,
411  'isArchive' => $isArchive,
412  'isVideo' => $isVideo,
413  'isUsed' => $isUsed,
414  'lastChange' => @filemtime($file),
415  'title' => $title,
416  'description' => (string) $this->page->extra['mediapool'][md5($sub_dir)][$name_key]['description'],
417  'copyright' => (string) $this->page->extra['mediapool'][md5($sub_dir)][$name_key]['copyright'],
418  'order' => (int) $this->page->extra['mediapool'][md5($sub_dir)][$name_key]['order'],
419  'nav_hide' => (int) $this->page->extra['mediapool'][md5($sub_dir)][$name_key]['nav_hide'],
420  'clip' => $this->page->extra['mediapool'][md5($sub_dir)][$name_key]['clip'],
421  'rotation' => (int) $this->page->extra['mediapool'][md5($sub_dir)][$name_key]['rotation'],
422  'mirror' => (string) $this->page->extra['mediapool'][md5($sub_dir)][$name_key]['mirror'],
423  'grayscale' => (string) $this->page->extra['mediapool'][md5($sub_dir)][$name_key]['grayscale'],
424  'quarantine' => (bool) $this->page->extra['mediapool'][md5($sub_dir)][$name_key]['quarantine'],
425  'convertIgnore' => $convert_ignore,
426  'vtt' => $this->page->extra['mediapool'][md5($sub_dir)][$name_key]['vtt'],
427  'extra' => $extra,
428  'extra_key' => implode('.', ['mediapool', md5($sub_dir), $name_key])
429  ), $sub_data);
430  return $data;
431  }
432 
441  public function file($name, $dir = '', &$convert = []) {
442  $dir = $this->getDir($dir);
443  $file = $this->dir()
444  .rtrim($dir, DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR.Ego_System::base64Encode($name);
445  if (Ego_System::file_exists($file)) {
446  return $file;
447  } else {
448  // Abwärtskompatibilität zu alten base64 Strings
449  $file = $this->dir()
450  .rtrim($dir, DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR.base64_encode($name);
451  if (Ego_System::file_exists($file)) {
452  return $file;
453  }
454  }
455 
456  // Datei könnte eine dynamisch umwandelbare Datei sein
457  require_once 'base/Ego_Output.php';
458  foreach (Ego_Output::$convert_types as $type => $info) {
459  if (
460  ($matches = preg_split('/\.' . preg_quote($type, '/') . '$/i', $name, 2))
461  && sizeof($matches) > 1
462  ) {
463  $basename = preg_quote($matches[0], '/');
464  $convertable_file = $this->first('/^' . $basename . '\..*?$/', $dir, $found);
465  if ($convertable_file) {
466  $convert = [
467  'name' => $found,
468  'convert' => $type,
469  'mime' => $info['mime']
470  ];
471  }
472  return $convertable_file;
473  }
474  }
475 
476  return null;
477  }
478 
487  private function first($pattern, $dir = '', &$found = '') {
488  $dir = $this->getDir($dir);
489  $folder = $this->dir()
490  .rtrim($dir, DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR;
491  if (Ego_System::file_exists($folder)) {
492  $d = dir($folder);
493  $path = null;
494  while (($file = $d->read()) !== false) {
495  if (
496  preg_match($pattern, ($decoded = Ego_System::base64Decode($file)))
497  || preg_match($pattern, ($decoded = base64_decode($file)))
498  ) {
499  $found = $decoded;
500  $path = $folder.$file;
501  break;
502  }
503  }
504  $d->close();
505  return $path;
506  }
507  return null;
508  }
509 
517  public function delete($name, $dir = '', $replication = true) {
518  if (!isset($GLOBALS['__egotec_skip_replication'])) {
519  $GLOBALS['__egotec_skip_replication'] = 'pool.delete';
520  }
521 
522  if ($original_page = $this->page->getCloneOriginal()) {
523  return $original_page->getMediapool()->delete($name, $dir);
524  }
525  $dir = $this->getDir($dir);
526  $file = $this->dir()
527  .rtrim($dir, DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR.Ego_System::base64Encode($name);
528  if (!Ego_System::file_exists($file)) {
529  // Abwärtskompatibilität zu alten base64 Strings
530  $file = $this->dir()
531  .rtrim($dir, DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR.base64_encode($name);
532  }
533 
534  // Umgewandelte Dateien löschen
535  require_once 'base/Ego_Output.php';
536  $output = new Ego_Output($this->page, $name, $dir);
537  $output->clearConvertedImages();
538 
539  if (
540  (is_dir($file) && Ego_System::deldir($file))
541  || @unlink($file)
542  ) {
543  if ($dir == $this->currentDir) {
544  $this->page->update();
545  }
546 
547  if ($replication) {
548  $this->page->replicate("pool.delete", $name, $dir);
549  }
550 
551  return true;
552  }
553 
554  return false;
555  }
556 
565  public function edit($name, $params = array(), $dir = '') {
566  if (!isset($GLOBALS['__egotec_skip_replication'])) {
567  $GLOBALS['__egotec_skip_replication'] = 'pool.edit';
568  }
569 
570  if ($original_page = $this->page->getCloneOriginal()) {
571  return $original_page->getMediapool()->put($name, $params, $dir);
572  }
573  $dir = $this->getDir($dir);
574  $file = $params['new_file'] ?: $this->file($name, $dir);
575  $sub_dir = $this->subDir($dir);
576  $new_name = trim($params['new_name']);
577 
578  if (
579  !empty($file)
580  && !empty($new_name)
581  && $name != $new_name
582  && ($data = $this->put($file, $new_name, $dir, false, (bool) $params['replace']))
583  ) {
584  if ($this->delete($name, $dir, false)) {
585  // Alle Verweise auf den originalen Namen ändern
586  $this->page->field['content'] = $this->renameRecursive($name, $new_name, $this->page->field['content']);
587  $this->page->field['short'] = $this->renameRecursive($name, $new_name, $this->page->field['short']);
588  $this->page->extra = $this->renameRecursive($name, $new_name, $this->page->extra);
589  $this->page->extra['mediapool'][md5($sub_dir)][md5($new_name)] = $this->page->extra['mediapool'][md5($sub_dir)][md5($name)];
590  unset($this->page->extra['mediapool'][md5($sub_dir)][md5($name)]);
591  $name = $new_name;
592  } else {
593  // Änderungen zurücksetzen
594  $this->delete($new_name, $dir);
595  return false;
596  }
597  }
598  // Hinzufügen der Datei in das Extra-Feld der Seite
599  if (empty($this->page->extra['mediapool'][md5($sub_dir)][md5($name)])) {
600  $this->page->extra['mediapool'][md5($sub_dir)][md5($name)] = array();
601  }
602 
603  unset($params['new_name'], $params['replace']);
604  $this->page->extra['mediapool'][md5($sub_dir)][md5($name)] = array_merge($this->page->extra['mediapool'][md5($sub_dir)][md5($name)], $params);
605 
606  $this->page->replicate("pool.edit", $name, $params, $dir);
607 
608  $this->page->update(array(
609  'field' => array(
610  'content' => $this->page->field['content'],
611  'short' => $this->page->field['short']
612  ),
613  'extra' => $this->page->extra
614  ), true, true);
615 
616  return true;
617  }
618 
627  private function renameRecursive($name, $new_name, $value) {
628  if (is_array($value)) {
629  foreach ($value as $key => $v) {
630  $value[$key] = $this->renameRecursive($name, $new_name, $value[$key]);
631  }
632  } elseif (preg_match_all('/index\.php\?[^>"]+/ims', $value, $matches)) {
639  $encode = function($s) {
640  return str_replace(' ', '+', $s);
641  };
642  foreach ($matches[0] as $match) {
643  $new_url = preg_replace('/([&?])pool='.preg_quote($encode($name), '/').'/msi', '$1pool='.$encode($new_name), $match);
644  $value = str_replace($match, $new_url, $value);
645  }
646  }
647  return $value;
648  }
649 
671  public function list($dir = '', $params = array(), $block = '') {
672  $dir = $this->getDir($dir);
673  $list = array();
674  $path = $this->dir()
675  .rtrim($dir, DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR;
676  if (Ego_System::file_exists($path)) {
677  if ($handle = opendir($path)) {
678  $params2 = $params;
679  unset(
680  $params2['sort_field'],
681  $params2['sort_reverse'],
682  $params2['search'],
683  $params2['only_image']
684  );
685  while (false !== ($file = readdir($handle))) {
686  if ($file != '.' && $file != '..' && !is_dir($path.$file)) {
687  $data = $this->get(Ego_System::base64Decode($file), $dir, $params2, false, $block);
688  if (
689  !empty($data)
690  && (
691  (
692  !$params['only_image']
693  && !$_REQUEST['session']['insert_image']
694  )
695  || $data['isImage']
696  )
697  && (
698  (
699  !$params['only_video']
700  && !$_REQUEST['session']['insert_video']
701  )
702  || $data['isVideo']
703  )
704  && (
705  (
706  !$params['only_file']
707  && !$_REQUEST['session']['insert_file']
708  )
709  || !$data['isImage']
710  )
711  && (
712  (
713  !$params['only_media']
714  && !$_REQUEST['session']['insert_media']
715  )
716  || $data['isImage']
717  || $data['isVideo']
718  )
719  && (
720  empty($params['mime_type'])
721  || preg_match('#'.$params['mime_type'].'#i', $data['mime'])
722  )
723  && (
724  empty($params['search'])
725  || stripos($data['name'], $params['search']) !== false
726  || stripos($data['title'], $params['search']) !== false
727  )
728  ) {
729  if ($this->site->admin['mediapool']['video_compress'] && $data['mime'] === 'video/mp4') {
730  foreach (Ego_System::VIDEO_RESOLUTIONS as $height => $scale) {
731  $data['compressed_files'][str_replace(':', ' x ', $scale)] = $this->get("{$data['title']}_{$height}p.mp4", '_compress');
732  }
733  }
734 
735  $list[] = $data;
736  }
737  }
738  }
739  closedir($handle);
740  }
741  }
742  if (!empty($list)) {
743  $sort = array();
744  $names = array();
745  foreach ($list as $file) {
746  $sort_field = ($params['sort_field'] && isset($file[$params['sort_field']]))
747  ? $file[$params['sort_field']]
748  : $file['order'];
749  $sort[] = is_string($sort_field)
750  ? mb_strtolower($sort_field)
751  : $sort_field;
752  $names[] = mb_strtolower($file['name']);
753  }
754  if (!$params['sort_field'] && sizeof(array_unique($sort)) == 1) {
755  // Standardmäßig nach Namen sortieren
756  array_multisort(
757  $names,
758  $params['sort_reverse'] ? SORT_DESC : SORT_ASC,
759  SORT_STRING,
760  $list
761  );
762  } else {
763  // Individuelle Sortierung
764  array_multisort(
765  $sort,
766  $params['sort_reverse'] ? SORT_DESC : SORT_ASC,
767  is_string($sort_field) ? SORT_STRING : SORT_NUMERIC,
768  $list
769  );
770  }
771  }
772  if (isset($params['start'])) {
773  // Einen Teil ausgeben
774  $list = array_slice($list, $params['start'], $params['end']);
775  }
776  return $list;
777  }
778 
785  public function getDirs($archives = false) {
786  $dirs = [];
787 
788  foreach (glob($this->dir() . '*', GLOB_ONLYDIR) as $path) {
789  $dir = basename($path);
790  if ($dir == $this->currentDir) {
791  $dirs[] = '';
792  } elseif (!is_numeric($dir) || $archives) {
793  $dirs[] = $dir;
794  }
795  }
796 
797  return $dirs;
798  }
799 
809  public function setInfo($dir, $name, $key, $value = null) {
810  $sub_dir = $this->subDir($dir);
811  if ($value === null) {
812  unset($this->page->extra['mediapool'][md5($sub_dir)][md5($name)][$key]);
813  } else {
814  $this->page->extra['mediapool'][md5($sub_dir)][md5($name)][$key] = $value;
815  }
816  return implode('.', array('mediapool', md5($sub_dir), md5($name), $key));
817  }
818 
826  public function dir($relative = false, $source = null) {
827  if ($source) {
828  $site = $source->getSite();
829  $name = $site->name;
830  $lang = $site->language;
831  $id = $source->field['id'];
832  } else {
833  $name = $this->site->name;
834  $lang = $this->site->language;
835  $id = $this->page->field['id'];
836  }
837  return (!$relative ? $GLOBALS['egotec_conf']['var_dir'] : '').'media'.
838  DIRECTORY_SEPARATOR.$name.
839  DIRECTORY_SEPARATOR.$lang.
840  DIRECTORY_SEPARATOR. 'pool' .
841  DIRECTORY_SEPARATOR.$id.
842  DIRECTORY_SEPARATOR;
843  }
844 
851  private function subDir($dir) {
852  $sub_dir = '';
853  if ($dirs = explode(DIRECTORY_SEPARATOR, $dir)) {
854  if ($dirs[0] == $this->currentDir) {
855  unset($dirs[0]);
856  }
857  $sub_dir = implode(DIRECTORY_SEPARATOR, $dirs);
858  }
859  return $sub_dir;
860  }
861 
868  private function getDir($dir) {
869  if (is_numeric(explode(DIRECTORY_SEPARATOR, $dir)[0])) {
870  // Archive sind niemals Unterverzeichnisse
871  return $dir;
872  } elseif (empty($dir) || $dir == $this->currentDir) {
873  // Standard Verzeichnis
874  return $this->currentDir;
875  }
876  // Unterverzeichnis
877  return $this->currentDir . DIRECTORY_SEPARATOR . $this->subDir($dir);
878  }
879 
887  public function archive($c_date, $dir = '') {
888  if ($original_page = $this->page->getCloneOriginal()) {
889  return $original_page->getMediapool()->archive($c_date, $dir);
890  }
891  $dir = $this->getDir($dir);
892  $path = $this->dir();
893  if (Ego_System::file_exists($path)) {
894  $src = $path.rtrim($dir, DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR;
895  $dest = $path.($dir != $this->currentDir ? $dir : '')
896  .Ego_System::dateEncode($c_date).DIRECTORY_SEPARATOR;
897  Ego_System::deldir($dest); // Archiv vorher löschen, falls es bereits existiert
898  return Ego_System::copy($src, $dest, '', true); // Kopie mit hard links
899  }
900  return false;
901  }
902 
911  public function restore($c_date, $name = '', $dir = '') {
912  if (!isset($GLOBALS['__egotec_skip_replication'])) {
913  $GLOBALS['__egotec_skip_replication'] = 'pool.restore';
914  }
915 
916  if ($original_page = $this->page->getCloneOriginal()) {
917  return $original_page->restore($c_date, $name, $dir);
918  }
919  if (!empty($c_date)) {
920  $dir = $this->getDir($dir);
921  if (empty($name)) {
922  // Gesamten Mediapool wiederherstellen
923  $dest = $this->dir()
924  .rtrim($dir, DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR;
925  $source = $this->dir().$c_date.DIRECTORY_SEPARATOR;
926  if (
927  Ego_System::file_exists($source)
928  && Ego_System::file_exists($dest)
929  ) {
930  $archive_page = $this->page->getArchivePage(is_numeric($c_date) ? date('Y-m-d H:i:s', $c_date) : $c_date);
931  $mediapool = $archive_page ? $archive_page->extra['mediapool'] : array();
932  $this->clear($dir, $mediapool);
933 
934  $this->page->replicate("pool.restore", $c_date, $name, $dir);
935 
936  return Ego_System::copy($source, $dest, '', false, false, true);
937  }
938  } else {
939  // Eine Datei im Mediapool wiederherstellen
940  $path = $dir == $this->currentDir
941  ? $c_date
942  : rtrim($dir, DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR.$c_date;
943  $source = $this->get($name, $path);
944 
945  $this->page->replicate("pool.restore", $c_date, $name, $dir);
946 
947  return (bool) $this->put($source['file'], $name, $dir);
948  }
949  }
950 
951  return false;
952  }
953 
959  private function create() {
960  $dir = $this->dir();
961  if (!Ego_System::file_exists($dir)) {
962  Ego_System::mkdir($dir);
963  }
964  }
965 
980  public function copy(Page $target, $dir = '', $clear = false, $integrate = false, $archive = true, $asis = true, $specific_sub_dir = false, $rename = '', $matrix = true) {
981  if (!isset($GLOBALS['__egotec_skip_replication'])) {
982  $GLOBALS['__egotec_skip_replication'] = 'pool.copy';
983  }
984 
985  $path = $this->dir();
986 
987  // Wenn ein bestimmter Unterordner selektiert werden soll, muss man noch das currentDir ergänzen damit der Pfad stimmt
988  if ($specific_sub_dir) {
989  $path .= $this->currentDir.DIRECTORY_SEPARATOR;
990  }
991 
992  if (!empty($dir)) {
993  $path .= rtrim($dir, DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR;
994  }
995 
996  if (Ego_System::file_exists($path)) {
997  // Original kopieren
998  $dest = $this->dir(false, $target);
999 
1000  // Wenn ein bestimmter Unterordner selektiert werden soll, muss man noch das currentDir ergänzen damit der Pfad stimmt
1001  if ($specific_sub_dir) {
1002  $dest .= $this->currentDir.DIRECTORY_SEPARATOR;
1003  }
1004 
1005  if (!empty($dir)) {
1006  $dest .= rtrim($rename ?: $dir, DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR;
1007  }
1008 
1009  if (!$integrate && $this->page->getIdentity() != $target->getIdentity()) {
1010  Ego_System::deldir($dest);
1011  }
1012 
1013  $this->page->replicate("pool.copy", $target, $dir, $clear, $integrate, $archive, $asis);
1014 
1015  Ego_System::copy($path, $dest, ($archive ? '' : '/^\d+$/'), true); // Hard Links erstellen
1016 
1017  // Verweise anpassen
1018  $target->getMediapool()->import(true, true, $dir, true, $asis, $rename, $matrix);
1019 
1020  /* Wichtig: Nur wenn die Sprachmatrix berücksichtigt wird!
1021  * Andernfalls wurde die Sprachmatrix bereits vorher berücksichtigt und die Mediapool Informationen (ggf. übersetzt) kopiert
1022  * @see Page._update */
1023  if ($matrix) {
1024  if (!empty($dir)) {
1025  $target->extra['mediapool'][md5($dir)] = $this->page->extra['mediapool'][md5($dir)];
1026  } else {
1027  $target->extra['mediapool'] = $this->page->extra['mediapool'];
1028  }
1029  $target->extra['_asis'] = 5;
1030  $target->update(array(), $matrix, true);
1031  }
1032 
1033  // Original löschen
1034  if ($clear) {
1035  $this->clear($dir);
1036  }
1037  }
1038  }
1039 
1049  public function move($target, $dir = '', $integrate = false, $archive = true) {
1050  if (!isset($GLOBALS['__egotec_skip_replication'])) {
1051  $GLOBALS['__egotec_skip_replication'] = 'pool.move';
1052  }
1053 
1054  $this->copy($target, $dir, true, $integrate, $archive);
1055 
1056  $this->page->replicate("pool.move", $target, $dir, $integrate, $archive);
1057  }
1058 
1066  public function exists($dir = '', $empty = true) {
1067  $dir = $this->getDir($dir);
1068  $path = $this->dir()
1069  .rtrim($dir, DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR;
1070  return Ego_System::file_exists($path) && ($empty || sizeof(is_array($scanned_dir = scandir($path)) ? $scanned_dir : []) > 2);
1071  }
1072 
1081  public function clear($dir = '', $mediapool = array(), $update = true) {
1082  if (!isset($GLOBALS['__egotec_skip_replication'])) {
1083  $GLOBALS['__egotec_skip_replication'] = 'pool.clear';
1084  }
1085 
1086  if ($original_page = $this->page->getCloneOriginal()) {
1087  return $original_page->getMediapool()->clear($dir);
1088  }
1089  $path = $this->dir();
1090  if (!empty($dir)) {
1091  $path .= rtrim($dir, DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR;
1092  }
1093  $sub_dir = $this->subDir($dir);
1094 
1095  // Zusätzliche Informationen zu diesem Mediapool löschen/setzen
1096  if (!empty($mediapool)) {
1097  $this->page->extra['mediapool'] = $mediapool;
1098  } else {
1099  unset($this->page->extra['mediapool'][md5($sub_dir)]);
1100  }
1101  if ($update) {
1102  $this->page->update(array(), true, true);
1103  }
1104 
1105  $this->page->replicate("pool.clear", $dir, $mediapool, $update);
1106 
1107  Ego_System::deldir($path);
1108  }
1109 
1122  public function import($only_pool = false, $replace = false, $dir = '', $update = true, $asis = true, $rename = '', $matrix = true) {
1123  $this->page->field['content'] = $this->importRecursive($this->page->field['content'], $only_pool, $replace, $dir, $rename);
1124  $this->page->field['short'] = $this->importRecursive($this->page->field['short'], $only_pool, $replace, $dir, $rename);
1125  $this->page->extra = $this->importRecursive($this->page->extra, $only_pool, $replace, $dir, $rename);
1126  if ($update) {
1127  $this->page->update(array(
1128  'field' => array(
1129  'content' => $this->page->field['content'],
1130  'short' => $this->page->field['short']
1131  ),
1132  'extra' => $this->page->extra
1133  ), $matrix, $asis);
1134  }
1135  }
1136 
1148  private function importRecursive($value, $only_pool = false, $replace = false, $dir = '', $rename = '') {
1149  if (is_array($value)) {
1150  foreach ($value as $key => $v) {
1151  $value[$key] = $this->importRecursive($v, $only_pool, $replace, $dir, $rename);
1152  }
1153  } elseif (preg_match_all('/index\.php\?[^>"\\\]+/ims', $value, $matches)) {
1154  $dir = $dir == '' ? '' : rtrim($dir, DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR;
1155  foreach ($matches[0] as $url) {
1156  $page = Ego_System::urltopage($url, array(
1157  'params' => array(
1158  'param' => array(
1159  'auth_or' => '1=1',
1160  'deleted_or' => '1=1',
1161  'inactive' => true,
1162  'only_active' => false
1163  )
1164  )
1165  ));
1166  $info = Ego_System::getUrlInfo($url);
1167  if ($page) {
1168  if (
1169  !$only_pool
1170  && in_array($page->field['type'], array('multimedia/file', 'multimedia/image'))
1171  ) {
1172  // Multimedia
1173  $site = $page->getSite();
1174  $path = $GLOBALS['egotec_conf']['var_dir'].'media/'.$site->name.'/';
1175  $file = $path.$page->getMediaFilename();
1176  if (Ego_System::file_exists($file)) {
1177  $name = $page->field['name'];
1178  $suffix = '';
1179  if ($page->extra['image_type']) {
1180  $suffix = '.'.$page->extra['image_type'];
1181  }
1182  if (!$replace) {
1183  while ($this->file($name.$suffix, $dir)) {
1184  // Eine Datei mit dem selben Namen existiert bereits
1185  if (preg_match('/_(\d+)$/ims', $name, $match)) {
1186  $num = ((int) $match[1]) + 1;
1187  $name = preg_replace('/_\d+$/ims', '', $name);
1188  } else {
1189  $num = 1;
1190  }
1191  $name .= '_'.$num;
1192  }
1193  }
1194  $media = $this->put($file, $name.$suffix, $rename ?: $dir);
1195  if (!empty($media['url'])) {
1196  $value = str_replace($url, $media['url'], $value);
1197  }
1198  }
1199  } elseif (!empty($info['params']['pool'])) {
1200  // Mediapool
1201  $media = $page->getMediapool()->get(urldecode($info['params']['pool']), $dir);
1202  if ($media['file']) {
1203  $media = $this->put(
1204  $media['file'],
1205  $media['name'],
1206  $rename ?: $dir,
1207  false,
1208  $replace,
1209  '',
1210  true,
1211  !$this->page->isClone() // Beim Import in einen Klon, werden die Mediapool URLs auf den Klon umgeschrieben
1212  );
1213  }
1214  if (!empty($media['url'])) {
1215  $value = str_replace($url, $media['url'] . (!empty($info['params']['clip']) ? "&clip=" . $info['params']['clip'] : ""), $value);
1216  }
1217  }
1218  }
1219  }
1220  }
1221  return $value;
1222  }
1223 
1229  public function getQuarantine() {
1230  $files = [];
1231 
1232  if (is_array($this->page->extra['mediapool'])) {
1233  $recursive = function($dir, $sub = '') use (&$recursive, &$files) {
1234  $d = @dir($dir);
1235  if ($d !== false) {
1236  while (($entry = $d->read()) !== false) {
1237  if ($entry[0] != '.' && $entry == 'current') {
1238  $sub_dir = rtrim($dir) . DIRECTORY_SEPARATOR . $entry;
1239  if (is_dir($sub_dir)) {
1240  $recursive($sub_dir, ($sub ? $sub . DIRECTORY_SEPARATOR : '') . $entry);
1241  } else {
1242  $info = $this->get(Ego_System::base64Decode($entry), $sub);
1243  if ($info && $info['quarantine']) {
1244  $files[] = ($sub ? $sub . DIRECTORY_SEPARATOR : '') . basename($info['file']);
1245  }
1246  }
1247  }
1248  }
1249  $d->close();
1250  }
1251  };
1252  $recursive($this->dir());
1253  }
1254 
1255  return $files;
1256  }
1257 
1263  public function getPage() {
1264  return $this->page;
1265  }
1266 
1272  public function getSite() {
1273  return $this->site;
1274  }
1275 }
const EXIF_COPYRIGHT
Definition: Ego_Image.php:24
static $convert_types
Definition: Ego_Output.php:146
static urltopage($url, $params=array(), $only_site=false, $error_page=false, $commit_params=false)
static getFormats($type)
static deldir($location, $del=true, $without='', $rename=true)
Definition: Ego_System.php:803
static base64Encode($s)
static dateEncode($string)
Definition: Ego_System.php:651
static getFileInfo($file)
static base64Decode($s)
static getUrlInfo($url, $encode=false)
static file_exists($file)
static mkdir($dir, $mode=0755, $recursive=true)
Definition: Ego_System.php:669
const VIDEO_RESOLUTIONS
Definition: Ego_System.php:33
static copy($src, $dest, $except='', $useLinks=false, $noArchive=false, $preserveDate=false)
restore($c_date, $name='', $dir='')
Definition: Mediapool.php:911
clear($dir='', $mediapool=array(), $update=true)
Definition: Mediapool.php:1081
edit($name, $params=array(), $dir='')
Definition: Mediapool.php:565
__construct(Page $page)
Definition: Mediapool.php:24
duplicate($name, $dir='')
Definition: Mediapool.php:162
exists($dir='', $empty=true)
Definition: Mediapool.php:1066
copy(Page $target, $dir='', $clear=false, $integrate=false, $archive=true, $asis=true, $specific_sub_dir=false, $rename='', $matrix=true)
Definition: Mediapool.php:980
list($dir='', $params=array(), $block='')
Definition: Mediapool.php:671
setInfo($dir, $name, $key, $value=null)
Definition: Mediapool.php:809
archive($c_date, $dir='')
Definition: Mediapool.php:887
getDirs($archives=false)
Definition: Mediapool.php:785
move($target, $dir='', $integrate=false, $archive=true)
Definition: Mediapool.php:1049
put($source, $name, $dir='', $extract=false, $replace=true, $types='', $save=true, $original=true, $source_extra=array(), &$files=array())
Definition: Mediapool.php:46
dir($relative=false, $source=null)
Definition: Mediapool.php:826
file($name, $dir='', &$convert=[])
Definition: Mediapool.php:441
extract($name, $dir='', &$files=[])
Definition: Mediapool.php:178
Definition: Page.php:28
getSite()
Definition: Page.php:5374
getMediapool()
Definition: Page.php:5383
getIdentity()
Definition: Page.php:11918
update($param=array(), $matrix_flag=true, $asis=false, $silent=false)
Definition: Page.php:4124