Erweiterung zum Betrieb bei "Safe_mode=on"

Ideen für neue Funktionen in CONTENIDO?
Antworten
rethus
Beiträge: 1851
Registriert: Di 28. Mär 2006, 11:55
Wohnort: Mönchengladbach
Kontaktdaten:

Erweiterung zum Betrieb bei "Safe_mode=on"

Beitrag von rethus » Di 11. Apr 2006, 08:09

Hallo,
ich habe selbst einige Jahre an einem eigenen CMS-System entwickelt. Nun bin ich aus synergie-effekten auf contenido umgestiegen.

Schade finde ich, dass sich Contenido och icht ohne Safe_mode betreiben lässt, wobei das doch eingentlich eines der geringsten Probleme ist, eine Software so zu schreiben, das Sie auch ohne Safemode funktioniert.

(Klar, große Sprüche kann jeder klopfen :roll: ... komme aber gleich zu einem Lösungsansatz)


Ich weiß nicht, wie genau Contenido technsich aufgebaut ist, da ich noch bei einer intensiven Einarbeitung und Handbucherstellung für die Verwaltung von Contenido stecke. Jedoch habe ich bei meinem alten CMS-System das Problem so gelößt:


Mein altes System hatte alle SQL-Befehlt in einer Datenbank-Schnittstellen-Klasse (AppDbManager.class) gekapselt. Über diese Klasse wurden alle Datenbankverbindungen aufgebaut und verwaltet. So ist es unter anderem möglich, mit der Änderung dieser einene Klasse auch andere Datenbanken zu unterstützen (interportabilität)

Nun zum Safe_Mode:
Ich habe eine Schnittstellen-Klasse (FtpManager.class) geschreiben, die von der Datenbank-Schnittstelle erbt. In dieser FTP-Klasse handle ich dann Verbindungen zum eigenen Server, die eine Dummy-Datei dort positionieren.
Die Dummy-Datei ist wichtig, da man im Safe_Mode Dateien umbenennen und bearbeiten kann. So öffne ich im zweiten Schritt die Dummy-Datei und fülle Sie mit den Inhalten, wie es beliebt.

Programmiertechnisch ist das nicht viel mehr Aufwand als das normale erzeugen oder kopieren einer Datei, da dies dann anstatt über einen php-Befehl (mkdir) über eine eigene Funktion erzeugt wird, die auf FtpManager.class zugreift (z:b: mkFtpDir() ).

Anbei ein Codebeispiel für die FtpManager-Klasse:
FtpManager.class
<?php
/*______________________________________________________________________________
* @(#)FtpManager.class.php
* Datum : 03.06.2004
* Letzte Änderung :
* geändert von : Samuel Suther
* Art der Änderung :
* Version : 0.5_beta
*______________________________________________________________________________
*/
include_once(dirname(__FILE__)."/ConnectionManager.class.php");

class FtpManager extends AppDbManager
{
//------------------------------------------------------------------------------
// KONSTANTEN
//------------------------------------------------------------------------------
/* Die Folgenden Werte werden als Kostanten abgelegt,
* damit sie waehrend der Laufzeit nicht mehr veraendert werden koennen.
*/
var $FTP_USER =""; // Benutzername fuer den FTP-Zugang
var $FTP_PASSWD =""; // Passwort fuer den FTP-Zugang
var $FTP_SERVER =""; // URL des FTP-Servers (Standart-URL: 127.0.0.1)
var $FTP_PORT ="21"; // PORT des FTP-Zugang (Standartport: 21)
//------------------------------------------------------------------------------
// PROPERTIES
//------------------------------------------------------------------------------
var $ftpStatus = false; // Kontrollflag ob Verbindung besteht
var $errorM = null; // Fehler Meldung (Text)
var $statusM = null; // Meldung des aktuellen Verarbeitungsstatus
var $theConnection = null; // FTP-Verbindung
var $persObj = null; // PeristenzObjekt

var $resultNum = null; // Anzahl der gefundenen Datens&auml;tze
var $result = null; // Datensaetze der Abfrage

var $debug = 1; // Debugausgabe fuer Entwicklung (Fehlerausgabe inkl. exit) (1|0)
//------------------------------------------------------------------------------
/**
* FtpManager Konstruktor
* @param PersObj - PersistenzObjekt (alle Objekte, die
* das Interface "PersistenzIF" implementieren)
**/
function FtpManager($inPersObj)
{
$this->persObj = $inPersObj;
if($ftpStatus == FALSE)
{
if(!$this->theConnection = ConnectionManager::getFtpConnection($this->FTP_SERVER,$this->FTP_PORT,$this->FTP_USER,$this->FTP_PASSWD))
{
$this->setErrorMsg("Die Verbindung zum FTP-Server konnte nicht hergestellt werden");
}
else $this->ftpStatus = TRUE;
$this->setStatusMsg("Aktuelles Verzeichnis:".ftp_pwd($this->theConnection)."<br>");
}
}
/**
* getFtpVerz Methode
* gibt das aktuelle Verzeichnis aus
**/
function getFtpVerz()
{
return ftp_pwd($this->theConnection);
}
/**
* changeFtpVerz Methode
* wechselt von dem aktuellen in das angegebene Verzeichnis
* @ $ftpVerz = Pfad zum Verzeichnis (ohne beginnenden "/")
**/
function changeFtpVerz($ftpVerz)
{
if(!@ftp_chdir($this->theConnection,$ftpVerz))
$this->setErrorMsg("Kann nicht in das Zielverzeichnis $ftpVerz wechseln.");
}
/**
* mkFtpVerz Methode
* erstellt ein neues Verzeichnis
* @ $newFtpVerz = vollständiger Verzeichnisname (wird kein Pfad angegeben, wird das Verzeichnis direkt im FTP-Root erzeugt)
**/
function mkFtpVerz($newFtpVerz)
{
if(!@ftp_mkdir($this->theConnection,$newFtpVerz))
$this->setErrorMsg("Das Verzeichnis $newFtpVerz konnte nicht angelegt werden.");
}
/**
* mkFtpVerz Methode
* löscht ein bestehendes Verzeichnis
* @ $newFtpVerz = vollständiger Verzeichnisname (wird kein Pfad angegeben, wird das Verzeichnis direkt im FTP-Root erzeugt)
**/
function rmFtpVerz($delFtpVerz)
{
if(!@ftp_rmdir($this->theConnection,$delFtpVerz))
$this->setErrorMsg("Das Verzeichnis $delFtpVerz konnte nicht gelöscht werden.");
}
/**
* getFtpFileList Methode
* gibt eine Liste der Dateien in dem entsprechenden Verzeichnis zurück
* @ $listFtpVerz = vollständiger Dateiname
**/
# später in Array zurückgeben Verzeichnis,Dateiname, größe, letzte Änderung usw.
function getFtpFileList($listFtpVerz)
{
$name = @ftp_nlist($this->theConnection, $listFtpVerz);
if(isset($name) and is_array($name))
{
reset($name);
while(list($k,$v)=each($name))
{
printf("%s - %s<br>\n", $k, $v);
}
}
}
/**
* getFtpFileSize Methode
* gibt die Dateigröße der im Parameter angegebenen Datei zurück.
* @ $ftpFile = vollständiger Dateiname
**/
function getFtpFileSize($ftpFile)
{
if(!$size=@ftp_size($this->theConnection, $ftpFile))
$this->setErrorMsg("Die angegebene Datei konnte nicht gefunden werden.");
return $size;
}
/**
* getFtpFile Methode
* lädt eine Datei vom FTP-Server.
* @ $localFileName = bestimmt den Dateinamen im aktuellen Verzeichnis
* @ $remoteFileName = hochzuladende Datei (ggf. inkl. Pfadangaben)
* @ $mode = Übertragungsart 2 Konstanten möglich (FTP_ASCII | FTP_BINARY)
* ACHTUNG, nicht als String übergeben, nur Konstante angeben (ohne Präfix $)
**/
function getFtpFile($localFileName,$remoteFileName,$mode)
{
$result = ftp_get($this->theConnection, $localFileName, $remoteFileName, $mode);
if (!$result)
$this->setErrorMsg("Download der Datei $remoteFileName fehlgeschlagen.");
else
$this->setStatusMsg("Download der Datei $remoteFileName erfolgreich.");
}
/**
* putFtpFile Methode
* überträgt eine Datei auf den FTP-Server.
* @ $localFileName = bestimmt den Dateinamen im aktuellen Verzeichnis
* @ $remoteFileName = hochzuladende Datei (ggf. inkl. Pfadangaben)
* @ $mode = Übertragungsart 2 Konstanten möglich (FTP_ASCII | FTP_BINARY)
* ACHTUNG, nicht als String übergeben, nur Konstante angeben (ohne Präfix $)
**/
function putFtpFile($remoteFileName,$localFileName,$mode)
{
ftp_pasv($this->theConnection,$cfgSystem["ftp_passiv"]);
$result=ftp_put($this->theConnection, $remoteFileName, $localFileName, $mode);
if(!$result)
{
$this->setErrorMsg("Upload der Datei $remoteFileName fehlgeschlagen.");
return true;
}
else
{
$this->setStatusMsg("Upload der Datei $remoteFileName erfolgreich.");
return true;
}
}
/**
* chmodFtpFile Methode
* überträgt eine Datei auf den FTP-Server.
* @ $ftpFile = Dateinamen, dessen Zugriffsrechte geändert werden sollen
* @ $parm = Änderungsstring (linux z.B. 775)
**/
function chmodFtpFile($ftpFile,$parm)
{
if (!@ftp_site($this->theConnection, "chmod $parm $ftpFile"))
{
$this->setErrorMsg("Dateirechte für $remoteFileName konnten nicht verändert werden.");
return true;
}
else
{
$this->setStatusMsg("Dateirechte für $remoteFileName wurden verändert.");
return false;
}
}


/**
* closeFtpSession Methode
* beendet die aktuelle FTP-Sitzung
**/
function closeFtpSession()
{
ConnectionManager::setFtpConnectionFree();
}
//------------------------------------------------------------------------------
/**
* getlastError Methode
* gibt die als letztes aufgetretene Fehlermeldung aus.
* @return Fehlermeldung (Text)
**/
function getLastError()
{
return $this->errorM;
}
//------------------------------------------------------------------------------
/**
* getlastStatus Methode
* gibt eine Stausmeldung des als letztes aufgetretenen Ereignisses aus.
* @return Statusmeldung (Text)
**/
function getStatus()
{
return $this->statusM;
}
//------------------------------------------------------------------------------
// Properties
//------------------------------------------------------------------------------
/**
* setErrorMsg Property
* @ $inErrM - FTP-Felermeldung
**/
function setErrorMsg($inErrM)
{
$this->ftpStatus = FALSE;
$this->errorM = trim($inErrM);
}
/**
* setErrorMsg Property
* @ $inErrM - FTP-Felermeldung
**/
//------------------------------------------------------------------------------
function setStatusMsg($inMsg)
{
$this->statusM = trim($inMsg);
}
//------------------------------------------------------------------------------
} // END_CLASS FtpManager
//------------------------------------------------------------------------------
und hier noch ein Beispiel für eine Funktion, die auf diese Klasse zugreift... mein ehemaliger Template-Parser (es wurde analog zur Verzeichnisstruktur auf wunsch auch eine physikalische Struktur erzeugt)
//------------------------------------------------------------------------------

/**

* writeTemplate Methode

* Oeffnet eine Datei mit dem Template-Dateinamen mit der Endung ".tmp"

* (falls nicht vorhanden wird diese angelegt!) und schreibt in ihr

* den Inhalt dieses Templates

**/

function writeTemplate($fileDir, $fileName, $fileType, $output)

{



extract($_SESSION,EXTR_REFS);



$cached_file = $cfgSystem["site_path"].$sep.$fileName.$fileType;

$cached_dir = $cfgSystem["site_path"].$sep.$fileDir;

$safe_mode = $cfgSystem["safe_mode"];

$dirHandle = @opendir($cached_dir);

// Konfiguration auslesen, ob safe_mode on|off, wenn on, dann FTP-aktivieren

// um Dateischreibrechte zu umgehen


if($safe_mode==1)

{

include_once(dirname(__FILE__)."/FtpManager.class.php");

$ftpManager = new FtpManager($this); // FTP-Session starten und User Anmelden

}

//Prüfen ob Verzeichnis besteht, sonst anlegen

if(!$dirHandle)

{

$verzErrMsg = "Verzeichnis ".$cached_dir."konnte nicht erstellt werden!";

//Verzeichnis erstellen

if($safe_mode==1)

{

if($cfgSystem["baseDir"]==1)

{

$cached_dir_FTP=str_replace($cfgSystem["slice_ftproot"],".",$cached_dir);

$ftpManager->mkFtpVerz($cached_dir_FTP);

$ftpManager->chmodFtpFile($cached_dir_FTP,"777");

}else

{

$ftpManager->mkFtpVerz($cached_dir);

$ftpManager->chmodFtpFile($cached_dir,"777");

}

}

if($safe_mode==0)

{

if(!mkdir($cached_dir,0700)) echo $verzErrMsg;

}

}else @closedir($dirHandle);



if($safe_mode==1)

{

/* Bei FTP-Upload: Dummydatei auf den Server laden,

* um Inhalt mit fopen einfügen zu können und Zugriffsberechtigung zu haben

* Wenn Basedir gesetzt wurde, schneide das vom Pfad weg, was vor dem baseDir liegt

* Beipsiel:

* Vorher: /srv/www/htdocs/<domain>/html

* Nachher:/html

*/

//


if($cfgSystem["baseDir"]==1)

{

$cached_file_FTP=str_replace($cfgSystem["slice_ftproot"],".",$cached_file);

$ftpManager->putFtpFile($cached_file_FTP,$cfgSystem["ftp_dummy"],FTP_ASCII);

$ftpManager->chmodFtpFile($cached_file_FTP,"777");

}

else

{

$ftpManager->putFtpFile($cached_file,$cfgSystem["ftp_dummy"],FTP_ASCII);

$ftpManager->chmodFtpFile($cached_file,"777");

}





}

$fp = fopen($cached_file, "w") or die("Kann Datei ".$cached_file." nicht finden / öffnen");

if($safe_mode==0)

{

// Zugriffsrechte für UNIX/Linux setzten

@chmod ($cached_file, 0777) or die ($cached_file.": konnte Zugriffsberechtigungen rwx-rwx-rwx nicht setzen.<br> Bitte Servereinstellung des Safe_mode pr&uuml;fen. Ggf. in Konfinguration anpassen!");

}

// Template-String in die Datei schreiben:

// Schreibe in die ersten Zeilen alle nötigen include.

$inc = "<?php\n";

$inc.= "include_once(dirname(__FILE__).\"/".$this->relPfad."admin/classes/classes.inc.php\");\n";

$inc.= "include_once(dirname(__FILE__).\"/".$this->relPfad."admin/functions/site_functions.inc.php\");\n";

$inc.= "if(!site_get_onlineStatus() )

{

\$template_id = site_cfg_get_value_from_key(\"SITE_OFFLINE_PAGE_ID\");

\$siteFactory = new SiteFactory(\$template_id,0);

\$siteFactory->createSite(true);

exit;

}else{\n";

$inc.= "@session_start(); // Session-Starten\n";

$inc.= "\$PAGE_ID='".$this->node_id.".php';\n";

$inc.= "@session_start();\n";

$inc.= "\$_SESSION['PAGE_ID']=\$PAGE_ID;";

$inc.= "?>\n";

$inc.= $output;

$inc.="<?}?>";

fputs($fp, $inc);

// Datei schliessen und Lock aufgeben

fclose($fp);

//Zugriffsberechtigung zurücksetzen

if($safe_mode==0)

{ // Zugriffsrechte für UNIX/Linux setzten

@chmod ($cached_file, 0755) or die ($cached_file.": konnte Zugriffsb. rwx-rwx-rwx nicht setzen.<br> Bitte Servereinstellung des Safe_mode pr&uuml;fen. Ggf. in Konfinguration anpassen!");

}else

{

if($cfgSystem["baseDir"]==1)

{

$ftpManager->chmodFtpFile($cached_file_FTP,"755");

}

else

{

$ftpManager->chmodFtpFile($cached_file,"755");

}

}

}
Auf diese Art hat mein System - das ja durch die Erstellung aller in der Datebbank abgelegten Strukturen als physikalischen Verzeichnisbaum, sehr viel mit Dateierstellung zu tun hatte- immer tadellos funktioniert.

Wäre toll, wenn Ihr das ins Contendio übernehmen könntet, denn bis ich ans entwickeln bzw. weiterentwickeln von Contenido komme, dauert es noch ein paar wochen...

Sollte es bis dahin noch nicht eingepflegt sein, erstelle ich diese Funktion gerne selbst...

Bei Fragen, oder dem wunsch nach näheren Informationien einfach hier posten.

Halchteranerin
Beiträge: 5478
Registriert: Di 2. Mär 2004, 21:11
Wohnort: Halchter, wo sonst? ;-)
Kontaktdaten:

Re: Erweiterung zum Betrieb bei "Safe_mode=on"

Beitrag von Halchteranerin » Di 11. Apr 2006, 08:30

rethus hat geschrieben:Wäre toll, wenn Ihr das ins Contendio übernehmen könntet, denn bis ich ans entwickeln bzw. weiterentwickeln von Contenido komme, dauert es noch ein paar wochen...

Sollte es bis dahin noch nicht eingepflegt sein, erstelle ich diese Funktion gerne selbst...
Selbst wenn das uebernommen werden sollte (ich habe es nur grob ueberflogen und kenne mich mit den "Innereien" von Contenido auch nicht wirklich aus), wird das mit an Sicherheit grenzender Wahrscheinlichkeit nicht in den naechsten Wochen passieren. Dafuer sind noch viel zu viele Bugs "offen".
Bitte keine unaufgeforderten Privatnachrichten mit Hilfegesuchen schicken. WENN ich helfen kann, dann mache ich das im Forum, da ich auch alle Postings lese. PN werden nicht beantwortet!

rethus
Beiträge: 1851
Registriert: Di 28. Mär 2006, 11:55
Wohnort: Mönchengladbach
Kontaktdaten:

Beitrag von rethus » Di 11. Apr 2006, 08:43

Naja, wenns bis dahin noch nicht upToDate ist, mach ich es wie gesagt selbst...

Aber Ich denke immer "Viele Hände... schnelles Ende"...

Und gerade sowas Grundlegendes sollte meiner Meinung nach fokusiert betrachtet werden.
Denn wenn die Annahme stimmt, das 45% der Anfragen (und wahrscheinlich auch einige Bugs) auf das Konto von Berechtigungen gehen ist es doch weitaus sinnvoller, dieses Problem zeitnah anzugehen...

HerrB
Beiträge: 6935
Registriert: Do 22. Mai 2003, 12:44
Wohnort: Berlin
Kontaktdaten:

Beitrag von HerrB » Di 11. Apr 2006, 12:55

Die Übertragung via FTP ist eine schöne Lösung, die sicherlich berücksichtigt werden sollte.

Gruß
HerrB
Bitte keine unaufgeforderten PMs oder E-Mails -> use da Forum!

Newsletter: V4.4.x | V4.6.0-15 (Module, Backend) | V4.6.22+
Standardartikelliste: V4.4.x | V4.6.x
http://www.contenido.org/forum/search.php | http://faq.contenido.org | http://www.communido.net

rethus
Beiträge: 1851
Registriert: Di 28. Mär 2006, 11:55
Wohnort: Mönchengladbach
Kontaktdaten:

Beitrag von rethus » Mi 25. Apr 2007, 11:11

Hallo HerrB,
kannst du mir ein paar Tipps geben, wie ich mich in die Basis-Struktur von Contenido schneller einarbeiten kann (oder gibts da vielleicht sogar was zu lesen drüber)?

Das würde mir zeit sparen, und so könnte ich die FTP-Lösung umsetzen

HerrB
Beiträge: 6935
Registriert: Do 22. Mai 2003, 12:44
Wohnort: Berlin
Kontaktdaten:

Beitrag von HerrB » Do 26. Apr 2007, 13:25

Na ja, ich kann Hinweise geben.

Die Klassen für Dateioperationen sind classes/class.upload.php und classes/class.dbfs.php (das sind i.A. aber nur die Abstraktionsklassen für die DB-Tabellen).

Viele Dateioperationen sind in contenido/includes/functions.upl.php definiert, die die Klassen nutzen.

Die Dateiverwaltung findet sich in den includes/include.upl*-Dateien.

include.upl_dirs_overview.php ist die Baumstruktur links.
include.upl_files_overview.php die Dateiliste rechts.
include.upl_edit.php ist das Fenster zum Ändern der Dateieigenschaften.

Wenn ich mich recht entsinne, werden Dateien, die hochgeladen werden (nach Absenden von include.upl_files_upload.php) zunächst von einer Action in der DB behandelt (siche Actions-Tabelle).

Grundsätzlich gilt: Das Absenden eines Forms führt zum Auslesen der Action aus der Actions-Tabelle; in dieser kann direkt Code zur Ausführung stehen oder nix. Aus Action, Area und Frame ergibt sich das frame_file (siehe Tabelle) und daraus ein File (siehe Tabelle), welches ausgeführt wird. Steht nix in der Actions-Tabelle, wird nur der Code aus dem File ausgeführt.

Gruß
HerrB
Bitte keine unaufgeforderten PMs oder E-Mails -> use da Forum!

Newsletter: V4.4.x | V4.6.0-15 (Module, Backend) | V4.6.22+
Standardartikelliste: V4.4.x | V4.6.x
http://www.contenido.org/forum/search.php | http://faq.contenido.org | http://www.communido.net

rethus
Beiträge: 1851
Registriert: Di 28. Mär 2006, 11:55
Wohnort: Mönchengladbach
Kontaktdaten:

Beitrag von rethus » So 29. Apr 2007, 17:46

Ok, danke schon mal für die Hinweise.
Hab kommende woche erstmal 2 Wochen Urlaub. Danach werde ich mich mal damit beschäftigen.

HerrB
Beiträge: 6935
Registriert: Do 22. Mai 2003, 12:44
Wohnort: Berlin
Kontaktdaten:

Beitrag von HerrB » Mi 2. Mai 2007, 11:40

Mag eine blöde Frage sein, aber der FTP-Transfer nützt mir doch nix, wenn ich Dateien von lokal auf den Webserver übertragen möchte, oder?

Gruß
HerrB
Bitte keine unaufgeforderten PMs oder E-Mails -> use da Forum!

Newsletter: V4.4.x | V4.6.0-15 (Module, Backend) | V4.6.22+
Standardartikelliste: V4.4.x | V4.6.x
http://www.contenido.org/forum/search.php | http://faq.contenido.org | http://www.communido.net

rethus
Beiträge: 1851
Registriert: Di 28. Mär 2006, 11:55
Wohnort: Mönchengladbach
Kontaktdaten:

Beitrag von rethus » Mi 23. Mai 2007, 08:59

Ne, im Grunde nicht. Der FTP-Transfer ist in diesem Fall nur eine interne Funktion, die sich sich mit dem eigenen Rechner (auf dem das Script läuft) verbindet, um Dateien mit der eigenen Benutzerkennung (die als FTP-User angegeben wurde) zu speichern, so das der Zugriff auf die Datei gewährleistet ist.

So wird gewährleistet, das man owner der Dateien bleibt, und nicht der User www oder apache.

Antworten