openrat-cms

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

commit cbe59851971db6a46044c341b36012f5a0bfc443
parent fa326848f98ca08cf5f69025cf8937cac016adcc
Author: Jan Dankert <devnull@localhost>
Date:   Sat, 11 Aug 2018 01:41:04 +0200

Neues Modul "cms-publish", welches die Funktionen zum Veröffentlichen erhalten soll. Als erstes gibt es hier einen "LinkScheme" zum Generieren von Links von Seiten auf andere Objekte.

Diffstat:
modules/cms-core/model/Folder.class.php | 7+++++++
modules/cms-core/model/Page.class.php | 176+++++++++++++------------------------------------------------------------------
modules/cms-core/require.php | 1+
modules/cms-publish/PreviewLinkSchema.class.php | 81+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
modules/cms-publish/PublicLinkSchema.class.php | 177+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
modules/cms-publish/Publish.class.php | 394+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
modules/cms-publish/require.php | 5+++++
modules/util/Publish.class.php | 394-------------------------------------------------------------------------------
8 files changed, 694 insertions(+), 541 deletions(-)

diff --git a/modules/cms-core/model/Folder.class.php b/modules/cms-core/model/Folder.class.php @@ -646,6 +646,13 @@ class Folder extends BaseObject } + /** + * Liefert alle übergeordneten Ordner. + * + * @param bool $with_root Mit Root-Folder? + * @param bool $with_self Mit dem aktuellen Ordner? + * @return array + */ function parentObjectFileNames( $with_root = false, $with_self = false ) { $db = \Session::getDatabase(); diff --git a/modules/cms-core/model/Page.class.php b/modules/cms-core/model/Page.class.php @@ -16,6 +16,7 @@ namespace cms\model; // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +use cms\publish\PreviewLinkSchema;use cms\publish\PublicLinkSchema; /** @@ -138,9 +139,9 @@ class Page extends BaseObject function parentfolder() { $folder = new Folder(); - $folder->folderid = $this->folderid; + $folder->folderid = $this->parentid; - return $folder->parentfolder( false,false ); + return $folder->parentObjectFileNames( false,true ); } @@ -154,152 +155,18 @@ class Page extends BaseObject */ public function path_to_object( $objectid ) { - global $conf_php, - $SESS; - $inhalt = ''; - if ( ! BaseObject::available( $objectid) ) return ''; - $param = array( - 'oid' => '__OID__'.$objectid.'__', - REQ_PARAM_MODEL_ID => $this->modelid , - REQ_PARAM_LANGUAGE_ID => $this->languageid , - REQ_PARAM_EMBED => '1' ); - - if ( $this->icons ) - $param['withIcons'] = '1'; - - $object = new BaseObject( $objectid ); - $object->objectLoad(); - - if ( $object->projectid != $this->projectid ) - { - // Target is in another Project. So we have to create an absolute URL. - $targetProject = new Project( $object->projectid ); - $targetProject->load(); - $inhalt = $targetProject->url; - if ( ! strpos($inhalt,'://' ) === FALSE ) { - // No protocol in hostname. So we have to prepend the URL with '//'. - $inhalt = '//'.$inhalt; - } - } - - $cut_index = ( is_object($this->publish) && $this->publish->cut_index ); - $content_negotiation = ( is_object($this->publish) && $this->publish->content_negotiation ); - if ( $this->public ) - { - switch( $object->typeid ) - { - case OR_TYPEID_FILE: - case OR_TYPEID_IMAGE: - case OR_TYPEID_TEXT: - - $inhalt = $this->up_path(); - - $f = new File( $objectid ); - $f->content_negotiation = $content_negotiation; - $f->load(); - $inhalt .= $f->full_filename(); - break; - - case OR_TYPEID_PAGE: - - $inhalt = $this->up_path(); - - $p = new Page( $objectid ); - $p->languageid = $this->languageid; - $p->modelid = $this->modelid; - $p->cut_index = $cut_index; - $p->content_negotiation = $content_negotiation; - $p->withLanguage = $this->withLanguage; - $p->withModel = $this->withModel; - $p->load(); - $inhalt .= $p->full_filename(); - break; - - case OR_TYPEID_LINK: - $link = new Link( $objectid ); - $link->load(); - - $linkedObject = new BaseObject( $link->linkedObjectId ); - $linkedObject->objectLoad(); - - switch( $linkedObject->getType() ) - { - case OR_TYPEID_FILE: - $f = new File( $link->linkedObjectId ); - $f->load(); - $f->content_negotiation = $content_negotiation; - $inhalt = $this->up_path(); - $inhalt .= $f->full_filename(); - break; - - case OR_TYPEID_PAGE: - $p = new Page( $link->linkedObjectId ); - $p->languageid = $this->languageid; - $p->modelid = $this->modelid; - $p->cut_index = $cut_index; - $p->content_negotiation = $content_negotiation; - $p->withLanguage = $this->withLanguage; - $p->withModel = $this->withModel; - $p->load(); - $inhalt = $this->up_path(); - $inhalt .= $p->full_filename(); - break; - } - break; - - case OR_TYPEID_URL: - $url = new Url( $objectid ); - $url->load(); - $inhalt = $url->url; - break; - } - } + $linkSchema = new PublicLinkSchema(); else - { - // Interne Verlinkungen in der Seitenvorschau - switch( $object->typeid ) - { - case OR_TYPEID_FILE: - case OR_TYPEID_IMAGE: - case OR_TYPEID_TEXT: - $inhalt = \Html::url('file','show',$objectid,$param); - break; - case OR_TYPEID_PAGE: - $inhalt = \Html::url('page','show',$objectid,$param); - break; - - case OR_TYPEID_LINK: - $link = new Link( $objectid ); - $link->load(); - - $linkedObject = new BaseObject( $link->linkedObjectId ); - $linkedObject->objectLoad(); - - switch( $linkedObject->typeid ) - { - case OR_TYPEID_FILE: - $inhalt = \Html::url('file','show',$link->linkedObjectId,$param); - break; - - case OR_TYPEID_PAGE: - $inhalt = \Html::url('page','show',$link->linkedObjectId,$param); - break; - } - break; - - case OR_TYPEID_URL: - $url = new Url( $objectid ); - $url->load(); - $inhalt = $url->url; - - break; - } - } - + $linkSchema = new PreviewLinkSchema(); + + $to = new BaseObject($objectid); + $to->load(); + $inhalt = $linkSchema->linkToObject( $this, $to); + return $inhalt; } @@ -517,9 +384,25 @@ class Page extends BaseObject function full_filename() { $filename = $this->path(); + $filename .= $this->getFilename(); - if ( !empty($filename) ) - $filename .= '/'; + $this->fullFilename = $filename; + return $filename; + } + + + /** + * Ermitteln des Dateinamens dieser Seite. + * + * Wenn '$this->content_negotiation' auf 'true' steht, wird der Dateiname ggf. gekürzt, + * so wie er für HTML-Links verwendet wird. Sonst wird immer der echte Dateiname + * ermittelt. + * + * @return String Kompletter Dateiname, z.B. '/pfad/seite.en.html' + */ + function getFilename() + { + $filename = ''; if ( $this->cut_index && $this->filename == config('publish','default') ) { @@ -529,7 +412,7 @@ class Page extends BaseObject { $format = config('publish','format'); $format = str_replace('{filename}',$this->filename(),$format ); - + if ( !$this->withLanguage || $this->content_negotiation && config('publish','negotiation','page_negotiate_language' ) ) { $format = str_replace('{language}' ,'',$format ); @@ -559,7 +442,6 @@ class Page extends BaseObject $filename .= $format; } - $this->fullFilename = $filename; return $filename; } diff --git a/modules/cms-core/require.php b/modules/cms-core/require.php @@ -1,6 +1,7 @@ <?php // Require other modules +require_once(__DIR__ . '/../cms-publish/require.php'); require_once(__DIR__ . '/../database/require.php'); require_once(__DIR__ . '/../database-update/require.php'); require_once(__DIR__ . '/../util/require.php'); diff --git a/modules/cms-publish/PreviewLinkSchema.class.php b/modules/cms-publish/PreviewLinkSchema.class.php @@ -0,0 +1,80 @@ +<?php + +namespace cms\publish; + +use cms\model\BaseObject; +use cms\model\Link; +use cms\model\Url; + +/** + * Created by PhpStorm. + * User: dankert + * Date: 10.08.18 + * Time: 23:47 + */ + +class PreviewLinkSchema +{ + /** + * @param $from \cms\model\BaseObject + * @param $to \cms\model\BaseObject + */ + public function linkToObject( $from, $to ) + { + + $param = array( + 'oid' => '__OID__'.$to->objectid.'__', + REQ_PARAM_MODEL_ID => $from->modelid , + REQ_PARAM_LANGUAGE_ID => $from->languageid , + REQ_PARAM_EMBED => '1' ); + + if ( $from->icons ) + $param['withIcons'] = '1'; + + + // Interne Verlinkungen in der Seitenvorschau + switch( $to->typeid ) + { + case OR_TYPEID_FILE: + case OR_TYPEID_IMAGE: + case OR_TYPEID_TEXT: + $inhalt = \Html::url('file','show',$to->objectid,$param); + break; + case OR_TYPEID_PAGE: + $inhalt = \Html::url('page','show',$to->objectid,$param); + break; + + case OR_TYPEID_LINK: + $link = new Link( $to->objectid ); + $link->load(); + + $linkedObject = new BaseObject( $link->linkedObjectId ); + $linkedObject->objectLoad(); + + switch( $linkedObject->typeid ) + { + case OR_TYPEID_FILE: + $inhalt = \Html::url('file','show',$link->linkedObjectId,$param); + break; + + case OR_TYPEID_PAGE: + $inhalt = \Html::url('page','show',$link->linkedObjectId,$param); + break; + case OR_TYPEID_URL: + $inhalt = \Html::url('url','show',$link->linkedObjectId,$param); + break; + } + break; + + case OR_TYPEID_URL: + $url = new Url( $to->objectid ); + $url->load(); + $inhalt = $url->url; + + break; + } + + return $inhalt; + + } +}+ \ No newline at end of file diff --git a/modules/cms-publish/PublicLinkSchema.class.php b/modules/cms-publish/PublicLinkSchema.class.php @@ -0,0 +1,176 @@ +<?php + +namespace cms\publish; + +use cms\model\BaseObject; +use cms\model\File; +use cms\model\Folder; +use cms\model\Link; +use cms\model\Page; +use cms\model\Project; +use cms\model\Url; + +define('OR_LINK_SCHEMA_ABSOLUTE',1); +define('OR_LINK_SCHEMA_RELATIVE',2); + + +/** + * User: dankert + * Date: 10.08.18 + * Time: 23:47 + */ + +class PublicLinkSchema +{ + /** + * @param $from \cms\model\Page + * @param $to \cms\model\BaseObject + */ + public function linkToObject( $from, $to ) { + + if ( config('publish','url') == 'relative') + $schema = OR_LINK_SCHEMA_RELATIVE; + else + $schema = OR_LINK_SCHEMA_ABSOLUTE; + + + switch( $to->typeid ) + { + case OR_TYPEID_FILE: + case OR_TYPEID_IMAGE: + case OR_TYPEID_TEXT: + + $f = new File( $to->objectid ); + + $p = new Project( $to->projectid ); + $p->load(); + $f->content_negotiation = $p->content_negotiation; + + $f->load(); + $filename = $f->filename; + if ( !empty($f->extension)) + $filename .= '.'.$f->extension; + break; + + case OR_TYPEID_PAGE: + + $p = new Page( $to->objectid ); + $p->languageid = $from->languageid; + $p->modelid = $from->modelid; + $p->cut_index = $from->cut_index; + $p->content_negotiation = $from->content_negotiation; + $p->withLanguage = $from->withLanguage; + $p->withModel = $from->withModel; + $p->load(); + $filename = $p->getFilename(); + break; + + case OR_TYPEID_LINK: + $link = new Link( $to->objectid ); + $link->load(); + + $linkedObject = new BaseObject( $link->linkedObjectId ); + $linkedObject->objectLoad(); + + switch( $linkedObject->getType() ) + { + case OR_TYPEID_FILE: + $f = new File( $link->linkedObjectId ); + $f->load(); + $f->content_negotiation = $from->content_negotiation; + $filename = $f->filename; + $to = $f; + break; + + case OR_TYPEID_PAGE: + $p = new Page( $link->linkedObjectId ); + $p->languageid = $from->languageid; + $p->modelid = $from->modelid; + $p->cut_index = $from->cut_index; + $p->content_negotiation = $from->content_negotiation; + $p->withLanguage = $from->withLanguage; + $p->withModel = $from->withModel; + $p->load(); + $filename = $p->getFilename(); + $to = $p; + break; + } + break; + + case OR_TYPEID_URL: + $url = new Url( $to->objectid ); + $url->load(); + return $url->url; + } + + + if ( $from->projectid != $to->projectid ) + { + // Target object is in another project. + // we have to use absolute URLs. + $schema = OR_LINK_SCHEMA_ABSOLUTE; + + // Target is in another Project. So we have to create an absolute URL. + $targetProject = new Project( $to->projectid ); + $targetProject->load(); + $inhalt = $targetProject->url; + + if ( ! strpos($inhalt,'://' ) === FALSE ) { + // No protocol in hostname. So we have to prepend the URL with '//'. + $inhalt = '//'.$inhalt; + } + } + else { + $prefix = ''; + } + + + + + if ( $schema == OR_LINK_SCHEMA_RELATIVE ) + { + $folder = new Folder( $from->parentid ); + $folder->load(); + $fromPathFolders = $folder->parentObjectFileNames(false,true); + + + $folder = new Folder($to->parentid); + + $toPathFolders = $folder->parentObjectFileNames(false, true); + + // Shorten the relative URL + // if the actual page is /path/folder1/page1 + // and the target page is /path/folder2/page2 + // we shorten the link from ../../path/folder2/page2 + // to ../folder2/page2 + foreach( $fromPathFolders as $folderId ) { + if ( count($toPathFolders) >= 1 && array_keys($toPathFolders)[0] == $folderId ) { + unset( $fromPathFolders[$folderId] ); + unset( $toPathFolders [$folderId] ); + }else { + break; + } + + } + + $path = str_repeat( '../',count($fromPathFolders) ); + $path .= implode('/',$toPathFolders); + $path .= '/'; + } + else { + + $folder = new Folder($to->parentid); + $toPathFolders = $folder->parentObjectFileNames(false, true); + + $path = implode('/',$toPathFolders); + $path .= '/'; + } + + + $uri = $prefix . $path . $filename; + + if( empty($uri)) $uri = '.'; + + return $uri; + } +}+ \ No newline at end of file diff --git a/modules/cms-publish/Publish.class.php b/modules/cms-publish/Publish.class.php @@ -0,0 +1,393 @@ +<?php +// OpenRat Content Management System +// Copyright (C) 2002-2012 Jan Dankert, cms@jandankert.de +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +/** + * Diese Klasse kapselt das Veroeffentlichen von Dateien.<br> + * <br> + * Hier werden<br> + * - Dateien in das Zielverzeichnis kopiert<br> + * - Dateien per FTP veroeffentlicht<br> + * - Zielverzeichnisse aufgeraeumt<br> + * - Systembefehle ausgefuehrt. + * + * @author Jan Dankert + * @package openrat.services + */ +class Publish +{ + /** + * Enthaelt bei Bedarf das FTP-Objekt. N�mlich dann, wenn + * zu einem FTP-Server veroeffentlicht werden soll. + * @var Object + */ + var $ftp; + + /** + * Flag, ob in das lokale Dateisystem veroeffentlicht werden soll. + * @var boolean + */ + var $with_local = false; + + /** + * Flag, ob zu einem FTP-Server ver�ffentlicht werden soll. + * @var boolean + */ + var $with_ftp = false; + + var $local_destdir = ''; + + /** + * Enthaelt die gleichnamige Einstellung aus dem Projekt. + * @var boolean + */ + var $content_negotiation = false; + + /** + * Enthaelt die gleichnamige Einstellung aus dem Projekt. + * @var boolean + */ + var $cut_index = false; + + /** + * Enthaelt die gleichnamige Einstellung aus dem Projekt. + * @var String + */ + var $cmd_after_publish = ''; + + /** + * Enthaelt am Ende der Ver�ffentlichung ein Array mit den ver�ffentlichten Objekten. + * @var Array + */ + var $publishedObjects = array(); + + /** + * Enthaelt im Fehlerfall (wenn 'ok' auf 'false' steht) eine + * Fehlermeldung. + * + * @var String + */ + var $log = array(); + + /** + * Stellt nach der Ver�ffentlichung fest, ob der Vorgang erfolgreich ist. + * Falls nicht, enth�lt die Variable 'log' eine Fehlermeldung. + * @var boolean + */ + var $ok = true; + + /** + * Konstruktor.<br> + * <br> + * Oeffnet ggf. Verbindungen. + * + * @return Publish + */ + function __construct() + { + global $conf; + $confPublish = $conf['publish']; + + if ( $conf['security']['nopublish'] ) + { + $this->ok = false; + $this->log[] = 'publishing is disabled.'; + return; + } + + $project = Session::getProject(); + + // Feststellen, ob FTP benutzt wird. + // Dazu muss FTP aktiviert sein (enable=true) und eine URL vorhanden sein. + $ftpUrl = ''; + if ( $conf['publish']['ftp']['enable'] ) + { + if ( $conf['publish']['ftp']['per_project'] && !empty($project->ftp_url) ) + $ftpUrl = $project->ftp_url; + elseif ( !empty($conf['publish']['ftp']['host']) ) + $ftpUrl = $project->ftp_url; + } + + if ( ! empty($ftpUrl) ) + { + $this->with_ftp = true; + $this->ftp = new Ftp( $project->ftp_url ); // Aufbauen einer FTP-Verbindung + + if ( ! $this->ftp->ok ) // FTP-Verbindung ok? + { + $this->ok = false; + $this->log = $this->ftp->log; + return; // Ende. Ohne FTP brauchen wir nicht weitermachen. + } + + $this->ftp->passive = ( $project->ftp_passive == '1' ); + } + + $localDir = rtrim( $project->target_dir,'/' ); + + if ( $confPublish['filesystem']['per_project'] && (!empty($localDir)) ) + { + $this->local_destdir = $localDir; // Projekteinstellung verwenden. + } + else + { + if ( empty( $localDir)) + $localDir = $project->name; + // Konfiguriertes Verzeichnis verwenden. + $this->local_destdir = $confPublish['filesystem']['directory'].$localDir; + } + + + // Sofort pruefen, ob das Zielverzeichnis ueberhaupt beschreibbar ist. + if ( $this->local_destdir != '' ) + { + if ( !is_writeable( $this->local_destdir ) ) + { + $this->ok = false; + $this->log[] = 'directory not writable: '.$this->local_destdir; + $this->log[] = 'please correct the file permissions.'; + return; + } + + $this->with_local = true; + } + + $this->content_negotiation = ( $project->content_negotiation == '1' ); + $this->cut_index = ( $project->cut_index == '1' ); + + if ( $confPublish['command']['enable'] ) + { + if ( $confPublish['command']['per_project'] && !empty($project->cmd_after_publish) ) + $this->cmd_after_publish = $project->cmd_after_publish; + else + $this->cmd_after_publish = @$confPublish['command']['command']; + } + + // Im Systemkommando Variablen ersetzen + $this->cmd_after_publish = str_replace('{name}' ,$project->name ,$this->cmd_after_publish); + $this->cmd_after_publish = str_replace('{dir}' ,$this->local_destdir ,$this->cmd_after_publish); + $this->cmd_after_publish = str_replace('{dirbase}',basename($this->local_destdir),$this->cmd_after_publish); + } + + + + /** + * Kopieren einer Datei aus dem tempor�ren Verzeichnis in das Zielverzeichnis.<br> + * Falls notwenig, wird ein Hochladen per FTP ausgef�hrt. + * + * @param String $tmp_filename + * @param String $dest_filename + */ + function copy( $tmp_filename,$dest_filename,$lastChangeDate=null ) + { + if ( !$this->ok) + return; + + global $conf; + $source = $tmp_filename; + + if ( $this->with_local ) + { + $dest = $this->local_destdir.'/'.$dest_filename; + + if (!@copy( $source,$dest )); + { + if ( ! $this->mkdirs( dirname($dest) ) ) + return; // Fehler bei Verzeichniserstellung, also abbrechen. + + if (!@copy( $source,$dest )) + { + $this->ok = false; + $this->log[] = 'failed copying local file:'; + $this->log[] = 'source : '.$source; + $this->log[] = 'destination: '.$dest; + return; // Fehler beim Kopieren, also abbrechen. + } + if ( ! is_null($lastChangeDate) ) + @touch( $dest,$lastChangeDate ); + + Logger::debug("published: $dest"); + } + + if (!empty($conf['security']['chmod'])) + { + // CHMOD auf der Datei ausfuehren. + if ( ! @chmod($dest,octdec($conf['security']['chmod'])) ) + { + $this->ok = false; + $this->log[] = 'Unable to CHMOD file '.$dest; + return; + } + } + } + + if ( $this->with_ftp ) // Falls FTP aktiviert + { + $dest = $dest_filename; + $this->ftp->put( $source,$dest ); + + if ( ! $this->ftp->ok ) + { + $this->ok = false; + $this->log[] = $this->ftp->log; + } + } + } + + + + /** + * Rekursives Anlagen von Verzeichnisse + * Nett gemacht. + * Quelle: http://de3.php.net/manual/de/function.mkdir.php + * Thx to acroyear at io dot com + * + * @param String Verzeichnis + * @return boolean + */ + function mkdirs( $strPath ) + { + global $conf; + + if ( is_dir($strPath) ) + return true; + + $pStrPath = dirname($strPath); + if ( !$this->mkdirs($pStrPath) ) + return false; + + if ( ! @mkdir($strPath,0777) ) + { + $this->ok = false; + $this->log[] = 'Cannot create directory: '.$strPath; + return false; + } + + // CHMOD auf dem Verzeichnis ausgef�hren. + if (!empty($conf['security']['chmod_dir'])) + { + if ( ! @chmod($strPath,octdec($conf['security']['chmod_dir'])) ) + { + $this->ok = false; + $this->log[] = 'Unable to CHMOD directory: '.$strPath; + return false; + } + } + + + return $this->ok; + } + + + + /** + * Beenden des Ver�ffentlichungs-Vorganges.<br> + * Eine vorhandene FTP-Verbindung wird geschlossen.<br> + * Falls entsprechend konfiguriert, wird ein Systemkommando ausgef�hrt. + */ + public function close() + { + if ( $this->with_ftp ) + { + Logger::debug('Closing FTP connection' ); + $this->ftp->close(); + } + + // Ausfuehren des Systemkommandos. + if ( !empty($this->cmd_after_publish) && $this->ok ) + { + $ausgabe = array(); + $rc = false; + Logger::debug('Executing system command: '.$this->cmd_after_publish ); + $user = Session::getUser(); + putenv("CMS_USER_NAME=".$user->name ); + putenv("CMS_USER_ID=" .$user->userid); + putenv("CMS_USER_MAIL=".$user->mail ); + exec( $this->cmd_after_publish,$ausgabe,$rc ); + + if ( $rc != 0 ) // Wenn Returncode ungleich 0, dann Ausgabe ins Log schreiben und Fehler melden. + { + $this->log = $ausgabe; + $this->log[] = 'OpenRat: System command failed - returncode is '.$rc; + $this->ok = false; + + Logger::warn('System command '.$this->cmd_after_publish.' failed with status '.$rc ); + + } + else + { + Logger::debug('System command successful' ); + } + + } + } + + + + /** + * Aufraeumen des Zielverzeichnisses.<br><br> + * Es wird der komplette Zielordner samt Unterverzeichnissen durchsucht. Jede + * Datei, die laenger existiert als der aktuelle Request alt ist, wird geloescht.<br> + * Natuerlich darf diese Funktion nur nach einem Gesamt-Veroeffentlichen ausgefuehrt werden. + */ + function clean() + { + if ( $this->ok ) + return; + + if ( !empty($this->local_destdir) ) + $this->cleanFolder($this->local_destdir); + } + + + + /** + * Aufr�umen eines Verzeichnisses.<br><br> + * Dateien, die l�nger existieren als der aktuelle Request alt ist, werden gel�scht.<br> + * + * @param String Verzeichnis + */ + function cleanFolder( $folderName ) + { + $dh = opendir( $folderName ); + + while( $file = readdir($dh) ) + { + if ( $file != '.' && $file != '..') + { + $fullpath = $folderName.'/'.$file; + + // Wenn eine Datei beschreibbar und entsprechend alt + // ist, dann entfernen + if ( is_file($fullpath) && + is_writable($fullpath) && + filemtime($fullpath) < START_TIME ) + unlink($fullpath); + + // Bei Ordnern rekursiv absteigen + if ( is_dir( $fullpath) ) + { + $this->cleanFolder($fullpath); + @rmdir($fullpath); + } + } + } + } + +} + +?>+ \ No newline at end of file diff --git a/modules/cms-publish/require.php b/modules/cms-publish/require.php @@ -0,0 +1,5 @@ +<?php + + require_once( __DIR__.'/'.'Publish.class.php' ); + require_once( __DIR__.'/'.'PreviewLinkSchema.class.php' ); + require_once( __DIR__.'/'.'PublicLinkSchema.class.php' ); diff --git a/modules/util/Publish.class.php b/modules/util/Publish.class.php @@ -1,393 +0,0 @@ -<?php -// OpenRat Content Management System -// Copyright (C) 2002-2012 Jan Dankert, cms@jandankert.de -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -/** - * Diese Klasse kapselt das Veroeffentlichen von Dateien.<br> - * <br> - * Hier werden<br> - * - Dateien in das Zielverzeichnis kopiert<br> - * - Dateien per FTP veroeffentlicht<br> - * - Zielverzeichnisse aufgeraeumt<br> - * - Systembefehle ausgefuehrt. - * - * @author Jan Dankert - * @package openrat.services - */ -class Publish -{ - /** - * Enthaelt bei Bedarf das FTP-Objekt. N�mlich dann, wenn - * zu einem FTP-Server veroeffentlicht werden soll. - * @var Object - */ - var $ftp; - - /** - * Flag, ob in das lokale Dateisystem veroeffentlicht werden soll. - * @var boolean - */ - var $with_local = false; - - /** - * Flag, ob zu einem FTP-Server ver�ffentlicht werden soll. - * @var boolean - */ - var $with_ftp = false; - - var $local_destdir = ''; - - /** - * Enthaelt die gleichnamige Einstellung aus dem Projekt. - * @var boolean - */ - var $content_negotiation = false; - - /** - * Enthaelt die gleichnamige Einstellung aus dem Projekt. - * @var boolean - */ - var $cut_index = false; - - /** - * Enthaelt die gleichnamige Einstellung aus dem Projekt. - * @var String - */ - var $cmd_after_publish = ''; - - /** - * Enthaelt am Ende der Ver�ffentlichung ein Array mit den ver�ffentlichten Objekten. - * @var Array - */ - var $publishedObjects = array(); - - /** - * Enthaelt im Fehlerfall (wenn 'ok' auf 'false' steht) eine - * Fehlermeldung. - * - * @var String - */ - var $log = array(); - - /** - * Stellt nach der Ver�ffentlichung fest, ob der Vorgang erfolgreich ist. - * Falls nicht, enth�lt die Variable 'log' eine Fehlermeldung. - * @var boolean - */ - var $ok = true; - - /** - * Konstruktor.<br> - * <br> - * Oeffnet ggf. Verbindungen. - * - * @return Publish - */ - function __construct() - { - global $conf; - $confPublish = $conf['publish']; - - if ( $conf['security']['nopublish'] ) - { - $this->ok = false; - $this->log[] = 'publishing is disabled.'; - return; - } - - $project = Session::getProject(); - - // Feststellen, ob FTP benutzt wird. - // Dazu muss FTP aktiviert sein (enable=true) und eine URL vorhanden sein. - $ftpUrl = ''; - if ( $conf['publish']['ftp']['enable'] ) - { - if ( $conf['publish']['ftp']['per_project'] && !empty($project->ftp_url) ) - $ftpUrl = $project->ftp_url; - elseif ( !empty($conf['publish']['ftp']['host']) ) - $ftpUrl = $project->ftp_url; - } - - if ( ! empty($ftpUrl) ) - { - $this->with_ftp = true; - $this->ftp = new Ftp( $project->ftp_url ); // Aufbauen einer FTP-Verbindung - - if ( ! $this->ftp->ok ) // FTP-Verbindung ok? - { - $this->ok = false; - $this->log = $this->ftp->log; - return; // Ende. Ohne FTP brauchen wir nicht weitermachen. - } - - $this->ftp->passive = ( $project->ftp_passive == '1' ); - } - - $localDir = rtrim( $project->target_dir,'/' ); - - if ( $confPublish['filesystem']['per_project'] && (!empty($localDir)) ) - { - $this->local_destdir = $localDir; // Projekteinstellung verwenden. - } - else - { - if ( empty( $localDir)) - $localDir = $project->name; - // Konfiguriertes Verzeichnis verwenden. - $this->local_destdir = $confPublish['filesystem']['directory'].$localDir; - } - - - // Sofort pruefen, ob das Zielverzeichnis ueberhaupt beschreibbar ist. - if ( $this->local_destdir != '' ) - { - if ( !is_writeable( $this->local_destdir ) ) - { - $this->ok = false; - $this->log[] = 'directory not writable: '.$this->local_destdir; - $this->log[] = 'please correct the file permissions.'; - return; - } - - $this->with_local = true; - } - - $this->content_negotiation = ( $project->content_negotiation == '1' ); - $this->cut_index = ( $project->cut_index == '1' ); - - if ( $confPublish['command']['enable'] ) - { - if ( $confPublish['command']['per_project'] && !empty($project->cmd_after_publish) ) - $this->cmd_after_publish = $project->cmd_after_publish; - else - $this->cmd_after_publish = @$confPublish['command']['command']; - } - - // Im Systemkommando Variablen ersetzen - $this->cmd_after_publish = str_replace('{name}' ,$project->name ,$this->cmd_after_publish); - $this->cmd_after_publish = str_replace('{dir}' ,$this->local_destdir ,$this->cmd_after_publish); - $this->cmd_after_publish = str_replace('{dirbase}',basename($this->local_destdir),$this->cmd_after_publish); - } - - - - /** - * Kopieren einer Datei aus dem tempor�ren Verzeichnis in das Zielverzeichnis.<br> - * Falls notwenig, wird ein Hochladen per FTP ausgef�hrt. - * - * @param String $tmp_filename - * @param String $dest_filename - */ - function copy( $tmp_filename,$dest_filename,$lastChangeDate=null ) - { - if ( !$this->ok) - return; - - global $conf; - $source = $tmp_filename; - - if ( $this->with_local ) - { - $dest = $this->local_destdir.'/'.$dest_filename; - - if (!@copy( $source,$dest )); - { - if ( ! $this->mkdirs( dirname($dest) ) ) - return; // Fehler bei Verzeichniserstellung, also abbrechen. - - if (!@copy( $source,$dest )) - { - $this->ok = false; - $this->log[] = 'failed copying local file:'; - $this->log[] = 'source : '.$source; - $this->log[] = 'destination: '.$dest; - return; // Fehler beim Kopieren, also abbrechen. - } - if ( ! is_null($lastChangeDate) ) - @touch( $dest,$lastChangeDate ); - - Logger::debug("published: $dest"); - } - - if (!empty($conf['security']['chmod'])) - { - // CHMOD auf der Datei ausfuehren. - if ( ! @chmod($dest,octdec($conf['security']['chmod'])) ) - { - $this->ok = false; - $this->log[] = 'Unable to CHMOD file '.$dest; - return; - } - } - } - - if ( $this->with_ftp ) // Falls FTP aktiviert - { - $dest = $dest_filename; - $this->ftp->put( $source,$dest ); - - if ( ! $this->ftp->ok ) - { - $this->ok = false; - $this->log[] = $this->ftp->log; - } - } - } - - - - /** - * Rekursives Anlagen von Verzeichnisse - * Nett gemacht. - * Quelle: http://de3.php.net/manual/de/function.mkdir.php - * Thx to acroyear at io dot com - * - * @param String Verzeichnis - * @return boolean - */ - function mkdirs( $strPath ) - { - global $conf; - - if ( is_dir($strPath) ) - return true; - - $pStrPath = dirname($strPath); - if ( !$this->mkdirs($pStrPath) ) - return false; - - if ( ! @mkdir($strPath,0777) ) - { - $this->ok = false; - $this->log[] = 'Cannot create directory: '.$strPath; - return false; - } - - // CHMOD auf dem Verzeichnis ausgef�hren. - if (!empty($conf['security']['chmod_dir'])) - { - if ( ! @chmod($strPath,octdec($conf['security']['chmod_dir'])) ) - { - $this->ok = false; - $this->log[] = 'Unable to CHMOD directory: '.$strPath; - return false; - } - } - - - return $this->ok; - } - - - - /** - * Beenden des Ver�ffentlichungs-Vorganges.<br> - * Eine vorhandene FTP-Verbindung wird geschlossen.<br> - * Falls entsprechend konfiguriert, wird ein Systemkommando ausgef�hrt. - */ - public function close() - { - if ( $this->with_ftp ) - { - Logger::debug('Closing FTP connection' ); - $this->ftp->close(); - } - - // Ausfuehren des Systemkommandos. - if ( !empty($this->cmd_after_publish) && $this->ok ) - { - $ausgabe = array(); - $rc = false; - Logger::debug('Executing system command: '.$this->cmd_after_publish ); - $user = Session::getUser(); - putenv("CMS_USER_NAME=".$user->name ); - putenv("CMS_USER_ID=" .$user->userid); - putenv("CMS_USER_MAIL=".$user->mail ); - exec( $this->cmd_after_publish,$ausgabe,$rc ); - - if ( $rc != 0 ) // Wenn Returncode ungleich 0, dann Ausgabe ins Log schreiben und Fehler melden. - { - $this->log = $ausgabe; - $this->log[] = 'OpenRat: System command failed - returncode is '.$rc; - $this->ok = false; - - Logger::warn('System command '.$this->cmd_after_publish.' failed with status '.$rc ); - - } - else - { - Logger::debug('System command successful' ); - } - - } - } - - - - /** - * Aufraeumen des Zielverzeichnisses.<br><br> - * Es wird der komplette Zielordner samt Unterverzeichnissen durchsucht. Jede - * Datei, die laenger existiert als der aktuelle Request alt ist, wird geloescht.<br> - * Natuerlich darf diese Funktion nur nach einem Gesamt-Veroeffentlichen ausgefuehrt werden. - */ - function clean() - { - if ( $this->ok ) - return; - - if ( !empty($this->local_destdir) ) - $this->cleanFolder($this->local_destdir); - } - - - - /** - * Aufr�umen eines Verzeichnisses.<br><br> - * Dateien, die l�nger existieren als der aktuelle Request alt ist, werden gel�scht.<br> - * - * @param String Verzeichnis - */ - function cleanFolder( $folderName ) - { - $dh = opendir( $folderName ); - - while( $file = readdir($dh) ) - { - if ( $file != '.' && $file != '..') - { - $fullpath = $folderName.'/'.$file; - - // Wenn eine Datei beschreibbar und entsprechend alt - // ist, dann entfernen - if ( is_file($fullpath) && - is_writable($fullpath) && - filemtime($fullpath) < START_TIME ) - unlink($fullpath); - - // Bei Ordnern rekursiv absteigen - if ( is_dir( $fullpath) ) - { - $this->cleanFolder($fullpath); - @rmdir($fullpath); - } - } - } - } - -} - -?>- \ No newline at end of file