<?php
/**
 * @copyright (c) Kufer Software GmbH, Oderstraße 7, D-84453 Mühldorf
 */

class ContentNavFunctions extends ContentSubNavigation
{
  public function getNavItems()
  {
    $navItems = array();
    $subnavItems = array();

    $item = new NavItem();
    $item->name = 'Vorschaumodus';
    $item->objectName = $this->getObjectNameByAccess('functions', 'ContentPreviewMode');
    array_push($navItems, $item);

    $item = new NavItem();
    $item->name = 'Mehrsprachigkeit';
    $item->objectName = $this->getObjectNameByAccess('functions', 'ContentMehrsprachigkeit');
    array_push($navItems, $item);

    $item = new NavItem();
    $item->name = 'Sicherung';
    $item->objectName = $this->getObjectNameByAccess('functions', 'ContentBackup');
    array_push($navItems, $item);

    $item = new NavItem();
    $item->name = 'News';
    $item->objectName = $this->getObjectNameByAccess('functions', 'ContentNews');
    array_push($navItems, $item);

    $item = new NavItem();
    $item->name = 'Datei Upload TN-Anmeldung';
    $item->objectName = $this->getObjectNameByAccess('functions', 'ContentUpload');
    array_push($navItems, $item);

    $sitem = new NavItem();
    $sitem->name = 'Allgemeine Bereinigung';
    $sitem->objectName = $this->getObjectNameByAccess('functions', 'ContentAllgemeinBereinigung');
    array_push($subnavItems, $sitem);

    $sitem = new NavItem();
    $sitem->name = 'Merklisten bereinigen';
    $sitem->objectName = $this->getObjectNameByAccess('functions', 'ContentMerkliste');
    array_push($subnavItems, $sitem);

    $sitem = new NavItem();
    $sitem->name = 'Passwörter bereinigen';
    $sitem->objectName = $this->getObjectNameByAccess('functions', 'ContentPassword');
    array_push($subnavItems, $sitem);

    $sitem = new NavItem();
    $sitem->name = 'Generierte Fotos bereinigen';
    $sitem->objectName = $this->getObjectNameByAccess('functions', 'ContentFotos');
    array_push($subnavItems, $sitem);

    $sitem = new NavItem();
    $sitem->name = 'Cache bereinigen';
    $sitem->objectName = $this->getObjectNameByAccess('functions', 'ContentCache');
    array_push($subnavItems, $sitem);

    $item = new NavItem();
    $item->name = 'Bereinigungen';
    $item->subItems = $subnavItems;
    array_push($navItems, $item);

    if (SessionOperations::isReplikat()) {
      $item = new NavItem();
      $item->name = 'Kurse überprüfen';
      $item->objectName = $this->getObjectNameByAccess('functions', 'ContentKurseOnline');
      array_push($navItems, $item);

      $item = new NavItem();
      $item->name = 'E-Pay-Notify überprüfen';
      $item->objectName = $this->getObjectNameByAccess('functions', 'ContentMerchantId');
      array_push($navItems, $item);
    }

    $item = new NavItem();
    $item->name = 'Bestätigung generieren';
    $item->objectName = $this->getObjectNameByAccess('functions', 'ContentBestaetigung');
    array_push($navItems, $item);

    $item = new NavItem();
    $item->name = 'Dateien überprüfen';
    $item->objectName = $this->getObjectNameByAccess('functions', 'ContentFunctionValidateFiles');
    array_push($navItems, $item);

    $dbConnInfo = \DBConnectionInfo::getInstance();
    if ($dbConnInfo->db_replikat && $dbConnInfo->db_typ == \DBTypeEnum::MYSQLI) {
      $item = new NavItem();
      $item->name = 'MySQL Struktur';
      $item->objectName = $this->getObjectNameByAccess('functions', 'ContentMysqlStrukturUpdate');
      array_push($navItems, $item);
    }

    if (DEVELOP || DebugOperations::isKuferRequest()) {
      $item = new NavItem();
      $item->name = 'Zugang mit ausgewähltem Login';
      $item->objectName = $this->getObjectNameByAccess('functions', 'ContentLoginWeb');
      array_push($navItems, $item);
    }

    

    foreach ($navItems as $item) {
      $item->hardlink = str_replace(' ', '_', \StringOperations::strtolower($item->name));
    }

    return $navItems;
  }
}


class ContentAllgemeinBereinigung extends Content
{
  public function getContent()
  {
    $smarty = $this->getSmarty();
    ContentMerkliste::merklisteBereinigen($smarty);
    ContentPassword::passwoerterBereinigen($smarty);
    ContentFotos::fotosBereinigen($smarty);
    ContentCache::cacheBereinigen($smarty);

    return $smarty->fetch('functions/allgemeinbereinigung.html');
  }
}

class ContentMerkliste extends Content
{
  public static function merklisteBereinigen($smarty)
  {
    $merklistenbereinigen = PostOperations::getVarValue('merklistenbereinigen', false) !== false;
    $merklistenbereinigt = 0;
    $kurse = MerklisteAPI::getNichtAnzuzeigendeKurse();
    if ($merklistenbereinigen) {
      foreach ($kurse as $kursnr) {
        MerklisteAPI::delete($kursnr);
      }
      $merklistenbereinigt = 1;
    }
    $smarty->assign('merklistenbereinigt', $merklistenbereinigt);
    $smarty->assign('anzahlzubereinigenML', count($kurse));
  }

  public function getContent()
  {
    $smarty = $this->getSmarty();
    self::merklisteBereinigen($smarty);

    return $smarty->fetch('functions/merkliste.html');
  }
}

class ContentPassword extends Content
{
  public static function passwoerterBereinigen($smarty)
  {
    $dbw = new DBWorkWBLoginsPasswords();
    $passwordclear = PostOperations::getVarValue('passwortbereinigen', false);
    $passwörterBereinigt = 0;
    if ($passwordclear) {
      $dbw->deleteAllUnusedPasswords();
      $passwörterBereinigt = 1;
    }
    $value = $dbw->getUnusedPasswordCount();
    $smarty->assign('passwordcleared', $passwörterBereinigt);
    $smarty->assign('anzahlzubereinigenPW', $value);
  }

  public function getContent()
  {
    $smarty = $this->getSmarty();
    self::passwoerterBereinigen($smarty);

    return $smarty->fetch('functions/passwordclear.html');
  }
}

class ContentMerchantId extends Content
{
  public function getContent()
  {
    $smarty = $this->getSmarty();

    $smarty->assign('eingabe', '');
    $smarty->assign('ergebnis', '');
    $eingabe = PostOperations::getVarValue('merchantid');

    if (isset($eingabe) && $eingabe != '') {
      $smarty->assign('eingabe', $eingabe);
      $dbwepaytids = new DBWorkWebEpayTids();
      $webEpayTid = $dbwepaytids->getByMTid($eingabe);
      $transactionid = $webEpayTid->tid;
      $payonline = $webEpayTid->payonline;

      $provider = $payonline != '' ? ePaymentApi::getEPayDisplayName($payonline) : '';
      $istUebermittelnButtonAngezeigt = $this->showEntry($transactionid, $smarty, $provider, $payonline);
      if ($this->wurdeUebermittelnGedr() && $istUebermittelnButtonAngezeigt) {
        if ($this->getUebermittlungsergebnis($payonline, $transactionid, $webEpayTid->tid_merchant)) {
          $smarty = $this->showSuccessMessage($smarty);
        } else {
          $smarty = $this->showErrorMessage($smarty);
        }
      }
    }

    return $smarty->fetch('functions/merchantid.html');
  }

  private function showSuccessMessage($smarty)
  {
    $smarty->assign('ergebnis', '<br><div class="status_ok">Der Datensatz wurde erfolgreich an KuferSQL übermittelt.</div>');

    return $smarty;
  }

  private function showErrorMessage($smarty)
  {
    $smarty->assign('ergebnis', '<br><div class="status_error">Die Übertragung hat nicht funktioniert.</div>');

    return $smarty;
  }

  private function showEntry($transactionid, $smarty, $provider, $payonline)
  {
    if (isset($transactionid) && $transactionid != '') {
      $webEpayStateObj = DBWorkWebEpaystate::getDefaultInstance()->getEpaystateByTransactionId($transactionid);
      $smarty->assign('transactionid', $transactionid);
      $smarty->assign('provider', $provider);
      if (is_null($webEpayStateObj->payment_state)) {
        $smarty->assign('status_id', 'kein Status vorhanden');
        $smarty->assign('showbutton', false);
        $smarty->assign('ergebnis', '<br><div class="status_error">In diesem Datensatz fehlen Daten, daher kann dieser aktuell nicht an KuferSQL übermittelt werden.</div>');

        return false;
      }
      $epayStatusObj = DBWorkEpayStatus::getDefaultInstance()->getEpayStatusEntry($webEpayStateObj->payment_state, $payonline);
      $statusText = empty($epayStatusObj->beschreibung) ? 'Keine Beschreibung verfügbar' : $epayStatusObj->beschreibung;
      $smarty->assign('transactionid', $transactionid);
      $smarty->assign('status_id', $webEpayStateObj->payment_state);
      $smarty->assign('status_text', $statusText);
      $smarty->assign('provider', $provider);
      if ($transactionid == '' || $payonline == '' || $provider == '') {
        $smarty->assign('showbutton', false);
        $smarty->assign('ergebnis', '<br><div class="status_error">In diesem Datensatz fehlen Daten.</div>');

        return false;
      }
      $smarty->assign('showbutton', true);

      return true;
    }

    return false;
  }

  private function wurdeUebermittelnGedr()
  {
    $uebermitteln = PostOperations::getVarValue('uebermitteln');
    if (isset($uebermitteln) && $uebermitteln != '') {
      return true;
    }

    return false;
  }

  private function getUebermittlungsergebnis($payonline, $tid, $mTid)
  {
    if ($payonline != -1) {
      $epayState = DBWorkWebEpaystate::getDefaultInstance()->getEpaystateByTransactionId($tid);
      $epayInfo = new EPayInfo();
      $epayInfo->tid = $tid;
      $epayInfo->tidMerchant = $mTid;
      $epayInfo->paymentState = $epayState->payment_state;

      $epn = new EPayNotifyHandler();

      return $epn->uebermittlePaymentState(
        $payonline,
        $epayInfo,
        new EmailXML(),
        array(new EmailXMLKurse())
      );
    }

    return false;
  }
}

class ContentBestaetigung extends Content
{
  public function getContent()
  {
    $smarty = $this->getSmarty();
    $xmlDir = AdminBest::$templateDir;
    $files = FSOperations::getDirContent($xmlDir);

    $filteredFiles = array_filter(
      $files,
      function($fileName) {
        return !StringOperations::endsWith($fileName, '.html');
      }
    );

    $smarty->assign('files', $filteredFiles);
    $smarty->assign('filesempty', empty($filteredFiles));
    $smarty->assign('templatedir', $xmlDir);

    $script = "<script type=\"text/javascript\">
	          $(function () {
			    var button = $('input[type=\"submit\"]').prop('disabled', true);
			    var radios = $('input[type=\"radio\"]');
			    var arr    = $.map(radios, function(el) { 
			                return el.name; 
			              });
                            var span = $('span[class=\"erstzweiradios\"]');

			    var groups = $.grep(arr, function(v, k){
			            return $.inArray(v ,arr) === k;
			    }).length;

			    radios.on('change', function () {
			        button.prop('disabled', radios.filter(':checked').length < groups);
                                span.prop('style', radios.filter(':checked').length < groups ? 'float: right; padding: 5px 5px 0px 5px;' : 'display: none;');
			    });
			});
        </script>";

    $smarty->assign('script', $script);

    return $smarty->fetch('functions/bestaetigung.html');
  }
}

class ContentKurseOnline extends Content
{
  public const KURS_IN_DB = 0;
  public const KURS_ONLINE_FINDBAR = 1;

  public function getContent()
  {
    $smarty = $this->getSmarty();
    $eingabe = $eingabeHtml = '';
    if (strlen(PostOperations::getVarValue('kursnummer')) <= 19) {
      $eingabe = PostOperations::getVarValue('kursnummer');
      $eingabeHtml = CleanOperations::cleanStringForHtml($eingabe);
    }
    if (trim($eingabe) == '') {
      $smarty->assign('keineEingabe', true);
      $smarty->assign('keinekurse', true);
      $smarty->assign('knrKurzbezArray', array());
      $smarty->assign('eingabe', '');
    } else {
      $knrKurzbezArray = $this->getknrKurzbezArray($eingabe);
      $angezeigtekurse = $this->getInKurssucheAngezeigteKurse($eingabe);

      foreach ($angezeigtekurse as $kurs) {
        if (isset($knrKurzbezArray[$kurs->nr_anzeige])) {
          $knrKurzbezArray[$kurs->nr_anzeige]->status = self::KURS_ONLINE_FINDBAR;
          $knrKurzbezArray[$kurs->nr_anzeige]->grund = '';
        } else {
          $knrKurzbezArray[$kurs->nr_anzeige]->grund = $this->getGrundNichtAngezeigt($knrKurzbezArray[$kurs->nr_anzeige]);
        }
      }
      $keinekurse = empty($knrKurzbezArray) || count($knrKurzbezArray) == 0;

      $smarty->assign('keineEingabe', false);
      $smarty->assign('keinekurse', $keinekurse);
      $smarty->assign('knrKurzbezArray', $knrKurzbezArray);
      $smarty->assign('eingabe', $eingabeHtml);
    }

    return $smarty->fetch('functions/kurseonline.html');
  }

  private function getInKurssucheAngezeigteKurse($eingabe)
  {
    $toolsettings = ToolSettingsAPI::getToolSettings(4);
    $dbwkurse = new DBWorkKurseINetAktiv();
    $dbwkurse->newSearch();
    $dbwkurse->fromobject->id = '%' . $eingabe . '%';
    $dbwkurse->fromobject->semester = $toolsettings->semlist;
    $dbwkurse->toobject->semester = '';

    return ($dbwkurse->getKursebyCategoryLimit(-1, WBKursStore::getKurs(null), 1000));
  }

  private function getknrKurzbezArray(string $eingabe): array
  {
    $dbwkurse = new DBWorkKurseINetAktiv();
    $kursinformationen = $dbwkurse->getKursNrKurszbezMitUngenauerKnr($eingabe);
    $knrKurzbezArray = array();
    foreach ($kursinformationen as $kursinfo) {
      $kursobj = new stdClass();
      $kursobj->kurzbez = $kursinfo->kurzbez;
      $kursobj->status = self::KURS_IN_DB;
      $kursobj->grund = $this->getGrundNichtAngezeigt($kursinfo);
      $knrKurzbezArray[$kursinfo->id] = $kursobj;
    }

    return $knrKurzbezArray;
  }

  private function getGrundNichtAngezeigt($kursinfo)
  {
    $rueckgabe = '';

    $dbwk = new DBWorkKurse();
    $kurs = $dbwk->getKurs($kursinfo->id, true);
    $dbwkia = new DBWorkKurseINetAktiv();

    $settings = ToolSettingsAPI::getToolSettings(4);

    if (!in_array($kurs->semester, explode(',', $settings->semlist))) {
      $dtop = new DateTimeOperations();

      $inDBaberNichtFreigeschQuery = $dbwkia->getSelectQueryBuilder()
        ->select('k.*')
        ->from('kurse', 'k')
        ->where('k.nr = \'' . $kursinfo->id . '\'')
        ->and(' NOT ' . $dtop->getGueltigPart('k.', 'internetvon', 'internetbis'))
        ->getSQL();

      $dbwkia->dboperation->clear();
      $dbwkia->dboperation->query($inDBaberNichtFreigeschQuery);
      $ergebnis = $dbwkia->getFirstRow();

      if (isset($ergebnis->nr_anzeige) && $ergebnis->nr_anzeige != '' && !is_null($ergebnis->nr_anzeige)) {
        $rueckgabe .= 'Der Kurs ist zwar in der Datenbank, wird aber wegen der Internetfreigabe nicht angezeigt<br>';
      } else {
        $rueckgabe .= 'Das <a class="kurscheck hasnosubitems" href="index.php?action=settings&amp;sub1=2&amp;sub2=1" title="Semestereinstellungen">Semester</a> ist nicht freigeschalten. (' . $kurs->semester . ')<br>';
      }
    } else {
      if ($settings->colorkurseausf == '#blind') {
        $sqlHideAugefallene = 'SELECT k.nr FROM kurse k WHERE k.nr = \'' . $kurs->nr_anzeige . '\' AND k.ausfall = \'J\'';
        $dbwkia->dboperation->clear();
        $dbwkia->dboperation->query($sqlHideAugefallene);
        $ergebnis = $dbwkia->getFirstRowOrNull();
        if ($ergebnis != null) {
          $rueckgabe .= 'Der Kurs ist ausgefallen und ausgefallene Kurse werden ausgeblendet.<br>';
        }
      }

      if ($settings->kategorienImmerMitKursen && $settings->begonneneKurseInitialAusblenden) {
        if ((DateTimeOperations::getDaysFromTo(DateTimeOperations::getDateNow(), $kurs->beginn_dat)) < 1) {
          $rueckgabe .= 'Der Kurs hat schon begonnen und wird deshalb in der Kategorieübersicht nicht angezeigt.<br>';
        }
      }

      if ($settings->beendeteKurseAusblenden != '') {
        $sqlstr = $dbwkia->getSQLBeendeteKurseAusblenden($settings->beendeteKurseAusblenden, new DateTimeOperations(), $settings->beendeteKurseOffset, 'k.');
        $semestersql = ' AND k.semester in (' . StringOperations::convertArray2InList(array($settings->semlist)) . ') ';
        $dbwkia->dboperation->clear();
        $dbwkia->dboperation->query('SELECT k.nr FROM kurse k WHERE 1=1 ' . $sqlstr . $semestersql);
        $ergebnisse = $dbwkia->getAllRowsSingleColumn('nr');
        if (!in_array($kurs->nr_anzeige, $ergebnisse)) {
          $rueckgabe .= 'Bitte prüfen, ob in den Einstellungen der Kursübersicht "(beendete) Kurse ausblenden" greift.<br>';
        }
      }

      if ($settings->sqlRestrictionKurseNurFuerTnMitKennzVon != 0) {
        $dbwkennad = new DBWorkKennzAd();
        $kurs->kennzeichen = $dbwkennad->getKennzIdsForTypUndNr('K', $kurs->nr_anzeige);

        if (!empty($kurs->kennzeichen)) {
          foreach ($kurs->kennzeichen as $kurskennzeichen) {
            if ($kurskennzeichen <= $settings->sqlRestrictionKurseNurFuerTnMitKennzBis
              && $kurskennzeichen >= $settings->sqlRestrictionKurseNurFuerTnMitKennzVon) {
              $rueckgabe .= "Kurs wird eventuell anhand Kennzeichen $kurskennzeichen Versteckt.<br>";
            }
          }
        }
      }

      if ($settings->sqlRestrictionKeineKurseDieserKat != 0) {
        $sqlKategorieAusgeblendet = 'SELECT k.nr FROM kurse k'
          . ' JOIN kurse_kategorien kk ON kk.knr = k.nr '
          . ' WHERE kk.kategorie_id = ' . $settings->sqlRestrictionKeineKurseDieserKat
          . ' AND k.semester IN (' . StringOperations::convertCommaSeparatedList2InList($settings->semlist) . ')'
          . ' AND k.nr = \'' . $kurs->zusatztexte->id . '\'';
        $dbwkia->dboperation->clear();
        $dbwkia->dboperation->query($sqlKategorieAusgeblendet);
        $ergebnis = $dbwkia->getFirstRowOrNull();
        if ($ergebnis != null) {
          $rueckgabe .= 'Dieser Kurs wird den Frontendnutzern wegen seiner Kategorie nicht angezeigt.<br>';
        }
      }

      if ($settings->kategorienImmerMitKursen && $settings->ausgebuchteKurseInitialAusblenden) {
        $rueckgabe .= 'Bitte überprüfen Sie die Einstellungen für die
                <a class="kurscheck hasnosubitems" href="index.php?action=settings&amp;sub1=3&amp;sub2=1" title="Kursübersicht">Kursübersicht</a>.<br>';
      }
    }

    return $rueckgabe;
  }
}

class ContentFotos extends Content
{
  public static function fotosBereinigen($smarty)
  {
    $fotosbereinigen = PostOperations::getVarValue('fotosbereinigen', false) !== false;
    $bereinigt = 0;
    $fotoBasePath = FotoAPI::convertPathToGenerated(FotoAPI::getPhysicalPath('K'));
    $fotoBasePath = str_replace('kurs' . DIRECTORY_SEPARATOR, '', $fotoBasePath);
    $generatedDirExists = true;
    try {
      $subdirs = FSOperations::getSubDirectories($fotoBasePath);
      if ($fotosbereinigen) {
        foreach ($subdirs as $dir) {
          FSOperations::removeDir($dir);
        }
        $bereinigt = 1;
        $subdirs = FSOperations::getSubDirectories($fotoBasePath);
      }
      $subdirCount = count($subdirs);
      $fileCount = 0;
      foreach ($subdirs as $dir) {
        $fileCount += FSOperations::getFileCount($dir);
      }
      $smarty->assign('subdirCount', $subdirCount);
      $smarty->assign('anzahlzubereinigenFotos', $fileCount);
    } catch (Exception $e) {
      $generatedDirExists = false;
      $smarty->assign('subdirCount', 0);
      $smarty->assign('anzahlzubereinigenFotos', 0);
    }
    $smarty->assign('fotoBasePath', $fotoBasePath);
    $smarty->assign('fotosBereinigt', $bereinigt);
    $smarty->assign('generatedDirExists', $generatedDirExists);
  }

  public function getContent()
  {
    $smarty = $this->getSmarty();
    self::fotosBereinigen($smarty);

    return $smarty->fetch('functions/fotos.html');
  }
}

class ContentCache extends Content
{
  public static function cacheBereinigen($smarty)
  {
    $bereinigen = PostOperations::getVarValue('cachebereinigen', false) !== false;
    $bereinigt = 0;
    $cacheBasePath = ConstantOperations::getPathForKwCache();
    $dirExists = FSOperations::isDirWriteable($cacheBasePath);
    $fileCount = 0;
    if ($dirExists) {
      try {
        if ($bereinigen) {
          FSOperations::emptyDir($cacheBasePath);
          $bereinigt = 1;
        }
        $fileCount = FSOperations::getFileCount($cacheBasePath) + FSOperations::getDirCount($cacheBasePath);
      } catch (Exception $e) {
        Logger::logg('Webadmin: Fehler beim Leeren des Caches: ' . $e->getMessage(), 10001);
      }
    }

    $smarty->assign('cacheBasePath', $cacheBasePath);
    $smarty->assign('cachebereinigt', $bereinigt);
    $smarty->assign('dirExists', $dirExists);
    $smarty->assign('fileCountCache', $fileCount);
  }

  public function getContent()
  {
    $smarty = $this->getSmarty();
    self::cacheBereinigen($smarty);

    return $smarty->fetch('functions/cache.html');
  }
}

class ContentUpload extends Content
{
  public function getContent()
  {
    $lib = new LibWBFileUpload();
    $errors = array();

    $smarty = $this->getSmarty();
    if (ini_get('file_uploads') == 0) {
      $smarty->assign('nofileuploads', true);
    } else {
      $smarty->assign('nofileuploads', false);


      $settings = ToolSettingsAPI::getToolSettings(0);

      $sessionTime = ini_get('session.gc_maxlifetime');
      if ($sessionTime == '') {
        $sessionTime = 0;
      }

      $fileUploadDir = $settings->fileUploadPath;

      $period = 7200 + $sessionTime;
      $periodMin = floor(($period / 60) % 60);
      $periodHour = floor($period / 3600);

      $threshold = time() - $period; 

      $time = '';
      if ($periodHour > 0) {
        $time .= "$periodHour Stunden";
      }
      if ($periodMin > 0) {
        $time .= " $periodMin Minuten";
      }

      $delOldFiles = PostOperations::getVarValue('deloldfiles', false) !== false;

      $deletedFileCount = 0;

      if ($delOldFiles) {
        $deletedFileCount = $lib->deleteOldFiles($fileUploadDir, $threshold);
      }

      if (!LibInformation::isDirWriteable($fileUploadDir)) {
        $errors[] = array('error' => 'Schreibrechte',
          'details' => 'Für den Web-Server müssen noch Schreibrechte auf das Verzeichnis ' . CleanOperations::cleanStringForHtml($fileUploadDir) . ' vergeben werden!');
      }

      $smarty->assign('errorary', $errors);
      $smarty->assign('errors', count($errors) > 0);

      $smarty->assign('selflink', $this->getPageLink());

      $smarty->assign('fileuploaddir', CleanOperations::cleanStringForHtml($fileUploadDir));

      $fileCount = $lib->getFileCount($fileUploadDir);
      $smarty->assign('filecount', $fileCount);

      $smarty->assign('time', $time);

      $oldFileCount = count($lib->getOldFiles($fileUploadDir, $threshold));
      $smarty->assign('oldfilecount', $oldFileCount);

      $smarty->assign('deletedfilecount', $deletedFileCount);
    }

    return $smarty->fetch('functions/tnfileupload.html');
  }
}

class ContentPreviewMode extends Content
{
  public function getContent()
  {
    $lib = new LibPreview();
    $libInfo = new LibInformation();
    $errors = array();

    
    try {
      $lib->createPreviewDirs();
    } catch (Exception $e) {
      
      
      \Logger::logg('Vorschaumodus, Fehler beim Erstellen der Vorschau-Ordner:' . $e->getMessage(), 416);
    }

    $smarty = $this->getSmarty();

    $smarty->assign('previewmode', SessionOperations::isPreviewMode());

    $dir = ConstantOperations::getPathForCoreSettings() . 'preview/';
    if (!$libInfo->isDirWriteable($dir)) {
      $errors[] = array('error' => 'Systemeinstellungen: Fehlende Schreibberechtigung', 'details' => $dir);
    }
    $dir = ConstantOperations::getPathForSettingsOrig() . 'preview/';
    if (!$libInfo->isDirWriteable($dir)) {
      $errors[] = array('error' => 'Layouteinstellungen: Fehlende Schreibberechtigung', 'details' => $dir);
    }
    $dir = ConstantOperations::getPathForSightsOrig() . 'preview/';
    if (!$libInfo->isDirWriteable($dir)) {
      $errors[] = array('error' => 'Sichten: Fehlende Schreibberechtigung', 'details' => $dir);
    }
    $dir = ConstantOperations::getPathForKuferToolsUserOrig() . 'preview/';
    if (!$libInfo->isDirWriteable($dir)) {
      $errors[] = array('error' => 'KuferTools: Fehlende Schreibberechtigung', 'details' => $dir);
    }

    if (!SIGHTS_LOADFROMFILE) {
      $errors[] = array('error' => 'Sichten',
      'details' => 'Die Sichten werden aktuell in der Datenbank gespeichert. Seit 
      ' . KUFERWEB . ' 3.0.0 können diese auch im Dateisystem abgelegt werden. Dies 
      ist Voraussetzung für den Vorschaumodus!');
    }

    if (!SETTINGS_LOADFROMFILE) {
      $errors[] = array('error' => 'Einstellungen',
      'details' => 'Die Einstellungen (Settings) werden aktuell in der Datenbank gespeichert. Seit 
      ' . KUFERWEB . ' 3.0.0 können diese auch im Dateisystem abgelegt werden. Dies 
      ist Voraussetzung für den Vorschaumodus!');
    }

    $smarty->assign('errorary', $errors);
    $smarty->assign('errors', count($errors) > 0);

    return $smarty->fetch('functions/previewmode.html');
  }
}

class ContentMehrsprachigkeit extends Content
{
  public function getContent()
  {
    $errors = array();
    $libInfo = new LibInformation();


    $dirAry = ConstantOperations::getPathForSightsModus();
    foreach ($dirAry as $dir) {
      if (!preg_match('/mobile/', $dir) && !$libInfo->isDirWriteable($dir)) {
        $errors[] = array('error' => 'Sichten: Fehlende Schreibberechtigung', 'details' => $dir);
      }
    }

    if (!SIGHTS_LOADFROMFILE) {
      $errors[] = array('error' => 'Sichten',
      'details' => 'Die Sichten werden aktuell in der Datenbank gespeichert. Seit 
      ' . KUFERWEB . ' 3.0.0 können diese auch im Dateisystem abgelegt werden. Dies 
      ist Voraussetzung für die Mehrsprachigkeit!', );
    }

    $adminModus = SessionOperations::getAdminMode();
    $smarty = $this->getSmarty();

    $hlMsp = new DBWorkHLMsp(1, true);
    $sprachenAry = $hlMsp->getAll();

    if (count($sprachenAry) == 0) {
      $errors[] = array('error' => 'Keine Fremdsprache hinterlegt',
      'details' => 'In KuferSQL muss die Mehrsprachigkeit aktiviert werden, und 
      es muss mindestens eine Fremdsprache hinterlegt werden.');
    } else {
      
      if (GetOperations::isDefined('createLanguageFolder')) {
        $language = GetOperations::getVarValue('createLanguageFolder');
        $this->addOrDeleteLanguageFolder($language, $sprachenAry);
      }

      if (GetOperations::isDefined('deleteLanguageFolder')) {
        $language = GetOperations::getVarValue('deleteLanguageFolder');
        $this->addOrDeleteLanguageFolder($language, $sprachenAry, true);
      }

      
      $sfc = new SightsFolderControll();
      $sfc->loadSightsFolderFromSettings();

      
      foreach ($sprachenAry as $key => $mspObj) {
        $sprachenAry[$key] = get_object_vars($mspObj);

        
        
        $sprachenAry[$key]['modus'] = '1' . ($sprachenAry[$key]['id'] < 10 ? '0' : '') . $sprachenAry[$key]['id'] . '1';
        
        $sprachenAry[$key]['hasFolder'] = $sfc->isFolderWithMode($sprachenAry[$key]['modus']);
        
        $sprachenAry[$key]['isAktive'] = floor($adminModus / 10) == '1' . ($sprachenAry[$key]['id'] < 10 ? '0' : '') . $sprachenAry[$key]['id'];
      }

      $smarty->assign('mspary', $sprachenAry);
    }

    $smarty->assign('errorary', $errors);
    $smarty->assign('errors', count($errors) > 0);

    return $smarty->fetch('functions/mehrsprachigkeit.html');
  }

  
  private function addOrDeleteLanguageFolder($pLanguage, $pSprachenAry, $pDelete = false)
  {
    
    $sfc = new SightsFolderControll();
    $sfc->loadSightsFolderFromSettings();

    $folder = '';
    foreach ($pSprachenAry as $mspObj) {
      if ($mspObj->id == $pLanguage) {
        $modus = '1' . ($pLanguage < 10 ? '0' : '') . $pLanguage;
        $folder = new SightsFolder('language' . $pLanguage, $mspObj->bemerkung, $modus . '1');
      }
    }
    if (!empty($folder)) {
      if ($pDelete) {
        $sfc->deleteFolder($folder);
      } else {
        $sfc->addFolder($folder);
      }
      $sfc->saveSightsFolderToSettings();
    } else {
      return false;
    }

    return true;
  }
}

class ContentBackup extends Content
{
  protected function doBackups()
  {
    $pathToGlobalSettings = ConstantOperations::getPathForCoreSettings();
    $layoutpathwithDirSeparator = new Path(ConstantOperations::getPathForSettingsOrig());
    $layoutpath = $layoutpathwithDirSeparator->dirOnly();

    $lib = new LibBackup();
    $backups = array(
    'system' => array('Systemeinstellungen', array($pathToGlobalSettings . 'allgeinstell.cfg', $pathToGlobalSettings . 'connect.php')),
    'settings' => array('Layouteinstellungen', array($layoutpath->toString())),
    'constants' => array('Konstanten', array(ConstantOperations::getUserConstantsPath())),
    'sights' => array('Sichten', array(ConstantOperations::getPathForSightsOrig())),
    'css' => array('CSS - Dateien', $this->getCssFiles()),
    'kufertools_layout' => array('KuferTools Layout', array(BASEDIR . 'kufertools/settings/user/'))
    );

    
    $users = $pathToGlobalSettings . 'users.php';
    if (file_exists($users)) {
      $backups['system'][1][] = $users;
    }

    $doBackupAll = PostOperations::getVarValue('dobackup_all', false) !== false;
    $doBackupSystem = PostOperations::getVarValue('dobackup_system', false) !== false;
    $doBackupSettings = PostOperations::getVarValue('dobackup_settings', false) !== false;
    $doBackupConstants = PostOperations::getVarValue('dobackup_constants', false) !== false;
    $doBackupSights = PostOperations::getVarValue('dobackup_sights', false) !== false;
    $doBackupCss = PostOperations::getVarValue('dobackup_css', false) !== false;
    $doBackupToolsLayout = PostOperations::getVarValue('dobackup_kufertools_layout', false) !== false;

    $backupObjs = array();
    if ($doBackupAll) {
      $files = array();
      foreach ($backups as $backupAry) {
        $files = array_merge($files, $backupAry[1]);
      }
      $backupObjs[] = $lib->createMultipartBackup('Komplette Sicherung', $files);
    } else {
      if ($doBackupSystem) {
        $backupObjs[] = $lib->createMultipartBackup($backups['system'][0], $backups['system'][1]);
      }
      if ($doBackupSettings) {
        $backupObjs[] = $lib->createMultipartBackup($backups['settings'][0], $backups['settings'][1]);
      }
      if ($doBackupConstants) {
        $backupObjs[] = $lib->createMultipartBackup($backups['constants'][0], $backups['constants'][1]);
      }
      if ($doBackupSights) {
        $backupObjs[] = $lib->createMultipartBackup($backups['sights'][0], $backups['sights'][1]);
      }
      if ($doBackupCss) {
        $backupObjs[] = $lib->createMultipartBackup($backups['css'][0], $backups['css'][1]);
      }
      if ($doBackupToolsLayout) {
        $backupObjs[] = $lib->createMultipartBackup($backups['kufertools_layout'][0], $backups['kufertools_layout'][1]);
      }
    }

    return $backupObjs;
  }

  protected function getCssFiles()
  {
    $lib = new LibCss();
    $layoutDir = ConstantOperations::getPathForLayoutOrig();

    return $lib->getCssFiles($layoutDir);
  }

  public function getContent()
  {
    $smarty = $this->getSmarty();
    $lib = new LibBackup();

    
    $doBackup = PostOperations::getVarValue('dobackup', false) !== false;

    if ($doBackup) {
      $backupObjs = $this->doBackups();

      $errors = array();
      foreach ($backupObjs as $obj) {
        if (!is_null($obj)) {
          $errors[] = $obj;
        }
      }
      $smarty->assign('succeed', count($errors) == 0);
      $smarty->assign('backuperrors', $errors);
    }
    $smarty->assign('execbackup', $doBackup);

    
    $smarty->assign('restore', false);
    if (PostOperations::getVarValue('restore', false) !== false) {
      $smarty->assign('restore', true);
      $id = PostOperations::getVarValue('backupid', false);
      $backup = $lib->getBackupById($id);
      $result = $lib->restoreBackup($backup);
      $smarty->assign('restorebackuptitle', CleanOperations::cleanStringForHtml($backup->title));
      $smarty->assign('restorebackupdate', date('d.m.Y H:i:s', $backup->date));
      $smarty->assign('restoresuccess', $result);
    }

    
    $smarty->assign('delete', false);
    if (PostOperations::getVarValue('del', false) !== false) {
      $smarty->assign('delete', true);
      $id = PostOperations::getVarValue('backupid', false);
      $backup = $lib->getBackupById($id);
      $message1 = $lib->removeBackup($backup);
      $smarty->assign('deletebackuptitle', CleanOperations::cleanStringForHtml($backup->title));
      $smarty->assign('deletebackupdate', date('d.m.Y H:i:s', $backup->date));
      $smarty->assign('deletesuccess', $message1);
    }

    $smarty->assign('selflink', $this->getPageLink());

    
    $backups = $lib->getBackups();
    $smarty->assign('countbackups', count($backups));
    $bAry = array();
    foreach ($backups as $b) {
      $bAry[] = array('title' => CleanOperations::cleanStringForHtml($b->title), 'date' => date('d.m.Y H:i:s', $b->date),
      'originalpath' => $b->originalPath, 'backuppath' => $b->backupPath, 'id' => CleanOperations::cleanStringForHtml($b->id));
    }
    $smarty->assign('backups', $bAry);

    return $smarty->fetch('functions/backup.html');
  }
}


class ContentNews extends Content
{
  private $lib;
  private $info = array();

  public function getContent()
  {
    
    $this->lib = new LibNews();

    
    $newsaction = GetOperations::getVarValue('news', 'list');
    $newsObj = GetOperations::getVarValue('newsobj', false);
    $newsObj = PostOperations::getVarValue('newsobj', $newsObj);
    $newsObj['bildpfad'] = $_FILES['newsobj']['tmp_name']['bildpfad'];

    
    if ($newsObj) {
      $this->parseNewsObj($newsaction, $newsObj);
    }

    
    switch ($newsaction) {
      case 'new':
        return $this->getNewsCreateForm($newsObj);
      case 'edit':
        return $this->getNewsEditForm();
      case 'list':
      default:
        return $this->getNewsList();
    }
  }

  
  private function parseNewsObj($newsaction, $newsObj)
  {
    if (is_array($newsObj) && isset($newsObj['action'])) {
      switch ($newsObj['action']) {
        case 'create':
          $this->createNews($newsaction, $newsObj);
          break;
        case 'change':
          $this->changeNews($newsaction, $newsObj);
          break;
        case 'del':
          $this->deleteNews($newsaction, $newsObj);

          if ($newsaction == 'edit') {
            $newsaction = 'list';
          }
          break;

        case 'del-old-news':
          $this->deleteOldNews();
          break;
      }
    } elseif (is_array($newsObj)) {
      foreach ($newsObj as $news) {
        $this->parseNewsObj($newsaction, $news);
      }
    }
  }

  
  private function createNews($newsaction, $newsObj)
  {
    $id = $this->lib->createNews(
      $newsObj['titel'],
      $newsObj['inhalt'],
      $newsObj['autor'],
      isset($newsObj['bildpfad']) ? $newsObj['bildpfad'] : '',
      $newsObj['anzeige_news'],
      $newsObj['anzeige_rss'],
      isset($newsObj['gueltigAb']) ? $newsObj['gueltigAb'] : DEFAULTDATE,
      isset($newsObj['gueltigBis']) ? $newsObj['gueltigBis'] : DEFAULTDATE
    );
    if ($id === false) {
      $this->info[] = array('level' => 'warning', 'type' => 'MissingFields');
      $newsaction = 'new';

      return false;
    } else {
      if (!$this->lib->checkNews(
        $id,
        $newsObj['titel'],
        $newsObj['inhalt'],
        $newsObj['autor'],
        isset($newsObj['bildpfad']) ? $newsObj['bildpfad'] : false,
        isset($newsObj['anzeige_news']) ? $newsObj['anzeige_news'] : false,
        isset($newsObj['anzeige_rss']) ? $newsObj['anzeige_rss'] : false,
        isset($newsObj['gueltigAb']) ? $newsObj['gueltigAb'] : false,
        isset($newsObj['gueltigBis']) ? $newsObj['gueltigBis'] : false
      )) {
        $this->info[] = array('level' => 'warning', 'type' => 'FilteredContent');
        $newsaction = 'edit';
        $_GET['newsid'] = $id;

        return false;
      } else {
        $this->info[] = array('level' => 'ok', 'type' => 'NewsWritten');

        return true;
      }
    }
  }

  
  private function deleteOldNews()
  {
    $delnewsdate = PostOperations::getVarValue('delnewsdate');

    $dtop = new DateTimeOperations();
    $delnewsdate = $dtop->getWbDateStringFromISO8601($delnewsdate);
    if (StringOperations::strlen($delnewsdate) == 10 && $dtop->isValidDate($delnewsdate) && !DateTimeOperations::isDateTimeDefault($delnewsdate)) {
      $this->lib->deleteNewsOlderThan($delnewsdate);
      $this->info[] = array('level' => 'ok', 'type' => 'OldNewsDeleted');

      return true;
    }
    $this->info[] = array('level' => 'warning', 'type' => 'OldNewsDeletedWrongDateFormat');

    return false;
  }

  
  private function changeNews($newsaction, $newsObj, $mitBild = true)
  {
    $error = $this->lib->updateNews(
      $newsObj['id'],
      isset($newsObj['titel']) ? $newsObj['titel'] : null,
      isset($newsObj['inhalt']) ? $newsObj['inhalt'] : null,
      isset($newsObj['autor']) ? $newsObj['autor'] : null,
      isset($newsObj['bildpfad']) ? strstr($newsObj['bildpfad'], 'bilder') : null,
      isset($newsObj['anzeige_news']) ? $newsObj['anzeige_news'] : null,
      isset($newsObj['anzeige_rss']) ? $newsObj['anzeige_rss'] : null,
      isset($newsObj['gueltigAb']) ? $newsObj['gueltigAb'] : null,
      isset($newsObj['gueltigBis']) ? $newsObj['gueltigBis'] : null,
      isset($newsObj['erstelldatum']) ? $newsObj['erstelldatum'] : null
    );
    if ($mitBild) {
      $image = $this->handleUpload($newsObj);

      return true;
    }

    if (!$error) {
      $this->info[] = array('level' => 'warning', 'type' => 'MissingFields');
      $newsaction = 'edit';
      $_GET['newsid'] = $newsObj['id'];

      return false;
    } else {
      if (!$this->lib->checkNews(
        $newsObj['id'],
        isset($newsObj['titel']) ? $newsObj['titel'] : null,
        isset($newsObj['inhalt']) ? $newsObj['inhalt'] : null,
        isset($newsObj['autor']) ? $newsObj['autor'] : null,
        isset($newsObj['bildpfad']) ? $newsObj['bildpfad'] : null,
        isset($newsObj['anzeige_news']) ? $newsObj['anzeige_news'] : null,
        isset($newsObj['anzeige_rss']) ? $newsObj['anzeige_rss'] : null,
        isset($newsObj['gueltigAb']) ? $newsObj['gueltigAb'] : null,
        isset($newsObj['gueltigBis']) ? $newsObj['gueltigBis'] : null
      )) {
        $this->info[] = array('level' => 'warning', 'type' => 'FilteredContent');
        $newsaction = 'edit';
        $_GET['newsid'] = $newsObj['id'];

        return false;
      } else {
        $this->info[] = array('level' => 'ok', 'type' => 'NewsWritten');

        return true;
      }
    }
  }

  
  private function deleteNews($newsaction, $newsObj)
  {
    $this->lib->deleteNews($newsObj['id']);
    $this->info[] = array('level' => 'ok', 'type' => 'NewsDeleted');

    return true;
  }

  
  private function getNewsCreateForm($newsAry = null)
  {
    if (!is_array($newsAry)) {
      $newsObj = new AktuellesWB();
      $newsObj->id = 'new';
      $newsObj->erstelldatum = 'now';
      $newsAry = $this->convertObjectToArray($newsObj);
    }

    $smarty = $this->getSmarty();
    $smarty->assign('selflink', $this->getPageLink());
    $smarty->assign('informations', $this->info);
    $smarty->assign('news', $newsAry);
    $smarty->assign('newsinhalt', CleanOperations::cleanStringContainingHtml($newsAry['inhalt']));

    $date = new DateTime();
    $dtop = new DateTimeOperations();
    $date->add(new DateInterval('P2M'));
    $smarty->assign('aktuellertag', date('Y-m-d'));
    $smarty->assign('twomonthsfromnow', $date->format('Y-m-d'));
    $smarty->assign('deletednewsdate', CleanOperations::cleanStringForHtml($dtop->getWbDateStringFromISO8601(PostOperations::getVarValue('delnewsdate'))));

    return $smarty->fetch('functions/news_edit.html');
  }

  
  private function getNewsEditForm()
  {
    $newsid = GetOperations::getVarValue('newsid', '');
    $news = $this->lib->getSingleNews($newsid);

    if (!is_object($news)) {
      $this->info[] = array('level' => 'warning', 'type' => 'NewsN/A');

      return $this->getNewsList();
    }

    foreach (get_object_vars($news) as $key => $value) {
      $news->{$key} = CleanOperations::cleanStringForHtml($value);
    }
    $news = $this->convertObjectToArray($news);

    $smarty = $this->getSmarty();
    $smarty->assign('selflink', $this->getPageLink());
    $smarty->assign('informations', $this->info);
    $smarty->assign('news', $news);
    $smarty->assign('newsinhalt', htmlspecialchars_decode($news['inhalt']));
    $smarty->assign('bildfile', $_FILES['newsobj']);
    $smarty->assign('bildpfad', $news['bildpfad']);

    $dtop = new DateTimeOperations();
    $date = new DateTime();
    $date->add(new DateInterval('P2M'));
    $smarty->assign('aktuellertag', date('Y-m-d'));
    $smarty->assign('twomonthsfromnow', $date->format('Y-m-d'));
    $smarty->assign('deletednewsdate', CleanOperations::cleanStringForHtml($dtop->getWbDateStringFromISO8601(PostOperations::getVarValue('delnewsdate'))));

    return $smarty->fetch('functions/news_edit.html');
  }

  
  private function getNewsList()
  {
    $lib = new LibNews();
    $smarty = $this->getSmarty();

    $news = $lib->getNews();
    if (empty($news)) {
      $this->info[] = array('level' => 'ok', 'type' => 'NoNews');

      return $this->getNewsCreateForm();
    }

    $anzNews = count($news);
    for ($i = 0; $i < $anzNews; $i++) {
      foreach (get_object_vars($news[$i]) as $key => $value) {
        if (!is_bool($news[$i]->{$key})) {
          $news[$i]->{$key} = CleanOperations::cleanStringContainingHtml($value);
        } else {
          $news[$i]->{$key} = $news[$i]->{$key} ? 1 : 0;
        }
      }
    }
    $news = $this->convertObjectToArray($news);

    for ($i = 0; $i < count($news); $i++) {
      $bildpfad = '';
      if (strstr($news[$i]['bildpfad'], 'bilder') != '') {
        $bildpfad = strstr($news[$i]['bildpfad'], 'bilder');
      }
      $news[$i]['bildpfad'] = $bildpfad;
      $news[$i]['bildtag'] = $bildpfad == '' ? '' : '<img class="newsbild" src="..\\webbasys\\' . $bildpfad . '" alt="Newsbild" style="max-height:200px; max-width:200px;">';
    }

    $smarty->assign('news', $news);
    $smarty->assign('selflink', $this->getPageLink());
    $smarty->assign('informations', $this->info);

    $smarty->assign('aktanzahl', $lib->getLength());
    $smarty->assign('aktseite', $lib->getCurrentPage());
    $smarty->assign('seiten', $lib->getNumPages());
    $smarty->assign('newsinhaltstyle', '<style>p{margin:1em 0 0 0}</style>');

    $dtop = new DateTimeOperations();

    $smarty->assign('delnewsdate', $dtop->reformatDateString($dtop->getDateDaysBefore($dtop->getDateNow(), 14)));
    $smarty->assign('deletednewsdate', CleanOperations::cleanStringForHtml($dtop->getWbDateStringFromISO8601(PostOperations::getVarValue('delnewsdate'))));

    return $smarty->fetch('functions/news.html');
  }

  

  private function handleUpload($newsObj): array
  {
    $fehlerAry = array();
    $uploader = new FileUploadNews();

    $result = $uploader->upload('webbasys/bilder/aktuelles');
    $fieldFilenames = array_map(function($file) {
      return $file['name'];
    }, $_FILES);
    foreach ($result as $filename => $status) {
      if ($status != FileUpload::UPLOAD_OK) {
        $field = array_search($filename, $fieldFilenames);
        $fehlerAry[$field] = "Fehler beim Upload der Datei '{$filename}'";
        Logger::logg(FileUpload::getStatusMessage($status), 2000);
      }
    }

    $newsObj['bildpfad'] = $uploader->getUploadedAttachments()[0]->localname;
    $this->changeNews('edit', $newsObj, false);

    return $fehlerAry;
  }
}

class ContentArchive extends Content
{
  private const ARCHIVE_FILENAME = 'kuferweb.tar.gz';
  private const KUFERWEB_PATH = '../../';
  private const KUFERWEB_DIRNAME = 'kuferweb';

  public function getContent()
  {
    $smarty = $this->getSmarty();
    $smarty->assign('uploadmaxfilesize', $this->getMaxFileSize());

    if (PostOperations::isDefined('create')) {
      $archiveSuccess = $this->createArchive();
      $smarty->assign('archiveSuccess', $archiveSuccess);
      $smarty->assign('archivePath', realpath('./' . self::KUFERWEB_PATH . self::ARCHIVE_FILENAME));
    }

    if (PostOperations::isDefined('upload')) {
      try {
        
        if ($_FILES['archiveFile']['name'] == '') {
          $filename = 'kuferweb_neu.zip';
        } else {
          $filename = $this->uploadArchive();
        }
        $uploadSuccess = $this->unzipArchive($filename);
        $smarty->assign('uploadSuccess', $uploadSuccess);
      } catch (Exception $e) {
        $smarty->assign('uploadSuccess', false);
        $smarty->assign('uploadError', $e->getMessage());
      }
    }

    return $smarty->fetch('functions/kuferwebarchive.html');
  }

  private function getMaxFileSize()
  {
    $tool0Settings = \ToolSettingsAPI::getToolSettings(0);
    $maxFilesize = \ConstantOperations::getMaxFileSize4Upload(($tool0Settings->uploadmaxsize));

    return \MathOperations::getBytesUmrechnung($maxFilesize);
  }

  private function createArchive()
  {
    
    shell_exec('tar -czf ' . self::KUFERWEB_PATH . self::ARCHIVE_FILENAME . ' --directory=' . self::KUFERWEB_PATH . ' ' . self::KUFERWEB_DIRNAME);

    return file_exists(self::KUFERWEB_PATH . self::ARCHIVE_FILENAME);
  }

  private function uploadArchive()
  {
    $target_file = self::KUFERWEB_PATH . basename($_FILES['archiveFile']['name']);
    $filetype = \StringOperations::strtolower(pathinfo($target_file, PATHINFO_EXTENSION));
    if ($filetype != 'zip') {
      throw new Exception('Inkompatible Dateiendung: ' . $filetype);
    }
    if (move_uploaded_file($_FILES['archiveFile']['tmp_name'], $target_file)) {
      return basename($_FILES['archiveFile']['name']);
    } else {
      throw new Exception('Die hochgeladene Datei konnte nicht angelegt werden');
    }
  }

  private function unzipArchive($filename)
  {
    if (!file_exists(self::KUFERWEB_PATH . $filename)) {
      throw new Exception('Das Zip Archiv wurde nicht auf dem Webserver gefunden');
    }
    
    shell_exec('tar -xzf ' . self::KUFERWEB_PATH . $filename . ' --directory=' . self::KUFERWEB_PATH);
    unlink(self::KUFERWEB_PATH . $filename);

    return file_exists(self::KUFERWEB_PATH . 'kuferweb_neu');
  }
}

class ContentLoginWeb extends Content
{
  public function getContent()
  {
    $smarty = $this->getSmarty();
    $login = PostOperations::getVarValue('username');
    $success = false;
    $meldung = '';
    if (!empty($login)) {
      try {
        $this->login($login);
        $success = true;
      } catch (\Exception $e) {
        $meldung = $e->getMessage();
      }
    }
    $smarty->assign('login', $login);
    $smarty->assign('selflink', $this->getPageLink());
    $smarty->assign('meldung', $meldung);
    $smarty->assign('loginErfolgreich', $success);

    return $smarty->fetch('functions/loginweb.html');
  }

  private function login(string $login): void
  {
    $dbw = new DBWorkWBLogins();
    $wblogin = $dbw->getByLogin($login);
    if ($wblogin->isEmpty()) {
      throw new \Exception('Das angegebene Login existiert nicht!');
    }
    $wblogin = LoginApi::getWbLogin($wblogin);
    SessionOperations::getWBLoginToSession($wblogin);
  }
}

class ContentFunctionValidateFiles extends Content
{
  public function getContent()
  {
    $smarty = $this->getSmarty();
    $isDebugDefined = \SessionOperations::getVarValueIntern('debug');
    $smarty->assign('isDevelop', $isDebugDefined);

    if (PostOperations::isDefined('validate')) {
      $errors = \LibValidateFileHashes::validateHashes();
      $smarty->assign('errors', $errors);
      if (empty($errors)) {
        $smarty->assign('success', array('Alle Dateien entsprechen den Original-Dateien.'));
      }
    } elseif ($isDebugDefined && PostOperations::isDefined('regenHashes')) {
      $timeStart = microtime(true);
      \LibValidateFileHashes::generateHashes();
      $timeEnd = microtime(true);
      $timeDiff = $timeEnd - $timeStart;
      $smarty->assign('success', array('Dateihashes erfolgreich generiert (Zeit: ' . number_format($timeDiff, 2, ',', '.') . ')!'));
    } elseif (PostOperations::getVarValue('lowercasedirskufertools') === 'all') {
      list($success, $errors) = \LibValidateFileHashes::renameKuferToolsDirectories();
      $smarty->assign('success', $success);
      $smarty->assign('errors', $errors);
    }

    return $smarty->fetch('functions/validatefiles.html');
  }
}

class ContentMysqlStrukturUpdate extends Content
{
  public function getContent()
  {
    $smarty = $this->getSmarty();

    $dbop = \DBOperation::getInstanceDB1(true);
    if ($dbop->connectionInfo->db_replikat && $dbop->connectionInfo->db_typ == \DBTypeEnum::MYSQLI) {
      $dbwWorkInfoTables = new \Kufer\Web\Classes\Db\DBWorkInformationSchemaTables();
      $tables = array_map(
        \FunctionOperations::getAttribute('table_name'),
        $dbwWorkInfoTables->getTemporaryKuferTransferTables()
      );
      $smarty->assign('tablesKuferTransfer', $tables);

      if (PostOperations::isDefined('delete_stale_tables')) {
        $errors = array();

        $tablesDeleted = array();
        $tablesFromPost = \PostOperations::getVarValue('stale_tables', array());
        if (!is_array($tablesFromPost)) {
          $errors[] = 'Ein technischer Fehler ist aufgetreten';
        } else {
          $tablesToDelete = array_intersect($tables, $tablesFromPost);
          if (empty($tablesToDelete)) {
            $errors[] = 'Keine Tabelle zum löschen angegeben';
          } else {
            foreach ($tablesToDelete as $table) {
              if ($dbwWorkInfoTables->dboperation->executeDontDie('DROP TABLE IF EXISTS ' . $table)) {
                $tablesDeleted[] = $table;
              }
            }

            $smarty->assign('tablesKuferTransfer', array_diff($tables, $tablesDeleted));
          }
        }

        if (!empty($errors)) {
          $smarty->assign('errors', array_map('\\CleanOperations::cleanStringForHtml', $errors));
        } else {
          $smarty->assign('success', array(count($tablesDeleted) . ' Tabellen wurde erfolgreich gelöscht'));
        }
      } elseif (PostOperations::isDefined('convert_utf8mb4_german2_ci')) {
        $structureInfo = new \DBStructureInfo();
        $webTables = $structureInfo->findWebTables();
        $webTables[] = 'anw2';
        $webTables[] = 'anw_extra2';
        $webTables[] = 'web_suggestions';
        $webTables[] = 'web_aktuelles_freigabe';
        $webTables[] = 'web_replikat_settings';

        $tablesFromMoh = $structureInfo->createTablesMappedByGroupNumber();

        $tables = array_unique(array_merge(
          $webTables,
          ...$tablesFromMoh
        ));

        
        if (in_array('hlurlaub_gr', $tables, true) && !in_array('gen_hlurlaub_gr', $tables, true)) {
          $tables[] = 'gen_hlurlaub_gr';
        }

        $errors = array();

        $targetCharset = 'utf8mb4';
        $targetCollation = $targetCharset . '_german2_ci';

        $dbInfo = \DBConnectionInfo::getInstance();
        if ($dbop->execute("ALTER DATABASE {$dbInfo->db_name} CHARACTER SET $targetCharset COLLATE $targetCollation") === false) {
          $errors[] = 'SQL-Fehler: ' . $dbop->getError();
        }

        foreach ($tables as $table) {
          if ($dbop->execute("ALTER TABLE $table CONVERT TO CHARACTER SET $targetCharset COLLATE $targetCollation") === false) {
            $errors[] = 'SQL-Fehler: ' . $dbop->getError();
          }
        }

        if (!empty($errors)) {
          $smarty->assign('errors', array_map('\\CleanOperations::cleanStringForHtml', $errors));
        } else {
          $smarty->assign('success', array('Collation wurde erfolgreich aktualisiert'));
        }
      } elseif (PostOperations::isDefined('updatestructure')) {
        $structureInfo = new \DBStructureInfoCurrent();
        $sqlData = $structureInfo->getMysqlStrukturCodeTxt() . $structureInfo->getMysqlStrukturTxt();
        $sqlParser = new \SQLParser($sqlData);
        $sqlData = implode('', $sqlParser->statements);

        $errors = array();

        $dbop->runTransaction(function() use ($dbop, $sqlParser, &$errors) {
          foreach ($sqlParser->statements as $key => $statement) { 
            
            
            
            
            
            
            
            
            if (StringOperations::startsWith($statement, 'CALL')) {
              $status = $dbop->callStoredProcedure($statement);
            } else {
              $status = $dbop->execute($statement);
            }

            if ($status === false) {
              $errors[] = 'SQL-Fehler bei Zeile: ' . ($key + 1) . ', ' . $dbop->getError();
            }
          }
        });

        if (!empty($errors)) {
          $smarty->assign('errors', array_map('\\CleanOperations::cleanStringForHtml', $errors));
        } else {
          $smarty->assign('success', array('Struktur wurde erfolgreich aktualisiert'));
        }

        
      }
    }

    return $smarty->fetch('functions/mysqlstructureupdate.html');
  }
}