ispconfig_addon_installer_base.inc.php 6.18 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
<?php

/**
 * Base class for app installer
 *
 * @author Marius Burkard
 */
class ispconfig_addon_installer_base {
	
	protected $addon_name;
	protected $addon_ident;
	protected $addon_version;
	
	protected $temp_dir;
	
	public function __construct() {
		$this->addon_ident = preg_replace('/_addon_installer$/', '', get_called_class());
	}
	
	public function setAddonName($name) {
		$this->addon_name = $name;
	}
	
	public function setAddonIdent($ident) {
		$this->addon_ident = $ident;
	}
	
	public function setAddonVersion($version) {
		$this->addon_version = $version;
	}
	
	public function setAddonTempDir($path) {
		$this->temp_dir = $path;
	}
	
	protected function copyInterfaceFiles() {
		global $conf;
		
Marius Burkard's avatar
Marius Burkard committed
39
		$app->log('Copying interface files.', 0, false);
40 41 42 43 44 45 46 47
		$install_dir = realpath($conf['rootpath'] . '/..');
		
		if(is_dir($this->temp_dir . '/interface')) {
			$ret = null;
			$retval = 0;
			$command = 'cp -rf ' . escapeshellarg($this->temp_dir . '/interface') . ' ' . escapeshellarg($install_dir . '/');
			exec($command, $ret, $retval);
			if($retval != 0) {
Marius Burkard's avatar
Marius Burkard committed
48
				$app->log('Copying interface files failed.', 2, false);
49 50 51 52 53 54 55 56 57 58 59 60
				throw new AddonInstallerException('Command ' . $command . ' failed with code ' . $retval);
			}
			
			return true;
		} else {
			return false;
		}
	}
	
	protected function copyServerFiles() {
		global $conf;
		
Marius Burkard's avatar
Marius Burkard committed
61 62
		$app->log('Copying server files.', 0, false);
		
63 64 65 66 67 68 69 70
		$install_dir = realpath($conf['rootpath'] . '/..');
		
		if(is_dir($this->temp_dir . '/server')) {
			$ret = null;
			$retval = 0;
			$command = 'cp -rf ' . escapeshellarg($this->temp_dir . '/server'). ' ' . escapeshellarg($install_dir . '/');
			exec($command, $ret, $retval);
			if($retval != 0) {
Marius Burkard's avatar
Marius Burkard committed
71
				$app->log('Copying interface files failed.', 2, false);
72 73 74 75 76 77 78 79
				throw new AddonInstallerException('Command ' . $command . ' failed with code ' . $retval);
			}
			return true;
		} else {
			return false;
		}		
	}
	
80 81 82
	protected function copyAddonFiles() {
		global $app, $conf;
		
Marius Burkard's avatar
Marius Burkard committed
83 84
		$app->log('Copying addon files.', 0, false);
		
85 86 87
		$install_dir = realpath($conf['rootpath'] . '/..') . '/addons/' . $this->addon_ident;
		if(!is_dir($install_dir)) {
			if(!$app->system->mkdir($install_dir, false, 0750, true)) {
Marius Burkard's avatar
Marius Burkard committed
88
				$app->log('Addons dir missing and could not be created.', 2, false);
89 90 91 92 93 94 95
				throw new AddonInstallerException('Could not create addons dir ' . $install_dir);
			}
		}
		
		if(is_dir($this->temp_dir . '/install')) {
			$ret = null;
			$retval = 0;
Marius Burkard's avatar
Marius Burkard committed
96
			$command = 'cp -rf ' . escapeshellarg($this->temp_dir . '/addon.ini') . ' ' . escapeshellarg($this->temp_dir . '/' . $this->addon_ident . '.addon.php') . ' ' . escapeshellarg($this->temp_dir . '/install'). ' ' . escapeshellarg($install_dir . '/');
97 98
			exec($command, $ret, $retval);
			if($retval != 0) {
Marius Burkard's avatar
Marius Burkard committed
99
				/* TODO: logging */
Marius Burkard's avatar
Marius Burkard committed
100
				$app->log('Warning or error on copying addon files. Returncode of command ' . $command . ' was: ' . $retval .'.', 0, false);
101 102 103 104 105 106 107 108
			}
			
			return true;
		} else {
			return false;
		}		
	}
	
109 110 111
	protected function executeSqlStatements() {
		global $app, $conf;
		
Marius Burkard's avatar
Marius Burkard committed
112
		$app->log('Adding addon entry to db.', 0, false);
113 114 115 116 117 118 119 120 121 122
		// create addon entry if not existing
		$qry = 'INSERT IGNORE INTO `addons` (`addon_ident`, `addon_version`, `addon_name`, `db_version`) VALUES (?, ?, ?, ?)';
		$app->db->query($qry, $this->addon_ident, $this->addon_version, $this->addon_name, 0);
		
		$incremental = false;
		$check = $app->db->queryOneRecord('SELECT `db_version` FROM `addons` WHERE `addon_ident` = ?', $this->addon_ident);
		if($check) {
			$incremental = 0;
			if($check['db_version']) {
				$incremental = $check['db_version'];
Marius Burkard's avatar
Marius Burkard committed
123
				$app->log('Current db version is ' . $incremental . '.', 0, false);
124 125 126 127 128 129 130 131 132 133 134
			}
		}
		
		
		$mysql_command = 'mysql --default-character-set=' . escapeshellarg($conf['db_charset']) . ' --force -h ' . escapeshellarg($conf['db_host']) . ' -u ' . escapeshellarg($conf['db_user']) . ' -p' . escapeshellarg($conf['db_password']) . ' -P ' . escapeshellarg($conf['db_port']) . ' -D ' . escapeshellarg($conf['db_database']);
		
		if($incremental === false) {
			$sql_file = $this->temp_dir . '/install/sql/' . $this->addon_ident . '.sql';
			if(is_file($sql_file)) {
				$ret = null;
				$retval = 0;
Marius Burkard's avatar
Marius Burkard committed
135
				$app->log('Loading ' . $sql_file . ' into db.', 0, false);
136 137 138
				exec($mysql_command . ' < ' . escapeshellarg($sql_file), $ret, $retval);
				if($retval != 0) {
					/* TODO: log error! */
Marius Burkard's avatar
Marius Burkard committed
139
					$app->log('Loading ' . $sql_file . ' into db failed.', 1, false);
140 141 142 143 144 145 146 147 148 149 150
				}
			}
		} else {
			$new_db_version = $incremental;
			while(true) {
				$sql_file = $this->temp_dir . '/install/sql/incremental/upd_' . str_pad($new_db_version + 1, '0', 5, STR_PAD_LEFT) . '.sql';
				if(!is_file($sql_file)) {
					break;
				} else {
					$ret = null;
					$retval = 0;
Marius Burkard's avatar
Marius Burkard committed
151
					$app->log('Loading ' . $sql_file . ' into db.', 0, false);
152 153 154
					exec($mysql_command . ' < ' . escapeshellarg($sql_file), $ret, $retval);
					if($retval != 0) {
						/* TODO: log error! */
Marius Burkard's avatar
Marius Burkard committed
155
						$app->log('Loading ' . $sql_file . ' into db failed.', 1, false);
156 157 158 159 160 161 162
					}
				}
				
				$new_db_version++;
			}
			
			$app->db->query('UPDATE `addons` SET `addon_version` = ?, `db_version` = ? WHERE `addon_ident` = ?', $this->addon_version, $new_db_version, $this->addon_ident);
Marius Burkard's avatar
Marius Burkard committed
163
			$app->log('Db version of addon is now ' . $new_db_version . '.', 0, false);
164 165 166 167 168 169 170 171
		}
		
		return true;
	}
	
	public function onBeforeInstall() { }
	
	public function onInstall() {
Marius Burkard's avatar
Marius Burkard committed
172
		$app->log('Running onInstall()', 0, false);
173
		$this->copyAddonFiles();
174 175 176
		$this->copyInterfaceFiles();
		$this->copyServerFiles();
		$this->executeSqlStatements();
Marius Burkard's avatar
Marius Burkard committed
177
		$app->log('Finished onInstall()', 0, false);
178 179 180 181 182 183 184
	}
	
	public function onAfterInstall() { }
	
	public function onBeforeUpdate() { }
	
	public function onUpdate() {
Marius Burkard's avatar
Marius Burkard committed
185
		$app->log('Running onUpdate()', 0, false);
186
		$this->copyAddonFiles();
187 188 189
		$this->copyInterfaceFiles();
		$this->copyServerFiles();
		$this->executeSqlStatements();
Marius Burkard's avatar
Marius Burkard committed
190
		$app->log('Finished onUpdate()', 0, false);
191 192 193 194 195 196
	}
	
	public function onAfterUpdate() { }
	
	
	
197
	public function onRaisedInstallerEvent($event_name, $data = false) {
198 199 200 201 202 203 204 205 206 207 208
		
	}
}

class AddonInstallerException extends Exception {
	public function __construct($message = "", $code = 0, $previous = null) {
		parent::__construct($message, $code, $previous);
	}
}

class AddonInstallerValidationException extends AddonInstallerException { }