2014-05-02 04:03:02 +02:00
< ? php
namespace ManiaControl\Update ;
use ManiaControl\Callbacks\CallbackListener ;
use ManiaControl\Callbacks\CallbackManager ;
use ManiaControl\Callbacks\TimerListener ;
use ManiaControl\Commands\CommandListener ;
2017-03-30 20:27:57 +02:00
use ManiaControl\Files\AsyncHttpRequest ;
2014-05-02 17:50:30 +02:00
use ManiaControl\Files\BackupUtil ;
2014-05-02 04:03:02 +02:00
use ManiaControl\Files\FileUtil ;
2014-08-03 13:29:54 +02:00
use ManiaControl\Logger ;
2014-05-02 04:03:02 +02:00
use ManiaControl\ManiaControl ;
use ManiaControl\Players\Player ;
2014-07-01 21:23:50 +02:00
use ManiaControl\Plugins\InstallMenu ;
2014-07-24 23:15:25 +02:00
use ManiaControl\Plugins\Plugin ;
2014-05-02 04:03:02 +02:00
use ManiaControl\Plugins\PluginManager ;
2014-05-02 17:50:30 +02:00
use ManiaControl\Plugins\PluginMenu ;
2014-06-27 01:18:55 +02:00
use ManiaControl\Utils\WebReader ;
2014-05-02 04:03:02 +02:00
/**
* Manager checking for ManiaControl Plugin Updates
2014-05-02 17:50:30 +02:00
*
* @ author ManiaControl Team < mail @ maniacontrol . com >
2017-02-04 11:49:23 +01:00
* @ copyright 2014 - 2017 ManiaControl Team
2014-05-02 17:50:30 +02:00
* @ license http :// www . gnu . org / licenses / GNU General Public License , Version 3
2014-05-02 04:03:02 +02:00
*/
class PluginUpdateManager implements CallbackListener , CommandListener , TimerListener {
/*
2014-07-25 16:28:47 +02:00
* Private properties
2014-05-02 04:03:02 +02:00
*/
2014-08-02 22:31:46 +02:00
/** @var ManiaControl $maniaControl */
2014-05-02 04:03:02 +02:00
private $maniaControl = null ;
/**
2014-07-25 16:28:47 +02:00
* Create a new plugin update manager instance
2014-05-02 17:50:30 +02:00
*
2014-05-02 04:03:02 +02:00
* @ param ManiaControl $maniaControl
*/
public function __construct ( ManiaControl $maniaControl ) {
$this -> maniaControl = $maniaControl ;
2014-05-02 17:50:30 +02:00
2014-08-03 01:34:18 +02:00
// Callbacks
2014-08-13 11:05:52 +02:00
$this -> maniaControl -> getCallbackManager () -> registerCallbackListener ( CallbackManager :: CB_MP_PLAYERMANIALINKPAGEANSWER , $this , 'handleManialinkPageAnswer' );
2014-05-02 17:50:30 +02:00
2014-08-03 01:34:18 +02:00
// Chat commands
2014-08-13 11:05:52 +02:00
$this -> maniaControl -> getCommandManager () -> registerCommandListener ( 'checkpluginsupdate' , $this , 'handle_CheckPluginsUpdate' , true , 'Check for Plugin Updates.' );
$this -> maniaControl -> getCommandManager () -> registerCommandListener ( 'pluginsupdate' , $this , 'handle_PluginsUpdate' , true , 'Perform the Plugin Updates.' );
2014-05-02 04:03:02 +02:00
}
/**
* Handle //checkpluginsupdate command
2014-05-02 17:50:30 +02:00
*
* @ param array $chatCallback
2014-05-02 04:03:02 +02:00
* @ param Player $player
*/
public function handle_CheckPluginsUpdate ( array $chatCallback , Player $player ) {
2014-08-13 11:05:52 +02:00
if ( ! $this -> maniaControl -> getAuthenticationManager () -> checkPermission ( $player , UpdateManager :: SETTING_PERMISSION_UPDATECHECK )
2014-08-05 02:17:41 +02:00
) {
2014-08-13 11:05:52 +02:00
$this -> maniaControl -> getAuthenticationManager () -> sendNotAllowed ( $player );
2014-05-02 04:03:02 +02:00
return ;
}
2014-05-02 17:50:30 +02:00
$this -> checkPluginsUpdate ( $player );
2014-05-02 04:03:02 +02:00
}
/**
* Check if there are Outdated Plugins installed
2014-05-02 17:50:30 +02:00
*
2014-05-02 04:03:02 +02:00
* @ param Player $player
*/
public function checkPluginsUpdate ( Player $player = null ) {
$message = 'Checking Plugins for newer Versions...' ;
if ( $player ) {
2014-08-13 11:05:52 +02:00
$this -> maniaControl -> getChat () -> sendInformation ( $message , $player );
2014-05-02 04:03:02 +02:00
}
2014-08-05 01:49:13 +02:00
Logger :: log ( $message );
2014-05-02 17:50:30 +02:00
2014-08-13 11:05:52 +02:00
$this -> maniaControl -> getPluginManager () -> fetchPluginList ( function ( $data , $error ) use ( & $player ) {
2014-08-25 15:33:22 +02:00
if ( ! $data || $error ) {
$message = 'Error while checking Plugins for newer Versions!' ;
if ( $player ) {
$this -> maniaControl -> getChat () -> sendError ( $message , $player );
}
Logger :: logError ( $message );
return ;
}
$pluginsData = $this -> parsePluginsData ( $data );
$pluginClasses = $this -> maniaControl -> getPluginManager () -> getPluginClasses ();
$pluginUpdates = array ();
foreach ( $pluginClasses as $pluginClass ) {
/** @var Plugin $pluginClass */
$pluginId = $pluginClass :: getId ();
if ( ! isset ( $pluginsData [ $pluginId ])) {
continue ;
}
/** @var PluginUpdateData $pluginData */
$pluginData = $pluginsData [ $pluginId ];
$pluginVersion = $pluginClass :: getVersion ();
if ( $pluginData -> isNewerThan ( $pluginVersion )) {
$pluginUpdates [ $pluginId ] = $pluginData ;
$message = " There is an Update of ' { $pluginData -> pluginName } ' available! (' { $pluginClass } ' - Version { $pluginData -> version } ) " ;
if ( $player ) {
$this -> maniaControl -> getChat () -> sendSuccess ( $message , $player );
}
Logger :: log ( $message );
}
}
if ( empty ( $pluginUpdates )) {
$message = 'Plugins Update Check completed: All Plugins are up-to-date!' ;
if ( $player ) {
$this -> maniaControl -> getChat () -> sendSuccess ( $message , $player );
}
Logger :: log ( $message );
} else {
$updatesCount = count ( $pluginUpdates );
$message = " Plugins Update Check completed: There are { $updatesCount } Updates available! " ;
if ( $player ) {
$this -> maniaControl -> getChat () -> sendSuccess ( $message , $player );
}
Logger :: log ( $message );
}
});
2014-05-02 04:03:02 +02:00
}
2014-05-02 17:50:30 +02:00
/**
* Get an Array of Plugin Update Data from the given Web Service Result
*
* @ param mixed $webServiceResult
* @ return mixed
*/
public function parsePluginsData ( $webServiceResult ) {
if ( ! $webServiceResult || ! is_array ( $webServiceResult )) {
return false ;
}
$pluginsData = array ();
foreach ( $webServiceResult as $pluginResult ) {
$pluginData = new PluginUpdateData ( $pluginResult );
$pluginsData [ $pluginData -> pluginId ] = $pluginData ;
}
return $pluginsData ;
}
/**
* Handle //pluginsupdate command
*
* @ param array $chatCallback
* @ param Player $player
*/
public function handle_PluginsUpdate ( array $chatCallback , Player $player ) {
2014-08-13 11:05:52 +02:00
if ( ! $this -> maniaControl -> getAuthenticationManager () -> checkPermission ( $player , UpdateManager :: SETTING_PERMISSION_UPDATE )
2014-08-05 02:17:41 +02:00
) {
2014-08-13 11:05:52 +02:00
$this -> maniaControl -> getAuthenticationManager () -> sendNotAllowed ( $player );
2014-05-02 17:50:30 +02:00
return ;
}
$this -> performPluginsUpdate ( $player );
}
2014-05-02 04:03:02 +02:00
/**
* Perform an Update of all outdated Plugins
2014-05-02 17:50:30 +02:00
*
2014-05-02 04:03:02 +02:00
* @ param Player $player
*/
public function performPluginsUpdate ( Player $player = null ) {
$pluginsUpdates = $this -> getPluginsUpdates ();
if ( empty ( $pluginsUpdates )) {
$message = 'There are no Plugin Updates available!' ;
if ( $player ) {
2014-08-13 11:05:52 +02:00
$this -> maniaControl -> getChat () -> sendInformation ( $message , $player );
2014-05-02 04:03:02 +02:00
}
2014-08-05 01:49:13 +02:00
Logger :: log ( $message );
2014-05-02 04:03:02 +02:00
return ;
}
2014-05-02 17:50:30 +02:00
2014-05-02 05:04:55 +02:00
$message = " Starting Plugins Updating... " ;
2014-05-02 04:03:02 +02:00
if ( $player ) {
2014-08-13 11:05:52 +02:00
$this -> maniaControl -> getChat () -> sendInformation ( $message , $player );
2014-05-02 04:03:02 +02:00
}
2014-08-05 01:49:13 +02:00
Logger :: log ( $message );
2014-05-02 17:50:30 +02:00
2014-08-13 11:05:52 +02:00
$performBackup = $this -> maniaControl -> getSettingManager () -> getSettingValue ( $this -> maniaControl -> getUpdateManager (), UpdateManager :: SETTING_PERFORM_BACKUPS );
2014-05-02 04:03:02 +02:00
if ( $performBackup && ! BackupUtil :: performPluginsBackup ()) {
$message = 'Creating Backup before Plugins Update failed!' ;
if ( $player ) {
2014-08-13 11:05:52 +02:00
$this -> maniaControl -> getChat () -> sendError ( $message , $player );
2014-05-02 04:03:02 +02:00
}
2014-08-05 01:49:13 +02:00
Logger :: logError ( $message );
2014-05-02 04:03:02 +02:00
}
2014-05-02 17:50:30 +02:00
2014-05-02 04:03:02 +02:00
foreach ( $pluginsUpdates as $pluginUpdateData ) {
2014-05-02 05:04:55 +02:00
$this -> installPlugin ( $pluginUpdateData , $player , true );
2014-05-02 04:03:02 +02:00
}
}
/**
* Check for Plugin Updates
2014-05-02 17:50:30 +02:00
*
2014-05-02 04:03:02 +02:00
* @ return mixed
*/
public function getPluginsUpdates () {
2014-05-02 17:50:30 +02:00
$url = ManiaControl :: URL_WEBSERVICE . 'plugins' ;
2014-08-25 15:29:45 +02:00
$response = WebReader :: getUrl ( $url );
2014-06-27 01:18:55 +02:00
$dataJson = $response -> getContent ();
2014-05-02 04:03:02 +02:00
$pluginData = json_decode ( $dataJson );
if ( ! $pluginData || empty ( $pluginData )) {
return false ;
}
2014-05-02 17:50:30 +02:00
2014-05-02 04:03:02 +02:00
$pluginsUpdates = $this -> parsePluginsData ( $pluginData );
2014-05-02 17:50:30 +02:00
$updates = array ();
2014-08-13 11:05:52 +02:00
$pluginClasses = $this -> maniaControl -> getPluginManager () -> getPluginClasses ();
2014-05-02 04:03:02 +02:00
foreach ( $pluginClasses as $pluginClass ) {
2014-05-30 03:17:39 +02:00
/** @var Plugin $pluginClass */
2014-05-02 04:03:02 +02:00
$pluginId = $pluginClass :: getId ();
if ( isset ( $pluginsUpdates [ $pluginId ])) {
2014-05-02 15:35:52 +02:00
/** @var PluginUpdateData $pluginUpdateData */
2014-05-02 04:03:02 +02:00
$pluginUpdateData = $pluginsUpdates [ $pluginId ];
2014-05-02 17:50:30 +02:00
$pluginVersion = $pluginClass :: getVersion ();
2014-05-02 04:03:02 +02:00
if ( $pluginUpdateData -> isNewerThan ( $pluginVersion )) {
$updates [ $pluginId ] = $pluginUpdateData ;
}
}
}
2014-05-02 17:50:30 +02:00
2014-05-02 04:03:02 +02:00
if ( empty ( $updates )) {
return false ;
}
return $updates ;
}
/**
* Load the given Plugin Update Data
2014-05-02 17:50:30 +02:00
*
2014-05-02 04:03:02 +02:00
* @ param PluginUpdateData $pluginUpdateData
2014-05-02 17:50:30 +02:00
* @ param Player $player
* @ param bool $update
2014-05-02 04:03:02 +02:00
*/
private function installPlugin ( PluginUpdateData $pluginUpdateData , Player $player = null , $update = false ) {
2017-03-30 20:27:57 +02:00
$asyncHttpRequest = new AsyncHttpRequest ( $this -> maniaControl , $pluginUpdateData -> url );
$asyncHttpRequest -> setContentType ( AsyncHttpRequest :: CONTENT_TYPE_JSON );
$asyncHttpRequest -> setCallable ( function ( $updateFileContent , $error ) use (
2014-08-25 15:33:22 +02:00
& $pluginUpdateData , & $player , & $update
) {
if ( ! $updateFileContent || $error ) {
$message = " Error loading Update Data for ' { $pluginUpdateData -> pluginName } ': { $error } ! " ;
if ( $player ) {
$this -> maniaControl -> getChat () -> sendInformation ( $message , $player );
}
Logger :: logError ( $message );
return ;
}
$actionNoun = ( $update ? 'Update' : 'Install' );
$actionVerb = ( $update ? 'Updating' : 'Installing' );
$actionVerbDone = ( $update ? 'updated' : 'installed' );
$message = " Now { $actionVerb } ' { $pluginUpdateData -> pluginName } '... " ;
if ( $player ) {
$this -> maniaControl -> getChat () -> sendInformation ( $message , $player );
}
Logger :: log ( $message );
$tempDir = FileUtil :: getTempFolder ();
$updateFileName = $tempDir . $pluginUpdateData -> zipfile ;
2014-10-24 20:28:11 +02:00
$bytes = @ file_put_contents ( $updateFileName , $updateFileContent );
2014-08-25 15:33:22 +02:00
if ( ! $bytes || $bytes <= 0 ) {
$message = " Plugin { $actionNoun } failed: Couldn't save { $actionNoun } Zip! " ;
if ( $player ) {
$this -> maniaControl -> getChat () -> sendError ( $message , $player );
}
Logger :: logError ( $message );
return ;
}
$zip = new \ZipArchive ();
$result = $zip -> open ( $updateFileName );
if ( $result !== true ) {
$message = " Plugin { $actionNoun } failed: Couldn't open { $actionNoun } Zip! ( { $result } ) " ;
if ( $player ) {
$this -> maniaControl -> getChat () -> sendError ( $message , $player );
}
Logger :: logError ( $message );
return ;
}
$zip -> extractTo ( MANIACONTROL_PATH . 'plugins' . DIRECTORY_SEPARATOR );
$zip -> close ();
2014-10-24 20:28:11 +02:00
@ unlink ( $updateFileName );
2014-08-25 15:33:22 +02:00
FileUtil :: deleteTempFolder ();
$messageExtra = '' ;
if ( $update ) {
$messageExtra = ' (Restart ManiaControl to load the new Version!)' ;
}
$message = " Successfully { $actionVerbDone } ' { $pluginUpdateData -> pluginName } '! { $messageExtra } " ;
if ( $player ) {
$this -> maniaControl -> getChat () -> sendSuccess ( $message , $player );
}
Logger :: log ( $message );
if ( ! $update ) {
$newPluginClasses = $this -> maniaControl -> getPluginManager () -> loadPlugins ();
if ( empty ( $newPluginClasses )) {
$message = " Loading fresh installed Plugin ' { $pluginUpdateData -> pluginName } ' failed! " ;
if ( $player ) {
$this -> maniaControl -> getChat () -> sendError ( $message , $player );
}
Logger :: log ( $message );
} else {
$message = " Successfully loaded fresh installed Plugin ' { $pluginUpdateData -> pluginName } '! " ;
if ( $player ) {
$this -> maniaControl -> getChat () -> sendSuccess ( $message , $player );
}
Logger :: log ( $message );
$this -> maniaControl -> getConfigurator () -> showMenu ( $player , InstallMenu :: getTitle ());
}
}
});
2017-03-30 20:27:57 +02:00
$asyncHttpRequest -> getData ();
2014-05-02 04:03:02 +02:00
}
2014-05-02 17:50:30 +02:00
/**
* Handle PlayerManialinkPageAnswer callback
*
* @ param array $callback
*/
public function handleManialinkPageAnswer ( array $callback ) {
$actionId = $callback [ 1 ][ 2 ];
$update = ( strpos ( $actionId , PluginMenu :: ACTION_PREFIX_UPDATEPLUGIN ) === 0 );
2014-07-01 21:23:50 +02:00
$install = ( strpos ( $actionId , InstallMenu :: ACTION_PREFIX_INSTALL_PLUGIN ) === 0 );
2014-05-02 17:50:30 +02:00
if ( ! $update && ! $install ) {
return ;
}
$login = $callback [ 1 ][ 1 ];
2014-08-13 11:05:52 +02:00
$player = $this -> maniaControl -> getPlayerManager () -> getPlayer ( $login );
2014-05-02 17:50:30 +02:00
if ( $update ) {
$pluginClass = substr ( $actionId , strlen ( PluginMenu :: ACTION_PREFIX_UPDATEPLUGIN ));
2014-06-14 14:32:29 +02:00
if ( $pluginClass === 'All' ) {
2014-05-02 17:50:30 +02:00
$this -> performPluginsUpdate ( $player );
} else {
$pluginUpdateData = $this -> getPluginUpdate ( $pluginClass );
if ( $pluginUpdateData ) {
$this -> installPlugin ( $pluginUpdateData , $player , true );
} else {
$message = 'Error loading Plugin Update Data!' ;
2014-08-13 11:05:52 +02:00
$this -> maniaControl -> getChat () -> sendError ( $message , $player );
2014-05-02 17:50:30 +02:00
}
}
} else {
2014-07-01 21:23:50 +02:00
$pluginId = substr ( $actionId , strlen ( InstallMenu :: ACTION_PREFIX_INSTALL_PLUGIN ));
2014-05-02 17:50:30 +02:00
2014-06-17 23:27:28 +02:00
$url = ManiaControl :: URL_WEBSERVICE . 'plugins/' . $pluginId ;
2017-03-30 20:27:57 +02:00
$asyncHttpRequest = new AsyncHttpRequest ( $this -> maniaControl , $url );
$asyncHttpRequest -> setContentType ( AsyncHttpRequest :: CONTENT_TYPE_JSON );
$asyncHttpRequest -> setCallable ( function ( $data , $error ) use ( & $player ) {
2014-08-25 15:33:22 +02:00
if ( $error || ! $data ) {
$message = " Error loading Plugin Install Data! { $error } " ;
$this -> maniaControl -> getChat () -> sendError ( $message , $player );
return ;
}
$data = json_decode ( $data );
if ( ! $data ) {
$message = " Error loading Plugin Install Data! { $error } " ;
$this -> maniaControl -> getChat () -> sendError ( $message , $player );
return ;
}
$pluginUpdateData = new PluginUpdateData ( $data );
$this -> installPlugin ( $pluginUpdateData , $player );
});
2017-03-30 20:27:57 +02:00
$asyncHttpRequest -> getData ();
2014-05-02 17:50:30 +02:00
}
}
/**
* Check given Plugin Class for Update
*
* @ param string $pluginClass
* @ return mixed
*/
public function getPluginUpdate ( $pluginClass ) {
$pluginClass = PluginManager :: getPluginClass ( $pluginClass );
2014-05-30 03:17:39 +02:00
/** @var Plugin $pluginClass */
$pluginId = $pluginClass :: getId ();
$url = ManiaControl :: URL_WEBSERVICE . 'plugins/' . $pluginId ;
2014-08-25 15:29:45 +02:00
$response = WebReader :: getUrl ( $url );
2014-06-27 01:18:55 +02:00
$dataJson = $response -> getContent ();
2014-05-30 03:17:39 +02:00
$pluginVersion = json_decode ( $dataJson );
if ( ! $pluginVersion ) {
2014-05-02 17:50:30 +02:00
return false ;
}
2014-05-30 03:17:39 +02:00
$pluginUpdateData = new PluginUpdateData ( $pluginVersion );
$version = $pluginClass :: getVersion ();
if ( $pluginUpdateData -> isNewerThan ( $version )) {
2014-05-02 17:50:30 +02:00
return $pluginUpdateData ;
}
return false ;
}
2014-05-02 04:03:02 +02:00
}