EGOCMS  24.0
EGOTEC Content-Managament-System
Site.php
gehe zur Dokumentation dieser Datei
1 <?php
5 require_once('base/functions.php');
6 
10 class Site_Exception extends Exception
11 {
12  const SITE_DOESNT_EXIST = 1;
13  const LANG_DOESNT_EXIST = 2;
14  const LANG_NOT_DELETABLE = 3;
15  const MISSING_TEMPLATE = 4;
16 }
17 
29 class Site
30 {
31  private $_isDefault;
33  private $_onlyActive;
34  private $_time;
35  private $_types;
36  private $_typesFlat;
37  private $_param = array();
38  private $_cachedMetaUrls = array();
39  private $_cache;
40  private $_languages;
41  private $_classes = array();
42  private $_root;
44  public $name;
45  public $site;
46  public $admin;
47  public $global = null;
48  public $language;
49  public $pageTable;
50  public $skin = '';
51  public $theme = '';
52  public $rootId = 1;
53  public $importFlag = false;
55  public $conf = array();
57  private $virtualHosts = array();
59  private $mediaSites = array();
60  private $dataSites = array();
62  private static $confs = array();
71  public function __call($function, $params) {
72  if (strpos($function, '__') !== 0) {
73  $magic_file = $GLOBALS['egotec_conf']['lib_dir'].'base/'.get_class($this).'.'.$function.'.php';
74  if (file_exists($magic_file)) {
75  require_once($magic_file);
76  return call_user_func($function, $this, $params);
77  } else {
78  throw new Exception("Method 'Site.$function' not found");
79  }
80  }
81  }
82 
90  private function _loadConfig($recalc = false) {
91  if (!$recalc && $this->pageTable && isset(self::$confs[$this->pageTable])) {
92  // Zwischengespeicherte Site Konfiguration verwenden
93  $this->conf = self::$confs[$this->pageTable];
94  } else {
95  $this->conf = array();
96 
97  // Standard Mandanten Einstellungen laden
98  $this->conf = Ego_System::getJSON($GLOBALS['egotec_conf']['lib_dir'] . '/admin/conf.json', $this->conf, true);
99 
100  // Mandanten spezifische Einstellungen laden
101  if (Ego_System::file_exists($conf = $GLOBALS['egotec_conf']['site_dir'] . $this->name . '/admin/conf.json')) {
102  $this->conf = Ego_System::getJSON($conf, $this->conf, true, ['plugins', 'toolbar', 'menubar']);
103  }
104 
105  if (empty($this->conf['site'])) {
106  // Abwärtskompatibilität: site Konfiguration aus conf.ini laden
107  if (Ego_System::file_exists($GLOBALS['egotec_conf']['site_dir'] . $this->name . '/conf.ini')) {
108  $this->conf['site'] = parse_ini_file($GLOBALS['egotec_conf']['site_dir'] . $this->name . '/conf.ini', true);
109  } else {
110  throw new Site_Exception("Site '$this->name' doesn't exist.", Site_Exception::SITE_DOESNT_EXIST);
111  }
112  }
113 
114  // Verwendete Sprache erkennen (wenn vorher kein setLanguage() stattgefunden hat, ist diese erst jetzt bekannt)
115  if (!$this->language) {
116  $this->language = $this->conf['site']['default_language'];
117  }
118  $this->pageTable = $this->name.'_'.$this->language;
119 
120  if (!$recalc && isset(self::$confs[$this->pageTable])) {
121  // Sollte eine zwischengespeicherte Site Konfiguration nun gefunden werden können, dann diese verwenden
122  $this->conf = self::$confs[$this->pageTable];
123  } else {
124  // ...ansonsten weitere Konfigurationen laden
125 
126  // Globale Einstellungen laden (werden nachträglich mit den site Einstellungen zusammengeführt, überschreiben diese aber nicht)
127  if ($this->globalAllowed() && Ego_System::file_exists($conf = $GLOBALS['egotec_conf']['site_dir'] . '_global/admin/conf.json')) {
128  $this->conf = Ego_System::getJSON($conf, $this->conf, true, ['plugins', 'toolbar', 'menubar'], false);
129  }
130 
131  if (empty($this->conf['admin'])) {
132  // Abwärtskompatibilität: admin Konfiguration aus conf.ini laden
133  if (Ego_System::file_exists($GLOBALS['egotec_conf']['site_dir'] . $this->name . '/admin/conf.ini')) {
134  $this->conf['admin'] = parse_ini_file($GLOBALS['egotec_conf']['site_dir'] . $this->name . '/admin/conf.ini', true);
135  } else {
136  throw new Site_Exception("Site '$this->name' doesn't exist.", Site_Exception::SITE_DOESNT_EXIST);
137  }
138  }
139 
140  $allowed_conf_keys = array('panel', 'navigation', 'layouts', 'blocks', 'page', 'notification');
141 
142  // Einstellungen der Designvorlage übernehmen
143  if (!empty($this->conf['site']['theme'])) {
144  $theme_paths = array(
145  $GLOBALS['egotec_conf']['pub_dir'] . 'theme/' . $this->conf['site']['theme'] . '/site/admin/conf.json',
146  $this->globalAllowed() ? $GLOBALS['egotec_conf']['site_dir'] . '_global/admin/' . $this->conf['site']['theme'] . '.json' : ''
147  );
148  foreach ($theme_paths as $theme_path) {
149  if ($theme_path && Ego_System::file_exists($theme_path)) {
150  $theme_conf = Ego_System::getJSON($theme_path);
151  foreach ($allowed_conf_keys as $key) {
152  if (!empty($theme_conf[$key])) {
153  if (empty($this->conf[$key])) {
154  $this->conf[$key] = array();
155  }
156  $this->conf[$key] = array_replace_recursive($theme_conf[$key], $this->conf[$key]);
157  }
158  }
159  }
160  }
161  }
162 
163  // Einstellungen des Systems übernehmen
164  if (Ego_System::file_exists($system_path = $GLOBALS['egotec_conf']['var_dir'] . 'lib/admin/conf.json')) {
165  $system_conf = Ego_System::getJSON($system_path);
166  foreach ($allowed_conf_keys as $key) {
167  if (!empty($system_conf[$key])) {
168  if (empty($this->conf[$key])) {
169  $this->conf[$key] = array();
170  }
171  $this->conf[$key] = array_replace_recursive($system_conf[$key], $this->conf[$key]);
172  }
173  }
174  }
175 
176  // Die Meta Daten werden nach Sprache gesetzt (abwärtskompatibel)
177  $this->conf['site']['robots'] = $this->conf['site']['robots_' . $this->language] ?
178  $this->conf['site']['robots_' . $this->language] : ($this->conf['site']['robots_' . $this->conf['site']['default_language']] ?
179  $this->conf['site']['robots_' . $this->conf['site']['default_language']] :
180  $this->conf['site']['robots']);
181  $this->conf['site']['keywords'] = $this->conf['site']['keywords_' . $this->language] ?
182  $this->conf['site']['keywords_' . $this->language] : ($this->conf['site']['keywords_' . $this->conf['site']['default_language']] ?
183  $this->conf['site']['keywords_' . $this->conf['site']['default_language']] :
184  $this->conf['site']['keywords']);
185  $this->conf['site']['description'] = $this->conf['site']['description_' . $this->language] ?
186  $this->conf['site']['description_' . $this->language] : ($this->conf['site']['description_' . $this->conf['site']['default_language']] ?
187  $this->conf['site']['description_' . $this->conf['site']['default_language']] :
188  $this->conf['site']['description']);
189 
190  // Bei Multimedia-Seiten immer die Multimediatypen aktivieren
191  if ($this->conf['site']['type'] == 'media') {
192  $this->conf['admin']['enabled_types']['multimedia'] = 1;
193  $this->conf['admin']['enabled_types']['multimedia/image'] = 1;
194  $this->conf['admin']['enabled_types']['multimedia/file'] = 1;
195  $this->conf['admin']['enabled_types']['multimedia/category'] = 1;
196  }
197 
198  // Bezeichnung bestimmen
199  if (!empty($this->conf['site']['title_' . $this->language])) {
200  $this->conf['site']['title'] = $this->conf['site']['title_' . $this->language];
201  } elseif (!empty($this->conf['site']['title_' . $this->conf['site']['default_language']])) {
202  $this->conf['site']['title'] = $this->conf['site']['title_' . $this->conf['site']['default_language']];
203  } elseif (empty($this->conf['site']['title'])) {
204  // Abwärtskompatibilität: Fallback auf Name wenn keine Bezeichnung existiert
205  $this->conf['site']['title'] = $this->name;
206  }
207 
211  self::$confs[$this->pageTable] = &$this->conf;
212  }
213  }
214 
215  // Globale Konfigurationen laden
216  $this->loadGlobalConfig();
217 
218  // Abwärtskompatibilität: site und admin als Referenz setzen
219  $this->site = &$this->conf['site'];
220  $this->admin = &$this->conf['admin'];
221  }
222 
234  static function createSite($new_site) {
235  Ego_System::mkdir($GLOBALS['egotec_conf']['site_dir'] . $new_site['name']);
236 
237  if ($new_site['type']=='media') {
238  Ego_System::mkdir($GLOBALS['egotec_conf']['var_dir'] . 'media/' . $new_site['name']);
239  }
240 
241  if (!empty($new_site['default_skin'])) {
242  $skin_dir = $GLOBALS['egotec_conf']['skin_dir'] . $new_site['default_skin'];
243 
244  if (!Ego_System::file_exists($skin_dir)) {
245  Ego_System::mkdir($skin_dir);
246  }
247  }
248 
250  copy($GLOBALS['egotec_conf']['lib_dir'] . 'template/site/conf.ini', $GLOBALS['egotec_conf']['site_dir'] . $new_site['name'] . '/conf.ini');
251  Ego_System::mkdir($GLOBALS['egotec_conf']['site_dir'] . $new_site['name'] . '/admin');
252  copy($GLOBALS['egotec_conf']['lib_dir'] . 'template/site/admin/conf.ini', $GLOBALS['egotec_conf']['site_dir'] . $new_site['name'] . '/admin/conf.ini');
253 
254  $newSite = new Site($new_site['name']);
255 
256  if ($new_site['lang']) {
257  $new_site['default_language'] = $new_site['lang'];
258  $new_site['languages'] = $new_site['lang'];
259  }
260 
261  // Die Mandantenbezeichnung wird der Standardsprache zugeordnet
262  if ($new_site['title'] && $new_site['default_language']) {
263  $new_site['title_' . $new_site['default_language']] = $new_site['title'];
264  unset($new_site['title']);
265  }
266 
267  $rights = $new_site['rights'];
268  unset($new_site['name'], $new_site['lang'], $new_site['rights']);
269 
270  $newSite->save($new_site);
271  $newSite->createTables();
272 
273  require_once 'base/Ego_Search_Factory.php'; // Den Suchindex initialisieren.
274 
275  $search = Ego_Search_Factory::start($newSite->pageTable);
276  $search->reset();
277 
278  $date = date('Y-m-d H:i:s');
279  $field = [
280  'id' => 1,
281  'name' => 'Homepage',
282  'title' => 'Homepage',
283  'url' => '',
284  'short' => '',
285  'content' => 'This is the Homepage of a new site.',
286  'extra' => serialize([]),
287  'a_date' => $date,
288  'c_date' => $date,
289  'm_date' => $date,
290  'a_user' => $GLOBALS['auth']->getId(),
291  'c_user' => $GLOBALS['auth']->getId(),
292  'm_user' => $GLOBALS['auth']->getId(),
293  'type' => $new_site['type'] == 'media' ? 'multimedia/category' : ($new_site['type'] == 'data' ? 'data' : 'page'),
294  'children_order' => 'type',
295  'order_field' => 0,
296  'nav_hide' => 0,
297  'inactive' => 0,
298  'cache' => 7,
299  'release_from' => '0000-00-00 00:00:00',
300  'release_until' => '0000-00-00 00:00:00',
301  'workflow' => '',
302  'workflow_state' => 0,
303  'deleted' => 0
304  ];
305  $db = new_db_connection();
306  $no_null_rights = trim(Auth::NO_NULL_RIGHTS, ',');
307  $no_null_rights = explode(',', $no_null_rights);
308  $insert_rights = [
309  'set' => [
310  'page_id' => 1,
311  'group_id' => '*',
312  'role_id' => '*'
313  ]
314  ];
315 
316  foreach ($newSite->getLanguages() as $lang) {
317  $db->insert(['table' => $newSite->name . '_' . $lang, 'set' => $field]);
318  $insert_rights['table'] = $newSite->name . '_' . $lang . '_rights';
319 
320  foreach ($no_null_rights as $no_null_right) {
321  if ($no_null_right != 'live') {
322  $insert_rights['set']['perm'] = $no_null_right;
323  $db->insert($insert_rights);
324  }
325  }
326  }
327 
328  /* Typenverwaltung setzen - #36701 */
329  if ($newSite->site['type'] == 'media') {
330  $newSite->save_admin([
331  'enabled_types' => [
332  'multimedia' => 1,
333  'multimedia/image' => 1,
334  'multimedia/file' => 1,
335  'multimedia/category' => 1
336  ]
337  ]);
338  } elseif($newSite->site['type'] == 'data') {
339  $newSite->save_admin([
340  'enabled_types' => [
341  'data' => 1,
342  'data/address' => 1,
343  'data/address/authority' => 1,
344  'data/address/building' => 1,
345  'data/address/department' => 1,
346  'data/address/person' => 1,
347  'data/events' => 1,
348  'data/events/organizer' => 1,
349  'data/events/venue' => 1,
350  'data/list' => 1,
351  ]
352  ]);
353  } else {
354  $newSite->save_admin([
355  'enabled_types' => [
356  'page' => 1
357  ]
358  ]);
359  }
360 
361  /* Bei neuen Mandanten gleich Rechte setzen - #66260 und #100979 */
362  $default_group = is_array($rights) && $rights['group'] ? $rights['group'] : $GLOBALS['egotec_conf']['superuser']['group'];
363  $default_role = is_array($rights) && $rights['role'] ? $rights['role'] : $GLOBALS['egotec_conf']['superuser']['role'];
364 
365  $right = $newSite->site['right'];
366 
367  foreach (['admin', 'translate', 'view', 'linkto', 'addclone', 'newclone', 'trashcan', 'stats', 'liveserver', 'site', 'skin', 'change_type', 'linkchecker', 'nousechecker', 'barriercheck'] as $type) {
368  $right["{$type}_group_0"] = $default_group;
369  $right["{$type}_role_0"] = $default_role;
370  }
371 
372  $newSite->save_admin([
373  'right' => $right
374  ]);
375 
376  // Konfiguration aus dem internen Cache entfernen, da diese bereits geändert wurde, und neu laden
377  self::$confs[$newSite->pageTable];
378  $newSite = new Site($newSite->name);
379 
380  // Frontend Administration aktivieren, wenn es ein Layout gibt
381  if ($newSite->getSkinFile('layout.tpl') || $newSite->getSkinFile('layout.html')) {
382  $newSite->save_admin([
383  'frontend_admin' => 1
384  ]);
385  }
386 
387  // Allgemeine Cache löschen
388  $cache = Ego_System::getCache();
389  $cache->reset();
390 
391  return $newSite;
392  }
393 
433  function __construct($site_name = '', $language = '', $skin = '', $only_active = true, $time = '', $recalc = false)
434  {
435  $this->_onlyActive = $only_active;
436  if ($_REQUEST['preview'] && $GLOBALS['auth'] && !$GLOBALS['auth']->isNobody()) {
437  $this->_onlyActive = false;
438  }
439 
440  $site_name = str_replace('/', '', $site_name); // #197684
441  if (!file_exists($GLOBALS['egotec_conf']['site_dir'].$site_name))
442  {
443  throw new Site_Exception("Site '$site_name' doesn't exist.", Site_Exception::SITE_DOESNT_EXIST);
444  }
445  if ($site_name=='')
446  { // Wenn keine Site übergeben wurde,
447  $this->_isDefault = true;
449  $site_name = $GLOBALS['egotec_conf']['default_site'];
450  }
451  $this->name = $site_name;
452  $this->_loadConfig($recalc);
453  if ($skin && in_array($skin, $this->getSkins()))
454  {
455  $this->skin = $skin;
456  } else {
457  $this->skin = $this->site['default_skin'];
458  }
459  $this->theme = (string) $this->site['theme'];
460  $this->setLanguage($language);
461  if ($GLOBALS['virtual_host_site'] && $GLOBALS['virtual_host_lang'] && $GLOBALS['virtual_host_site']==$this->name)
462  { // Falls ein virtueller Host eingetragen ist,
463  $this->site['default_language'] = $GLOBALS['virtual_host_lang'];
464  }
465  $this->setTime($time);
466 
467  /* Wenn diese Site keine Multimedia Site ist
468  * oder keine Multimedia Site zugewiesen hat,
469  * dann muss der Mediapool aktiviert sein. */
470  if (
471  !$this->hasMediaSite()
472  && !$this->admin['mediapool']['active']
473  ) {
474  $this->save_admin(array(
475  'mediapool' => array(
476  'active' => 1
477  )
478  ));
479  }
480  }
481 
488  public function setOnlyActive($b) {
489  $this->_onlyActive = $b;
490  }
491 
502  function setTime($time='')
503  {
504  if ($time)
505  {
506  $this->_time = $time;
507  } else {
508  $expire_time = $this->_cache->getExpire();
509  $this->_time = date('Y-m-d H:i:s', (int)($expire_time ? $expire_time : time()));
510  }
511  }
512 
519  function setLanguage($language='')
520  {
521  // Alle zwischengespeicherten virtuellen Hosts leeren
522  $this->virtualHosts = array();
523 
524  if ($language=='')
525  {
526  $language = $this->site['default_language'];
527  }
528  if (in_array($language, $this->getLanguages()))
529  { // Die Sprache nur setzen, wenn Sie in der Site vorhanden ist.
530  $new_page_table = $this->name.'_'.$language;
531  if ($this->_param['auth_or'])
532  { // Tabellenverweise anpassen.
533  $this->_param['auth_or'] = str_replace($this->pageTable, $new_page_table, $this->_param['auth_or']);
534  }
535  if ($this->_param['deleted_or'])
536  { // Tabellenverweise anpassen.
537  $this->_param['deleted_or'] = str_replace($this->pageTable, $new_page_table, $this->_param['deleted_or']);
538  }
539  $this->language = $language;
540  $this->pageTable = $new_page_table; // Der Name der Seitentabelle setzt sich aus dem Namen der Site und dem Sprachkürzel zusammen.
541  } else {
542  $this->language = $this->site['default_language'];
543  $this->pageTable = $this->name.'_'.$this->site['default_language']; // Der Name der Seitentabelle setzt sich aus dem Namen der Site und dem Sprachkürzel zusammen.
544  throw new Site_Exception('Die Sprache existiert nicht', Site_Exception::LANG_DOESNT_EXIST );
545  }
546 
547  // Cache erzeugen.
548  $path = $this->name.'/'.$this->language.'/';
549  if ($this->_cache)
550  {
551  $this->_cache->setPath($this->name.'/'.$this->language.'/');
552  } else {
553 
554  if (empty($GLOBALS["egotec_conf"]["cachemedia_dir"])) {
555  $GLOBALS["egotec_conf"]["cachemedia_dir"] = $GLOBALS["egotec_conf"]["var_dir"]."cachemedia/";
556  }
557 
558  switch ($GLOBALS['egotec_conf']['site_cache_type'])
559  {
560  case 'apcu':
561  require_once('base/Ego_Cache_apcu.php');
562  $this->_cache = new Ego_Cache_apcu($path);
563  break;
564  case 'custom':
565  require_once($GLOBALS['egotec_conf']['var_dir'].'lib/Ego_Cache_custom.php');
566  $this->_cache = new Ego_Cache_custom($path);
567  break;
568  default:
569  require_once('base/Ego_Cache_file.php');
570  $this->_cache = new Ego_Cache_file($path);
571  }
572  }
573  if ($this->_cache->isExpired()) {
574  $this->clearCache();
575  }
576  $this->_loadConfig();
577  }
578 
584  function setRights($rights = array())
585  {
586  $this->_rights = array_unique($rights);
587  $this->setParam(array('rights' => $this->_rights));
588  }
589 
595  function addParam($param)
596  {
597  if ($this->_param)
598  {
599  $this->_param = array_merge($this->_param, $param);
600  } else {
601  $this->_param = $param;
602  }
603  }
604 
610  function setParam($param)
611  {
612  $this->_param = $param;
613  }
614 
618  function getHash()
619  {
620  return md5(serialize($this->_param));
621  }
622 
628  function getLanguages()
629  {
630  if (!$this->_languages) {
631  $this->_languages = explode(',', $this->site['languages']);
632  }
633  return $this->_languages;
634  }
635 
642  public function getSkins($theme = false) {
643  $skins = explode(',', $this->site['skins']);
644 
645  // Das Standard Skin muss immer enthalten sein
646  if (!in_array($this->site['default_skin'], $skins)) {
647  $skins[] = $this->site['default_skin'];
648  }
649 
650  // Designvorlage ebenfalls anführen
651  if ($theme && !empty($this->theme)) {
652  $skins[] = $this->theme;
653  }
654 
655  return array_filter($skins);
656  }
657 
666  function getPageId($name, $param = []) {
667  $name = addslashes($name);
668  $id_file = $GLOBALS['egotec_conf']['cache_dir'] . $this->name . '/_id/' . $name;
669 
670  if (file_exists($id_file)) { // Die ID aus dem Cache holen => keine DB Abfrage notwendig.
671  return file_get_contents($id_file);
672  } else if ($name) {
673  $db = new_db_connection([ // Zunächst die ID über die Url bestimmen.
674  'fields' => 'id',
675  'table' => $this->pageTable,
676  'where' => 'url like :name',
677  'bind' => ['name' => $name]
678  ]);
679 
680  if ($db->nextRecord()) {
681  return (int) $db->Record['id'];
682  } else { // Falls über die Url keine ID gefunden wurde, dann wird die ID über den Namen bestimmt-
683  $db->select([
684  'fields' => 'id',
685  'table' => $this->pageTable,
686  'where' => 'name like :name',
687  'bind' => ['name' => $name],
688  'order' => 'id asc', // Damit eine Seite, die später mit dem gleichen Namen eingefügt wurde, nicht gefunden wird.
689  'limit' => '1'
690  ]);
691 
692  if ($db->nextRecord()) {
693  return (int) $db->Record['id'];
694  }
695  }
696 
697  return 0;
698  } else {
699  return $this->rootId;
700  }
701  }
702 
708  public function getOnlyActive() {
709  return $this->_onlyActive;
710  }
711 
717  public function getTime() {
718  return $this->_time;
719  }
720 
755  function getPages($query=array(), $param = array())
756  {
757  if (is_array($param))
758  {
759  $param = array_merge($this->_param, $param);
760  } else {
761  $param = $this->_param;
762  }
763  if (!$param['lang'])
764  { // Wird keine Sprache übergeben, was meist der Fall ist, dann wird die Sprache des $site Objekts verwendet.
765  $param['lang'] = $this->language;
766  $site = $this;
767  } else {
768  $site = clone $this;
769  try {
770  $site->setLanguage($param['lang']);
771  } catch (Site_Exception $e) {
772  if ($e->getCode() == Site_Exception::LANG_DOESNT_EXIST) {
773  return new Page_Iterator($this);
774  }
775  }
776  }
777  $page_table = $site->name.'_'.$param['lang'];
778 
779  if (is_string($query)||is_bool($query))
780  { // Beim Aufruf über Smarty liegt query als string in der Form array("where" => "...") vor
781  egotec_error_log('$query wurde als String übergeben Query: '.$query);
782  eval ("\$query = $query;");
783  }
784  if (trim($query['where']))
785  { // Um weitere Bedingungen anfügen zu können, müssen die übergebenen Bedingungen geklammert werden.
786  $query['where'] = '('.$query['where'].')';
787  } else
788  {
789  $query['where'] = '1=1';
790  }
791 
792  // "fields2" als Array verwenden
793  if (!isset($query['fields2'])) {
794  $query['fields2'] = [];
795  } elseif (is_string($query['fields2'])) {
796  $query['fields2'] = [$query['fields2']];
797  }
798 
799  if (($site->getOnlyActive() && !$param['inactive']) || $param['only_active'])
800  { // Die ursprüngliche Zeile $query.=... gab beim Aufruf über Smarty eine Fehlermeldung
801  $query['where'] = $query['where']."
802  and $page_table.inactive=0
803  ";
804  $query['where'] = $query['where']."
805  and ($page_table.release_until='0000-00-00 00:00:00' or $page_table.release_until >= '".$site->getTime()."')
806  and ($page_table.release_from='0000-00-00 00:00:00' or $page_table.release_from < '".$site->getTime()."')
807  ";
808  } elseif (($_REQUEST['preview'] || $GLOBALS['frontend_admin']) && empty($param['expired'])) {
809  // In der Vorschau/Frontend Administration werden inaktive Seiten durch das Freigabe bis Datum nicht angezeigt
810  $query['where'] = $query['where']."
811  and ($page_table.release_until='0000-00-00 00:00:00' or $page_table.release_until >= '".$site->getTime()."')
812  ";
813  }
814 
815  // Bitand ermitteln
816  $bitand_query = $this->getBitandQuery($param, $page_table);
817  if (!empty($bitand_query) && !empty($query['fields']) && strpos($query['fields'], 'nav_hide') === false) {
818  $query['fields'] .= ','.$page_table.'.nav_hide';
819  }
820  $query['bitand'] = $bitand_query;
821 
822  if ((integer)$param['deleted']>=0)
823  { // Gelöschte Seiten ausblenden.
824  $query['where'] = $query['where'].' AND ('.$page_table.'.deleted='.
825  (integer)$param['deleted'].($param['deleted_or']?' OR '.$param['deleted_or']:'').')';
826  }
827  $query['table'] = ($query['table']?$query['table'].',':'').$page_table;
828  if (!isset($param['rights']))
829  {
830  $param['rights'] = array('view');
831  }
832  if (!isset($query['fields']))
833  {
834  $query['fields'] = $page_table.'.*';
835  }
836  if ($param['where'])
837  {
838  $query['where'] = ($query['where']?$query['where'].' AND ':'').'('.$param['where'].')';
839  }
840  if ($param['auth_or']!='1=1')
841  {
842  $query = $GLOBALS['auth']->getPageTableQuery($page_table, $param['rights'], $query, $param);
843  }
844  if ($param['fulltext'] || $param['extra'] || $param['filter'])
845  {
846  require_once('base/Ego_Search_Factory.php');
847  try {
848  $search = Ego_Search_Factory::start($site->pageTable, array_merge(['only_active' => $site->getOnlyActive()], $param));
849  } catch (Exception $e) {
850  // Ist die Suche nicht erreichbar, darf es hier zu keinem Abbruch kommen
851  $search = null;
852  }
853 
854  if ($search) {
855  if ($param['extra']) {
856  // Extra Suche durchführen
857  if (isset($param['extra_bind'])) {
858  // Fallback für extra_bind, da extra-bind nicht als Smarty Parameter übergeben werden kann
859  $param['extra-bind'] = $param['extra_bind'];
860  }
861  $search->setExtraQuery($param['extra'], (array) $param['extra-bind']);
862  }
863 
864  if ($query['where'] && preg_match_all('/\W'.$this->pageTable.'\.id in \‍(([0-9, ]+)\‍)/i', $query['where'], $matches)) {
865  $query['id_list'] = [];
866  foreach ($matches[1] as $match) {
867  $query['id_list'] = array_merge($query['id_list'], array_map('trim', explode(',', $match)));
868  }
869  }
870 
871  if ($GLOBALS['egotec_conf']['search_engine'] == 'sql') {
872  $query = $search->search((string) $param['fulltext'], $site->pageTable.'.id', $query, true);
873  } elseif ($GLOBALS['egotec_conf']['search_engine'] == 'lucene' || $GLOBALS['egotec_conf']['search_engine'] == 'elastic') {
874  $query = $search->search((string) $param['fulltext'], $site->pageTable.'.id', $query, $param['filter'], (bool) $param['fuzzy']);
875  if ($GLOBALS['egotec_conf']['search_engine'] == 'elastic') {
876  // Limit wird bereits von Elasticsearch verarbeitet
877  unset($query['limit']);
878  }
879  } else {
880  $query = $search->search((string) $param['fulltext'], $site->pageTable.'.id', $query);
881  }
882  $query['distinct'] = true;
883  } else {
884  // Ist die Suche nicht erreichbar, wird nichts zurückgeliefert
885  require_once('base/Page_Iterator.php');
886  return new Page_Iterator($site);
887  }
888  }
889  if ($param['without_types'])
890  {
891  $query['where'].= ' AND '.$page_table.'.type NOT IN (\''.str_replace(",","','",$param['without_types']).'\')';
892  }
893  if ($param['search_keywords'])
894  {
895  if ($this->admin['keyword_register_own_site']) {
896  // Neues Schlagwortregister
897  $page_ids = [];
898  if (is_numeric($param['search_keywords'])) {
899  $keywords_query = [
900  'where' => "type = '_keywords/entry' AND id = :id",
901  'bind' => [
902  'id' => $param['search_keywords']
903  ]
904  ];
905  } else {
906  $keywords_query = [
907  'where' => "type = '_keywords/entry' AND name = :name",
908  'bind' => [
909  'name' => $param['search_keywords']
910  ]
911  ];
912  }
913  $keywords = $this->getPages(array_merge([
914  'fields' => 'id, type',
915  ], $keywords_query));
916  foreach ($keywords as $keyword) {
917  $children = $keyword->getChildren([
918  'fields' => 'id, type',
919  'where' => "type != '_keywords/entry'"
920  ]);
921  foreach ($children as $child) {
922  $page_ids[] = $child->field['id'];
923  }
924  }
925  return $this->getPages([
926  'where' => "id IN ('" . implode("', '", $page_ids) . "')"
927  ]);
928  } else {
929  // Altes Schlagwortregister
930  if ($site->admin['keywords']['site'])
931  {
932  $keywords_tbl = $site->admin['keywords']['site'].'_'.$site->language;
933  } else
934  {
935  $keywords_tbl = $site->pageTable;
936  }
937  require_once('base/Ego_Search_Sql.php');
938  $search = new Ego_Search_Sql($keywords_tbl, '_keywords');
939  $query = $search->search(
940  $param['search_keywords'],
941  $site->pageTable.'.id',
942  $query,
943  true,
944  'page_id',
945  'word',
946  '',
947  $site->name.'_keywords_rel.page_id',
948  ','.$site->name.'_keywords_rel',
949  $site->name.'_keywords_rel.keyword_id='.$keywords_tbl.'_keywords.id',
950  'SELECT SUM(page_id/page_id) FROM '.$keywords_tbl.'_keywords,'.$site->name.'_keywords_rel WHERE '.
951  $site->name.'_keywords_rel.keyword_id='.$keywords_tbl.'_keywords.id',
952  true
953  );
954  $query['distinct'] = true;
955  }
956  }
957  if ($query['andor'])
958  {
959  $and = array();
960  foreach ($query['andor'] as $ors)
961  {
962  $and[] = '('.join(') OR (', $ors).')';
963  }
964  $query['where'].= "\n AND (".join(") AND (", $and).')';
965  unset($query['andor']);
966  }
967  if ($query['and'])
968  {
969  $query['where'].= "\n AND ".join(' AND ', $query['and']);
970  unset($query['and']);
971  }
972  if ($query['or'])
973  {
974  $query['where'].= "\n AND ( (".join(")\n OR (", $query['or']).') )';
975  unset($query['or']);
976  }
977  if ($query['score'])
978  {
979  $query['fields2'][] = '(LN(('.join(') + (', $query['score']).'))+1) AS score';
980  unset($query['score']);
981  }
982  if ($param['has_children'])
983  {
984  $has_children_where = $param['has_children_where'] ? ' AND ('.$param['has_children_where'].') ' : '';
985  if ((integer)$param['deleted']>=0)
986  { // Gelöschte Seiten ausblenden.
987  $has_children_where.= ' AND (has_table.deleted='.
988  (integer)$param['deleted'].($param['deleted_or']?' OR '.$param['deleted_or']:'').')';
989  }
990  if (($site->getOnlyActive() && !$param['inactive']) || $param['only_active'])
991  { // Die ursprüngliche Zeile $query.=... gab beim Aufruf über Smarty eine Fehlermeldung
992  $has_children_where.= ' AND has_table.inactive=0'.
993  ' AND (has_table.release_until=\'0000-00-00 00:00:00\' or has_table.release_until>=\''.$site->getTime().'\')'.
994  ' AND (has_table.release_from=\'0000-00-00 00:00:00\' or has_table.release_from<\''.$site->getTime().'\')';
995  } elseif (($_REQUEST['preview'] || $GLOBALS['frontend_admin']) && empty($param['expired'])) {
996  // In der Vorschau/Frontend Administration werden inaktive Seiten durch das Freigabe bis Datum nicht angezeigt
997  $has_children_where.= ' AND (has_table.release_until=\'0000-00-00 00:00:00\' or has_table.release_until>=\''.$site->getTime().'\')';
998  }
999 
1000  /* Bitand für has_children ermitteln
1001  * (die pageTable muss mit "has_table" ersetzt werden, damit die bitand Anweisungen auch auf den Sub-Select angewendet werden)
1002  */
1003  $query['field_as_bitand']['has_children'] = array_map(function($value) {
1004  $value[0] = str_replace($this->pageTable . '.', 'has_table.', $value[0]);
1005  return $value;
1006  }, $bitand_query);
1007 
1008  $children_query = [
1009  'page_table' => 'has_table',
1010  'where' => $page_table .'.id='.$page_table.'_children.page_id'.
1011  ' AND '.$page_table.'_children.child=has_table.id'.
1012  $has_children_where
1013  ];
1014  $query['distinct'] = true;
1015 
1016  if ($param['auth_or']!='1=1')
1017  {
1018  $children_query = $GLOBALS['auth']->getPageTableQuery($page_table, $param['rights'], $children_query, $param);
1019  }
1020  $query['field_as']['has_children'] = 'SELECT '.($param['children_count']===false?'DISTINCT 1':'count(DISTINCT child)').
1021  ' FROM '.$page_table.'_children,'.$page_table.' has_table'.
1022  ($children_query['join']?' LEFT JOIN '.(is_array($children_query['join'])?
1023  implode(' LEFT JOIN ', $children_query['join']):$children_query['join']):'').
1024  ' WHERE '.$children_query['where'];
1025  if ($param['children_count'] === false) {
1026  $query['field_as_limit']['has_children'] = '0,1';
1027  }
1028  }
1029  if ($param['multi_parents'])
1030  {
1031  $multi_where = '';
1032  if ((integer)$param['deleted']>=0)
1033  { // Gelöschte Seiten ausblenden.
1034  $multi_where.= ' AND (multi_table.deleted='.
1035  (integer)$param['deleted'].($param['deleted_or']?' OR '.$param['deleted_or']:'').')';
1036  }
1037  if (($site->getOnlyActive() && !$param['inactive']) || $param['only_active'])
1038  { // Die ursprüngliche Zeile $query.=... gab beim Aufruf über Smarty eine Fehlermeldung
1039  $multi_where.= ' AND multi_table.inactive=0'.
1040  ' AND (multi_table.release_until=\'0000-00-00 00:00:00\' or multi_table.release_until>=\''.$site->getTime().'\')'.
1041  ' AND (multi_table.release_from=\'0000-00-00 00:00:00\' or multi_table.release_from<\''.$site->getTime().'\')';
1042  } elseif (($_REQUEST['preview'] || $GLOBALS['frontend_admin']) && empty($param['expired'])) {
1043  // In der Vorschau/Frontend Administration werden inaktive Seiten durch das Freigabe bis Datum nicht angezeigt
1044  $multi_where.= ' AND (multi_table.release_until=\'0000-00-00 00:00:00\' or multi_table.release_until>=\''.$site->getTime().'\')';
1045  }
1046 
1047  // Bitand für multi_parents ermitteln
1048  $query['field_as_bitand']['multi_parents'] = $bitand_query;
1049 
1050  $query['field_as']['multi_parents'] = 'SELECT count(page_id)-1'.
1051  ' FROM '.$page_table.'_children,'.$page_table.' multi_table'.
1052  ' WHERE '.$page_table.'.id=child'.
1053  ' AND '.$page_table.'_children.page_id=multi_table.id'.
1054  $multi_where;
1055  $query['distinct'] = true;
1056  }
1057  require_once('base/Page_Iterator.php');
1058  if ($GLOBALS['egotec_conf']['pages_cache'] && !$param['no_cache'])
1059  {
1060  return new Page_Iterator($site, new_db_connection($query, $site->getCache()));
1061  } else {
1062  return new Page_Iterator($site, new_db_connection($query));
1063  }
1064  }
1065 
1074  private function getBitandQuery($param, $page_table = '') {
1075  $query = array();
1076  if (!$page_table) {
1077  $page_table = $this->pageTable;
1078  }
1079  if (
1080  !isset($param['sitemap'])
1081  && $param['fulltext']
1082  && !$GLOBALS['admin_area']
1083  ) {
1084  // In der Frontend Suche standardmäßig nur Seiten finden, die auch in der Sitemap angezeigt werden
1085  $param['sitemap'] = true;
1086  }
1087  if ($param['no_nav_hide'])
1088  { // Nur Seiten, die in der Navigation angezeigt werden (nav_hide&1=0)
1089  $query[] = array($page_table.'.nav_hide', 1, 0);
1090  $param['sitemap'] = true; // Außerdem nur Seiten, die in der Sitemap angezeigt werden
1091  }
1092  if ($param['no_intranet'])
1093  { // Nur Seiten, die auf den Liveserver übertragen werden (nav_hide&2=0)
1094  $query[] = array($page_table.'.nav_hide', 2, 0);
1095  }
1096  if ($param['intranet'])
1097  { // Nur Seiten, die nur im Intranet angezeigt werden (nav_hide&2=2)
1098  $query[] = array($page_table.'.nav_hide', 2, 2);
1099  }
1100  if ($param['search'])
1101  { // Nur Seiten, die nicht von der Suche ausgeschlossen werden (nav_hide&4=0)
1102  $query[] = array($page_table.'.nav_hide', 4, 0);
1103  }
1104  if ($param['sitemap'] && (!$GLOBALS['egotec_conf']['show_hidden_sitemap'] || !$GLOBALS['admin_area']))
1105  { // Nur Seiten, die in der Sitemap angezeigt werden (nav_hide&8=0)
1106  $query[] = array($page_table.'.nav_hide', 8, 0);
1107  }
1108  if ($param['nouse'])
1109  { // Nur Seiten, die im Verwendungsnachweis berücksichtigt werden sollen (nav_hide&16=0)
1110  $query[] = array($page_table.'.nav_hide', 16, 0);
1111  }
1112  if (isset($param['flag0']))
1113  { // Weitere Flag für offene Anwendungsfälle (nav_hide&32=0)
1114  $query[] = array($page_table.'.nav_hide', 32, $param['flag0']?32:0);
1115  }
1116  if (isset($param['flag1']))
1117  { // Weitere Flag für offene Anwendungsfälle (nav_hide&64=0)
1118  $query[] = array($page_table.'.nav_hide', 64, $param['flag1']?64:0);
1119  }
1120  if (isset($param['flag2']))
1121  { // Weitere Flag für offene Anwendungsfälle (nav_hide&128=0)
1122  $query[] = array($page_table.'.nav_hide', 128, $param['flag2']?128:0);
1123  }
1124  if (isset($param['flag3']))
1125  { // Weitere Flag für offene Anwendungsfälle (nav_hide&256=0)
1126  $query[] = array($page_table.'.nav_hide', 256, $param['flag3']?256:0);
1127  }
1128  if (isset($param['flag4']))
1129  { // Weitere Flag für offene Anwendungsfälle (nav_hide&512=0)
1130  $query[] = array($page_table.'.nav_hide', 512, $param['flag4']?512:0);
1131  }
1132  if (isset($param['flag5']))
1133  { // Weitere Flag für offene Anwendungsfälle (nav_hide&1024=0)
1134  $query[] = array($page_table.'.nav_hide', 1024, $param['flag5']?1024:0);
1135  }
1136  if (isset($param['flag6']))
1137  { // Weitere Flag für offene Anwendungsfälle (nav_hide&2048=0)
1138  $query[] = array($page_table.'.nav_hide', 2048, $param['flag6']?2048:0);
1139  }
1140  if (isset($param['flag7']))
1141  { // Weitere Flag für offene Anwendungsfälle (nav_hide&4096=0)
1142  $query[] = array($page_table.'.nav_hide', 4096, $param['flag7']?4096:0);
1143  }
1144 
1145  return $query;
1146  }
1147 
1154  function getLostPages($deleted = -1)
1155  {
1156  /* Verlorene Seiten sind:
1157  * 1. Seiten ohne Elternseite
1158  * 2. Seiten die als Elternseite nur Schlagwörter haben (aber selbst kein Schlagwort sind) */
1159  return $this->getPages(
1160  array(
1161  'join' => array($this->pageTable.'_children ON child = id'),
1162  'where' => "id != {$this->rootId} AND (child IS NULL OR (type != '_keywords/entry' AND id IN (SELECT child FROM {$this->pageTable}_children INNER JOIN {$this->pageTable} ON page_id = id WHERE type = '_keywords/entry') AND id NOT IN (SELECT child FROM {$this->pageTable}_children INNER JOIN {$this->pageTable} ON page_id = id WHERE type != '_keywords/entry')))"
1163  ),
1164  array(
1165  'deleted' => $deleted,
1166  'auth_or' => '1=1'
1167  )
1168  );
1169  }
1170 
1182  function getPage($id, $param = []) {
1183  if (
1184  $id == ''
1185  || !is_numeric($id)
1186  ) {
1187  return null;
1188  }
1189 
1190  $cache_key = md5(serialize([$this->language, $param]));
1191 
1192  if ($id == $this->rootId && $page = $this->_root[$cache_key]) {
1193  return $page;
1194  }
1195 
1196  if (is_numeric($_REQUEST['id']) && $id == $_REQUEST['id']) {
1197  // Falls möglich, die aktuelle abgelaufene Seite anzeigen
1198  $param['expired'] = true;
1199  }
1200 
1201  if ($param['original']) {
1202  // Die originale Seite holen (für "Speichern und Veröffentlichen")
1203  $GLOBALS['public_save_get_original_page'] = true;
1204  unset($param['original']);
1205  }
1206 
1207  $pages = $this->getPages([
1208  'fields' => $param['fields'],
1209  'where' => 'id=:id',
1210  'bind' => ['id' => (int) $id]
1211  ],
1212  $param
1213  );
1214 
1215  $page = $pages->nextPage();
1216  unset($GLOBALS['public_save_get_original_page']);
1217 
1218  if ($id == $this->rootId) { // Die root Seite cachen, da auf diese oft zugefriffen wird.
1219  $this->_root[$cache_key] = $page;
1220  }
1221 
1222  return $page;
1223  }
1224 
1236  function getRoot($param = array())
1237  {
1238  return $this->getPage($this->rootId, $param);
1239  }
1240 
1249  function getErrorPage()
1250  {
1251  $GLOBALS['_SERVER']['REDIRECT_STATUS'] = '404';
1252  if (!($page = $this->getPage($this->site['error_id'] ? $this->site['error_id'] : $this->rootId))) {
1253  // Falls die eingestellte Fehlerseite nicht erreichbar ist, wird die Startseite verwendet
1254  $page = $this->getRoot();
1255  }
1256  return $page;
1257  }
1258 
1265  function getUrl($param, $page = null)
1266  {
1267  if (!$this->_onlyActive && !isset($param['nonactive']))
1268  { // Auch inaktive Seiten anzeigen.
1269  $param['nonactive'] = true;
1270  }
1271  if (isset($param['nonactive']) && !$param['nonactive'])
1272  {
1273  unset($param['nonactive']);
1274  }
1275  if (!isset($param['lang']))
1276  {
1277  $param['lang'] = $this->language;
1278  }
1279  if (!isset($param['skin']) && $this->skin!=$this->site['default_skin'])
1280  {
1281  $param['skin'] = $this->skin;
1282  }
1283  if (!isset($param['site']))
1284  {
1285  $param['site'] = $this->name;
1286  }
1287 
1288  // Alphabetische Reihenfolge der URL Parameter
1289  ksort($param);
1290 
1291  if ($param['get_frontend_url']) {
1292  // Im Adminbereich eine sprechende URL ermitteln
1293  return get_url('index.php', $param, $page, true, 2);
1294  }
1295  return get_url('index.php', $param, $page);
1296  }
1297 
1305  function getPageUrl($page_id, $params = array(), $page = null)
1306  {
1307  return $page_id?$this->getUrl(array_merge(array('id' => $page_id), $params), $page):$this->getErrorPage();
1308  }
1309 
1323  function getMediaSite($lang = '') {
1324  if (
1325  $this->site['type'] != 'media'
1326  && empty($this->site['media'])
1327  ) {
1328  return null;
1329  }
1330 
1338  if ($lang == '') {
1339  $lang = $this->language;
1340  }
1341 
1342  if (isset($this->mediaSites[$lang])) {
1343  return $this->mediaSites[$lang];
1344  }
1345 
1346  if ($this->site['type'] == 'media') {
1347  $media_site = $this;
1348  } else {
1349  $media_site = new Site($this->site['media'], '', '', $this->_onlyActive);
1350  $media_site->setParam($this->_param);
1351  }
1352 
1353  // Prüfen, ob die aktuelle Sprache auch im Multimedia Mandanten existiert
1354  if (
1355  in_array($lang, $media_site->getLanguages())
1356  && $lang != $media_site->language
1357  ) {
1358  $media_site->setLanguage($lang);
1359  }
1360 
1361  return $this->mediaSites[$lang] = $media_site;
1362  }
1363 
1373  public function getDataSite($lang = '') {
1374  if (
1375  $this->site['type'] !== 'data'
1376  && empty($this->site['data'])
1377  ) {
1378  return null;
1379  }
1380 
1381  if ($lang == '') {
1382  $lang = $this->language;
1383  }
1384 
1385  if (isset($this->dataSites[$lang])) {
1386  return $this->dataSites[$lang];
1387  }
1388 
1389  if ($this->site['type'] == 'data') {
1390  $data_site = $this;
1391  } else {
1392  $data_site = new Site($this->site['data'], '', '', $this->_onlyActive);
1393  $data_site->setParam($this->_param);
1394  }
1395 
1396  // Prüfen, ob die aktuelle Sprache auch im Multimedia Mandanten existiert
1397  if (
1398  in_array($lang, $data_site->getLanguages())
1399  && $lang != $data_site->language
1400  ) {
1401  $data_site->setLanguage($lang);
1402  }
1403 
1404  return $this->dataSites[$lang] = $data_site;
1405  }
1406 
1412  public function hasMediaSite() {
1413  return ($this->site['type'] == 'media' || !empty($this->site['media']));
1414  }
1415 
1421  public function hasDataSite() {
1422  return ($this->site['type'] === 'data' || !empty($this->site['data']));
1423  }
1424 
1435  public function getFirstSite($type) {
1436  $site = null;
1437  $method = 'get' . ucfirst($type) .'Site';
1438  if (method_exists($this, $method) && ($connected_site = $this->{$method}()) && $connected_site->hasRight('desktop')) {
1439  $site = $connected_site;
1440  } else {
1441  foreach (Ego_System::getAllSites($GLOBALS['auth']->user->field['id'], 'desktop', false, $type) as $connected_site) {
1442  $site = $connected_site;
1443  break;
1444  }
1445  }
1446  return $site;
1447  }
1448 
1456  function getMediaUrl($id, $param = array(), $url_param = array())
1457  {
1458  if ($param['no_suffix'])
1459  {
1460  $url_param['no_suffix'] = $param['no_suffix'];
1461  unset($param['no_suffix']);
1462  }
1463  return $this->getMediaSite()->getPage($id, $param)->getUrl($url_param);
1464  }
1465 
1472  function clearCache($id=0, $all_languages = false)
1473  {
1474  if ($all_languages) {
1475  // Cache für alle Sprachen ungültig setzen
1476  $site = clone $this;
1477  foreach ($site->getLanguages() as $lang) {
1478  $site->setLanguage($lang);
1479  $site->clearCache($id);
1480  }
1481  return;
1482  }
1483 
1484  $language = $this->language;
1485  $pageTable = $this->name.'_'.$language;
1486  if (!file_exists($GLOBALS['egotec_conf']['log_dir'].$this->name.'_'.$language))
1487  {
1488  Ego_System::mkdir($GLOBALS['egotec_conf']['log_dir'].$this->name.'_'.$language, 0777, true);
1489  }
1490 
1491  if ($id)
1492  { // Bei Bildern wird nicht der komplette Cache, sondern nur das aktuelle Bild gelöscht
1493  $cache_path = $GLOBALS['egotec_conf']['cachemedia_dir'].$this->name.'/'.$language.'/';
1494  Ego_System::deldir($cache_path.$id, true);
1495  }
1496 
1502  // Cache, Lebensdauer einstellen nun immer 24h
1503  $new_cache_lifetime = 86400;
1504 
1505  $cache_expire = date('Y-m-d H:i:s', time()+$new_cache_lifetime);
1506  $time = date('Y-m-d H:i:s');
1507  $db = new_db_connection(array( // Datum der nächsten Änderung durch Ablauf von Freigabefenstern bestimmen.
1508  'fields' => '*',
1509  'table' => $pageTable,
1510  'where' => 'release_from>:time',
1511  'bind' => array('time' => $time),
1512  'order' => 'release_from asc',
1513  'limit' => '1'
1514  ));
1515  if ($db->nextRecord())
1516  {
1517  if ($db->Record['release_from']<$cache_expire)
1518  {
1519  $cache_expire = $db->Record['release_from'];
1520  }
1521  }
1522  $db->select(array(
1523  'fields' => '*',
1524  'table' => $pageTable,
1525  'where' => 'release_until>:time',
1526  'bind' => array('time' => $time),
1527  'order' => 'release_until asc',
1528  'limit' => '1'
1529  ));
1530  if ($db->nextRecord())
1531  {
1532  if ($db->Record['release_until']<$cache_expire)
1533  {
1534  $cache_expire = $db->Record['release_until'];
1535  }
1536  }
1537  $d = preg_split('/[-, ,:]/', $cache_expire);
1538  $this->_cache->reset();
1539 
1540  $this->_cache->setExpire(mktime($d[3], $d[4], $d[5], $d[1], $d[2], $d[0]));
1541  $this->setTime(); // Der Zeitstempel für die Freigabeabfrage muss neu gesetzt werden.
1542 
1543  // types.cache und classes.cache löschen
1544  Ego_System::clearTypeCache($this->name);
1545 
1546  // Allgemeine Cache löschen (nicht für APCu, da hier die allgemeine Cache die selbe ist wie die Site Cache)
1547  if ($GLOBALS['egotec_conf']['site_cache_type'] != 'apcu') {
1548  $cache = Ego_System::getCache();
1549  $cache->reset();
1550  }
1551  Ego_System::clearNginxCache();
1552  }
1553 
1559  public function getGlobalConfig($type) {
1560  if ($this->global !== null && !empty($this->global[$type])) {
1561  return $this->global[$type];
1562  }
1563  return null;
1564  }
1565 
1573  private function loadGlobalConfig($types = ['site', 'admin']) {
1574  if ($this->global === null) {
1575  if (Ego_System::file_exists($file = $GLOBALS['egotec_conf']['var_dir'] . 'conf/global.json')) {
1576  $this->global = json_decode(Ego_System::file_get_contents($file), true);
1577  } else {
1578  $this->global = [];
1579  }
1580  }
1581 
1582  if (!empty($this->global)) {
1592  $set_value = function($meta, $type, $key) {
1593  if (!$this->useGlobalConfig($meta)) {
1594  return;
1595  }
1596 
1597  if (isset($meta['value'])) {
1598  Ego_System::setAssocValue($this->conf[$type], $key, $meta['value']);
1599  } elseif (isset($meta['env'])) {
1600  Ego_System::setAssocValue($this->conf[$type], $key, $_ENV[$meta['env']]
1601  ?? $_SERVER[$meta['env']]
1602  ?? (getenv($meta['env'], true) ?: getenv($meta['env']))
1603  );
1604  }
1605  };
1606 
1607  foreach ($types as $type) {
1608  if (is_array($this->global[$type])) {
1609  foreach ($this->global[$type] as $key => $meta) {
1610  if (is_array($meta['values'])) {
1611  foreach ($meta['values'] as $value) {
1612  $set_value($value, $type, $key);
1613  }
1614  } else {
1615  $set_value($meta, $type, $key);
1616  }
1617  }
1618  }
1619  }
1620  }
1621  }
1622 
1630  private function setGlobalConfig($type) {
1631  if (!empty($this->global) && is_array($this->global[$type])) {
1632  foreach ($this->global[$type] as $key => $meta) {
1633  if (
1634  Ego_System::getAssocValue($this->{$type}, $key) !== null
1635  && $this->isGlobalConfig($type, $key)
1636  ) {
1637  Ego_System::setAssocValue($this->{$type}, $key, null);
1638  }
1639  }
1640  }
1641  }
1642 
1651  private function isGlobalConfig($type, $search_key) {
1652  if (!empty($this->global) && is_array($this->global[$type])) {
1653  foreach ($this->global[$type] as $key => $meta) {
1654  if ($search_key == $key) {
1655  if ($this->useGlobalConfig($meta)) {
1656  return true;
1657  }
1658  break;
1659  }
1660  }
1661  }
1662  return false;
1663  }
1664 
1672  public function useGlobalConfig($meta) {
1673  if (is_array($meta['values'])) {
1674  foreach ($meta['values'] as $value) {
1675  if ($this->useGlobalConfig($value)) {
1676  return true;
1677  }
1678  }
1679  return false;
1680  } else {
1681  if (is_array($meta['include'])) {
1682  foreach ($meta['include'] as $value) {
1683  if (strpos($value, 'type:') === 0) {
1684  if ($this->site['type'] == substr($value, 5)) {
1685  return true;
1686  }
1687  } elseif ($this->name == $value) {
1688  return true;
1689  }
1690  }
1691  return false;
1692  } elseif (is_array($meta['exclude'])) {
1693  foreach ($meta['exclude'] as $value) {
1694  if (strpos($value, 'type:') === 0) {
1695  if ($this->site['type'] == substr($value, 5)) {
1696  return false;
1697  }
1698  } elseif ($this->name == $value) {
1699  return false;
1700  }
1701  }
1702  }
1703  }
1704  return true;
1705  }
1706 
1714  function save($site) {
1715  require_once 'base/Ego_System.php';
1716 
1717  // Sprachen müssen migriert werden, wenn die Standardsprache sich ändert, oder eine Sprache gelöscht wird
1718  $migrateLanguages = ($this->site['default_language'] !== $site['default_language']) || ($this->site['languages'] !== $site['languages']);
1719 
1720  $this->site = array_merge($this->site, $site);
1721 
1722  // Globale Konfigurationen werden nicht gespeichert
1723  $this->setGlobalConfig('site');
1724 
1725  if (isset($site['icon'])) {
1726  $this->site['icon'] = $site['icon'];
1727  }
1728 
1729  // Diese Keys gibt es nicht mehr und sind mittlerweile unterteilt in Sprachen
1730  unset(
1731  $this->site['title'],
1732  $this->site['robots'],
1733  $this->site['keywords'],
1734  $this->site['description'],
1735  $this->_languages
1736  );
1737 
1738  $this->site = Ego_System::cleanTypes($this->site);
1739  Ego_System::write_ini_file($GLOBALS['egotec_conf']['site_dir'].$this->name.'/conf.ini', $this->site);
1740 
1741  if ($migrateLanguages) {
1742  Ego_Queue::add([$this, 'migrateLanguages']);
1743  }
1744 
1745  // Globale Konfigurationen wieder laden
1746  $this->loadGlobalConfig(['site']);
1747 
1748  return false;
1749  }
1750 
1757  function save_admin($admin=array())
1758  {
1759  require_once('base/Ego_System.php');
1760  $original_admin = $this->admin;
1761  $this->admin = array_merge($this->admin, $admin);
1762  $reload_sitemap = false;
1763 
1764  // Globale Konfigurationen werden nicht gespeichert
1765  $this->setGlobalConfig('admin');
1766 
1770  $enabled_types = array();
1771  if(is_array($this->admin['enabled_types']))
1772  {
1773  foreach ($this->admin['enabled_types'] as $key => $value)
1774  {
1775  if ($value == '1')
1776  {
1777  $enabled_types[$key] = $value;
1778  }
1779  }
1780  }
1781  $this->admin['enabled_types'] = $enabled_types;
1782 
1783  // Schlagwortregister anlegen
1784  if ($this->admin['keyword_register_own_site']) {
1785  if (!isset($this->admin['keywords']['site'])) {
1786  $this->admin['keywords']['site'] = $this->name;
1787  }
1788  $reset = $this->admin['keywords']['site'] != $original_admin['keywords']['site'];
1789  if ($this->name !== $this->admin['keywords']['site']) {
1790  $origin_site = new Site($this->admin['keywords']['site']);
1791  $this->createKeywordRegister($origin_site, $reset);
1792  } else {
1793  $this->createKeywordRegister(null, $reset);
1794  }
1795 
1796  // Schlagwortregister mit DeepL übersetzen
1797  if (Ego_System::checkLicence($GLOBALS['egotec_conf']['lib_dir'] . 'translate')) {
1798  $keyword_register_page = $this->getPages([
1799  'where' => "type='_keywords/list'"
1800  ], [
1801  'auth_or' => '1=1'
1802  ])->nextPage();
1803 
1804  if ($keyword_register_page) {
1805  $language_link = [];
1806  foreach ($this->getLanguages() as $lang) {
1807  $language_link[$lang] = $lang == $this->site['default_language']
1808  ? 1
1809  : ($this->admin['deepl_keywords'] ? 2 : 0);
1810  }
1811  if (
1812  serialize($keyword_register_page->extra['language_link'] ?? []) != serialize($language_link)
1813  || $keyword_register_page->extra['language_standard'] != $this->site['default_language']
1814  ) {
1815  $keyword_register_page->extra['language_link'] = $language_link;
1816  $keyword_register_page->extra['language_standard'] = $this->site['default_language'];
1817  $keyword_register_page->update();
1818  }
1819 
1820  foreach ($keyword_register_page->getDescendants([
1821  'where' => "type = '_keywords/entry'"
1822  ], [
1823  'auth_or' => '1=1'
1824  ]) as $keyword) {
1825  if (
1826  serialize($keyword->extra['language_link'] ?? []) != serialize($language_link)
1827  || $keyword->extra['language_standard'] != $this->site['default_language']
1828  ) {
1829  $keyword->extra['language_link'] = $language_link;
1830  $keyword->extra['language_standard'] = $this->site['default_language'];
1831  $keyword->update();
1832  }
1833  }
1834  }
1835  }
1836  } elseif ($original_admin['keyword_register_own_site'] && !$this->admin['keyword_register_own_site']) {
1837  // wenn Neues Schlagwortregistermodul nicht mehr verwendet wird, dann Schlagwortregister komplett löschen
1838  $this->createKeywordRegister(null, true, true);
1839  }
1840 
1841  // Seite mit Seitentyp "extern/link" anlegen, falls noch nicht vorhanden
1842  if ($this->admin['smarty']['external_links']) {
1843  if ($enabled_types['extern/link']) {
1844  $extern_link = $this->getPages([
1845  'where' => "type = 'extern/link'"
1846  ], [
1847  'auth_or' => '1=1',
1848  'inactive' => true,
1849  'only_active' => false
1850  ])->nextPage();
1851  if (!$extern_link) {
1852  $field = array(
1853  'name' => $GLOBALS['auth']->translate('Externe Links'),
1854  'title' => $GLOBALS['auth']->translate('Externe Links'),
1855  'type' => 'extern/link'
1856  );
1857  $this->getRoot()->newChild($field);
1858  $reload_sitemap = true;
1859  }
1860  }
1861  }
1862 
1863  // One-Way-Sync: die Datei "ignore_ids" automatisch löschen, wenn diese nicht mehr benötigt wird
1864  $clusters = Ego_System::getCluster($this);
1865  $oneway = false;
1866  if (!empty($clusters)) {
1867  foreach ($clusters as $cluster) {
1868  if ($cluster['oneway']) {
1869  $oneway = true;
1870  break;
1871  }
1872  }
1873  }
1874  if (!$oneway) {
1875  foreach ($this->getLanguages() as $lang) {
1876  $ignore_file = $GLOBALS['egotec_conf']['log_dir'] . $this->name . '_' . $lang . '/ignore_ids';
1877  if (Ego_System::file_exists($ignore_file)) {
1878  @unlink($ignore_file);
1879  }
1880  }
1881  }
1882 
1883  $this->admin = Ego_System::cleanTypes($this->admin);
1884  Ego_System::write_ini_file($GLOBALS['egotec_conf']['site_dir'].$this->name.DIRECTORY_SEPARATOR.'admin'.DIRECTORY_SEPARATOR.'conf.ini', $this->admin);
1885  Ego_System::clearTypeCache($this->name);
1886 
1887  // Globale Konfigurationen wieder laden
1888  $this->loadGlobalConfig(['admin']);
1889 
1890  return $reload_sitemap;
1891  }
1892 
1898  public function migrateLanguages() {
1899  $params = [
1900  'inactive' => true,
1901  'only_active' => false,
1902  'deleted' => 1,
1903  'deleted_or' => '1=1',
1904  'auth_or' => '1=1',
1905  'no_cache' => true,
1906  ];
1907  $pages = $this->getPages([], $params);
1908 
1909  foreach ($pages as $page) {
1910  $currentLanguages = explode(',', $this->site['languages']);
1911 
1912  foreach ($currentLanguages as $currentLanguage) {
1913  $hasChanges = false;
1914  if ($languagePage = $page->getLanguagePage($currentLanguage, $params)) {
1915  if (!in_array($languagePage->extra['language_standard'] ?: '', $currentLanguages)) {
1916  $languagePage->extra['language_standard'] = $this->site['default_language'];
1917 
1918  $hasChanges = true;
1919  }
1920 
1921  $languagesToDelete = [];
1922  $languageLink = !empty($languagePage->extra['language_link']) ? $languagePage->extra['language_link'] : [];
1923 
1924  foreach (array_keys($languageLink) as $lang) {
1925  if (!in_array($lang, explode(',', $this->site['languages']))) {
1926  $languagesToDelete[] = $lang;
1927 
1928  $hasChanges = true;
1929  }
1930  }
1931 
1932  foreach ($languagesToDelete as $languageToDelete) {
1933  unset($languagePage->extra['language_link'][$languageToDelete]);
1934  }
1935 
1936  if ($hasChanges) {
1937  $languagePage->update([], true, true);
1938  }
1939  }
1940  }
1941  }
1942  }
1943 
1952  private function createKeywordRegister($origin_site = null, $reset = false, $delete = false) {
1953  $root_page = $this->getRoot();
1954 
1955  // Überprüfen ob es bereits ein Schlagwortregister existiert
1956  $keyword_register_page = $this->getPages([
1957  'where' => "type='_keywords/list'"
1958  ], [
1959  'auth_or' => '1=1'
1960  ])->nextPage();
1961 
1962  if ($keyword_register_page) {
1963  if ($reset) {
1964  // Wenn das Schlagwortregister gewechselt wird, muss es neu angelegt werden
1965  $keyword_register_page->delete(false, false, true, [
1966  'where' => "type = '_keywords/entry'"
1967  ]);
1968  $this->clearTrashcan([
1969  'where' => "type = '_keywords/list' OR type = '_keywords/entry'"
1970  ]);
1971  } else {
1972  // Wenn ein Schlagwortregister existiert, dann nicht machen.
1973  return;
1974  }
1975  }
1976 
1977  if ($origin_site && !$delete) {
1978  // Schlagwortregisterstartseite klonen.
1979  $origin_page = $origin_site->getPages([
1980  'where' => "type='_keywords/list'"
1981  ], [
1982  'auth_or' => '1=1'
1983  ])->nextPage();
1984 
1985  if (!$origin_page) { // Wenn beim Originalmandant kein Schlagwortregister existiert,
1986  $keyword_register_field = [
1987  'name' => "Schlagwortregister",
1988  'title' => "Schlagwortregister",
1989  'type' => "_keywords/list",
1990  'inactive' => 0,
1991  'nav_hide' => 1+4+8 // Aus Navigation, Sitemap und Suche ausschließen.
1992  ];
1993 
1994  $origin_page = $origin_site->getRoot()->newChild($keyword_register_field); // dann dieses erstellen.
1995  } elseif ($origin_page->isClone()) { // Wenn der ausgewählte Mandant ebenfalls Klone nutzt,
1996  $origin_page = $origin_page->getCloneOriginal(); // so wird das Original geklont.
1997  }
1998  $clone_page = $root_page->createClone($origin_page);
1999 
2000  $keyword_recursive = function($origin_page, $clone_page) use (&$keyword_recursive) {
2001  $origin_children = $origin_page->getChildren([
2002  'where' => "type='_keywords/entry'"
2003  ], [
2004  'auth_or' => '1=1'
2005  ]);
2006 
2007  foreach ($origin_children as $origin_child) {
2008  // Wenn das Schlagwort ein Klon ist, dann Klon von Original erstellen
2009  if ($origin_child->isClone()) {
2010  $clone_child = $clone_page->createClone($origin_child->getCloneOriginal());
2011  } else {
2012  $clone_child = $clone_page->createClone($origin_child);
2013  }
2014  $keyword_recursive($origin_child, $clone_child);
2015  }
2016  };
2017  $keyword_recursive($origin_page, $clone_page);
2018  } elseif (!$delete) {
2019  $keyword_register_field = [
2020  'name' => "Schlagwortregister",
2021  'title' => "Schlagwortregister",
2022  'type' => "_keywords/list",
2023  'inactive' => 0,
2024  'nav_hide' => 1+4+8 // Aus Navigation, Sitemap und Suche ausschließen.
2025  ];
2026  $root_page->newChild($keyword_register_field);
2027  }
2028  }
2029 
2036  private function _sortTypes(&$arr) {
2037  $names = [];
2038  foreach ($arr as $value) {
2039  $names[] = str_replace(
2040  ['ä', 'ö', 'ü', 'ß', '-', ' '],
2041  ['ae', 'oe', 'ue', 'ss', '_', '_'],
2042  mb_strtolower($value['fullname'])
2043  );
2044  }
2045 
2046  array_multisort($names, SORT_ASC, SORT_NATURAL, $arr);
2047  }
2048 
2061  private function _getTypesOfDirectory($root_dir, $site_name, $type='', $fullname='', $depth=-1, $site_type='')
2062  {
2063  $original_root_dir = $root_dir;
2064  if (
2065  file_exists($type_file = rtrim($root_dir.($type?$type.'/':''), '/').'/type.ini')
2066  || (
2067  $root_dir != $GLOBALS['egotec_conf']['site_dir'].'_global/'
2068  && file_exists($type_file = rtrim($GLOBALS['egotec_conf']['site_dir'].'_global/'.($type?$type.'/':''), '/').'/type.ini')
2069  && ($root_dir = $GLOBALS['egotec_conf']['site_dir'].'_global/')
2070  )
2071  || (
2072  $root_dir != $GLOBALS['egotec_conf']['lib_dir'].'type/site/'
2073  && file_exists($type_file = rtrim($GLOBALS['egotec_conf']['lib_dir'].'type/site/'.($type?$type.'/':''), '/').'/type.ini')
2074  && ($root_dir = $GLOBALS['egotec_conf']['lib_dir'].'type/site/')
2075  )
2076  ) {
2077  $entry = parse_ini_file($type_file, true);
2078 
2079  $fullname = ($fullname?$fullname.'/':'').$entry['title'];
2080  $global = false;
2081  if (
2082  $root_dir == $GLOBALS['egotec_conf']['lib_dir'].'type/site/'
2083  || $root_dir == $GLOBALS['egotec_conf']['site_dir'].'_global/'
2084  ) {
2085  $global = true;
2086  }
2087 
2088  $system = false;
2089  switch ($type) {
2090  case '_keywords':
2091  case '_keywords/abbreviations':
2092  case '_keywords/entry':
2093  case '_keywords/list':
2094  if ($this->admin['keyword_register_own_site']) {
2095  $system = true;
2096  } else {
2097  $entry['hidden'] = true;
2098  }
2099  }
2100 
2101  $inherit = false;
2102  $parent_type = explode('/', $type)[0];
2103  if (
2104  $root_dir == $GLOBALS['egotec_conf']['lib_dir'].'type/site/'
2105  && !$this->admin['enabled_types'][$type]
2106  && (
2107  is_dir($GLOBALS['egotec_conf']['site_dir'] . "{$this->name}/$parent_type")
2108  || ($this->theme && is_dir($GLOBALS['egotec_conf']['pub_dir'] . "theme/{$this->theme}/site/$parent_type"))
2109  )
2110  ) {
2111  $inherit = true;
2112  }
2113 
2114  $types = array(
2115  'depth' => $depth,
2116  'type' => $type,
2117  'name' => $entry['title'],
2118  'fullname' => $fullname,
2119  'active' => !$entry['inactive'],
2120  'hidden' => (bool) $entry['hidden'],
2121  'global' => $global,
2122  'system' => $system,
2123  'inherit' => $inherit,
2124  'blacklist' => $entry['blacklist'],
2125  'whitelist' => $entry['whitelist']
2126  );
2127 
2128  // Blacklist - Wenn der Seitentyp vom Mandanten ausgeschlossen ist.
2129  $excluded_sites = explode(',', $types['blacklist']);
2130 
2131  if ($types['whitelist']) {
2132  // Whitelist - Wenn der Seitentyp nur auf bestimmten Mandanten verfügbar ist.
2133  $included_sites = explode(',', $types['whitelist']);
2134  }
2135  // Wenn sich der Seitentyp auf der Blacklist befindet, nicht anzeigen.
2136  if (is_array($excluded_sites) && in_array($site_name, $excluded_sites)) {
2137  return [];
2138  }
2139 
2140  // Wenn eine Whitelist vorhanden ist und der Seitentyp nicht auf dieser ist, nicht anzeigen.
2141  if (is_array($included_sites) && !empty($included_sites) && !in_array($site_name, $included_sites) ) {
2142  return [];
2143  }
2144 
2145  // Der Seitentyp wird nicht angezeigt
2146  if ($types['hidden']) {
2147  return [];
2148  }
2149 
2150  foreach (array("icon","jquery") as $k)
2151  {
2152  if ($entry[$k])
2153  {
2154  $types[$k] = $entry[$k];
2155  }
2156  }
2157 
2158  }
2159 
2160  $get_types = function($this_dir) use ($site_name, $type, $fullname, $depth, $site_type, &$types) {
2161  $dir = dir($this_dir.($type?$type.'/':''));
2162  while ($file = $dir->read())
2163  {
2164  if ($file[0]!='.' && is_dir($dir->path.$file) && ($file!='multimedia' || $site_type=='media'))
2165  {
2166  $type_array = $this->_getTypesOfDirectory($this_dir, $site_name, ($type?$type.'/':'').$file, $fullname, $depth+1, $site_type);
2167  if ($type_array)
2168  {
2169  $types['children'][$type_array['type']] = $type_array;
2170  }
2171  }
2172  }
2173  };
2174 
2175  if ($root_dir != $original_root_dir && is_dir($root_dir.($type?$type.'/':'')))
2176  {
2177  // Fallback Seitentypen aufnehmen
2178  $get_types($root_dir);
2179  }
2180  if (is_dir($original_root_dir.($type?$type.'/':'')))
2181  {
2182  $get_types($original_root_dir);
2183  }
2184 
2185  if ($types['children'])
2186  {
2187  $this->_sortTypes($types['children']);
2188  }
2189 
2190  return $types;
2191  }
2192 
2199  private static function _getFlatTypes($tree)
2200  {
2201  $types_array = array();
2202  if(is_array($tree))
2203  {
2204  foreach ($tree as $item)
2205  {
2206  $types_array[] = $item;
2207  if ($item['children'])
2208  {
2209  $types_array = array_merge($types_array, Site::_getFlatTypes($item['children']));
2210  }
2211  }
2212  }
2213  return $types_array;
2214  }
2215 
2230  function getTypes($flat=true,$params=array())
2231  {
2232  $get = function() use ($flat, $params) {
2233  $cache_file = $GLOBALS['egotec_conf']['cache_dir'].$this->name.'/types'.($flat ? 'Flat' : '').md5(serialize(array($params)));
2234  if (
2235  Ego_System::file_exists($cache_file)
2236  && ($types = @unserialize(Ego_System::file_get_contents($cache_file)))
2237  ) {
2238  return $types;
2239  }
2240 
2241  if ($params['only_system'])
2242  {//Systemseitentypen die NICHT durch Mandantenspezifische Seitentypen überschrieben werden
2243  $types = $this->_getTypesOfDirectory($GLOBALS['egotec_conf']['site_dir'].$this->name.'/', $this->name);
2244  $types1 = $this->_getTypesOfDirectory($GLOBALS['egotec_conf']['pub_dir'].'type/site/', $this->name);
2245  $types2 = $this->theme ? $this->_getTypesOfDirectory($GLOBALS['egotec_conf']['pub_dir']."theme/{$this->theme}/site/", $this->name) : null;
2246  $types3 = $this->globalAllowed() ? $this->_getTypesOfDirectory($GLOBALS['egotec_conf']['site_dir'].'_global/', $this->name) : null;
2247  $types4 = $this->_getTypesOfDirectory($GLOBALS['egotec_conf']['lib_dir'].'type/site/', $this->name, '', '', -1, $this->site['type']);
2248 
2249  if (is_array($types)) {
2250  $result_types['children'] = array_diff_key($types4['children'],$types['children']);
2251  } else {
2252  $result_types = $types4;
2253  }
2254  if (is_array($types3)) {
2255  $result_types['children'] = array_diff_key($result_types['children'],$types3['children']);
2256  }
2257  if (is_array($types2)) {
2258  $result_types['children'] = array_diff_key($result_types['children'], $types2['children']);
2259  }
2260  if (is_array($types1)) {
2261  $result_types['children'] = array_merge($result_types['children'],$types1['children']);
2262  }
2263  $this->_types = $result_types['children']?$result_types['children']:array();
2264  if ($params['include_theme']) {
2265  $theme_types = $types2['children']?$types2['children']:array();
2266  $this->_types = array_merge($this->_types, $theme_types);
2267  }
2268  if ($params['include_global']) {
2269  $global_types = $types3['children']?$types3['children']:array();
2270  $this->_types = array_merge($this->_types, $global_types);
2271  }
2272  } elseif ($params['only_global'])
2273  {
2274  if ($this->globalAllowed()) {
2275  $types = $this->_getTypesOfDirectory($GLOBALS['egotec_conf']['site_dir'].'_global/', $this->name);
2276  $this->_types = $types['children']?$types['children']:array();
2277  } else {
2278  $this->_types = array();
2279  }
2280  } elseif ($params['only_site'])
2281  {
2282  $types = $this->_getTypesOfDirectory($GLOBALS['egotec_conf']['site_dir'].$this->name.'/', $this->name);
2283  $this->_types = $types['children']?$types['children']:array();
2284  } elseif ($params['only_theme'])
2285  {
2286  $types = $this->_getTypesOfDirectory($GLOBALS['egotec_conf']['pub_dir'].'theme/'.$this->theme.'/site/', $this->name);
2287  $this->_types = $types['children']?$types['children']:array();
2288  } else
2289  {
2290  if (!$this->_types)
2291  {
2292  $types_filename=$GLOBALS['egotec_conf']['cache_dir'].$this->name.'/types.cache';
2293  if (Ego_System::file_exists($types_filename))
2294  {
2295  $this->_types = @unserialize(Ego_System::file_get_contents($types_filename));
2296  } else
2297  {
2298  $types = $this->_getTypesOfDirectory($GLOBALS['egotec_conf']['site_dir'].$this->name.'/', $this->name);
2299  $types1 = $this->_getTypesOfDirectory($GLOBALS['egotec_conf']['pub_dir'].'type/site/', $this->name);
2300  $types2 = $this->theme ? $this->_getTypesOfDirectory($GLOBALS['egotec_conf']['pub_dir']."theme/{$this->theme}/site/", $this->name) : null;
2301  $types3 = $this->globalAllowed() ? $this->_getTypesOfDirectory($GLOBALS['egotec_conf']['site_dir'].'_global/', $this->name) : null;
2302  $types4 = $this->_getTypesOfDirectory($GLOBALS['egotec_conf']['lib_dir'].'type/site/', $this->name, '', '', -1, $this->site['type']);
2303 
2304  $this->_types = array_merge(
2305  $types4['children']?$types4['children']:array(),
2306  $types3['children']?$types3['children']:array(),
2307  $types2['children']?$types2['children']:array(),
2308  $types1['children']?$types1['children']:array(),
2309  $types['children']?$types['children']:array()
2310  );
2311  Ego_System::file_put_contents($types_filename, serialize($this->_types));
2312  }
2313  }
2314  }
2315 
2316  if ($flat)
2317  {
2318  $md5 = md5(serialize($params));
2319  if (!$this->_typesFlat[$md5])
2320  {
2321  $this->_typesFlat[$md5] = Site::_getFlatTypes($this->_types);
2322  }
2323  $this->_sortTypes($this->_typesFlat[$md5]);
2324  Ego_System::file_put_contents($cache_file, serialize($this->_typesFlat[$md5]));
2325  return $this->_typesFlat[$md5];
2326  } else
2327  {
2328  $this->_sortTypes($this->_types);
2329  Ego_System::file_put_contents($cache_file, serialize($this->_types));
2330  return $this->_types;
2331  }
2332  };
2333 
2334  $types = $get();
2335 
2336  // Kundenspezifischen Filter anwenden
2337  if (Ego_System::file_exists($system_path = $GLOBALS['egotec_conf']['var_dir'] . 'lib/site_get_types.php')) {
2338  require_once $system_path;
2339  if (function_exists('site_get_types')) {
2340  $types = site_get_types($this, $types, $flat, $params);
2341  }
2342  }
2343 
2344  return $types;
2345  }
2346 
2352  function getKeywords($query = []) {
2353  $keywords = [];
2354 
2355  $recursive = function($parent, $depth = 0) use (&$recursive, &$keywords, $query) {
2356  $query_where = "type = '_keywords/entry'" . ($query['where'] ? " AND ({$query['where']})" : '');
2357  unset($query['where']);
2358  $children = $parent->getChildren(array_merge(['where' => $query_where], $query), ['sitemap' => false]);
2359  foreach ($children as $child) {
2360  $child->field['depth'] = $depth;
2361  $keywords[] = $child;
2362  $recursive($child, $depth + 1);
2363  }
2364  };
2365 
2366  $keyword_lists = $this->getPages(['where' => 'type = "_keywords/list"'], ['sitemap' => false]);
2367  foreach ($keyword_lists as $keyword_list) {
2368  $recursive($keyword_list);
2369  }
2370 
2371  return $keywords;
2372  }
2373 
2380  function getTypeInfo($name) {
2381  if (!empty($this->_types)) {
2382  $parts = explode('/', $name);
2383  $type = $this->_types[$parts[0]];
2384  $child = '';
2385  foreach ($parts as $index => $part) {
2386  if ($type['type'] == $name) {
2387  return $type;
2388  } else {
2389  if (empty($child)) {
2390  $child = $part;
2391  } else {
2392  $child .= '/'.$part;
2393  }
2394  if (!empty($type['children']) && !empty($type['children'][$child])) {
2395  $type = $type['children'][$child];
2396  if ($type['type'] == $name) {
2397  return $type;
2398  }
2399  }
2400  }
2401  }
2402  } else {
2403  $types = $this->getTypes();
2404  foreach ($types as $type) {
2405  if ($type['type'] == $name) {
2406  return $type;
2407  }
2408  }
2409  }
2410  return array();
2411  }
2412 
2420  function getTypeFiles($type)
2421  {
2422  $files = array();
2423  $dirs_to_read = array(
2424  'site &raquo; ' => array(
2425  $GLOBALS['egotec_conf']['lib_dir'].'type/site/'.$type,
2426  $this->globalAllowed() ? $GLOBALS['egotec_conf']['site_dir'].'_global/'.$type : '',
2427  $GLOBALS['egotec_conf']['site_dir'].$this->name.'/'.$type,
2428  ),
2429  'site/admin &raquo; ' => array(
2430  $GLOBALS['egotec_conf']['lib_dir'].'type/site/'.$type.'/admin',
2431  $this->globalAllowed() ? $GLOBALS['egotec_conf']['site_dir'].'_global/'.$type.'/admin' : '',
2432  $GLOBALS['egotec_conf']['site_dir'].$this->name.'/'.$type.'/admin',
2433  ),
2434  'skin &raquo; ' => array(
2435  $GLOBALS['egotec_conf']['bin_dir'].'type/skin/'.$type,
2436  $GLOBALS['egotec_conf']['lib_dir'].'type/skin/'.$type,
2437  $this->globalAllowed() ? $GLOBALS['egotec_conf']['skin_dir'].'_global/'.$type : '',
2438  $GLOBALS['egotec_conf']['skin_dir'].$this->skin.'/'.$type
2439  )
2440  );
2441  if (!empty($this->theme)) {
2442  $dirs_to_read[$this->theme.' &raquo; '] = array(
2443  $GLOBALS['egotec_conf']['pub_dir'].'theme/'.$this->theme.'/site/'.$type,
2444  $GLOBALS['egotec_conf']['pub_dir'].'theme/'.$this->theme.'/skin/'.$type,
2445  );
2446  $dirs_to_read[$this->theme.'/admin &raquo; '] = array(
2447  $GLOBALS['egotec_conf']['pub_dir'].'theme/'.$this->theme.'/site/'.$type.'/admin'
2448  );
2449  }
2450 
2451  foreach ($dirs_to_read as $key => $dirs)
2452  {
2453  foreach ($dirs as $d)
2454  {
2455  if (!$d) {
2456  continue;
2457  }
2458  $dir = @dir($d);
2459  while ($dir && false !== ($f = $dir->read()))
2460  {
2461  if ($f[0]=='.' || is_dir($dir->path.'/'.$f)) continue;
2462 
2463  $files[$key.'/'.$f] = $dir->path.'/'.$f;
2464  }
2465  }
2466  }
2467 
2468  return $files;
2469  }
2470 
2480  function getSitemapRootIdArray($param = array(), $recalc = false, $user = true, $query = array())
2481  {
2482  $key = md5($this->pageTable.json_encode($this->_param));
2483 
2484  // Aus dem User Objekt holen
2485  if (
2486  !$recalc
2487  && $user
2488  && is_array($GLOBALS['auth']->user->extra['rootIdArray'])
2489  && is_array($GLOBALS['auth']->user->extra['rootIdArray'][$key])
2490  ) {
2491  return $GLOBALS['auth']->user->extra['rootIdArray'][$key];
2492  }
2493 
2494  $where = $query['where'];
2495  unset($query['where']);
2496  $query = array_merge(array(
2497  'fields' => $this->pageTable.'.id, '. $this->pageTable.'_children.page_id, parent.type',
2498  'inner' => array(
2499  $this->pageTable.'_children ON '.$this->pageTable.'_children.child='.$this->pageTable.'.id',
2500  $this->pageTable.' AS parent ON '.$this->pageTable.'_children.page_id=parent.id'
2501  ),
2502  'distinct' => true
2503  ), $query);
2504  $query['where'] = "parent.type != '_keywords/entry'";
2505  if ($where) {
2506  $query['where'] .= " AND ($where)";
2507  }
2508  $all_parents = $this->getPages($query, $param);
2509 
2510  $id_string = '';
2511  $parent_string = '';
2512  foreach ($all_parents as $page)
2513  {
2514  if ($page->field['page_id']) {
2515  $parent_string = $parent_string.','.$page->field['page_id'];
2516  }
2517  $id_string = $id_string.','.$page->field['id'];
2518  }
2519  $parent_string = trim($parent_string,',');
2520  $id_string = trim($id_string,',');
2521 
2522  $parents = array();
2523  $all_ids = array();
2524  $parents = empty($parent_string) ? array() : explode(',', $parent_string);
2525  $all_ids = empty($id_string) ? array() : explode(',', $id_string);
2526  $parents = array_unique($parents);
2527  $all_ids = array_unique($all_ids);
2528 
2529  if ($param['deleted'] == 1)
2530  { // Die Eltern aller gelöschten Seiten zurückgeben.
2531  $ids = $parents;
2532  } elseif (empty($parents))
2533  { // es gibt keine Eltern
2534  $ids = array();
2535  } else {
2536  $with_permission = $all_ids; // Alle Eltern bestimmen, auf die der Benutzer eine Berechtigung besitzt.
2537  $ids = array(); // Alle Vorfahren zu den Eltern bestimmen, für die der Benutzer keine Berechtigung besitzt.
2538  $page = $this->getRoot(array('auth_or' => '1=1', 'deleted_or' => '1=1'));
2539 
2540  foreach ($parents as $id)
2541  {
2542  if (!in_array($id, $with_permission))
2543  {
2544  $ids = array_merge($ids,$page->_getAncestorsIds(
2545  $this->getPage($id, array('auth_or' => '1=1')),
2546  array('limit' => 1, 'order' => 'id'),
2547  array('auth_or' => '1=1', 'deleted' => -1)
2548  ));
2549  $ids[] = $id;
2550  }
2551  }
2552  }
2553 
2554  if ($param['all_ids']) {
2555  $ids = array_merge($ids, $all_ids);
2556  }
2557 
2558  $ids = array_unique($ids);
2559 
2560  // Im User Objekt speichern
2561  if (!isset($param['deleted']) && $user) {
2562  if (!is_array($GLOBALS['auth']->user->extra['rootIdArray'])) {
2563  $GLOBALS['auth']->user->extra['rootIdArray'] = array();
2564  }
2565  $GLOBALS['auth']->user->extra['rootIdArray'][$key] = $ids;
2566  $GLOBALS['auth']->user->update();
2567  }
2568 
2569  return $ids;
2570  }
2571 
2581  function hasRight($right, $flag=false, $user_id = false, $rights = array())
2582  {
2583  $rights = !empty($rights) ? $rights : $this->admin['right'];
2584  if ($right == "desktop")
2585  {
2586  $flag = true;
2587  }
2588  $i = 0;
2589  do
2590  {
2591  $group = $rights[$right.'_group_'.$i];
2592  if ($group=='')
2593  {
2594  break;
2595  }
2596  $role = $rights[$right.'_role_'.$i];
2597  if ($GLOBALS['auth']->hasPermission($group, $role, $flag, $user_id))
2598  {
2599  return true;
2600  }
2601  $i++;
2602  } while ($group!='');
2603  return $i==0;
2604  }
2605 
2612  function hasPermission($right)
2613  {
2614  $rights = $this->admin['right'];
2615 
2616  if (is_array($rights))
2617  {
2618  foreach ($rights as $r => $value)
2619  {
2620  if (preg_match('/^'.$right.'_group_(\d+)/i', $r, $g))
2621  {
2622  $group = $g[1];
2623 
2624  if (isset($rights[$right.'_role_'.$group]) && !$this->isPermission($value, $rights[$right.'_role_'.$group]))
2625  {
2626  return false;
2627  }
2628  }
2629  }
2630  }
2631 
2632  return true;
2633  }
2634 
2638  function isPermission($group, $role)
2639  {
2640  if (empty($group) && empty($role))
2641  {
2642  return true;
2643  }
2644 
2645  $db = new_db_connection(
2646  array(
2647  'fields' => 'group_id',
2648  'table' => 'egotec_group',
2649  'where' => 'group_id =:group',
2650  'bind' => array(
2651  'group' => $group
2652  )
2653  )
2654  );
2655  if($db->nextRecord())
2656  {
2657  $db = new_db_connection(
2658  array(
2659  'fields' => 'role_id',
2660  'table' => 'egotec_role',
2661  'where' => 'role_id =:role',
2662  'bind' => array(
2663  'role' => $role
2664  )
2665  )
2666  );
2667 
2668  return $db->nextRecord();
2669  }else
2670  {
2671  return false;
2672  }
2673  }
2674 
2687  public function checkCondition($condition) {
2688  $valid = false;
2689 
2690  $sub_queries = preg_split('/\s+(and|or)\s+/si', $condition);
2691  foreach ($sub_queries as $sub_query) {
2692  if (preg_match('/(!?(site|admin|conf|egotec_conf)\.([^ !=<>]+))(\s*(like|>=|<=|!=|=|>|<)\s*(.*?))?$/si', trim($sub_query, '() '), $matches)) {
2693  $param = $matches[1];
2694  $type = $matches[2];
2695  $operator = mb_strtolower($matches[5]);
2696  $check = trim($matches[6], '\'"');
2697  $field = $matches[3];
2698 
2699  // Feld darf nicht gesetzt sein
2700  $exclude = $param[0] == '!';
2701 
2702  // Aktueller Wert
2703  if ($type == 'egotec_conf') {
2704  $value = Ego_System::getAssocValue($GLOBALS['egotec_conf'], $field);
2705  } else {
2706  $value = Ego_System::getAssocValue($this->{$type}, $field);
2707  }
2708 
2709  if ($exclude) {
2710  $valid = !isset($value);
2711  } else {
2712  switch ($operator) {
2713  case 'like':
2714  $valid = mb_strpos($check, $value) !== false;
2715  break;
2716  case '>=':
2717  $valid = $value >= $check;
2718  break;
2719  case '<=':
2720  $valid = $value <= $check;
2721  break;
2722  case '!=':
2723  $valid = $value != $check;
2724  break;
2725  case '=':
2726  $valid = $value == $check;
2727  break;
2728  case '>':
2729  $valid = $value > $check;
2730  break;
2731  case '<':
2732  $valid = $value < $check;
2733  break;
2734  default:
2735  $valid = isset($value);
2736  }
2737  }
2738  }
2739  }
2740 
2741  return $valid;
2742  }
2743 
2751  function checkRight($right, $flag=false)
2752  {
2753  if ($this->hasRight($right, $flag))
2754  {
2755  return true;
2756  } else {
2758  }
2759  }
2760 
2767  public function getRights($right) {
2768  $rights = array();
2769  $i = 0;
2770  do {
2771  $group = $this->admin['right'][$right.'_group_'.$i];
2772  if ($group == '') {
2773  break;
2774  }
2775  $role = $this->admin['right'][$right.'_role_'.$i];
2776  $rights[] = array('group' => $group, 'role' => $role);
2777  $i++;
2778  } while ($group != '');
2779  return $rights;
2780  }
2781 
2788  public function setRight($right, $rights) {
2789  // Zunächst alle bisherigen Einträge löschen.
2790  $i = 0;
2791  do {
2792  $group = $this->admin['right'][$right.'_group_'.$i];
2793  if ($group == '') {
2794  break;
2795  }
2796  unset($this->admin['right'][$right.'_group_'.$i]);
2797  unset($this->admin['right'][$right.'_role_'.$i]);
2798  $i++;
2799  } while ($group != '');
2800 
2801  // Jetzt die Rechte setzen.
2802  $i = 0;
2803  foreach ($rights as $one_right) {
2804  $this->admin['right'][$right.'_group_'.$i] = $one_right['group'];
2805  $this->admin['right'][$right.'_role_'.$i] = $one_right['role'];
2806  }
2807  }
2808 
2813  function destroyIDs($ids)
2814  {
2815  $languages = $this->getLanguages();
2816  $name = $this->name;
2817  foreach($languages as $language)
2818  {
2819  foreach($ids as $id)
2820  {
2821  $_dbErase = new_db_connection();
2822  $_dbErase->delete(array('from' => $name.'_'.$language, 'where' => 'id = \''.$id.'\''));
2823  $_dbErase->delete(array('from' => $name.'_'.$language.'_fulltext', 'where' => 'id = \''.$id.'\''));
2824  $_dbErase->delete(array('from' => $name.'_'.$language.'_rights', 'where' => 'page_id = \''.$id.'\''));
2825  $_dbErase->delete(array('from' => $name.'_'.$language.'_users', 'where' => 'page_id = \''.$id.'\''));
2826  $_dbErase->delete(array('from' => $name.'_'.$language.'_v', 'where' => 'id = \''.$id.'\''));
2827  }
2828  }
2829  }
2830 
2839  function hasRightsOnId($id, $rights, $user_id = false, $cache = true)
2840  {
2841  if (!$user_id && $GLOBALS['auth']->hasSuperuserPermission()) {
2842  return true;
2843  }
2844 
2845  $cache_key = 'rights' . md5(serialize([
2846  $GLOBALS['auth']->isNobody()
2847  ? null
2848  : $GLOBALS['auth']->user->field['user_id'],
2849  $id,
2850  $rights,
2851  $user_id
2852  ]));
2853  $cache_entry = $this->getCacheEntry($cache_key);
2854  if (!$cache || $cache_entry === null) {
2855  $query = array(
2856  'fields'=> 'id',
2857  'from' => $this->pageTable,
2858  'where' => 'id='.$id
2859  );
2860  $db = new_db_connection(
2861  $GLOBALS['auth']->getPageTableQuery(
2862  $this->pageTable,
2863  $rights,
2864  $query,
2865  array(
2866  'user_id' => $user_id
2867  )
2868  )
2869  );
2870  $cache_entry = (boolean) $db->nextRecord();
2871  $this->setCacheEntry($cache_key, $cache_entry);
2872  }
2873  return $cache_entry;
2874  }
2875 
2884  public function isMetaUrl($path)
2885  {
2886  if (isset($this->_cachedMetaUrls[$path])) {
2887  return $this->_cachedMetaUrls[$path];
2888  }
2889  $db = new_db_connection(array(
2890  'table' => $this->pageTable,
2891  'fields' => 'url',
2892  'where' => 'url = :url',
2893  'bind' => array(
2894  'url' => $path
2895  )
2896  ));
2897  return $this->_cachedMetaUrls[$path] = ((bool) $db->nextRecord());
2898  }
2899 
2905  public function isPublicSave() {
2906  return $this->site['type'] == 'content' && $GLOBALS['egotec_conf']['save_method'] == 'public';
2907  }
2908 
2914  public function __toString()
2915  {
2916  return 'Site('.$this->name.'.'.$this->language.')';
2917  }
2918 
2924  public function __clone()
2925  {
2926  if ($this->_cache) {
2927  /* Wenn das Site Objekt geklont wird, muss das Cache Objekt ebenfalls geklont werden,
2928  * da es ansonsten eine Referenz zum originalen Objekt ist. */
2929  $this->_cache = clone $this->_cache;
2930  }
2931  }
2932 
2941  public function enoughDiskSpace()
2942  {
2943  $need_space = 2*1024*1024*1024; // 2 GB
2944  $dir_name = $GLOBALS['egotec_conf']['backup_dir'].'site/'.$this->name;
2945  if (Ego_System::file_exists($dir_name))
2946  {
2947  $times = array();
2948  $newest = 0;
2949  $dir = dir($GLOBALS['egotec_conf']['backup_dir'].'site/'.$this->name);
2950  while (false !== ($f = $dir->read()))
2951  {
2952  if (strrpos($f, '.tar.gz')===strlen($f)-7)
2953  {
2954  $time = filemtime($dir_name.'/'.$f);
2955  $times[$time] = filesize($dir_name.'/'.$f);
2956  $newest = $time > $newest ? $time : $newest;
2957  }
2958  }
2959  $dir->close();
2960  ksort($times);
2961  if (sizeof($times)>0)
2962  {
2963  $need_space = intval($times[$newest]) *3;
2964  }
2965  } else
2966  {
2967  if (!Ego_System::file_exists($GLOBALS['egotec_conf']['backup_dir']))
2968  {
2969  Ego_System::mkdir($GLOBALS['egotec_conf']['backup_dir']);
2970  }
2971  $dir_name = $GLOBALS['egotec_conf']['backup_dir'];
2972 
2973  // Backup Verzeichnis existiert nicht, dann anlegen
2974  if (!Ego_System::file_exists($dir_name))
2975  {
2976  Ego_System::mkdir($dir_name);
2977  }
2978  }
2979  if ($need_space < disk_free_space($dir_name))
2980  {
2981  return true;
2982  } else
2983  {
2984  return false;
2985  }
2986  }
2987 
2993  public function getCache()
2994  {
2995  return $this->_cache;
2996  }
2997 
3003  public function getCacheExpire()
3004  {
3005  $expire = (int) $this->admin['cache_expire_time'];
3006  if ($expire == 0) {
3007  $expire = 3600; // Standard: 1 Stunde
3008  }
3009  return $expire;
3010  }
3011 
3017  public function getCacheEntry($key)
3018  {
3019  if ($_REQUEST['preview']) {
3020  $key .= 'P';
3021  }
3022  if ($_REQUEST['c_date']) {
3023  $key .= 'C' . md5($_REQUEST['c_date']);
3024  }
3025  return $this->_cache->get($key);
3026  }
3027 
3035  public function setCacheEntry($key, $value)
3036  {
3037  if ($_REQUEST['preview']) {
3038  $key .= 'P';
3039  }
3040  if ($_REQUEST['c_date']) {
3041  $key .= 'C' . md5($_REQUEST['c_date']);
3042  }
3043  $this->_cache->set($key, $value);
3044  }
3045 
3049  public function getCacheLastChanged()
3050  {
3051  return $this->_cache->getLastChanged();
3052  }
3053 
3061  public function getDesklets($rights = false, $trashcan = false) {
3062  $site = $this;
3063  $auth = clone $GLOBALS['auth'];
3064  $smarty = clone $GLOBALS['smarty'];
3065  $active_cells = $GLOBALS['active_cells'] = explode(',', $GLOBALS['auth']->user->extra[$this->name.'_desktop_cells']);
3066 
3067  // Standard Inhalt für leere Desklets
3068  $desklet_default_content = '<p class="refresh"><a href="javascript:void(0)" onclick="egoDesktop.refresh()">'
3069  .$GLOBALS['auth']->translate('Laden Sie den Desktop neu, um den Inhalt dieses Desklets anzuzeigen.')
3070  .'</a></p>';
3071  $smarty->assign('desklet_default_content', $desklet_default_content);
3072 
3073  $desktop_dir = dir($GLOBALS['egotec_conf']['lib_dir'].'desktop/'.($trashcan ? 'trashcan/' : ''));
3074  while ($desktop_file = $desktop_dir->read()) {
3075  if (
3076  is_file($desktop_dir->path.$desktop_file)
3077  && substr($desktop_file, strlen($desktop_file)-4) == '.php'
3078  && file_exists($desktop_dir->path.$desktop_file)
3079  ) {
3080  require($desktop_dir->path.$desktop_file);
3081  }
3082  }
3083  $desktop_dir->close();
3084  if (!$trashcan) {
3085  if ($this->globalAllowed() && file_exists($GLOBALS['egotec_conf']['site_dir'].'_global/admin/desktop/')) {
3086  $desktop_dir = dir($GLOBALS['egotec_conf']['site_dir'].'_global/admin/desktop/');
3087  while ($desktop_file = $desktop_dir->read()) {
3088  if (
3089  is_file($desktop_dir->path.$desktop_file)
3090  && substr($desktop_file, strlen($desktop_file)-4) == '.php'
3091  && file_exists($desktop_dir->path.$desktop_file)
3092  ) {
3093  require($desktop_dir->path.$desktop_file);
3094  }
3095  }
3096  $desktop_dir->close();
3097  }
3098  if (file_exists($GLOBALS['egotec_conf']['site_dir'].$this->name.'/admin/desktop/')) {
3099  $desktop_dir = dir($GLOBALS['egotec_conf']['site_dir'].$this->name.'/admin/desktop/');
3100  while ($desktop_file = $desktop_dir->read()) {
3101  if (
3102  is_file($desktop_dir->path.$desktop_file)
3103  && substr($desktop_file, strlen($desktop_file)-4) == '.php'
3104  && file_exists($desktop_dir->path.$desktop_file)
3105  ) {
3106  require($desktop_dir->path.$desktop_file);
3107  }
3108  }
3109  $desktop_dir->close();
3110  }
3111  foreach ($this->getTypes() as $type) {
3112  $desktop_file = $GLOBALS['egotec_conf']['site_dir'].$this->name.'/'.$type['type'].'/admin/desktop.php';
3113  if ($this->globalAllowed() && !file_exists($desktop_file)) { // Fallback in das _global Verzeichnis.
3114  $desktop_file = $GLOBALS['egotec_conf']['site_dir'].'_global/'.$type['type'].'/admin/desktop.php';
3115  }
3116  if (!file_exists($desktop_file)) { // Fallback in das lib/type Verzeichnis.
3117  $desktop_file = $GLOBALS['egotec_conf']['lib_dir'].'type/site/'.$type['type'].'/admin/desktop.php';
3118  }
3119  if (file_exists($desktop_file)) {
3120  require($desktop_file);
3121  }
3122  }
3123 
3124  foreach ($GLOBALS['cells'] as $index => &$cell_item) {
3125  if (is_array($cell_item)) {
3126  foreach ($cell_item as &$cell) {
3127  if ($rights && isset($site->admin['desklets'][$cell['id']])) {
3128  $rights = explode(';', $site->admin['desklets'][$cell['id']]);
3129  if (sizeof($rights) > 0) {
3130  $perm = false;
3131  foreach ($rights as $right) {
3132  $group_role = explode(',', $right);
3133  if (
3134  empty($group_role[0])
3135  || empty($group_role[1])
3136  ||$GLOBALS['auth']->hasPermission($group_role[0], $group_role[1])
3137  ) {
3138  $perm = true;
3139  }
3140  }
3141  if (!$perm) {
3142  unset($GLOBALS['cells'][$index]);
3143  break;
3144  }
3145  }
3146  }
3147  $cell['visible'] = ($cell['permanent'] || in_array($this->name.'_'.$cell['id'], $active_cells));
3148  $cell['permanent'] = !empty($cell['permanent']);
3149 
3150  // Leere Desklets mit einem Standard Inhalt befüllen
3151  if (trim($cell['body']) == '') {
3152  $cell['body'] = $desklet_default_content;
3153  }
3154  }
3155  }
3156  }
3157  }
3158  return $GLOBALS['cells'] = array_values($GLOBALS['cells']);
3159  }
3160 
3166  public function getCRS() {
3167  $crs = json_decode(Ego_System::file_get_contents($GLOBALS['egotec_conf']['lib_dir'] . 'smarty/plugins/leaflet/crs.json'), true);
3168  if ($custom_crs = $this->getSiteFile('admin/crs.json')) {
3169  $crs = array_merge($crs, json_decode(Ego_System::file_get_contents($custom_crs), true));
3170  }
3171  return $crs;
3172  }
3173 
3180  public function getUploaderPage($page = null) {
3181  if ($file = $this->getSiteFile('admin/uploader.php')) {
3182  require_once($file);
3183  if (function_exists('getUploaderPage')) {
3184  if (!$page && $GLOBALS['page']) {
3185  $page = $GLOBALS['page'];
3186  }
3187  return getUploaderPage($this, $page);
3188  }
3189  } elseif ($this->hasMediaSite()) {
3190  $media_site = $this->getMediaSite();
3191  $media_site->addParam(array(
3192  'auth_or' => '1=1'
3193  ));
3194  $_users_page = $media_site->getPages(
3195  array('where' => 'name=\'_users\''),
3196  array(
3197  'auth_or' => '1=1',
3198  'inactive' => true,
3199  'only_active' => false
3200  )
3201  )->nextPage();
3202  if (!$_users_page)
3203  {
3204  $media_root_page = $media_site->getRoot(array('auth_or' => '1=1'));
3205  if (!$media_root_page) {
3206  return null;
3207  } else {
3208  $_users_page = $media_root_page->newChild(array(
3209  'name' => '_users',
3210  'title' => '_users',
3211  'type' => 'multimedia/category',
3212  'inactive' => 0
3213  ));
3214  }
3215  }
3216  $user_page = $_users_page->getChildren(
3217  array(
3218  'where' => 'name=:name',
3219  'bind' => array(
3220  'name' => $GLOBALS['auth']->user->field['username']
3221  )
3222  ),
3223  array(
3224  'auth_or' => '1=1',
3225  'inactive' => true,
3226  'only_active' => false
3227  )
3228  )->nextPage();
3229  if (!$user_page && !empty($GLOBALS['auth']->user->field['username']))
3230  {
3231  $user_page = $_users_page->newChild(array(
3232  'name' => $GLOBALS['auth']->user->field['username'],
3233  'title' => $GLOBALS['auth']->user->field['username'],
3234  'type' => 'multimedia/category',
3235  'inactive' => 0
3236  ));
3237  $user_page->setUsersArray(array(
3238  'edit' => array(array('user_id' => $GLOBALS['auth']->getId())),
3239  'child' => array(array('user_id' => $GLOBALS['auth']->getId())),
3240  'remove' => array(array('user_id' => $GLOBALS['auth']->getId()))
3241  ));
3242 
3243  // Sicherstellen, dass es mindestens eine Gruppen/Rollen Kombination gibt
3244  $rights = $user_page->getRightsArray();
3245  foreach (array('edit', 'child', 'remove') as $perm) {
3246  if (
3247  empty($rights[$perm])
3248  || in_array('*', array($rights[$perm][0]['group_id'], $rights[$perm][0]['role_id']))
3249  ) {
3250  $rights[$perm] = array(
3251  array(
3252  'group_id' => $GLOBALS['egotec_conf']['superuser']['group'],
3253  'role_id' => $GLOBALS['egotec_conf']['superuser']['role']
3254  )
3255  );
3256  }
3257  }
3258  $user_page->setRightsArray($rights);
3259  }
3260  return $user_page;
3261  }
3262  return null;
3263  }
3264 
3270  public function hasDeleted() {
3271  $deleted = $this->getPages(array(), array(
3272  'auth_or' => '1=1',
3273  'deleted' => 1
3274  ));
3275  return (bool) $deleted->nextPage();
3276  }
3277 
3284  public function clearTrashcan($query = array()) {
3285  $cluster_list = Ego_System::getCluster($this);
3286  $original_where = '';
3287  if (empty($query['where'])) {
3288  $query['where'] = '1=1';
3289  } else {
3290  $original_where = $query['where'];
3291  }
3292  if (count($cluster_list) > 0) {
3293  $time = array();
3294  foreach ($cluster_list as $cluster) {
3295  $log_filename = $GLOBALS['egotec_conf']['log_dir'].$this->name.'/live.'.$this->name.'_'.$this->language.'.'.$cluster['id'].'.up.date';
3296  if (file_exists($log_filename)) {
3297  $time[] = file_get_contents($log_filename);
3298  }
3299  }
3300  sort($time);
3301  if (count($time) > 0) {
3302  $query['where'].= " AND ".$this->pageTable.".m_date<'{$time[0]}'";
3303  }
3304  } else {
3305  $log_filename = $GLOBALS['egotec_conf']['log_dir'].$this->name.'/live.'.$this->name.'_'.$this->language.'.date';
3306  if (!file_exists($log_filename)) {
3307  $log_filename = $GLOBALS['egotec_conf']['log_dir'].$this->name.'/live.date';
3308  }
3309  if (file_exists($log_filename)) {
3310  $live_date = file_get_contents($log_filename);
3311  $query['where'].= " AND ".$this->pageTable.".m_date<'$live_date'";
3312  }
3313  }
3314 
3315  $del_pages = $this->getPages($query, array(
3316  'deleted' => 1,
3317  'inactive' => true,
3318  'only_active' => false,
3319  'no_cache' => 1,
3320  'rights' => array('delete')
3321  ));
3322  while ($page = $del_pages->nextPage()) {
3323  $page->destroy();
3324  }
3325 
3326  $query['where'] = $original_where;
3327  $rest = $this->getPages($query, array(
3328  'deleted' => 1,
3329  'inactive' => true,
3330  'only_active' => false,
3331  'no_cache' => 1
3332  ));
3333  $msg = $GLOBALS['auth']->translate("Der Papierkorb wurde geleert.");
3334  $z = $rest->numRecords();
3335  if ($z > 0) {
3336  $msg.= '<p class="warning">'
3337  . $GLOBALS['auth']->translate("%z Seiten können wegen mangelnder Berechtigung nicht gelöscht werden oder werden beim nächsten Liveabgleich gelöscht.", [
3338  'z' => $z
3339  ]) . '</p>';
3340  }
3341  return $msg;
3342  }
3343 
3350  public function getPageClass($type = 'page') {
3351  $cache_key = 'pageClasses';
3352  if (empty($this->_classes)) {
3353  $this->_classes = $this->getCacheEntry($cache_key);
3354  }
3355  if ($this->_classes === null || !isset($this->_classes[$type])) {
3356  if (!is_array($this->_classes)) {
3357  $this->_classes = array();
3358  }
3359  $this->_classes[$type] = $this->_getPageClass($type);
3360  $this->setCacheEntry($cache_key, $this->_classes);
3361  }
3362 
3363  if (!class_exists($this->_classes[$type]['class'], false) && !empty($this->_classes[$type]['file'])) {
3364  $file = $GLOBALS['egotec_conf']['egotec_dir'].ltrim($this->_classes[$type]['file'], DIRECTORY_SEPARATOR);
3365  require_once($file);
3366  }
3367  return $this->_classes[$type]['class'];
3368  }
3369 
3377  private function _getPageClass($type) {
3378  $prefix = 'Page' . ($this->conf['page']['prefix'] ?? '');
3379 
3380  // Page Erweiterung für den Seitentyp suchen
3381  $class = $prefix;
3382  foreach (explode('/', $type) as $part) {
3383  $class .= ucfirst($part);
3384  }
3385 
3386  // Seitentyp Page Erweiterung suchen
3387  if ($file = $this->getSiteFile($type.'/page.php', array('module'), true, true)) {
3388  return array('file' => $file, 'class' => $this->conf['page']['extension'][$class] ?? $class);
3389  }
3390 
3391  // Mandanten Page Erweiterung suchen
3392  $class = 'Page' . ucfirst($this->name);
3393  if ($file = $this->getSiteFile('page.php', array('module', 'global', 'parent_theme'), true, true)) {
3394  return array('file' => $file, 'class' => $class);
3395  }
3396 
3397  // Designvorlage Page Erweiterung suchen (nur in pub/theme/)
3398  if ($this->theme) {
3399  $class = 'Page' . implode('', array_map('ucfirst', explode('-', $this->theme)));
3400  if ($file = $this->getSiteFile('page.php', array('custom', 'global', 'system', 'module', 'parent_custom'), true, true)) {
3401  return array('file' => $file, 'class' => $class);
3402  }
3403  }
3404 
3405  // Globale Page Erweiterung suchen
3406  $class = 'PageGlobal';
3407  if ($file = $this->getSiteFile('page.php', array('custom', 'system', 'module'), true, true)) {
3408  return array('file' => $file, 'class' => $class);
3409  }
3410 
3411  // Es gibt keine Page Erweiterung
3412  return array('file' => '', 'class' => 'Page');
3413  }
3414 
3421  public function updateLinks($output = false) {
3422  set_time_limit(0);
3423 
3424  // Alle alten Verweise löschen
3425  $this->removeLinks();
3426 
3427  $params = array(
3428  'inactive' => true,
3429  'only_active' => false,
3430  'no_cache' => true,
3431  'auth_or' => '1=1'
3432  );
3433 
3434  $site = clone $this;
3435  foreach ($this->getLanguages() as $lang) {
3436  $site->setLanguage($lang);
3437  foreach ($site->getPages(array(), $params) as $page) {
3438  if ($output) {
3439  Ego_System::flush('.');
3440  }
3441  $page->updateLinks(false, true);
3442  }
3443  }
3444  }
3445 
3456  public function updateMediaIndex($resume, $c_date, $skipFirst, $dryRun, $timeout) {
3457  if($this->site['type'] != 'media') {
3458  echo "Is not a media site\n";
3459  return;
3460  }
3461 
3462  if ($GLOBALS['egotec_conf']['openoffice']['active'] != 1) {
3463  echo "index is not active\n";
3464  return;
3465  }
3466 
3467  require_once('openoffice/openoffice.php');
3468 
3469  // kl. Migration auf Sprach Verzeichnisse
3470  $old_file = $GLOBALS['egotec_conf']['log_dir'].$this->name;
3471  $new_file = $GLOBALS['egotec_conf']['log_dir'].$this->name."_".$this->language;
3472 
3473  if(Ego_System::file_exists($old_file."/index.tmp")) {
3474  if(!Ego_System::file_exists($new_file."/index.date")) {
3475  Ego_System::file_put_contents($new_file."/index.date", Ego_System::file_get_contents($old_file."/index.date"));
3476  }
3477  @unlink($old_file);
3478  }
3479 
3480  $position = 0;
3481  if($resume && Ego_System::file_exists($new_file."/index.date")) {
3482  $position = Ego_System::file_get_contents($new_file."/index.date");
3483  }
3484 
3485  $files = array();
3486  $addFile = function($path, $entry) use (&$files) {
3487  if($entry[0] === '.') { // '.' Einträge überspringen
3488  return;
3489  }
3490 
3491  if(preg_match('/_/', $entry)) { // ein Archiveintrag, wird übersprungen
3492  return;
3493  }
3494  $files[$entry] = filemtime($path.'/'.$entry).' '.$entry;
3495  };
3496 
3497  $path = $GLOBALS['egotec_conf']['var_dir'] . 'media/' . $this->name;
3498 
3499  if (!Ego_System::file_exists($path)) {
3500  // Abbrechen, wenn es das Multimedia Verzeichnis nicht gibt
3501  return;
3502  }
3503 
3504  // alle direkt unter /media/multimedia/*
3505  $d = dir($path);
3506  while (false !== ($entry = $d->read())) {
3507  if (!is_dir($d->path.'/'.$entry)) {
3508  $addFile($d->path, $entry);
3509  }
3510  }
3511  $d->close();
3512 
3513  // alle direkt unter /media/multimedia/language/*
3514  if (Ego_System::file_exists($d->path.'/'.$this->language)) {
3515  $d = dir($d->path.'/'.$this->language);
3516  while (false !== ($_entry = $d->read())) {
3517  $files[$this->language.'/'.$_entry] = filemtime($d->path.'/'.$_entry).' '.$this->language.'/'.$_entry;
3518  }
3519  $d->close();
3520  }
3521 
3522  asort($files);
3523  $startTime = time();
3524  clearstatcache();
3525 
3526  foreach($files as $entry => $fileTime) {
3527  if($resume && $fileTime <= $position) {
3528  continue;
3529  }
3530 
3531  $timeRound = strtok($fileTime, ' '); // Den Unixzeitstempel extrahieren.
3532 
3533  if ($skipFirst) {
3534  $skipFirst = false;
3535  echo "[Fs ] $entry ".date("Y-m-d H:i:s", $timeRound)."\n";
3536  continue;
3537  }
3538 
3539  $id = preg_replace('/^[^\d]+/', '', $entry);
3540  if (!is_numeric($id)) {
3541  continue;
3542  }
3543 
3544  $page = $this->getPage($id, array('inactive' => 1, 'auth_or' => '1=1'));
3545  if(!$page) {
3546  echo "[F] $id not found in DB\n";
3547  continue;
3548  }
3549 
3550  echo "[DS ] ".$entry." ".date("Y-m-d H:i:s", $timeRound)."\n";
3551 
3552  $extra = $page->extra;
3553  $mime_type = $extra['mime_type'];
3554  $file_ext = $extra['image_type']; // wird von der convert_content benötigt
3555 
3556  if (!empty($mime_type)) {
3557  if (!empty($file_ext)) {
3558  $mime_type = Ego_System::getMimeTypes($file_ext);
3559  } else {
3560  continue;
3561  }
3562  }
3563 
3564  # nur Dateien vom Type ^application oder text... versuchen zu importieren
3565  if (!preg_match('/^application|text/', $mime_type)) {
3566  continue;
3567  }
3568 
3569  if (empty($file_ext)) {
3570  if (!$GLOBALS['mime2ext']) {
3571  $GLOBALS['mime2ext'] = array_flip(Ego_System::getMimeTypes());
3572  }
3573 
3574  $file_ext = $GLOBALS['mime2ext'][$mime_type];
3575  }
3576 
3577  $content = convert_content($path . '/' . $entry, $file_ext, $mime_type);
3578  if(!empty($content)) {
3579  echo "[FC";
3580  if(!$dryRun) {
3581  try {
3582  $page->update(array(
3583  'field' => array(
3584  'content' => Ego_System::filterNonUtf8($content, '', true)
3585  ), TRUE, !$c_date
3586  ));
3587  } catch(Exception $e) {
3588  echo "f] " . $e->getMessage() . "\n";
3589  Ego_System::file_put_contents($new_file."/index_error.log", date("Y-m-d H:i:s")." Datei: $entry (".$page->field["name"]."), Datenbankupdate fehlgeschlagen\n", FILE_APPEND);
3590  }
3591  echo "u] $entry\n";
3592  Ego_System::file_put_contents($new_file."/index.log", date("Y-m-d H:i:s")." $entry (".$page->field["name"].".".$extra['image_type'].") [".strlen($content)."]\n", FILE_APPEND);
3593  } else {
3594  echo " ] $entry\n";
3595  }
3596  } else {
3597  echo "[FCf] $entry (mime_type: $mime_type)\n";
3598  Ego_System::file_put_contents($new_file."/index_error.log", date("Y-m-d H:i:s")." Datei: $entry (".$page->field["name"].".".$extra['image_type']."), konnte nicht konvertiert werden\n", FILE_APPEND);
3599  }
3600 
3601  // position merken
3602  if(!$dryRun) {
3603  Ego_System::file_put_contents($new_file."/index.date", $fileTime);
3604  }
3605  if ($timeout && time() - $startTime > $timeout) {
3606  break;
3607  }
3608  }
3609 
3610  $this->clearCache();
3611  echo $this->name."_".$this->language." Cache cleared.\n";
3612  }
3613 
3620  public function removeLinks($language = '') {
3621  $db = new_db_connection();
3622  if ($language) {
3623  $db->delete(array(
3624  'table' => 'egotec_links',
3625  'where' => 'src_site = :site AND src_lang = :lang',
3626  'bind' => array(
3627  'site' => $this->name,
3628  'lang' => $language
3629  )
3630  ));
3631  } else {
3632  $db->delete(array(
3633  'table' => 'egotec_links',
3634  'where' => 'src_site = :site',
3635  'bind' => array(
3636  'site' => $this->name
3637  )
3638  ));
3639  }
3640  }
3641 
3648  public function removeUrls($language = '') {
3649  $db = new_db_connection();
3650  $db->begin();
3651  if ($language) {
3652  $db->delete(array(
3653  'table' => 'egotec_url',
3654  'where' => 'site = :site AND lang = :lang',
3655  'bind' => array(
3656  'site' => $this->name,
3657  'lang' => $language
3658  )
3659  ));
3660  } else {
3661  $db->delete(array(
3662  'table' => 'egotec_url',
3663  'where' => 'site = :site',
3664  'bind' => array(
3665  'site' => $this->name
3666  )
3667  ));
3668  }
3669  $db->commit();
3670  }
3671 
3679  public function updateUrls($reset = false, $verbose = false) {
3680  if ($reset) {
3681  // Alle zugehörigen URLs löschen
3682  $this->removeUrls($this->language);
3683  }
3684  if ($root = $this->getRoot(array(
3685  'auth_or' => '1=1',
3686  'inactive' => true,
3687  'only_active' => false
3688  ))) {
3689  $root->updateUrls($verbose, null, true);
3690  unset($GLOBALS['__page_update_urls_stack']); // Den Stack nach jedem Mandanten wieder freigeben
3691  $this->clearCache();
3692  }
3693  }
3694 
3700  public function getUnusedPages() {
3701  if ($this->site['type'] == 'media') {
3702  return $this->getPages(array(
3703  'join' => array('egotec_links ON ('
3704  .' egotec_links.dest_site = :site'
3705  .' AND egotec_links.dest_lang = :lang'
3706  .' AND id = egotec_links.dest_id)'),
3707  'where' => "egotec_links.src_id IS NULL"
3708  ." AND deleted = 0"
3709  ." AND type IN ('multimedia/file', 'multimedia/image')",
3710  'bind' => array(
3711  'site' => $this->name,
3712  'lang' => $this->language
3713  )
3714  ), array(
3715  'auth_or' => '1=1',
3716  'inactive' => 1,
3717  'only_active' => false,
3718  'nouse' => true
3719  ));
3720  } elseif ($media = $this->getMediaSite()) {
3721  return $media->getUnusedPages();
3722  }
3723  return new Page_Iterator($this);
3724  }
3725 
3733  public function getNonPublicPages($query = [], $param = []) {
3734  if ($GLOBALS['auth']->isNobody()) {
3735  // Nicht angemeldete Benutzer erhalten keine Ergebnisse
3736  return [];
3737  }
3738 
3739  // Limit muss logisch angewendet werden
3740  if (isset($query['limit'])) {
3741  [$start, $max] = explode(',', $query['limit']);
3742  $start = trim($start);
3743  $max = trim($max);
3744  unset($query['limit']);
3745  } else {
3746  $start = 0;
3747  $max = 0;
3748  }
3749 
3750  $query['where'] = "({$this->pageTable}_v.c_date > {$this->pageTable}.c_date AND {$this->pageTable}_v.c_user = :this_user)"
3751  . ($query['where'] ? " AND {$query['where']}" : '');
3752  $query['bind'] = array_merge($query['bind'] ?? [], [
3753  'this_user' => $GLOBALS['auth']->user->field['user_id']
3754  ]);
3755  $query['fields'] = "{$this->pageTable}.*, {$this->pageTable}_v.id, {$this->pageTable}_v.c_user, MAX({$this->pageTable}_v.c_date) AS v_date"
3756  . ($query['fields'] ? ", {$query['fields']}" : '');
3757  $query['inner'] = array_merge($query['inner'] ?? [], [
3758  "{$this->pageTable}_v ON {$this->pageTable}.id = {$this->pageTable}_v.id"
3759  ]);
3760  $query['group'] = "{$this->pageTable}_v.id";
3761  $query['order'] = $query['order'] ? $query['order'] : "v_date DESC";
3762 
3763  $param = array_merge([
3764  'sitemap' => true,
3765  'inactive' => true,
3766  'only_active' => false
3767  ], $param);
3768 
3769  $pages = [];
3770  $num = 0;
3771  foreach ($this->getPages($query, $param) as $page) {
3772  if ($page->isPublicSave()) {
3773  if ($num >= $start) {
3774  $pages[] = $page;
3775 
3776  if ($max > 0 && ($num + 1) == $max) {
3777  break;
3778  }
3779  }
3780 
3781  $num++;
3782  }
3783  }
3784  return $pages;
3785  }
3786 
3805  public function getCopyrights($start = 0, $limit = 0, &$m = 0) {
3806  $copyrights = [];
3807  $n = 0;
3808  if ($m === null) {
3809  $m = 0;
3810  }
3811 
3812  // Multimedia Mandanten prüfen
3813  if ($media = $this->getMediaSite()) {
3814  $pages = $media->getPages([
3815  'fields' => $media->pageTable.'.*, egotec_links.src_id',
3816  'inner' => [
3817  'egotec_links ON ' . $media->pageTable . '.id = egotec_links.dest_id'
3818  ],
3819  'where' => 'src_site = :src_site AND src_lang = :src_lang AND dest_site = :dest_site',
3820  'bind' => [
3821  'src_site' => $this->name,
3822  'src_lang' => $this->language,
3823  'dest_site' => $media->name
3824  ]
3825  ]);
3826  foreach ($pages as $page) {
3827  if ($page->extra['copyright'] !== null) {
3828  $n++;
3829  if ($limit > 0) {
3830  if ($n <= $start) {
3831  continue;
3832  } elseif (($m + 1) > $limit) {
3833  $m++;
3834  break;
3835  }
3836  }
3837 
3838  $key = md5(mb_strtolower($page->extra['copyright']));
3839 
3840  if (!isset($copyrights[$key])) {
3841  $copyrights[$key] = [
3842  'title' => $page->extra['copyright'],
3843  'pages' => []
3844  ];
3845  }
3846 
3847  $identity = $page->getIdentity();
3848  if (!isset($copyrights[$key]['pages'][$identity])) {
3849  $copyrights[$key]['pages'][$identity] = [
3850  'page' => $page->getIdentity(),
3851  'pool' => null,
3852  'linked' => []
3853  ];
3854  }
3855 
3856  if ($link = $this->getPage($page->field['src_id'])) {
3857  $copyrights[$key]['pages'][$identity]['linked'][] = [
3858  'name' => $link->field['name'],
3859  'url' => $link->getUrl()
3860  ];
3861 
3862  $m++;
3863  }
3864  }
3865  }
3866  }
3867 
3868  // Mediapool Dateien prüfen
3869  if ($this->admin['mediapool']['active']) {
3870  $pages = $this->getPages();
3871  foreach ($pages as $page) {
3872  foreach ($page->getMediapool()->list() as $item) {
3873  if ($item['copyright']) {
3874  $n++;
3875  if ($limit > 0) {
3876  if ($n <= $start) {
3877  continue;
3878  } elseif (($m + 1) > $limit) {
3879  $m++;
3880  break 2;
3881  }
3882  }
3883 
3884  $key = md5(mb_strtolower($item['copyright']));
3885 
3886  if (!isset($copyrights[$key])) {
3887  $copyrights[$key] = [
3888  'title' => $item['copyright'],
3889  'pages' => []
3890  ];
3891  }
3892 
3893  $identity = $item['name'];
3894  if (!isset($copyrights[$key]['pages'][$identity])) {
3895  $copyrights[$key]['pages'][$identity] = [
3896  'page' => $page->getIdentity(),
3897  'pool' => $item,
3898  'linked' => []
3899  ];
3900  }
3901 
3902  $copyrights[$key]['pages'][$identity]['linked'][] = [
3903  'name' => $page->field['name'],
3904  'url' => $page->getUrl()
3905  ];
3906 
3907  $m++;
3908  }
3909  }
3910  }
3911  }
3912 
3913  usort($copyrights, function($a, $b) {
3914  return strcmp($a['title'], $b['title']);
3915  });
3916  return array_values($copyrights);
3917  }
3918 
3931  public function getTemplate($mobile = false, $name = 'index', $dir = '', $variant = '', $suffix = '', $fallback = true) {
3932  if (empty($suffix)) {
3933  $suffix = $_SERVER['REQUEST_SUFFIX'];
3934  }
3935  $key = 'template'.md5(serialize(array($this->skin, $mobile, $name, $dir, $variant, $suffix, $fallback)));
3936  $template = $this->getCacheEntry($key);
3937  if ($template === null) {
3938  $template = '';
3939 
3940  if (!empty($variant)) {
3941  $variant = ".{$variant}";
3942  }
3943  if ($suffix == '.htm') {
3944  // Bei .htm immer das .pdf Template verwenden
3945  $suffix = '.pdf';
3946  }
3947  $suffix = !in_array($suffix, array('.html', '.php')) ? $suffix : '';
3948  if ($suffix && $variant == $suffix) {
3949  $variant = '';
3950  }
3951  $base_dir = $dir ? explode('/', $dir)[0] : '';
3952  foreach (array('.tpl', '.html') as $file_suffix) {
3953  if (!empty($template)) {
3954  break;
3955  }
3956  $file = $mobile ? $name . $variant . '.mobile' . $suffix . $file_suffix : $name . $variant . $suffix . $file_suffix;
3957  if (
3958  $base_dir
3959  && $name == 'index'
3960  && !$this->skin
3961  && !$this->theme
3962  && ($template_file = $this->getSkinFile($base_dir . '/' . $name . $variant . $file_suffix))
3963  ) {
3964  $template = $template_file;
3965  } elseif (
3966  ($dir && ($template_file = $this->getSkinFile($dir . '/' . $file)))
3967  || ($template_file = $this->getSkinFile($file))
3968  ) {
3969  $template = $template_file;
3970  } elseif ($suffix != '') {
3971  $file = $mobile ? $name . $variant . '.mobile' . $suffix . $file_suffix : $name . $variant . $suffix . $file_suffix;
3972  if (
3973  ($dir && ($template_file = $this->getSkinFile($dir . '/' . $file)))
3974  || ($template_file = $this->getSkinFile($file))
3975  ) {
3976  $template = $template_file;
3977  }
3978  }
3979  }
3980  // Es gibt kein Template
3981  if (empty($template)) {
3982  if ($mobile) {
3983  // Wenn es kein Mobile Template gibt, dann versuchen ein Standard Template zu ermitteln
3984  $template = $this->getTemplate(false, $name, $dir, $variant, $suffix, $fallback);
3985  } elseif ($variant != '' && $suffix != '') {
3986  // Wenn es keine Template Variante mit dem Suffix gibt, dann versuchen ohne Variante zu ermitteln
3987  $template = $this->getTemplate(false, $name, $dir, '', $suffix, $fallback);
3988  } elseif ($fallback) {
3989  // Das Standard Template verwenden
3990  if ($suffix != '') {
3991  // Wenn es kein <name>.variant.suffix Template gibt, dann <name>.variant.html verwenden
3992  return $this->getTemplate($mobile, $name, $dir, $variant, '.html');
3993  } elseif ($variant != '') {
3994  // Wenn es kein <name>.variant.html Template gibt, dann <name>.html verwenden
3995  return $this->getTemplate($mobile, $name, $dir, '', '.html');
3996  } elseif ($name == 'body') {
3997  $template_file = $GLOBALS['egotec_conf']['lib_dir'] . 'type/skin/page/body.html';
3998  if (Ego_System::file_exists($template_file)) {
3999  $template = $template_file;
4000  }
4001  }
4002  }
4003  }
4004  if (empty($template) && $fallback) {
4005  throw new Site_Exception('Template does not exist.', Site_Exception::MISSING_TEMPLATE);
4006  }
4007  $this->setCacheEntry($key, $template);
4008  }
4009  return $template;
4010  }
4011 
4022  public function getSkinFile($path, $skip = array('module'), $url = false, $relative = false) {
4023  if (!$this->globalAllowed() && !in_array('global', $skip)) {
4024  // Für diesen Mandanten keine globalen Templates verwenden
4025  $skip[] = 'global';
4026  }
4027  return Ego_System::getFallbackFile('skin', $this->skin, $path, $skip, $url, $relative, $this->theme);
4028  }
4029 
4040  public function getSiteFile($path, $skip = array('module'), $url = false, $relative = false) {
4041  if (
4042  !$this->globalAllowed() && !in_array('global', $skip)
4043  ) {
4044  // Für diesen Mandanten keine globalen Skripte verwenden
4045  $skip[] = 'global';
4046  }
4047  return Ego_System::getFallbackFile('site', $this->name, $path, $skip, $url, $relative, $this->theme);
4048  }
4049 
4058  public function getFile($path, $type = 'skin') {
4059  switch ($type) {
4060  case 'skin':
4061  return $this->getSkinFile($path, array('module'), true);
4062  case 'site':
4063  return $this->getSiteFile($path, array('module'), true);
4064  }
4065  return '';
4066  }
4067 
4080  public function getInheritedFile($mode, $type, $path, $skip = array('module'), $url = false, $relative = false) {
4081  $parts = explode('/', $type);
4082  while (sizeof($parts) > 0) {
4083  if (($result = self::{'get' . ucfirst($mode) . 'File'}(implode('/', $parts) . '/' . $path, $skip, $url, $relative)) !== '') {
4084  return $result;
4085  }
4086  array_pop($parts);
4087  }
4088  return '';
4089  }
4090 
4098  public function getVariantFiles($path, $skip = array()) {
4099  $key = 'variant'.md5(serialize(array($path, $skip)));
4100  $variants = $this->getCacheEntry($key);
4101  if ($variants === null) {
4102  $variants = Ego_System::getVariantFiles('skin', $this->skin, $path, $skip, $this->theme);
4103  $this->setCacheEntry($key, $variants);
4104  }
4105  return $variants;
4106  }
4107 
4116  public function getLayoutFiles($path = '', $skip = array(), $conf = array()) {
4117  $key = 'layout'.md5(serialize(array($path, $skip)));
4118  $layouts = $this->getCacheEntry($key);
4119  if ($layouts === null) {
4120  $layouts = array_merge(
4121  Ego_System::getFiles('skin', $this->skin, 'layouts/*.tpl', $skip, $this->theme),
4122  $path != '' ? Ego_System::getFiles('skin', $this->skin, $path.'/layouts/*.tpl', $skip, $this->theme, false, false) : array()
4123  );
4124  $layouts = array('default' => $layouts['_empty']) + $layouts;
4125  if (empty($conf)) {
4126  $conf = $this->conf['layouts'];
4127  }
4128  if (!empty($conf)) {
4129  foreach ($layouts as $layout => $title) {
4130  if (!empty($conf[$layout]['title'])) {
4131  $layouts[$layout] = $GLOBALS['auth']->translate($conf[$layout]['title']);
4132  }
4133  }
4134  }
4135  unset($layouts['_empty']);
4136  $this->setCacheEntry($key, $layouts);
4137  }
4138  return $layouts;
4139  }
4140 
4148  public function getBlockFiles($path = '', $skip = array()) {
4149  $key = 'block'.md5(serialize(array($path, $skip)));
4150  $blocks = $this->getCacheEntry($key);
4151  if ($blocks === null) {
4152  $blocks = array_merge(
4153  Ego_System::getFiles('skin', $this->skin, 'blocks/*.tpl', $skip, $this->theme, false, false),
4154  $path != '' ? Ego_System::getFiles('skin', $this->skin, $path.'/blocks/*.tpl', $skip, $this->theme, false, false) : array()
4155  );
4156  $this->setCacheEntry($key, $blocks);
4157  }
4158  return $blocks;
4159  }
4160 
4167  public function isDisabledBlock($block) {
4168  foreach ([
4169  $GLOBALS['egotec_conf']['blocks']['design_disabled'],
4170  $this->admin['blocks']['design_disabled']
4171  ] as $conf) {
4172  if (!empty($conf)) {
4173  $disabled_blocks = explode(',', $conf);
4174 
4175  foreach ($disabled_blocks as $disabled_block) {
4176  [$name, $key] = explode('/', $disabled_block);
4177  if (!empty($key) && $key !== md5(trim(implode(' ', [$this->theme, $this->skin])))) {
4178  continue;
4179  }
4180  if ($name === $block) {
4181  return true;
4182  }
4183  }
4184  }
4185  }
4186 
4187  return false;
4188  }
4189 
4195  public function getEditorTemplates() {
4196  $templates = array();
4197  $template_dirs = array(
4198  array($GLOBALS['egotec_conf']['skin_dir'].$this->skin.'/blocks/', $GLOBALS['egotec_conf']['url_dir'].'skin/'.$this->skin.'/blocks/'),
4199  $this->globalAllowed() ? array($GLOBALS['egotec_conf']['skin_dir'].'_global/blocks/', $GLOBALS['egotec_conf']['url_dir'].'skin/_global/blocks/') : array()
4200  );
4201  if ($this->theme) {
4202  $template_dirs[] = array($GLOBALS['egotec_conf']['pub_dir']."theme/{$this->theme}/skin/blocks/", $GLOBALS['egotec_conf']['url_dir']."pub/theme/{$this->theme}/skin/blocks/");
4203  }
4204  foreach ($template_dirs as $template_dir) {
4205  if (!empty($template_dir) && Ego_System::file_exists($template_dir[0])) {
4206  // Alle Templates dieses Verzeichnisses ermitteln
4207  $dir = dir($template_dir[0]);
4208  while (($file = $dir->read()) !== false) {
4209  if (
4210  !in_array($file, array('.', '..'))
4211  && preg_match('/^(.*?)\.html$/i', $file, $match)
4212  ) {
4213  // Bezeichnung
4214  $name = $match[1];
4215 
4216  // Pfad
4217  $url = $template_dir[1].$file;
4218 
4219  // Beschreibung
4220  $description = '';
4221  if (Ego_System::file_exists($template_dir[0].$name.'_desc.php')) {
4222  // Es existiert eine Beschreibung für dieses Template
4223  $description = Ego_System::file_get_contents($template_dir[0].$name.'_desc.php');
4224  $description = preg_replace('/(\r\n|\r|\n|\t)/msi', '', strip_tags($description));
4225  $description = str_replace("'", "\'", $description);
4226  }
4227 
4228  $templates[] = array(
4229  'title' => $name,
4230  'url' => $url,
4231  'description' => $description
4232  );
4233  }
4234  }
4235  $dir->close();
4236  }
4237  }
4238  ksort($templates);
4239  return $templates;
4240  }
4241 
4247  public function hasLiveserver() {
4248  return (
4249  !$GLOBALS['egotec_conf']['liveserver']
4250  && $this->admin['live']['login']
4251  && $this->admin['live']['password']
4252  && ($this->admin['live']['location'] || Ego_System::getCluster($this))
4253  );
4254  }
4255 
4262  public function getSearchCount($weight = 0) {
4263  if (!is_numeric($weight)) {
4264  $weight = 0;
4265  }
4266 
4267  $counts = array();
4268  $default_counts = array(
4269  'keywords' => 100,
4270  'url' => 50,
4271  'name' => 25,
4272  'title' => 12,
4273  'short' => 6,
4274  'content' => 3,
4275  'extra' => 1
4276  );
4277  foreach ($default_counts as $key => $default_value) {
4278  $value = (!empty($this->admin['count'][$key]) ? (int)$this->admin['count'][$key] : $default_value) + $weight;
4279  $counts[$key] = $value > 0 ? $value : 1;
4280  }
4281  return $counts;
4282  }
4283 
4291  public function updatePiwikHosts() {
4292  require_once 'stats/Ego_Piwik.php';
4293  $piwik = new Ego_Piwik();
4294  $piwiksites = $this->getPages(array(
4295  'where' => "extra LIKE '%s:5:\"piwik\"%'"
4296  ));
4297  $hosts = $this->getVirtualHosts();
4298  // Wenn Seiten hinterlegt sind, werden die URLs geupdatet
4299  if ($piwiksites->numRecords()) {
4300  foreach ($piwiksites as $psite) {
4301  if ($psite->extra['piwik']) {
4302  if ($psite->extra['piwik']['auth_token'] == 'undefined' && $psite->extra['piwik']['red_id'] == 'undefined') {
4303  $piwikdata = $psite->addPiwikSite();
4304  $extra = $psite->extra;
4305  $extra['piwik'] = $piwikdata;
4306  $psite->updateExtra($extra);
4307  } else {
4308  if (!$psite->extra['piwik']['live_id'] && $this->hasLiveserver()) {
4309  $piwikdata = $piwik->createWebsite($psite, true);
4310  $extra = $psite->extra;
4311  $extra['piwik'] = $piwikdata;
4312  $psite->updateExtra($extra);
4313  }
4314 
4315  // Hosts aller Sprachverknüpfungen sammeln
4316  $language_hosts = $hosts;
4317  if (is_array($psite->extra['language_link']) && $psite->extra['language_link'][$this->language]) {
4318  foreach ($psite->extra['language_link'] as $lang => $flag) {
4319  if ($flag && $lang != $this->language) {
4320  // URLs der Sprachverknüpfung aufnehmen
4321  try {
4322  $lang_site = new Site($this->name, $lang);
4323 
4324  if ($lang == $psite->extra['language_standard']) {
4325  $language_hosts = array_merge($lang_site->getVirtualHosts(), $language_hosts);
4326  } else {
4327  $language_hosts = array_merge($language_hosts, $lang_site->getVirtualHosts());
4328  }
4329  } catch (Site_Exception $e) {
4330  // ignorieren
4331  }
4332  }
4333  }
4334  }
4335 
4336  $piwik->updateSiteURLs($psite->extra['piwik']['red_id'], $language_hosts, $psite->extra['piwik']['live_id'], $this);
4337  }
4338  }
4339  }
4340  } else { // Sind keine hinterlegt wird unterhalb der RootPage eine Statistikseite erstellt (auch für neue Mandanten)
4341  $new_psite = $this->getRoot();
4342  if ($new_psite && !$new_psite->extra['do_not_track']) {
4343  $piwikdata = $new_psite->addPiwikSite();
4344  $extra = $new_psite->extra;
4345  $extra['piwik'] = $piwikdata;
4346  $new_psite->updateExtra($extra);
4347  }
4348  }
4349  }
4350 
4358  public function getAdminText($suffix = '', $fallback = true) {
4359  if ($fallback && !$suffix && $GLOBALS['egotec_conf']['liveserver']) {
4360  $admin_text = $this->getAdminText('_live', false);
4361  return $admin_text ? $admin_text : $this->getAdminText('', false);
4362  }
4363  if (!empty($this->admin['administration']['admin_text'.$suffix])) {
4364  return array(
4365  'text' => $GLOBALS['auth']->translate($this->admin['administration']['admin_text'.$suffix]),
4366  'url' => (string) $this->admin['administration']['admin_url'.$suffix]
4367  );
4368  } elseif (!empty($GLOBALS['egotec_conf']['admin_text'.$suffix])) {
4369  return array(
4370  'text' => $GLOBALS['auth']->translate($GLOBALS['egotec_conf']['admin_text'.$suffix]),
4371  'url' => (string) $GLOBALS['egotec_conf']['admin_url'.$suffix]
4372  );
4373  }
4374  return null;
4375  }
4376 
4383  public function isFrontendAdmin($check_rights = true) {
4384  return $this->site['type'] == 'content'
4385  && $this->admin['frontend_admin']
4386  && (
4387  !$check_rights
4388  || (
4389  $GLOBALS['auth']
4390  && !$GLOBALS['auth']->isNobody()
4391  )
4392  );
4393  }
4394 
4400  public function cleanup() {
4401  $db = new_db_connection();
4402  if ( in_array(get_class($db), ["Ego_Sql_mssql", "Ego_Sql_oci", "Ego_Sql_sqlite"]) ) {
4403  return; // TODO make mssql and oracle compatible
4404  };
4405  $db->begin();
4406 
4407  foreach ($this->getLanguages() as $lang) {
4408  $pageTable = $this->name.'_'.$lang;
4409  foreach (array(
4410  array('_v', 'id', $pageTable, 'id'), // Alle Einträge aus _v entfernen, bei denen id nicht in $pageTable existiert
4411  array('_children', 'page_id', $pageTable, 'id'), // Alle Einträge aus _children entfernen, bei denen page_id nicht in $pageTable existiert
4412  array('_rights', 'page_id', $pageTable, 'id'), // Alle Einträge aus _rights entfernen, bei denen page_id nicht in $pageTable existiert
4413  array('_users', 'page_id', $pageTable, 'id'), // Alle Einträge aus _users entfernen, bei denen page_id nicht in $pageTable existiert
4414  array('_rights', 'group_id', 'egotec_group', 'group_id'), // Alle Einträge aus _rights entfernen, bei denen group_id nicht in egotec_group existiert
4415  array('_rights', 'role_id', 'egotec_role', 'role_id'), // Alle Einträge aus _rights entfernen, bei denen role_id nicht in egotec_role existiert
4416  array('_users', 'user_id', 'egotec_user', 'user_id') // Alle Einträge aus _users entfernen, bei denen user_id nicht in egotec_user existiert
4417  ) as $v) {
4418  $db->delete(array(
4419  'table' => "{$pageTable}{$v[0]} AS t",
4420  'fields' => "t.*",
4421  'join' => array("{$v[2]} ON t.{$v[1]} = {$v[2]}.{$v[3]}"),
4422  'where' => (in_array($v[1], array('group_id', 'role_id', 'user_id')) ? "t.{$v[1]} != '*' AND " : '')
4423  . "{$v[2]}.{$v[3]} IS NULL"
4424  ));
4425  }
4426  }
4427 
4428  $db->commit();
4429  }
4430 
4437  public function getNextReplicationDate($page = null) {
4438  if (
4439  empty($GLOBALS['egotec_conf']['liveserver']) // Nicht auf dem Liveserver
4440  && (!$page
4441  || (($page->field['nav_hide']&2) == 0 // Diese Seite darf übertragen werden
4442  && $page->isPublic())) // Diese Seite ist keine Zwischenspeicherung
4443  ) {
4444  // Das Datum des letzten Live-/Clusterupdates ermitteln
4445  $live_date = '';
4446  if (($clusters = Ego_System::getCluster()) && sizeof($clusters)) {
4447  // Clusterupdate
4448  foreach ($clusters as $cluster) {
4449  $cluster_date_file = $GLOBALS['egotec_conf']['log_dir'].$this->name.'/live.'.$this->name.'_'.$this->language.'.'.$cluster['id'].'.date';
4450  if (Ego_System::file_exists($cluster_date_file)) {
4451  $cluster_date = Ego_System::file_get_contents($cluster_date_file);
4452  if (!$live_date || $cluster_date > $live_date) {
4453  $live_date = $cluster_date;
4454  }
4455  }
4456  }
4457  } else {
4458  // Liveupdate
4459  $live_date_file = $GLOBALS['egotec_conf']['log_dir'] . $this->name . '/live.' . $this->name . '_' . $this->language . '.date';
4460  if (!Ego_System::file_exists($live_date_file)) {
4461  $live_date_file = $GLOBALS['egotec_conf']['log_dir'] . $this->name . '/live.date';
4462  }
4463  if (Ego_System::file_exists($live_date_file)) {
4464  $live_date = Ego_System::file_get_contents($live_date_file);
4465  }
4466  }
4467 
4468  // Das Datum des letzten Live-/Clusterupdates ist bekannt (und diese Seite wurde seitdem bearbeitet)
4469  if (!empty($live_date) && (!$page || $page->field['m_date'] > $live_date)) {
4470  // Prüfen, in welchen (aktiven) Diensten ein Live-/Clusterupdate aktiviert und das Intervall bekannt ist
4471  $next_date = '';
4472  require_once 'cron/Ego_Cron.php';
4473 
4474  foreach ($this->conf['admin'] as $key => $values) {
4475  if (
4476  strpos($key, 'cron_') === 0
4477  && !empty($GLOBALS['egotec_conf'][$key]['aktiv'])
4478  && !empty($GLOBALS['egotec_conf'][$key]['interval'])
4479  && (!empty($values['live_incr'])
4480  || !empty($values['cluster_incr']))
4481  ) {
4482  $date = Ego_Cron::getNextDate($GLOBALS['egotec_conf'][$key]['interval'], $page, $live_date);
4483  if (empty($next_date) || $date < $next_date) {
4484  $next_date = $date;
4485  }
4486  }
4487  }
4488  return $next_date;
4489  }
4490  }
4491  return '';
4492  }
4493 
4499  public function getRewriteConf() {
4500  $conf = $GLOBALS['egotec_conf']['rewrite'] ?? [];
4501  if ($this->conf['admin']['rewrite']['overwrite']) {
4502  $conf = $this->conf['admin']['rewrite'];
4503  unset($conf['overwrite']);
4504  }
4505  return $conf;
4506  }
4507 
4513  public function getSocialNetworks() {
4514  $networks = array();
4515 
4516  // Facebook
4517  if (!empty($this->admin['social']['facebook_page_id']) && !empty($this->admin['social']['facebook_access_token'])) {
4518  $networks[] = 'facebook';
4519  }
4520 
4521  // Twitter
4522  if (!empty($this->admin['social']['twitter_access_token'])) {
4523  $networks[] = 'twitter';
4524  }
4525 
4526  return $networks;
4527  }
4528 
4534  public function getVirtualHosts() {
4535  if (empty($this->virtualHosts)) {
4536  foreach (Ego_System::getVirtualHosts() as $virtual_host => $identity) {
4537  if (
4538  $identity['site'] == $this->name
4539  && $identity['lang'] == $this->language
4540  ) {
4541  $this->virtualHosts[] = (string) $virtual_host;
4542  }
4543  }
4544 
4545  if (empty($this->virtualHosts)) {
4546  // Gibt es keinen virtuellen Host, wird die Domain automatisch generiert
4547  $host = $_SERVER['HTTP_HOST'];
4548  if (!empty($GLOBALS['egotec_conf']['rewrite']['host'])) {
4549  $host = $GLOBALS['egotec_conf']['rewrite']['host'];
4550  }
4551  $default_host = rtrim($host, '/');
4552  if ($GLOBALS['egotec_conf']['default_site'] != $this->name) {
4553  $default_host .= '/' . $this->name;
4554  }
4555  if (sizeof($this->getLanguages()) > 1) {
4556  if ($this->language == $this->site['default_language']) {
4557  // Die Standardsprache kann auch ohne Sprachangabe aufgerufen werden
4558  $this->virtualHosts[] = $default_host;
4559  }
4560  $default_host .= (strpos($default_host, '/') === false ? '/' : '-') . $this->language;
4561  }
4562  $this->virtualHosts[] = $default_host;
4563  }
4564  }
4565  return $this->virtualHosts;
4566  }
4567 
4573  public function globalAllowed() {
4574  return !$GLOBALS['egotec_conf']['non_global_sites']
4575  || !in_array($this->name, explode(',', $GLOBALS['egotec_conf']['non_global_sites']));
4576  }
4577 
4586  public function compressFiles($type, $files) {
4587  $base = 'files/' . md5(serialize([
4588  $this->name,
4589  $GLOBALS['egotec_conf']['egotec_version'],
4590  $GLOBALS['egotec_conf']['project_version']
4591  ])) . ".$type";
4592  $path = $GLOBALS['egotec_conf']['pub_dir'] . $base;
4593 
4594  if (!Ego_System::file_exists($path)) {
4595  $content = '';
4596  foreach ($files as $file) {
4598  $absolute = $GLOBALS['egotec_conf']['egotec_dir']
4599  . substr($file, mb_strlen($GLOBALS['egotec_conf']['url_dir']))
4600  );
4601 
4602  // Relative Pfade zu absoluten Pfaden umwandeln
4603  if ($type == 'css') {
4604  $source = preg_replace_callback('/(import|url)\s*\‍(["\' ]*(.*?)["\' ]*\‍)/', function($match) use ($absolute) {
4605  if ($real = @realpath(dirname($absolute) . '/' . $match[2])) {
4606  return str_replace($match[2], substr($real, mb_strlen($GLOBALS['egotec_conf']['egotec_dir']) - 1), $match[0]);
4607  }
4608  return $match[0];
4609  }, $source);
4610  }
4611 
4612  $content .= "\n\n/* ---------- START $file ---------- */\n\n"
4613  . $source
4614  . "\n\n/* ---------- END $file ---------- */";
4615  }
4616 
4617  Ego_System::file_put_contents($path, trim($content));
4618  }
4619 
4620  return $GLOBALS['egotec_conf']['url_dir'] . 'pub/' . $base;
4621  }
4622 }
const PERMISSION_DENIED
Definition: Auth.php:51
const PERMISSION_DENIED_TEXT
Definition: Auth.php:52
const NO_NULL_RIGHTS
Definition: Auth.php:129
static start($table='', $param=[], $checkHealthy=false)
static filterNonUtf8($s, $substitute="", $strict=false)
Definition: Ego_System.php:481
static getCache($path='_system')
static getMimeTypes($ext='')
static file_put_contents($filename, $data, $flags=0, $context=null)
static getAssocValue($a, $k)
static getFallbackFile($type, $name, $path, $skip=array('module'), $url=false, $relative=false, $parent='')
static getVariantFiles($type, $name, $path, $skip=array(), $parent='')
static getVirtualHosts()
static getCluster($site=null)
static getFiles($type, $name, $path, $skip=array(), $parent='', $return_path=false, $get_variants=true)
static file_exists($file)
static mkdir($dir, $mode=0755, $recursive=true)
Definition: Ego_System.php:669
static file_get_contents($filename, $utf8=true, $context=null)
static getJSON($path, $values=[], $combine=false, $ignore=[], $replace=true, $no_cache=false)
static flush($string='')
Definition: Ego_System.php:934
const MISSING_TEMPLATE
Definition: Site.php:15
const SITE_DOESNT_EXIST
Definition: Site.php:12
const LANG_DOESNT_EXIST
Definition: Site.php:13
const LANG_NOT_DELETABLE
Definition: Site.php:14
Definition: Site.php:30
getVirtualHosts()
Definition: Site.php:4534
getSkinFile($path, $skip=array('module'), $url=false, $relative=false)
Definition: Site.php:4022
__call($function, $params)
Definition: Site.php:71
getPageId($name, $param=[])
Definition: Site.php:666
getHash()
Definition: Site.php:618
getTemplate($mobile=false, $name='index', $dir='', $variant='', $suffix='', $fallback=true)
Definition: Site.php:3931
getUploaderPage($page=null)
Definition: Site.php:3180
static createSite($new_site)
Definition: Site.php:234
$theme
Definition: Site.php:51
save_admin($admin=array())
Definition: Site.php:1757
hasDeleted()
Definition: Site.php:3270
hasLiveserver()
Definition: Site.php:4247
$importFlag
Definition: Site.php:53
$pageTable
Definition: Site.php:49
compressFiles($type, $files)
Definition: Site.php:4586
isFrontendAdmin($check_rights=true)
Definition: Site.php:4383
$skin
Definition: Site.php:50
getCacheExpire()
Definition: Site.php:3003
getPageClass($type='page')
Definition: Site.php:3350
getCacheEntry($key)
Definition: Site.php:3017
getSocialNetworks()
Definition: Site.php:4513
isMetaUrl($path)
Definition: Site.php:2884
destroyIDs($ids)
Definition: Site.php:2813
getNextReplicationDate($page=null)
Definition: Site.php:4437
getFile($path, $type='skin')
Definition: Site.php:4058
getTime()
Definition: Site.php:717
getEditorTemplates()
Definition: Site.php:4195
getSearchCount($weight=0)
Definition: Site.php:4262
clearTrashcan($query=array())
Definition: Site.php:3284
migrateLanguages()
Definition: Site.php:1898
addParam($param)
Definition: Site.php:595
__toString()
Definition: Site.php:2914
updatePiwikHosts()
Definition: Site.php:4291
setTime($time='')
Definition: Site.php:502
checkRight($right, $flag=false)
Definition: Site.php:2751
getLayoutFiles($path='', $skip=array(), $conf=array())
Definition: Site.php:4116
$language
Definition: Site.php:48
setCacheEntry($key, $value)
Definition: Site.php:3035
getPages($query=array(), $param=array())
Definition: Site.php:755
$rootId
Definition: Site.php:52
__construct($site_name='', $language='', $skin='', $only_active=true, $time='', $recalc=false)
Definition: Site.php:433
getDesklets($rights=false, $trashcan=false)
Definition: Site.php:3061
updateUrls($reset=false, $verbose=false)
Definition: Site.php:3679
setLanguage($language='')
Definition: Site.php:519
getCopyrights($start=0, $limit=0, &$m=0)
Definition: Site.php:3805
removeUrls($language='')
Definition: Site.php:3648
getUnusedPages()
Definition: Site.php:3700
$site
Definition: Site.php:45
getCacheLastChanged()
Definition: Site.php:3049
setOnlyActive($b)
Definition: Site.php:488
$global
Definition: Site.php:47
getBlockFiles($path='', $skip=array())
Definition: Site.php:4148
$name
Definition: Site.php:44
hasRightsOnId($id, $rights, $user_id=false, $cache=true)
Definition: Site.php:2839
getAdminText($suffix='', $fallback=true)
Definition: Site.php:4358
globalAllowed()
Definition: Site.php:4573
enoughDiskSpace()
Definition: Site.php:2941
getRights($right)
Definition: Site.php:2767
getNonPublicPages($query=[], $param=[])
Definition: Site.php:3733
setRight($right, $rights)
Definition: Site.php:2788
getCache()
Definition: Site.php:2993
hasMediaSite()
Definition: Site.php:1412
removeLinks($language='')
Definition: Site.php:3620
isPublicSave()
Definition: Site.php:2905
__clone()
Definition: Site.php:2924
$admin
Definition: Site.php:46
getVariantFiles($path, $skip=array())
Definition: Site.php:4098
getLanguages()
Definition: Site.php:628
clearCache($id=0, $all_languages=false)
Definition: Site.php:1472
setRights($rights=array())
Definition: Site.php:584
$conf
Definition: Site.php:55
getRewriteConf()
Definition: Site.php:4499
isDisabledBlock($block)
Definition: Site.php:4167
getInheritedFile($mode, $type, $path, $skip=array('module'), $url=false, $relative=false)
Definition: Site.php:4080
updateMediaIndex($resume, $c_date, $skipFirst, $dryRun, $timeout)
Definition: Site.php:3456
getSkins($theme=false)
Definition: Site.php:642
setParam($param)
Definition: Site.php:610
updateLinks($output=false)
Definition: Site.php:3421
getCRS()
Definition: Site.php:3166
getOnlyActive()
Definition: Site.php:708
cleanup()
Definition: Site.php:4400
getSiteFile($path, $skip=array('module'), $url=false, $relative=false)
Definition: Site.php:4040