openrat-cms

OpenRat Content Management System
git clone http://git.code.weiherhei.de/openrat-cms.git
Log | Files | Refs | README

commit ed3d7482d44914267369e826a7dc5cf7dc4924d0
parent 9c8e4c2e366bef8f5dfabaf4fc7a7c9b31b863cf
Author: Jan Dankert <develop@jandankert.de>
Date:   Wed, 14 Oct 2020 23:49:54 +0200

Refactoring: Creating the target instance with a Factory (Java style); Asynchronous publishing of files.

Diffstat:
Mmodules/cms/action/FileAction.class.php | 4+++-
Mmodules/cms/action/FolderAction.class.php | 9++++++---
Mmodules/cms/action/PageAction.class.php | 11+++++------
Mmodules/cms/action/PageelementAction.class.php | 6++++--
Mmodules/cms/base/DefaultConfig.class.php | 14++++++--------
Amodules/cms/generator/PublishOrder.class.php | 32++++++++++++++++++++++++++++++++
Mmodules/cms/generator/Publisher.class.php | 215+++++++++++++++++++++++++++++++++++--------------------------------------------
Mmodules/cms/generator/target/BaseTarget.class.php | 13-------------
Mmodules/cms/generator/target/Dav.class.php | 5-----
Mmodules/cms/generator/target/Fax.class.php | 5-----
Mmodules/cms/generator/target/Ftp.class.php | 4----
Mmodules/cms/generator/target/Ftps.class.php | 4----
Mmodules/cms/generator/target/Local.class.php | 5-----
Mmodules/cms/generator/target/NoTarget.class.php | 2+-
Mmodules/cms/generator/target/SFtp.class.php | 4----
Mmodules/cms/generator/target/Scp.class.php | 4----
Mmodules/cms/generator/target/Target.class.php | 3---
Amodules/cms/generator/target/TargetFactory.class.php | 65+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
18 files changed, 218 insertions(+), 187 deletions(-)

diff --git a/modules/cms/action/FileAction.class.php b/modules/cms/action/FileAction.class.php @@ -6,6 +6,7 @@ use cms\generator\FileContext; use cms\generator\FileGenerator; use cms\generator\Producer; use cms\generator\Publisher; +use cms\generator\PublishOrder; use cms\model\Folder; use cms\model\BaseObject; use cms\model\File; @@ -545,7 +546,8 @@ class FileAction extends ObjectAction $fileGenerator = new FileGenerator( new FileContext( $this->file->objectid, Producer::SCHEME_PUBLIC)); $publisher = new Publisher( $this->file->projectid ); - $publisher->publish( $fileGenerator->getCache()->load()->getFilename(),$fileGenerator->getPublicFilename(),$this->file->lastchangeDate ); + $publisher->addOrderForPublishing( new PublishOrder( $fileGenerator->getCache()->load()->getFilename(),$fileGenerator->getPublicFilename(),$this->file->lastchangeDate) ); + $publisher->publish(); $this->addNoticeFor($this->file,'PUBLISHED',Action::NOTICE_OK ); } diff --git a/modules/cms/action/FolderAction.class.php b/modules/cms/action/FolderAction.class.php @@ -9,6 +9,7 @@ use cms\generator\PageContext; use cms\generator\PageGenerator; use cms\generator\Producer; use cms\generator\Publisher; +use cms\generator\PublishOrder; use language\Messages; use util\ArchiveTar; use cms\model\Acl; @@ -1192,7 +1193,7 @@ class FolderAction extends ObjectAction $pageGenerator = new PageGenerator( $pageContext ); - $publisher->publish( $pageGenerator->getCache()->load()->getFilename(),$pageGenerator->getPublicFilename(), 0 ); + $publisher->addOrderForPublishing( new PublishOrder( $pageGenerator->getCache()->load()->getFilename(),$pageGenerator->getPublicFilename(), 0 ) ); } } } @@ -1204,10 +1205,12 @@ class FolderAction extends ObjectAction foreach( $folder->getFiles() as $fileid ) { $fileGenerator = new FileGenerator( new FileContext( $fileid, Producer::SCHEME_PUBLIC)); - $publisher->publish( $fileGenerator->getCache()->load()->getFilename(),$fileGenerator->getPublicFilename(),0 ); + $publisher->addOrderForPublishing( new PublishOrder( $fileGenerator->getCache()->load()->getFilename(),$fileGenerator->getPublicFilename(),0 ) ); } } + + $publisher->publish(); } @@ -1221,7 +1224,7 @@ class FolderAction extends ObjectAction $this->addNoticeFor( $this->folder, 'PUBLISHED', array(), - implode("\n",$publisher->publishedObjects) + implode("\n",$publisher->getDestinationFilenames() ) ); } diff --git a/modules/cms/action/PageAction.class.php b/modules/cms/action/PageAction.class.php @@ -5,6 +5,7 @@ namespace cms\action; use cms\generator\PageGenerator; use cms\generator\Producer; use cms\generator\Publisher; +use cms\generator\PublishOrder; use cms\model\Acl; use cms\model\Project; use cms\model\Value; @@ -14,13 +15,9 @@ use cms\model\Page; use cms\model\Folder; use cms\model\BaseObject; use cms\model\Language; -use cms\model\Model; use cms\generator\PageContext; -use cms\generator\PublishPreview; -use cms\generator\PublishPublic; use configuration\Config; use util\Html; -use util\Http; use logger\Logger; use util\Session; @@ -782,14 +779,16 @@ class PageAction extends ObjectAction $pageGenerator = new PageGenerator( $pageContext ); - $publisher->publish( $pageGenerator->getCache()->load()->getFilename(),$pageGenerator->getPublicFilename(), $this->page->lastchangeDate ); + $publisher->addOrderForPublishing( new PublishOrder( $pageGenerator->getCache()->load()->getFilename(),$pageGenerator->getPublicFilename(), $this->page->lastchangeDate ) ); } } + $publisher->publish(); + $this->addNoticeFor( $this->page, 'PUBLISHED', array(), - implode("\n",$publisher->publishedObjects) + implode("\n",$publisher->getDestinationFilenames() ) ); } diff --git a/modules/cms/action/PageelementAction.class.php b/modules/cms/action/PageelementAction.class.php @@ -7,6 +7,7 @@ use cms\generator\PageContext; use cms\generator\PageGenerator; use cms\generator\Producer; use cms\generator\Publisher; +use cms\generator\PublishOrder; use cms\generator\ValueContext; use cms\generator\ValueGenerator; use cms\model\Acl; @@ -1333,12 +1334,13 @@ class PageelementAction extends BaseAction $pageGenerator = new PageGenerator( $pageContext ); - $publisher->publish( $pageGenerator->getCache()->load()->getFilename(),$pageGenerator->getPublicFilename(), $this->page->lastchangeDate ); + $publisher->addOrderForPublishing( new PublishOrder( $pageGenerator->getCache()->load()->getFilename(),$pageGenerator->getPublicFilename(), $this->page->lastchangeDate ) ); } + $publisher->publish(); $this->addNoticeFor( $this->value,'PUBLISHED',array(), - implode("\n",$publisher->publishedObjects) ); + implode("\n",$publisher->getDestinationFilenames() ) ); } diff --git a/modules/cms/base/DefaultConfig.class.php b/modules/cms/base/DefaultConfig.class.php @@ -19,7 +19,6 @@ class DefaultConfig { [ 'applications' => [ - '' => 0, 'phpmyadmin' => [ 'name' => 'PHPYourAdmin', @@ -470,12 +469,12 @@ class DefaultConfig { 'ns_lookup' => false, 'format' => [ - 0 => 'time', - 1 => 'level', - 2 => 'host', - 3 => 'user', - 4 => 'action', - 5 => 'text', + 'time', + 'level', + 'host', + 'user', + 'action', + 'text', ], ], 'mail' => @@ -759,7 +758,6 @@ class DefaultConfig { ], 'publish' => [ - 'targets' => ['Local','Ftp','Ftps','Fax','SFtp','Scp','Dav'], 'edit' => true, 'default' => 'index', 'format' => '{filename}{language_sep}{language}{type_sep}{type}', diff --git a/modules/cms/generator/PublishOrder.class.php b/modules/cms/generator/PublishOrder.class.php @@ -0,0 +1,31 @@ +<?php + + +namespace cms\generator; + + +/** + * An order for publishing a file. + */ +class PublishOrder +{ + public $localFilename; + public $destinationFilename; + public $fileTime; + + /** + * PublishOrder constructor. + * + * @param $localFilename + * @param $destinationFilename + * @param $fileTime + */ + public function __construct($localFilename, $destinationFilename, $fileTime) + { + $this->localFilename = $localFilename; + $this->destinationFilename = $destinationFilename; + $this->fileTime = $fileTime; + } + + +}+ \ No newline at end of file diff --git a/modules/cms/generator/Publisher.class.php b/modules/cms/generator/Publisher.class.php @@ -5,24 +5,13 @@ namespace cms\generator; use cms\base\Configuration as C; -use cms\generator\target\Dav; -use cms\generator\target\Fax; -use cms\generator\target\Ftp; -use cms\generator\target\Ftps; use cms\generator\target\Local; -use cms\generator\target\NoBaseTarget; -use cms\generator\target\Scp; -use cms\generator\target\SFtp; +use cms\generator\target\NoTarget; use cms\generator\target\BaseTarget; -use cms\model\BaseObject; -use cms\model\File; -use cms\model\Folder; -use cms\model\Link; use cms\model\ModelBase; -use cms\model\Page; use cms\model\Project; -use cms\model\Url; use logger\Logger; +use cms\generator\target\TargetFactory; use util\exception\PublisherException; use util\Session; use util\text\variables\VariableResolver; @@ -30,7 +19,10 @@ use util\text\variables\VariableResolver; /** * Publisher for publishing files. * - * This publisher is publishing files to the live server. It doesn't care about the node type, it just publishes files. + * This publisher is publishing files to the live server. + * + * It doesn't care about the node type, it just publishes files, which means, all node types + * are recognized as bare files. * * @package cms\generator */ @@ -43,45 +35,17 @@ class Publisher */ private $target; - private $localDestinationDirectory = ''; - - /** - * Enthaelt die gleichnamige Einstellung aus dem Projekt. - * @var boolean - */ - private $contentNegotiation = false; - - /** - * Enthaelt die gleichnamige Einstellung aus dem Projekt. - * @var boolean - */ - private $cutIndex = false; - - /** - * Enthaelt die gleichnamige Einstellung aus dem Projekt. - * @var String - */ - private $commandAfterPublish = ''; - /** - * Enthaelt am Ende der Ver�ffentlichung ein Array mit den ver�ffentlichten Objekten. - * @var Array - */ - public $publishedObjects = array(); - - /** - * Enthaelt im Fehlerfall (wenn 'ok' auf 'false' steht) eine - * Fehlermeldung. - * - * @var String + * @var PublishOrder[] */ - public $log = array(); + private $publishingOrders = []; /** * @var Project */ private $project; + public function __construct( $projectid ) { $this->project = Project::create( $projectid ); @@ -90,130 +54,143 @@ class Publisher $this->init(); } - public function publish( $filename,$destination,$time ) { - $this->target->put( $filename,$destination,$time ); + /** + * Adds a file to the publishing process. + * + * @param PublishOrder order + */ + public function addOrderForPublishing($publishOrder ) { - $this->publishedObjects[] = $destination; + $this->publishingOrders[] = $publishOrder; } + /** + * The target is cleaned up, which means, older files (older than the start time of the request) are removed. + * + * @param int $time unused (always using the start time) + */ public function cleanOlderThan( $time ) { if ( $this->target instanceof Local ) $this->target->clean(); - } /** - * Konstruktor.<br> - * <br> - * Oeffnet ggf. Verbindungen. - * - * @return Publish + * Initializing the Publisher. */ public function init() { - $confPublish = C::subset('publish'); - if ( C::subset('security')->is('nopublish') ) { - $this->target = new NoBaseTarget(); + $this->target = new NoTarget(); Logger::warn('publishing is disabled.'); + } else { + $this->target = TargetFactory::getTargetForUrl( $this->project->target_dir ); } + } - $targetScheme = parse_url( $this->project->target_dir,PHP_URL_SCHEME ); - - $availableTargets = $confPublish->get('targets',[]); - - foreach($availableTargets as $target ) - { - $className = '\\cms\\generator\\target\\'.$target; - if ( !class_exists($className )) { - Logger::warn('Target '.$target.' is not available, class '.$className.' not found.'); - continue; - } - - /** @var BaseTarget $className */ - $targetObject = new $className( $this->project->target_dir ); - - if ( $targetObject::accepts( $targetScheme )) - { - if ( ! $targetObject::isAvailable() ) - throw new PublisherException('The target "'.$targetScheme.'" is not available.' ); + /** + * All files are being processed and published. + * + * @throws PublisherException + */ + public function publish() + { + $this->target->open(); // Open the connection to the target. - $this->target = $targetObject; - break; - } - } + foreach($this->publishingOrders as $publishOrder ) - if ( empty( $this->target ) ) - throw new PublisherException('The scheme "'.$targetScheme.'" is not supported.' ); + $this->target->put( $publishOrder->localFilename,$publishOrder->destinationFilename,$publishOrder->fileTime ); - $this->target->open(); // Open the connetion to the target. + $this->target->close(); - $commandConfig = $confPublish->subset('command'); - if ( $commandConfig->is('enable') ) - { - if ( $commandConfig->is('per_project') && !empty($project->cmd_after_publish) ) - $this->commandAfterPublish = $project->cmd_after_publish; - else - $this->commandAfterPublish = @$commandConfig->get('command'); - } + $this->executeSystemCommand(); + } - // Im Systemkommando Variablen ersetzen - $resolver = new VariableResolver(); - $resolver->addResolver('project', function( $property) { - return @$this->project->getProperties()[$property]; - }); - $resolver->addResolver('target', function( $property) { - return @parse_url( $this->project->target_dir )[$property]; - }); - $this->commandAfterPublish = $resolver->resolveVariables( $this->commandAfterPublish ); + /** + * Gets an array with all destination filenames. + * + * @return array + */ + public function getDestinationFilenames() { + return array_map( function($order) { + return $order->destinationFilename; + }, $this->publishingOrders ); } - /** - * Beenden des Ver�ffentlichungs-Vorganges.<br> - * Eine vorhandene FTP-Verbindung wird geschlossen.<br> - * Falls entsprechend konfiguriert, wird ein Systemkommando ausgef�hrt. + * @return array + * @throws PublisherException */ - public function end() + protected function executeSystemCommand() { - $this->target->close(); + $systemCommand = $this->getSystemCommand(); - // Ausfuehren des Systemkommandos. - if ( !empty($this->commandAfterPublish) ) - { + if ( $systemCommand ) { $ausgabe = array(); - $rc = false; - Logger::debug('Executing system command: '.Logger::sanitizeInput($this->commandAfterPublish) ); + $rc = false; + Logger::debug('Executing system command: ' . Logger::sanitizeInput($systemCommand)); /** @var ModelBase $baseObjectToEnv */ - foreach( ['user' => Session::getUser(), - 'project' => $this->project ] - as $key=> $baseObjectToEnv ) { + foreach (['user' => Session::getUser(), + 'project' => $this->project] + as $key => $baseObjectToEnv) { - foreach( $baseObjectToEnv->getProperties() as $name=>$property ) - putenv('CMS_'.strtoupper($key).'_'.strtoupper($name).'='.$property ); + foreach ($baseObjectToEnv->getProperties() as $name => $property) + putenv('CMS_' . strtoupper($key) . '_' . strtoupper($name) . '=' . $property); } - exec( $this->commandAfterPublish,$ausgabe,$rc ); + exec($systemCommand, $ausgabe, $rc); - if ( $rc != 0 ) // Wenn Returncode ungleich 0, dann Fehler melden. + if ($rc != 0) // Wenn Returncode ungleich 0, dann Fehler melden. throw new PublisherException('System command failed - returncode is ' . $rc . "\n" . $ausgabe); else - Logger::debug('System command successful' ); + Logger::debug('System command successful'); } } + /** + * Calculates the system command to execute after publishing. + * + * @return string|null The system command (or null, if there is no command) + */ + private function getSystemCommand() + { + $confPublish = C::subset('publish'); + $commandConfig = $confPublish->subset('command'); + + if ( ! $commandConfig->is('enable') ) + return null; + + if ( $commandConfig->is('per_project') && !empty($this->project->cmd_after_publish) ) + $commandAfterPublish = $this->project->cmd_after_publish; + else + $commandAfterPublish = @$commandConfig->get('command'); + + // Im Systemkommando Variablen ersetzen + $resolver = new VariableResolver(); + $resolver->addResolver('project', function( $property) { + return @$this->project->getProperties()[$property]; + }); + $resolver->addResolver('target', function( $property) { + return @parse_url( $this->project->target_dir )[$property]; + }); + + $commandAfterPublish = $resolver->resolveVariables( $commandAfterPublish ); + + return $commandAfterPublish; + } + + } \ No newline at end of file diff --git a/modules/cms/generator/target/BaseTarget.class.php b/modules/cms/generator/target/BaseTarget.class.php @@ -37,19 +37,6 @@ abstract class BaseTarget implements Target } - public static function accepts( $scheme ) { - return in_array( $scheme, static::acceptsSchemes() ); - } - - - /** - * For which types this target is reponsible? - * - * @return array - */ - protected abstract static function acceptsSchemes(); - - public function open() { } diff --git a/modules/cms/generator/target/Dav.class.php b/modules/cms/generator/target/Dav.class.php @@ -92,11 +92,6 @@ class Dav extends BaseTarget //fclose($this->socket); } - protected static function acceptsSchemes() - { - return ['dav']; - } - public function open() { $this->checkConnection(); diff --git a/modules/cms/generator/target/Fax.class.php b/modules/cms/generator/target/Fax.class.php @@ -44,11 +44,6 @@ class Fax extends BaseTarget Logger::debug("Hanging up........................... NO CARRIER"); } - protected static function acceptsSchemes() - { - return ['fax']; - } - public function __construct($targetUrl) { } diff --git a/modules/cms/generator/target/Ftp.class.php b/modules/cms/generator/target/Ftp.class.php @@ -31,10 +31,6 @@ class Ftp extends BaseTarget { private $connection; - public static function acceptsSchemes() { - return ['ftp']; - } - // Aufbauen der Verbindung public function open() { diff --git a/modules/cms/generator/target/Ftps.class.php b/modules/cms/generator/target/Ftps.class.php @@ -29,10 +29,6 @@ use util\exception\UIException; */ class Ftps extends Ftp { - public static function acceptsSchemes() { - return ['ftps']; - } - /** * Creates a new connection. * diff --git a/modules/cms/generator/target/Local.class.php b/modules/cms/generator/target/Local.class.php @@ -37,11 +37,6 @@ class Local extends BaseTarget */ private $localDestinationDirectory; - public static function acceptsSchemes() { - return ['file','']; - } - - /** * @param $url Url */ diff --git a/modules/cms/generator/target/NoTarget.class.php b/modules/cms/generator/target/NoTarget.class.php @@ -27,7 +27,7 @@ use util\exception\UIException; * * @author Jan Dankert */ -class NoBaseTarget extends BaseTarget +class NoTarget extends BaseTarget { public static function acceptsSchemes() { diff --git a/modules/cms/generator/target/SFtp.class.php b/modules/cms/generator/target/SFtp.class.php @@ -39,10 +39,6 @@ class SFtp extends Scp protected $sftpConnection; - public static function acceptsSchemes() { - return ['sftp']; - } - // Aufbauen der Verbindung public function open() { diff --git a/modules/cms/generator/target/Scp.class.php b/modules/cms/generator/target/Scp.class.php @@ -38,10 +38,6 @@ class Scp extends BaseTarget */ protected $sshConnection; - public static function acceptsSchemes() { - return ['scp']; - } - // Aufbauen der Verbindung public function open() { diff --git a/modules/cms/generator/target/Target.class.php b/modules/cms/generator/target/Target.class.php @@ -12,9 +12,6 @@ interface Target public function __construct( $targetUrl ); - public static function accepts( $scheme ); - - public function open(); diff --git a/modules/cms/generator/target/TargetFactory.class.php b/modules/cms/generator/target/TargetFactory.class.php @@ -0,0 +1,64 @@ +<?php + + +namespace cms\generator\target; + + +use util\ClassUtils; +use util\exception\PublisherException; + +class TargetFactory +{ + + /** + * Creates a target for publishing files. + * + * @param string $url URL + * @return Target + * @throws PublisherException if no target could be created + */ + public static function getTargetForUrl( $url ) { + + $scheme = parse_url( $url,PHP_URL_SCHEME ); + + /** @var Target $target */ + $target = null; + + switch( $scheme ) { + + case '': + case 'file': + case 'local': + $target = new Local($url); + break; + + case 'dav': + $target = new Dav($url); + break; + + case 'ftp': + $target = new Ftp($url); + break; + + case 'ftps': + $target = new Ftps($url); + break; + + case 'scp': + $target = new Scp($url); + break; + + case 'sftp': + $target = new SFtp($url); + break; + + default: + throw new PublisherException('The scheme "'.$scheme.'" is not supported.' ); + } + + if ( ! $target::isAvailable() ) + throw new PublisherException(ClassUtils::getSimpleClassName($target).' is not available.' ); + + return $target; + } +}+ \ No newline at end of file