[phpBB Debug] PHP Warning: in file [ROOT]/ext/tas2580/seourls/event/listener.php on line 213: Undefined array key "FORUM_NAME"
Redaxo 4 und PHP 7 - Seite 2 - REDAXO Forum
Hallo,

Wir haben in letzter Zeit festgestellt, dass die Kommunikation via Slack viel schneller und zielführender ist als ein Beitrag im Forum. Aufgrund der neuen und besseren Möglichkeiten der Kommunikation haben wir uns entschlossen das Forum nur noch als Archiv zur Verfügung zu stellen. Somit bleibt es weiterhin möglich hier nach Lösungen zu suchen. Neue Beiträge können nicht mehr erstellt werden.

Wir empfehlen, für deine Fragen/Probleme Slack zu nutzen. Dort sind viele kompetente Benutzer aktiv und beantworten jegliche Fragen, gerne auch von REDAXO-Anfängern! Slack wird von uns sehr intensiv und meistens "rund um die Uhr" benutzt :-)
Selbst einladen kannst Du dich hier: https://redaxo.org/slack/

Benutzeravatar
Gregor.Harlan
Entwickler
Beiträge: 1130
Registriert: 4. Jun 2007, 10:35
Wohnort: Frankfurt am Main

Re: Redaxo 4 und PHP 7

19. Apr 2016, 22:19

RexDude hat geschrieben:Überzeugt von deiner Lösung bin ich nicht weil ich es nie für eine gute Idee halte einfach Fehlermeldungen zu unterdrücken um ein Problem zu beseitigen.
Für aktiv entwickelte Versionen stimme ich dir voll zu. Bei auslaufenden Versionen, die man aber noch für eine möglichst lange Zeit rüsten möchte, würde ich das so pauschal nicht sagen. Da muss man Abwägen, und in diesem Fall sind wir zu der Entscheidung gekommen, die Meldungen zu unterdrücken.
Und irgendwann läuft nun mal jede Version aus.
RexDude hat geschrieben:Und ja ich weiss das das im Core abheschaltet wird, aber was ist denn wenn ich ein Addon entwickeln will und dann dessen Notices/Deprectes beseitigen will. Dann hab ich doch denn ganzen Schmodder vom Core auch mit einheschaltet?
Ja, das ist dann so. Redaxo 4 ist aber auch auslaufend, und nicht mehr für große Neuentwicklungen gedacht. Ich glaube nicht, dass es außer dir viele stören wird.
Und wenn es dich so sehr stört, kannst du gerne die Meldungen beseitigen und ein Pull Request dafür öffnen. Ich sage dir hiermit zu, dass ich ihn annehmen würde (Kompatibilität vorausgesetzt).
RexDude hat geschrieben:- Im Zip befindet sich ein Layout ordner.
Oh, danke für den Hinweis, ich werde das Zip nochmal korrigieren.
RexDude hat geschrieben:- Das Zip hat 7MB. Entpacket man es und packt es wieder sinds nur noch 2,8MB
Das ist mir letztens auch schon aufgefallen, dass das Release-Skript in R4 unnötig große Zips erzeugt, hatte jetzt aber nicht mehr dran gedacht. Werde ich ebenfalls korrigieren.
RexDude hat geschrieben:- Auf eine VM mit Linux und XAMPP (PHP7) scheint kommt dass hier.
Interessant, kann ich mir gerade nicht erklären. Ist es wirklich eine frische Installation, insbesondere mit einer frischen master.inc.php (oder zumindest mit der Fehler-Unterdrückungs-Zeile)?
Friends Of REDAXO: Gemeinsame REDAXO-Entwicklung!

Benutzeravatar
RexDude
Beiträge: 2543
Registriert: 22. Apr 2010, 11:24

Re: Redaxo 4 und PHP 7

19. Apr 2016, 22:30

Die Zeile ist drin. Ändere ich sie in error_reporting(0) sind die Meldungen weg.

Zum Thema auslaufend und nur ich habe damit ein Problem: Im ersten Post dieses Threads wurde dir Hauptproblematik bereits angesprochen: PHP5 wird z.t. schon forciert von den Hostern abgeschaltet. Und nicht jeder hat das Geld oder die Zeit oder auch die Lust auf R5 umzusteigen. Deshalb ist das wie ich finde schon ne sehr wichtige Sache hier was vernünftiges zu haben was stabil läuft, möglichst zukunftsicher ist und beim einschalten von einem error reporting nicht gleich "auseinanderfällt".
Zuletzt geändert von RexDude am 19. Apr 2016, 22:31, insgesamt 1-mal geändert.

Benutzeravatar
ds
Admin
Beiträge: 247
Registriert: 10. Okt 2006, 22:58
Wohnort: Berlin
Kontaktdaten: Website

Re: Redaxo 4 und PHP 7

19. Apr 2016, 22:31

Gregor.Harlan hat geschrieben:Wir haben heute die 4.7 veröffentlicht, mit PHP7-Unterstützung.
Großartig, vielen Dank! Sehr pragmatische Lösung mit dem MySQL-Shim, finde ich. Genau richtig für ein System, das nicht mehr aktiv weiterentwickelt wird, aber für bestehende Projekte u. U. noch lange erhalten bleibt.

Benutzeravatar
georgkaser
Beiträge: 12
Registriert: 11. Mär 2013, 20:27
Wohnort: Worms
Kontaktdaten: Website

Re: Redaxo 4 und PHP 7

19. Apr 2016, 23:17

Für mich passt die Lösung gut. Ich entwickle eh nicht mehr mit R4 sondern mit 5. Es geht wirklich nur darum, dass die aktuellen Seiten unter PHP7 weiterlaufen. Ubuntu LTS 16.04 unterstützt z.B. kein PHP5 mehr, denke da wirds bald mal Probleme bei verschiedenen Hostern geben. Und was in 5 Jahren ist, ist mir erstmal wurscht ;)

PS. Friede sei mit euch :D

Benutzeravatar
JeGr
Beiträge: 63
Registriert: 15. Jun 2013, 16:50

Re: Redaxo 4 und PHP 7

21. Apr 2016, 23:32

Hallo Georg,

also wir (für uns gesprochen) Hoster sind da eher in der Zwickmühle, da viele PHP Software noch PHP5.x benötigt. Bspw. sobald Crypto Kram ins Spiel kommt (*grusel*).
Insofern ist PHP5 für uns noch lange nicht tot und auch Ubuntu 16.04LTS kommt zwar mit PHP7 nativ, es gibt aber durchaus dafür schon Backports von PHP 5.6 - sogar zur parallelen Installation, was ja für den ein oder anderen Entwickler auch wichtig ist, notfalls beides parallel betreiben zu können ;)
Und bis die ersten Hosting Kollegen Xenial freigeben wird sicher auch nochmal ein wenig Zeit ins Land gehen, man will das ja erstmal auf der eigenen Infrastruktur ordentlich durchtesten. Ist ja auch kein Druck da, trusty wird noch bis 2019 supportet und PHP 5.6 hat dank Verlängerung fast das gleiche EndOfLife Datum wie PHP7, somit sind beide für uns gleichberechtigt :)

Grüße
Jens

Benutzeravatar
georgkaser
Beiträge: 12
Registriert: 11. Mär 2013, 20:27
Wohnort: Worms
Kontaktdaten: Website

Re: Redaxo 4 und PHP 7

22. Apr 2016, 00:12

Hi Jens,
gut zu hören :)

Zum Backport: Wenn du den meinst (https://launchpad.net/~ondrej/+archive/ubuntu/php5-5.6) - den hab ich bei mir hier lokal schon probiert. Bekomm denn nicht ordentlich mit Redaxo zu laufen - es gibt hier Probleme mit dem MySQL Modul. Müsste ich wahrscheinlich selbst kompilieren, ist mir dann aber doch zu aufwändig.

Benutzeravatar
Ruediger.Nitzsche
Beiträge: 2117
Registriert: 13. Dez 2005, 09:29
Wohnort: Coburg
Kontaktdaten: Website

Re: Redaxo 4 und PHP 7

6. Mai 2016, 23:12

georgkaser hat geschrieben: Ubuntu LTS 16.04 unterstützt z.B. kein PHP5 mehr, denke da wirds bald mal Probleme bei verschiedenen Hostern geben. Und was in 5 Jahren ist, ist mir erstmal wurscht ;)
Sehe ich auch so wie schon angemerkt, PHP 5 wird definiv noch länger unterstützt, es sei denn, die Hoster sind extrem masochistisch veranlagt, zum einen laufen viele Skripte noch ohne Unterstützung für PHP 7, außerdem ist definitiv auch der Verschlüsselungskrams (leider) ein relevantes Problem.

Rüdiger
gn2 netwerk | gn2 hosting | REDAXO Referenzen | Github
Supportanfragen per PN werden gepflegt ignoriert

Benutzeravatar
Koala
Beiträge: 1612
Registriert: 3. Okt 2005, 13:20

Re: Redaxo 4 und PHP 7

7. Mai 2016, 23:50

... und nicht zu vergessen, dass es da draußen auch noch diverse Redaxo 3 Versionen gibt!
Nicht wahr Rüdiger :D (Stichwort: Twitter-Kommentar)

Hoffentlich behält Hosteurope noch lange seine PHP 5 Unterstützung. Oder es findet sich hier jemand der eine Compat-Classe für Rex 3 zu PHP 7 schaffen kann :roll:
<?php print $Footer; ?>

Sven

Ich würde ja die Welt verändern,
doch der Quellcode ist mir zu absurd!


REX 5 :: Tricks und Tipps
REX 5 :: Modulesammlung

Wiki zu Redaxo 3 und 4 (!nur noch im Webarchiv!)

Benutzeravatar
JeGr
Beiträge: 63
Registriert: 15. Jun 2013, 16:50

Re: Redaxo 4 und PHP 7

10. Mai 2016, 23:13

@georgkaser
Ich vermute das liegt daran, dass das alte mysql Modul schon ewig deprecated ist und deshalb in den neueren PHP Versionen inzwischen nicht mehr mitgebaut wird. mysqli oder mysqlnd sind da meist mit drin. Vermutlich wirds daran hapern, könnte man aber Ondrej mal anhauen deswegen.

@rüdiger
PHP 5 wird mit PHP5.6 nun erstmal so lange wie auch PHP7 im extended Support sein. Damit sind die beiden, was Upstream (also PHP) angeht, recht gleichberechtigt. Was aber leider nichts für 5.4 oder 5.5 heißt. Mit 5.5 hat man noch Glück auf der trusty-Platform von Ubuntu, dass die noch bis 2019 im Support bleiben wird. Aber ansonsten sind 5.4 und 5.5 auch von Upstream schon Schnee von gestern.

@Koala
Redaxo 3 treibt sich auch noch rum? Whoa :O Und ich dachte einige alte Kunden mit 4.1.1 sind schon schlimm ;) Kommt Rex3 eigentlich mit PHP 5.5 oder 5.6 überhaupt klar? Ansonsten kann es dir schnell schlecht gehen, denn alles kleiner als 5.5 ist über kurz oder lang "des Todes" ;)

Grüße

Benutzeravatar
Gregor.Harlan
Entwickler
Beiträge: 1130
Registriert: 4. Jun 2007, 10:35
Wohnort: Frankfurt am Main

Re: Redaxo 4 und PHP 7

11. Mai 2016, 00:48

JeGr hat geschrieben:Kommt Rex3 eigentlich mit PHP 5.5 oder 5.6 überhaupt klar?
Ich habe eben mal testweise Redaxo 3.2.3 mit PHP 5.6 installiert.

Neuere Mysql-Datenbanken machen bei der Installation Probleme, da sind leichte Anpassungen in den SQL-Installationsskripten notwendig (betrifft auch die Exporte, zum Beispiel die Demo). Allerdings wird man ja R3 eher nicht mehr neu installieren.

Deprecated- und Strict-Meldungen müssen natürlich deaktiviert werden.

Bei Nutzung des Opcaches (PHP 5.5/5.6) kommt es teilweise zu verzögerten Auswirkungen bei Aktionen, wo Configdateien beschrieben werden. Zum Beispiel wenn man ein Addon installiert, wirkt sich das unter Umständen erst ein paar Sekunden später aus. Dieses Problem haben aber alle Redaxo-Versionen kleiner 4.7, in 4.7 werden Opcaches der Configdateien immer invalidiert bei Änderung.

Ansonsten scheint R3 aber mit PHP 5.6 zu laufen. Allzu ausgiebig war mein Test zugegebenermaßen aber nicht.
Friends Of REDAXO: Gemeinsame REDAXO-Entwicklung!

Benutzeravatar
JeGr
Beiträge: 63
Registriert: 15. Jun 2013, 16:50

Re: Redaxo 4 und PHP 7

11. Mai 2016, 01:16

@Gregor: Auch ein Nachtmensch? ;)

Aber prinzipiell ist die Aussage doch aber mal sehr schön, das heißt man hat zumindest (auch wenn mit Arbeits- und Testaufwand verbunden) eine reale Chance. Finde ich sehr erbaulich :)

Dank auch für die Info bezüglich Opcache, das ist uns tatsächlich schon mehrfach aufgefallen, dass bei einigen Redaxos manchmal "zwei-drei Klicks" notwendig waren, bis ein Addon installiert oder aktiviert angezeigt wurde (oft wars einfach "neuladen"). Hatten uns an der Stelle immer gewundert, woher das rührt -> Sehr fein, dass das ab 4.7 ebenfalls kein Thema mehr ist.

Grüße Jens

Benutzeravatar
Gregor.Harlan
Entwickler
Beiträge: 1130
Registriert: 4. Jun 2007, 10:35
Wohnort: Frankfurt am Main

Re: Redaxo 4 und PHP 7

11. Mai 2016, 10:26

JeGr hat geschrieben:@Gregor: Auch ein Nachtmensch? ;)
Tendenziell ja, aber auch nicht allzu extrem. ;)
JeGr hat geschrieben:Aber prinzipiell ist die Aussage doch aber mal sehr schön, das heißt man hat zumindest (auch wenn mit Arbeits- und Testaufwand verbunden) eine reale Chance. Finde ich sehr erbaulich :)
Jupp, ich denke die Chancen stehen recht gut.
JeGr hat geschrieben:Dank auch für die Info bezüglich Opcache, das ist uns tatsächlich schon mehrfach aufgefallen, dass bei einigen Redaxos manchmal "zwei-drei Klicks" notwendig waren, bis ein Addon installiert oder aktiviert angezeigt wurde (oft wars einfach "neuladen"). Hatten uns an der Stelle immer gewundert, woher das rührt -> Sehr fein, dass das ab 4.7 ebenfalls kein Thema mehr ist.
Ja, mir war das auch schon seit einer Weile hin und wieder aufgefallen, hatte mir aber irgendwie nicht allzu viel dabei gedacht. Während der Erstellung der 4.7 ist es dann aber häufiger aufgetreten, sodass ich der Ursache dann doch mal auf den Grund gegangen bin.
Wen es nervt, aber Redaxo nicht als ganzes updaten möchte, kann diese Änderungen in seine Redaxo-Version übernehmen (Zeilen können natürlich je nach Version bisschen variieren):
https://github.com/redaxo/redaxo4/commi ... 4c42b57ec9
Friends Of REDAXO: Gemeinsame REDAXO-Entwicklung!

a.albrecht
Beiträge: 141
Registriert: 17. Dez 2008, 23:43
Kontaktdaten: ICQ

Re: Redaxo 4 und PHP 7

1. Feb 2017, 08:58

Hallo.

Ich habe auch einige Projekte auf Redaxo 4.7 laufen.
Die ersten Hostingpakete laufen jetzt auf PHP 7.0.

Wie muss genau vorgegangen werden, um Redaxo 4.7 mit PHP 7 nutzen zu können?


Danke!

Benutzeravatar
Cheffchen
Beiträge: 1809
Registriert: 3. Mär 2009, 13:51
Wohnort: Berlin
Kontaktdaten: Website

Re: Redaxo 4 und PHP 7

3. Feb 2017, 18:45

Hallo @a.albrecht,

gar nicht, das läuft einfach, da musst nichts machen.

Cheffchen

a.albrecht
Beiträge: 141
Registriert: 17. Dez 2008, 23:43
Kontaktdaten: ICQ

Re: Redaxo 4 und PHP 7

14. Feb 2017, 08:47

Danke für die Info.

Wenn ich Rex 4.7 unter PHP7 versuche zu installieren,
gibts einen Haufen Fehlermeldungen.

Kann man diese dann "ausschalten"?

Benutzeravatar
Cheffchen
Beiträge: 1809
Registriert: 3. Mär 2009, 13:51
Wohnort: Berlin
Kontaktdaten: Website

Re: Redaxo 4 und PHP 7

14. Feb 2017, 09:56

Hallo,

die dürften aber nicht kommen.
sind das notice meldungen?
Abschalten entwerder im Hosting wenn zugrief hast PHP Fehlermeldungen (error) oder in den beiden index.php, eine im root und eine in /redaxo/

Code: Alles auswählen

Fehler ausblenden
ini_set('error_reporting', 0);
ini_set('display_errors', 0);

Cheffchen

Benutzeravatar
joachim123
Beiträge: 73
Registriert: 5. Feb 2007, 21:41
Wohnort: München
Kontaktdaten: Website

Re: Redaxo 4 und PHP 7

25. Feb 2017, 03:50

Hey all,

an dieser Stelle mal ein ganz dickes Lob für den eingangs geposteten mysql-Patch :)

Ich habe eine ältere Webseite, deren Hoster radikal und ohne Frühwarnung auf PHP 7 umgestellt hat, damit wieder zum Laufen gebracht. Vielleicht solltet Ihr diese Datei einfach in 4.7.1 integrieren (da wird ja noch mysql_connect genutzt). Ich konnte bislang jedenfalls keine Probleme feststellen (ausser mit einer ebenfalls zu alten opf_lang Version)

Andernfalls hätte ich die alte Seite auf eine 5er Version umstellen müssen, was vermutlich in einem Neubau geendet hätte. Viel Mühe gespart :)

*Schulterklopf*

Grüsse, Joachim
am Ende wird alles gut.

Benutzeravatar
Gregor.Harlan
Entwickler
Beiträge: 1130
Registriert: 4. Jun 2007, 10:35
Wohnort: Frankfurt am Main

Re: Redaxo 4 und PHP 7

25. Feb 2017, 11:08

Ähm, die 4.7 enthält doch extra https://github.com/dshafik/php7-mysql-shim für PHP 7?
Friends Of REDAXO: Gemeinsame REDAXO-Entwicklung!

Benutzeravatar
joachim123
Beiträge: 73
Registriert: 5. Feb 2007, 21:41
Wohnort: München
Kontaktdaten: Website

Re: Redaxo 4 und PHP 7

25. Feb 2017, 11:50

hm, grade nochmal gecheckt: tatsächlich, lokal gehts auf Anhieb. Ich hatte gestern noch weitere Fehler durch opf_lang, vielleicht hat das den automatischen Switch verhindert...

Anyway: super Job :)
am Ende wird alles gut.

JoSund
Beiträge: 1
Registriert: 24. Okt 2018, 19:28

Re: Redaxo 4 und PHP 7

24. Okt 2018, 19:32

Hallo,
unten stehendes funktioniert - danke erstmal - die Seite ist wieder erreichbar.
Eine Frage noch: Der Back-End Bereich läuft nicht und ich weiß nicht warum,
habe das Projekt neu übernommen und kenne mich mit Redaxo nicht aus. Gibt es da noch was was ich umstellen muss ?! Wenn ja / Wie ?
Danke vorab.
RexDude hat geschrieben:
18. Feb 2016, 02:27
Der geeeeht!!! :D

Ein Problem gibts aktuell aber noch: Im Frontend wie Backend werden die Sonderzeichen wie z.B. Umlaute nur kryptisch ausgegeben. Das setzen von utf8_encode() in Zeile 38 hilft, allerdings nur bedingt. Umlaute werden dann richtig dargestellt aber Anfürhungszeichen immer noch nicht. Jemand ne Idee?

class.rex_sql.inc.php
(Konstanten muss ich dann auch noch ersetzen bzw. auch in Addons etc.)

Code: Alles auswählen

<?php

/**
 * Klasse zur Verbindung und Interatkion mit der Datenbank
 * @version svn:$Id$
 */

// Hinweis: @ wurden aktuell auskommentiert

if (!extension_loaded('mysql') ){
    define('MYSQL_BOTH',MYSQLI_BOTH);
    define('MYSQL_NUM',MYSQLI_NUM);
    define('MYSQL_ASSOC',MYSQLI_ASSOC);
}

// wrapper for mysql_result, taken from (Thx!)
function mysqli_result($result, $row, $field) {
    $result->data_seek($row);

    // for no table prefix just go ahead and fetch assoc
    if ( strstr($field, ".") === false ) {
        // Fetch result array
        $data = $result->fetch_assoc();

        return $data[$field];
    }

    // workaround for assoc use and overwriting fieldnames like "a.timestamp" and "b.timestamp"
    list($tablename,$fieldname) = explode(".",$field);
    $resultData = $result->fetch_array(MYSQLI_NUM);

    foreach( $result->fetch_fields() as $index => $fieldData ) {
        if ( $fieldData->table == $tablename && $fieldData->name == $fieldname ) {
            return $resultData[$index]; // solution without utf8_encode ???
        }
    }

    return false;
}


class rex_sql
{
    var $values; // Werte von setValue
    var $fieldnames; // Spalten im ResultSet

    var $table; // Tabelle setzen
    var $wherevar; // WHERE Bediengung
    var $query; // letzter Query String
    var $counter; // ResultSet Cursor
    var $rows; // anzahl der treffer
    var $result; // ResultSet
    var $last_insert_id; // zuletzt angelegte auto_increment nummer
    var $debugsql; // debug schalter
    var $identifier; // Datenbankverbindung
    var $DBID; // ID der Verbindung

    var $error; // Fehlertext
    var $errno; // Fehlernummer

    /*private*/ function rex_sql($DBID = 1)
    {
        global $REX;

        $this->debugsql = false;
        $this->selectDB($DBID);

        $this->flush();
    }

    /**
     * Stellt die Verbindung zur Datenbank her
     */
    /*protected*/ function selectDB($DBID)
    {
        global $REX;

        $this->DBID = $DBID;

        if ($REX['DB'][$DBID]['PERSISTENT']) {
            $this->identifier = /*@*/mysqli_connect('p:' . $REX['DB'][$DBID]['HOST'], $REX['DB'][$DBID]['LOGIN'], $REX['DB'][$DBID]['PSW']);
        } else {
            $this->identifier = /*@*/mysqli_connect($REX['DB'][$DBID]['HOST'], $REX['DB'][$DBID]['LOGIN'], $REX['DB'][$DBID]['PSW']);
        }

        if (!/*@*/mysqli_select_db($this->identifier, $REX['DB'][$DBID]['NAME'])) {
            echo "<font style='color:red; font-family:verdana,arial; font-size:11px;'>Class SQL 1.1 | Database down. | Please contact <a href=mailto:" . $REX['ERROR_EMAIL'] . '>' . $REX['ERROR_EMAIL'] . "</a>\n | Thank you!\n</font>";
            exit;
        }

        if (!isset($REX['DB'][$DBID]['IDENTIFIER']) || $REX['DB'][$DBID]['IDENTIFIER'] != $this->identifier) {
            $REX['DB'][$DBID]['IDENTIFIER'] = $this->identifier;

            // ggf. Strict Mode abschalten
            $this->setQuery('SET SQL_MODE=""');

            // MySQL Version bestimmen
            $res = $this->getArray('SELECT VERSION() as VERSION');
            if (preg_match('/([0-9]+\.([0-9\.])+)/', $res[0]['VERSION'], $matches)) {
                $version = $matches[1];
                if ($DBID == 1) {
                    $REX['MYSQL_VERSION'] = $version;
                }
            } else {
                exit('Could not identifiy MySQL Version!');
            }

            // connection auf UTF8 trimmen
            if (function_exists('mysqli_set_charset') and version_compare($version, '5.0.7', '>=')) {
                mysqli_set_charset($this->identifier, 'utf8');
            } else {
                $this->setQuery('SET NAMES utf8');
            }
        }
    }

    /**
     * Gibt die DatenbankId der Abfrage (SQL) zurück,
     * oder false wenn die Abfrage keine DBID enthält
     *
     * @param $query Abfrage
     */
    static /*protected*/ function getQueryDBID($qry)
    {
        $qry = trim($qry);

        if (preg_match('/\(DB([1-9]){1}\)/i', $qry, $matches)) {
            return $matches[1];
        }

        return false;
    }

    /**
     * Entfernt die DBID aus einer Abfrage (SQL) und gibt die DBID zurück falls
     * vorhanden, sonst false
     *
     * @param $query Abfrage
     */
    static /*protected*/ function stripQueryDBID(&$qry)
    {
        $qry = trim($qry);

        if (($qryDBID = self::getQueryDBID($qry)) !== false) {
            $qry = substr($qry, 6);
        }

        return $qryDBID;
    }

    /**
     * Gibt den Typ der Abfrage (SQL) zurück,
     * oder false wenn die Abfrage keinen Typ enthält
     *
     * Mögliche Typen:
     * - SELECT
     * - SHOW
     * - UPDATE
     * - INSERT
     * - DELETE
     * - REPLACE
     *
     * @param $query Abfrage
     */
    static /*protected*/ function getQueryType($qry)
    {
        $qry = trim($qry);
        // DBID aus dem Query herausschneiden, falls vorhanden
        self::stripQueryDBID($qry);

        if (preg_match('/^(SELECT|SHOW|UPDATE|INSERT|DELETE|REPLACE)/i', $qry, $matches)) {
            return strtoupper($matches[1]);
        }

        return false;
    }

    /**
     * Setzt eine Abfrage (SQL) ab, wechselt die DBID falls vorhanden
     *
     * @param $query Abfrage
     * @return boolean True wenn die Abfrage erfolgreich war (keine DB-Errors
     * auftreten), sonst false
     */
    /*public*/ function setDBQuery($qry)
    {
        if (($qryDBID = self::stripQueryDBID($qry)) !== false) {
            $this->selectDB($qryDBID);
        }

        return $this->setQuery($qry);
    }

    /**
     * Setzt Debugmodus an/aus
     *
     * @param $debug Debug TRUE/FALSE
     */
    /*public*/ function setDebug($debug = true)
    {
        $this->debugsql = $debug;
    }

    /**
     * Setzt eine Abfrage (SQL) ab
     *
     * @param $query Abfrage
     * @return boolean True wenn die Abfrage erfolgreich war (keine DB-Errors
     * auftreten), sonst false
     */
    /*public*/ function setQuery($qry)
    {
        // Alle Werte zurücksetzen
        $this->flush();

        $qry = trim($qry);
        $this->query = $qry;
        $this->result = /*@*/ mysqli_query($this->identifier, $qry);

        if ($this->result) {
            if (($qryType = $this->getQueryType($this->query)) !== false) {
                switch ($qryType) {
                    case 'SELECT' :
                    case 'SHOW' :
                    {
                        $this->rows = mysqli_num_rows($this->result);
                        break;
                    }
                    case 'REPLACE' :
                    case 'DELETE' :
                    case 'UPDATE' :
                    {
                        $this->rows = mysqli_affected_rows($this->identifier);
                        break;
                    }
                    case 'INSERT' :
                    {
                        $this->rows = mysqli_affected_rows($this->identifier);
                        $this->last_insert_id = mysqli_insert_id($this->identifier);
                        break;
                    }
                }
            }
        } else {
            $this->error = mysqli_error($this->identifier);
            $this->errno = mysqli_errno($this->identifier);
            
            rex_register_extension_point('REX_SQL_ERROR', $this);
        }

        if ($this->debugsql || $this->error != '') {
            $this->printError($qry);
        }

        return $this->getError() === '';
    }

    /**
     * Setzt den Tabellennamen
     *
     * @param $table Tabellenname
     */
    /*public*/ function setTable($table)
    {
        $this->table = $table;
    }

    /**
     * Setzt den Wert eine Spalte
     *
     * @param string $feldname Spaltenname
     * @param string $wert Wert
     */
    /*public*/ function setValue($feldname, $wert)
    {
        $this->values[$feldname] = $wert;
    }

    /**
     * Setzt ein Array von Werten zugleich
     *
     * @param $valueArray Ein Array von Werten
     * @param $wert Wert
     */
    /*public*/ function setValues($valueArray)
    {
        if (is_array($valueArray)) {
            foreach ($valueArray as $name => $value) {
                $this->setValue($name, $value);
            }
            return true;
        }
        return false;
    }

    /**
     * Prüft den Wert einer Spalte der aktuellen Zeile ob ein Wert enthalten ist
     * @param $feld Spaltenname des zu prüfenden Feldes
     * @param $prop Wert, der enthalten sein soll
     */
    /*protected*/ function isValueOf($feld, $prop)
    {
        if ($prop == '') {
            return true;
        } else {
            return strpos($this->getValue($feld), $prop) !== false;
        }
    }

    /**
     * Setzt die WHERE Bedienung der Abfrage
     */
    /*public*/ function setWhere($where)
    {
        $this->wherevar = "WHERE $where";
    }

    /**
     * Gibt den Wert einer Spalte im ResultSet zurück
     * @param $value Name der Spalte
     * @param [$row] Zeile aus dem ResultSet
     */
    /*public*/ function getValue($feldname, $row = null)
    {
        if (isset($this->values[$feldname])) {
            return $this->values[$feldname];
        }

        $_row = $this->counter;
        if (is_int($row)) {
            $_row = $row;
        }

        $res = mysqli_result($this->result, $_row, $feldname);

        if ($res === false) {
            $sendWarnings = (error_reporting() & E_WARNING) == E_WARNING;

            if ($sendWarnings && function_exists('debug_backtrace')) {
                $trace = debug_backtrace();
                $loc = $trace[0];
                echo '<b>Warning</b>:  mysqli_result(' . $feldname . '): Initial error found in file <b>' . $loc['file'] . '</b> on line <b>' . $loc['line'] . '</b><br />';
            }
        }
        return $res;
    }

    /**
     * Gibt den Wert der aktuellen Zeile im ResultSet zurueck und
     * bewegt den internen Zeiger auf die naechste Zeile
     */
    /*public*/ function getRow($fetch_type = MYSQL_ASSOC)
    {
        return mysqli_fetch_array($this->result, $fetch_type);
    }

    /**
     * Prüft, ob eine Spalte im Resultset vorhanden ist
     * @param $value Name der Spalte
     */
    /*public*/ function hasValue($feldname)
    {
        return in_array($feldname, $this->getFieldnames());
    }

    /**
     * Prüft, ob das Feld mit dem Namen $feldname Null ist.
     *
     * Falls das Feld nicht vorhanden ist,
     * wird Null zurückgegeben, sonst True/False
     */
    /*public*/ function isNull($feldname)
    {
        if ($this->hasValue($feldname)) {
            return $this->getValue($feldname) === null;
        }

        return null;
    }

    /**
     * Gibt die Anzahl der Zeilen zurück
     */
    /*public*/ function getRows()
    {
        return $this->rows;
    }

    /**
     * Gibt die Zeilennummer zurück, auf der sich gerade der
     * interne Zähler befindet
     *
     * @deprecated since version 4.3.0
     */
    /*public*/ function getCounter()
    {
        return $this->counter;
    }

    /**
     * Gibt die Anzahl der Felder/Spalten zurück
     */
    /*public*/ function getFields()
    {
        return mysqli_num_fields($this->result);
    }

    /**
     * Baut den SET bestandteil mit der
     * verfügbaren values zusammen und gibt diesen zurück
     *
     * @see setValue
     */
    /*protected*/ function buildSetQuery()
    {
        $qry = '';
        if (is_array($this->values)) {
            foreach ($this->values as $fld_name => $value) {
                if ($qry != '') {
                    $qry .= ',';
                }

                // Bei <tabelle>.<feld> Notation '.' ersetzen, da sonst `<tabelle>.<feld>` entsteht
                if (strpos($fld_name, '.') !== false) {
                    $fld_name = str_replace('.', '`.`', $fld_name);
                }

                if ($value === null) {
                    $qry .= '`' . $fld_name . '`= NULL';
                } else {
                    $qry .= '`' . $fld_name . '`=\'' . $value . '\'';
                }

// Da Werte via POST/GET schon mit magic_quotes escaped werden,
// brauchen wir hier nicht mehr escapen
//        $qry .= '`' . $fld_name . '`=' . $this->escape($value);
            }
        }

        return $qry;
    }

    /**
     * Setzt eine Select-Anweisung auf die angegebene Tabelle
     * mit den WHERE Parametern ab
     *
     * @see #setTable()
     * @see #setWhere()
     */
    /*public*/ function select($fields)
    {
        return $this->setQuery('SELECT ' . $fields . ' FROM `' . $this->table . '` ' . $this->wherevar);
    }

    /**
     * Setzt eine Update-Anweisung auf die angegebene Tabelle
     * mit den angegebenen Werten und WHERE Parametern ab
     *
     * @see #setTable()
     * @see #setValue()
     * @see #setWhere()
     */
    /*public*/ function update($successMessage = null)
    {
        return $this->statusQuery('UPDATE `' . $this->table . '` SET ' . $this->buildSetQuery() . ' ' . $this->wherevar, $successMessage);
    }

    /**
     * Setzt eine Insert-Anweisung auf die angegebene Tabelle
     * mit den angegebenen Werten ab
     *
     * @see #setTable()
     * @see #setValue()
     */
    /*public*/ function insert($successMessage = null)
    {
        return $this->statusQuery('INSERT INTO `' . $this->table . '` SET ' . $this->buildSetQuery(), $successMessage);
    }

    /**
     * Setzt eine Replace-Anweisung auf die angegebene Tabelle
     * mit den angegebenen Werten ab
     *
     * @see #setTable()
     * @see #setValue()
     * @see #setWhere()
     */
    /*public*/ function replace($successMessage = null)
    {
        return $this->statusQuery('REPLACE INTO `' . $this->table . '` SET ' . $this->buildSetQuery() . ' ' . $this->wherevar, $successMessage);
    }

    /**
     * Setzt eine Delete-Anweisung auf die angegebene Tabelle
     * mit den angegebenen WHERE Parametern ab
     *
     * @see #setTable()
     * @see #setWhere()
     */
    /*public*/ function delete($successMessage = null)
    {
        return $this->statusQuery('DELETE FROM `' . $this->table . '` ' . $this->wherevar, $successMessage);
    }

    /**
     * Setzt den Query $query ab.
     *
     * Wenn die Variable $successMessage gefüllt ist, dann wird diese bei
     * erfolgreichem absetzen von $query zurückgegeben, sonst die MySQL
     * Fehlermeldung
     *
     * Wenn die Variable $successMessage nicht gefüllt ist, verhält sich diese
     * Methode genauso wie setQuery()
     *
     * Beispiel:
     *
     * <code>
     * $sql = rex_sql::factory();
     * $message = $sql->statusQuery(
     *    'INSERT  INTO abc SET a="ab"',
     *    'Datensatz  erfolgreich eingefügt');
     * </code>
     *
     *  anstatt von
     *
     * <code>
     * $sql = rex_sql::factory();
     * if($sql->setQuery('INSERT INTO abc SET a="ab"'))
     *   $message  = 'Datensatz erfolgreich eingefügt');
     * else
     *   $message  = $sql- >getError();
     * </code>
     */
    /*public*/ function statusQuery($query, $successMessage = null)
    {
        $res = $this->setQuery($query);
        if ($successMessage) {
            if ($res) {
                return $successMessage;
            } else {
                return $this->getError();
            }
        }
        return $res;
    }

    /**
     * Stellt alle Werte auf den Ursprungszustand zurück
     */
    /*public*/ function flush()
    {
        $this->flushValues();
        $this->fieldnames = array ();

        $this->table = '';
        $this->wherevar = '';
        $this->query = '';
        $this->counter = 0;
        $this->rows = 0;
        $this->result = '';
        $this->last_insert_id = '';
        $this->error = '';
        $this->errno = '';
    }

    /**
     * Stellt alle Values, die mit setValue() gesetzt wurden, zurück
     *
     * @see #setValue(), #getValue()
     */
    /*public*/ function flushValues()
    {
        $this->values = array ();
    }


    /**
     * Setzt den Cursor des Resultsets auf die nächst niedrigere Stelle
     */
    /*public*/ function previous()
    {
        $this->counter--;
    }

    /**
     * Setzt den Cursor des Resultsets auf die nächst höhere Stelle
     */
    /*public*/ function next()
    {
        $this->counter++;
    }

    /*
     * Prüft ob das Resultset weitere Datensätze enthält
     */
    /*public*/ function hasNext()
    {
        return $this->counter != $this->rows;
    }

    /**
     * Setzt den Cursor des Resultsets zurück zum Anfang
     */
    /*public*/ function reset()
    {
        $this->counter = 0;
    }

    /**
     * Setzt den Cursor des Resultsets aufs Ende
     */
    /*public*/ function last()
    {
        $this->counter = ($this->rows - 1);
    }

    /**
     * Gibt die letzte InsertId zurück
     */
    /*public*/ function getLastId()
    {
        return $this->last_insert_id;
    }

    /**
     * Lädt das komplette Resultset in ein Array und gibt dieses zurück und
     * wechselt die DBID falls vorhanden
     *
     * @param string $sql        Abfrage
     * @param string $fetch_type Default: MYSQL_ASSOC; weitere: MYSQL_NUM, MYSQL_BOTH
     * @return array
     */
    /*public*/ function getDBArray($sql = '', $fetch_type = MYSQL_ASSOC)
    {
        return $this->_getArray($sql, $fetch_type, 'DBQuery');
    }

    /**
     * Lädt das komplette Resultset in ein Array und gibt dieses zurück
     *
     * @param string $sql        Abfrage
     * @param string $fetch_type Default: MYSQL_ASSOC; weitere: MYSQL_NUM, MYSQL_BOTH
     * @return array
     */
    /*public*/ function getArray($sql = '', $fetch_type = MYSQL_ASSOC)
    {
        return $this->_getArray($sql, $fetch_type);
    }

    /**
     * Hilfsfunktion
     *
     * @see getArray()
     * @see getDBArray()
     * @param string $sql        Abfrage
     * @param string $fetch_type MYSQL_ASSOC, MYSQL_NUM oder MYSQL_BOTH
     * @param string $qryType    void oder DBQuery
     * @return array
     */
    /*private*/ function _getArray($sql, $fetch_type, $qryType = 'default')
    {
        if ($sql != '') {
            switch ($qryType) {
                case 'DBQuery': $this->setDBQuery($sql); break;
                default       : $this->setQuery($sql);
            }
        }

        $data = array();
        while ($row = /*@*/ mysqli_fetch_array($this->result, $fetch_type)) {
            $data[] = $row;
        }

        return $data;
    }

    /**
     * Gibt die zuletzt aufgetretene Fehlernummer zurück
     */
    /*public*/ function getErrno()
    {
        return $this->errno;
    }

    /**
     * Gibt den zuletzt aufgetretene Fehlernummer zurück
     */
    /*public*/ function getError()
    {
        return $this->error;
    }

    /**
     * Prüft, ob ein Fehler aufgetreten ist
     */
    /*public*/ function hasError()
    {
        return $this->error != '';
    }

    /**
     * Gibt die letzte Fehlermeldung aus
     */
    /*public*/ function printError($query)
    {
        if ($this->debugsql == true) {
            echo '<hr />' . "\n";
            echo 'Query: ' . nl2br(htmlspecialchars($query)) . "<br />\n";

            if (strlen($this->getRows()) > 0) {
                echo 'Affected Rows: ' . $this->getRows() . "<br />\n";
            }
            if (strlen($this->getError()) > 0) {
                echo 'Error Message: ' . htmlspecialchars($this->getError()) . "<br />\n";
                echo 'Error Code: ' . $this->getErrno() . "<br />\n";
            }
        }
    }

    /**
     * Setzt eine Spalte auf den nächst möglich auto_increment Wert
     * @param $field Name der Spalte
     */
    /*public*/ function setNewId($field)
    {
        // setNewId muss neues sql Objekt verwenden, da sonst bestehende informationen im Objekt überschrieben werden
        $sql = self::factory();
        if ($sql->setQuery('SELECT `' . $field . '` FROM `' . $this->table . '` ORDER BY `' . $field . '` DESC LIMIT 1')) {
            if ($sql->getRows() == 0) {
                $id = 0;
            } else {
                $id = $sql->getValue($field);
            }

            $id++;
            $this->setValue($field, $id);

            return $id;
        }

        return false;
    }

    /**
     * Gibt die Spaltennamen des ResultSets zurück
     */
    /*public*/ function getFieldnames()
    {
        if (empty($this->fieldnames)) {
            for ($i = 0; $i < $this->getFields(); $i++) {
                $this->fieldnames[] = mysqli_fetch_field_direct($this->result, $i)->name;
            }
        }
        return $this->fieldnames;
    }

    /**
     * Escaped den übergebenen Wert für den DB Query
     *
     * @param string $value den zu escapenden Wert
     * @param string $delimiter Delimiter der verwendet wird, wenn es sich bei $value um einen String handelt
     * @param boolean $force Escapen erzwingen, unabhängig davon ob es ein nummerischer Wert ist
     */
    /*public*/ function escape($value, $delimiter = '', $force = false)
    {
        // Quote if not a number or a numeric string
        if ($force || !is_numeric($value)) {
            $value = $delimiter . mysqli_real_escape_string($this->identifier, $value) . $delimiter;
        }
        return $value;
    }

    /**
     * Erstellt das CREATE TABLE Statement um die Tabelle $table
     * der Datenbankverbindung $DBID zu erstellen.
     *
     * @param $table string Name der Tabelle
     * @param $DBID int Id der Datenbankverbindung
     * @return string CREATE TABLE Sql-Statement zu erstsellung der Tabelle
     */
    static /*public*/ function showCreateTable($table, $DBID = 1)
    {

        $sql = self::factory($DBID);
        $create = $sql->getArray("SHOW CREATE TABLE `$table`");
        $create = current($create);
        $create = $create['Create Table'];

        return $create;
    }

    /**
     * Sucht alle Tabellen der Datenbankverbindung $DBID.
     * Falls $tablePrefix gesetzt ist, werden nur dem Prefix entsprechende Tabellen gesucht.
     *
     * @param $DBID int Id der Datenbankverbindung
     * @param $tablePrefix string Zu suchender Tabellennamen-Prefix
     * @return array Ein Array von Tabellennamen
     */
    static /*public*/ function showTables($DBID = 1, $tablePrefix = null)
    {
        $qry = 'SHOW TABLES';
        if ($tablePrefix != null) {
            $tablePrefix = str_replace('_', '\_', $tablePrefix);
            $qry .= ' LIKE "' . $tablePrefix . '%"';
        }

        $sql = self::factory($DBID);
        $tables = $sql->getArray($qry);
        $tables = array_map('reset', $tables);

        return $tables;
    }

    /**
     * Sucht Spalteninformationen der Tabelle $table der Datenbankverbindung $DBID.
     *
     * @param $table string Name der Tabelle
     * @param $DBID int Id der Datenbankverbindung
     * @return array Ein Array das die Metadaten enthält
     */
    static /*public*/ function showColumns($table, $DBID = 1)
    {
        $sql = self::factory($DBID);
        $sql->setQuery('SHOW COLUMNS FROM ' . $table);

        $columns = array();
        for ($i = 0; $i < $sql->getRows(); $i++) {
            $columns [] = array(
                'name' => $sql->getValue('Field'),
                'type' => $sql->getValue('Type'),
                'null' => $sql->getValue('Null'),
                'key' => $sql->getValue('Key'),
                'default' => $sql->getValue('Default'),
                'extra' => $sql->getValue('Extra')
            );
            $sql->next();
        }

        return $columns;
    }

    /**
     * Gibt die Serverversion zurück.
     *
     * Die Versionsinformation ist erst bekannt,
     * nachdem der rex_sql Konstruktor einmalig erfolgreich durchlaufen wurde.
     */
    static /*public*/ function getServerVersion()
    {
        global $REX;
        return $REX['MYSQL_VERSION'];
    }

    /**
     * @param int  $DBID
     * @param string $class
     * @return static
     */
    static /*public*/ function factory($DBID = 1, $class = null)
    {
        // keine spezielle klasse angegeben -> default klasse verwenden?
        if (!$class) {
            // ----- EXTENSION POINT
            $class = rex_register_extension_point('REX_SQL_CLASSNAME', 'rex_sql',
                array(
                    'DBID'      => $DBID
                )
            );
        }

        return new $class($DBID);
    }

    /**
     * Gibt ein SQL Singelton Objekt zurück
     *
     * @deprecated since 4.3.0
     */
    static /*public*/ function getInstance($DBID = 1, $deprecatedSecondParam = null)
    {
        return self::factory($DBID);
    }

    /**
     * Gibt den Speicher wieder frei
     */
    /*public*/ function freeResult()
    {
        if (is_resource($this->result)) {
            mysqli_free_result($this->result);
        }
    }

    /**
     * Prueft die uebergebenen Zugangsdaten auf gueltigkeit und legt ggf. die
     * Datenbank an
     */
    static /*public*/ function checkDbConnection($host, $login, $pw, $dbname, $createDb = false)
    {
        global $I18N;

        $err_msg = true;
        $link = /*@*/ mysqli_connect($host, $login, $pw);
        if (!$link) {
            $err_msg = $I18N->msg('setup_021');
        } else {
            $result = mysqli_query($link, 'SELECT VERSION() AS version');
            $result = mysqli_fetch_array($result, MYSQL_ASSOC);
            if (version_compare($result['version'], '5.0', '<')) {
                $err_msg = $I18N->msg('setup_021_1', $result['version']);
            } elseif (!/*@*/ mysqli_select_db($link, $dbname)) {
                if ($createDb) {
                    mysqli_query($link, 'CREATE DATABASE `' . $dbname . '`');
                    if (mysqli_error($link) != '') {
                        $err_msg = $I18N->msg('setup_022');
                    }
                } else {
                    $err_msg = $I18N->msg('setup_022');
                }
            }
        }

        if ($link) {
            mysqli_close($link);
        }
        return $err_msg;
    }

    /**
     * Schließt die Verbindung zum DB Server
     */
    static /*public*/ function disconnect($DBID = 1)
    {
        global $REX;

        // Alle Connections schließen
        if ($DBID === null) {
            foreach ($REX['DB'] as $DBID => $DBSettings) {
                self::disconnect($DBID);
            }

            return;
        }

        if (!$REX['DB'][$DBID]['PERSISTENT'] &&
             isset($REX['DB'][$DBID]['IDENTIFIER']) &&
             is_resource($REX['DB'][$DBID]['IDENTIFIER'])
        ) {
            $db = self::factory($DBID);

            if (self::isValid($db)) {
                mysqli_close($db->identifier);
            }
        }
    }

    /*public*/ function addGlobalUpdateFields($user = null)
    {
        global $REX;

        if (!$user) {
            $user = $REX['USER']->getValue('login');
        }

        $this->setValue('updatedate', time());
        $this->setValue('updateuser', $user);
    }

    /*public*/ function addGlobalCreateFields($user = null)
    {
        global $REX;

        if (!$user) {
            $user = $REX['USER']->getValue('login');
        }

        $this->setValue('createdate', time());
        $this->setValue('createuser', $user);
    }

    static /*public*/ function isValid($object)
    {
        return is_object($object) && is_a($object, 'rex_sql');
    }
} 

Rumi
Beiträge: 73
Registriert: 20. Aug 2010, 01:35

Re: Redaxo 4 und PHP 7

1. Nov 2018, 01:01

Hallo

ich verwende Redaxo 4.4.1, und habe gerade die class.rex_sql.inc.php von RexDude eingesetzt (herzlichen Dank dafür!), und die Struktur kommt schon mal wieder. Nur leider wird kein Inhalt angezeigt, welcher mit dem AddOn Textile gemacht wurde (d.h. mehr oder minder der gesamte Inhalt). Muss ich eine neuere Version von Textile installieren? Was muss ich beachten?

Danke!

Thomas.Skerbis
Beiträge: 1371
Registriert: 4. Aug 2006, 14:06
Wohnort: Rheinberg
Kontaktdaten: Website Twitter

Re: Redaxo 4 und PHP 7

6. Nov 2018, 16:13

Wir empfehlen ein Upgrade auf 4.7.2.
Änderungen an älteren Versionen führen meist zu mehr Problemen als ein sauberes Update.

Rumi
Beiträge: 73
Registriert: 20. Aug 2010, 01:35

Re: Redaxo 4 und PHP 7

6. Nov 2018, 18:48

Danke! Wie kann ich updaten wenn das Redaxo Backend auch nur noch eine weisse Seite ist? Gibt es eine Möglichkeit, trotzdem ein Backup runterzuladen, welches von einer neueren Version geladen werden kann?
Oder kann ich z.B. erfolgreich Redaxo 5 mit der DB von Redaxo 4 verknüpfen?

Eine Webseite ist jetzt in einem recht guten Zustand (gewisse Addons wurden einfach mit HTML ersetzt). Die andere ist trotz Hack von RexDude immer noch vollkommen weiss, sowohl Front- wie auch Backend.

Thomas.Skerbis
Beiträge: 1371
Registriert: 4. Aug 2006, 14:06
Wohnort: Rheinberg
Kontaktdaten: Website Twitter

Re: Redaxo 4 und PHP 7

8. Nov 2018, 15:00

1. Backup der Datenbank anlegen (für alle Fälle) .z..B. per PHPMyAdmin
2- Die alten REDAXO Dateien (außer /files) in einen neuen Ordner, z.B. Backup verschieben.
3. REDAXO 4.7 hochladen und Installation starten
4. Bei der Frage nach der Datenbank (weiß den Wortlaut gerade nicht) mitteilen dass eine 4er Datenbank bereits existiert.
5. Login-Daten festlegen
6. einloggen
7. Fehlende AddOns nachinstallierten

so hätte ich es versucht.

Zurück zu „Allgemeines [R4]“