Merge branch 'master' of ssh://172.20.0.1/var/git/espo/backend
This commit is contained in:
@@ -79,19 +79,6 @@ class Extension extends \Espo\Core\Controllers\Record
|
||||
return true;
|
||||
}
|
||||
|
||||
public function actionDeletePackage($params, $data, $request)
|
||||
{
|
||||
if (!$request->isPost()) {
|
||||
throw new Forbidden();
|
||||
}
|
||||
|
||||
$manager = new \Espo\Core\ExtensionManager($this->getContainer());
|
||||
|
||||
$manager->delete($data['id']);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function actionCreate()
|
||||
{
|
||||
throw new Forbidden();
|
||||
@@ -112,6 +99,15 @@ class Extension extends \Espo\Core\Controllers\Record
|
||||
throw new Forbidden();
|
||||
}
|
||||
|
||||
public function actionDelete($params, $data, $request)
|
||||
{
|
||||
$manager = new \Espo\Core\ExtensionManager($this->getContainer());
|
||||
|
||||
$manager->delete($params['id']);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function actionMassUpdate()
|
||||
{
|
||||
throw new Forbidden();
|
||||
|
||||
@@ -58,16 +58,6 @@ abstract class Base
|
||||
*/
|
||||
const SCRIPTS = 'scripts';
|
||||
|
||||
/**
|
||||
* Statuses of Extension Entity
|
||||
*/
|
||||
const DISABLED = 'Disabled';
|
||||
|
||||
/**
|
||||
* Statuses of Extension Entity
|
||||
*/
|
||||
const ENABLED = 'Enabled';
|
||||
|
||||
/**
|
||||
* Package types
|
||||
*/
|
||||
@@ -139,7 +129,7 @@ abstract class Base
|
||||
return $this->entityManager;
|
||||
}
|
||||
|
||||
protected function throwErrorWithDetelePackage($errorMessage = '')
|
||||
protected function throwErrorAndRemovePackage($errorMessage = '')
|
||||
{
|
||||
$this->deletePackageFiles();
|
||||
$this->deletePackageArchive();
|
||||
@@ -220,7 +210,7 @@ abstract class Base
|
||||
}
|
||||
}
|
||||
|
||||
$this->throwErrorWithDetelePackage('Your EspoCRM version doesn\'t match for this installation package.');
|
||||
$this->throwErrorAndRemovePackage('Your EspoCRM version doesn\'t match for this installation package.');
|
||||
}
|
||||
|
||||
protected function checkPackageType()
|
||||
@@ -232,11 +222,11 @@ abstract class Base
|
||||
$manifestType = isset($manifest['type']) ? strtolower($manifest['type']) : $this->defaultPackageType;
|
||||
|
||||
if (!in_array($manifestType, $this->packageTypes)) {
|
||||
$this->throwErrorWithDetelePackage('Unknown package type.');
|
||||
$this->throwErrorAndRemovePackage('Unknown package type.');
|
||||
}
|
||||
|
||||
if ($type != $manifestType) {
|
||||
$this->throwErrorWithDetelePackage('Wrong package type. You cannot install '.$manifestType.' package via '.ucfirst($type).' Manager.');
|
||||
$this->throwErrorAndRemovePackage('Wrong package type. You cannot install '.$manifestType.' package via '.ucfirst($type).' Manager.');
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -249,7 +239,7 @@ abstract class Base
|
||||
*/
|
||||
protected function runScript($type)
|
||||
{
|
||||
$packagePath = $this->getPath('packagePath');
|
||||
$packagePath = $this->getPackagePath();
|
||||
$scriptNames = $this->getParams('scriptNames');
|
||||
|
||||
$scriptName = $scriptNames[$type];
|
||||
@@ -262,7 +252,12 @@ abstract class Base
|
||||
if (file_exists($beforeInstallScript)) {
|
||||
require_once($beforeInstallScript);
|
||||
$script = new $scriptName();
|
||||
$script->run($this->getContainer());
|
||||
|
||||
try {
|
||||
$script->run($this->getContainer());
|
||||
} catch (\Exception $e) {
|
||||
$this->throwErrorAndRemovePackage($e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -282,6 +277,11 @@ abstract class Base
|
||||
return $path . $postfix;
|
||||
}
|
||||
|
||||
protected function getPackagePath($isPackage = false)
|
||||
{
|
||||
return $this->getPath('packagePath', $isPackage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of files defined in manifest.json
|
||||
*
|
||||
@@ -317,7 +317,7 @@ abstract class Base
|
||||
protected function getCopyFileList()
|
||||
{
|
||||
if (!isset($this->data['fileList'])) {
|
||||
$packagePath = $this->getPath('packagePath');
|
||||
$packagePath = $this->getPackagePath();
|
||||
$filesPath = Util::concatPath($packagePath, self::FILES);
|
||||
|
||||
$this->data['fileList'] = $this->getFileManager()->getFileList($filesPath, true, '', 'all', true);
|
||||
@@ -326,6 +326,17 @@ abstract class Base
|
||||
return $this->data['fileList'];
|
||||
}
|
||||
|
||||
protected function copy($sourcePath, $destPath, $recursively = false, array $fileList = null, $copyOnlyFiles = false)
|
||||
{
|
||||
try {
|
||||
$res = $this->getFileManager()->copy($sourcePath, $destPath, $recursively, $fileList, $copyOnlyFiles);
|
||||
} catch (\Exception $e) {
|
||||
$this->throwErrorAndRemovePackage($e->getMessage());
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy files from upgrade/extension package
|
||||
*
|
||||
@@ -334,31 +345,31 @@ abstract class Base
|
||||
*/
|
||||
protected function copyFiles()
|
||||
{
|
||||
$packagePath = $this->getPath('packagePath');
|
||||
$packagePath = $this->getPackagePath();
|
||||
$filesPath = Util::concatPath($packagePath, self::FILES);
|
||||
|
||||
return $this->getFileManager()->copy($filesPath, '', true);
|
||||
return $this->copy($filesPath, '', true);
|
||||
}
|
||||
|
||||
public function getManifest()
|
||||
{
|
||||
if (!isset($this->data['manifest'])) {
|
||||
$packagePath = $this->getPath('packagePath');
|
||||
$packagePath = $this->getPackagePath();
|
||||
|
||||
$manifestPath = Util::concatPath($packagePath, $this->manifestName);
|
||||
if (!file_exists($manifestPath)) {
|
||||
throw new Error('It\'s not an Installation package.');
|
||||
$this->throwErrorAndRemovePackage('It\'s not an Installation package.');
|
||||
}
|
||||
|
||||
$manifestJson = $this->getFileManager()->getContents($manifestPath);
|
||||
$this->data['manifest'] = Json::decode($manifestJson, true);
|
||||
|
||||
if (!$this->data['manifest']) {
|
||||
throw new Error('Syntax error in manifest.json.');
|
||||
$this->throwErrorAndRemovePackage('Syntax error in manifest.json.');
|
||||
}
|
||||
|
||||
if (!$this->checkManifest($this->data['manifest'])) {
|
||||
throw new Error('Unsupported package.');
|
||||
$this->throwErrorAndRemovePackage('Unsupported package.');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -392,10 +403,14 @@ abstract class Base
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function unzipArchive()
|
||||
protected function unzipArchive($packagePath = null)
|
||||
{
|
||||
$packagePath = $this->getPath('packagePath');
|
||||
$packageArchivePath = $this->getPath('packagePath', true);
|
||||
$packagePath = isset($packagePath) ? $packagePath : $this->getPackagePath();
|
||||
$packageArchivePath = $this->getPackagePath(true);
|
||||
|
||||
if (!file_exists($packageArchivePath)) {
|
||||
throw new Error('Package Archive doesn\'t exist.');
|
||||
}
|
||||
|
||||
$res = $this->getZipUtil()->unzip($packageArchivePath, $packagePath);
|
||||
if ($res === false) {
|
||||
@@ -410,7 +425,7 @@ abstract class Base
|
||||
*/
|
||||
protected function deletePackageFiles()
|
||||
{
|
||||
$packagePath = $this->getPath('packagePath');
|
||||
$packagePath = $this->getPackagePath();
|
||||
$res = $this->getFileManager()->removeInDir($packagePath, true);
|
||||
|
||||
return $res;
|
||||
@@ -423,7 +438,7 @@ abstract class Base
|
||||
*/
|
||||
protected function deletePackageArchive()
|
||||
{
|
||||
$packageArchive = $this->getPath('packagePath', true);
|
||||
$packageArchive = $this->getPackagePath(true);
|
||||
$res = $this->getFileManager()->removeFile($packageArchive);
|
||||
|
||||
return $res;
|
||||
|
||||
@@ -46,7 +46,7 @@ class Delete extends \Espo\Core\Upgrades\Actions\Base
|
||||
|
||||
protected function deletePackage()
|
||||
{
|
||||
$packageArchivePath = $this->getPath('packagePath', true);
|
||||
$packageArchivePath = $this->getPackagePath(true);
|
||||
$res = $this->getFileManager()->removeFile($packageArchivePath);
|
||||
|
||||
return $res;
|
||||
|
||||
@@ -26,6 +26,13 @@ use Espo\Core\Exceptions\Error;
|
||||
|
||||
class Install extends \Espo\Core\Upgrades\Actions\Base
|
||||
{
|
||||
/**
|
||||
* Is copied extension files to Espo
|
||||
*
|
||||
* @var [type]
|
||||
*/
|
||||
protected $isCopied = null;
|
||||
|
||||
/**
|
||||
* Main installation process
|
||||
*
|
||||
@@ -42,8 +49,10 @@ class Install extends \Espo\Core\Upgrades\Actions\Base
|
||||
|
||||
$this->setProcessId($processId);
|
||||
|
||||
$this->isCopied = false;
|
||||
|
||||
/** check if an archive is unzipped, if no then unzip */
|
||||
$packagePath = $this->getPath('packagePath');
|
||||
$packagePath = $this->getPackagePath();
|
||||
if (!file_exists($packagePath)) {
|
||||
$this->unzipArchive();
|
||||
$this->isAcceptable();
|
||||
@@ -56,16 +65,17 @@ class Install extends \Espo\Core\Upgrades\Actions\Base
|
||||
|
||||
/* remove files defined in a manifest */
|
||||
if (!$this->deleteFiles()) {
|
||||
throw new Error('Permission denied to delete files.');
|
||||
$this->throwErrorAndRemovePackage('Permission denied to delete files.');
|
||||
}
|
||||
|
||||
/* copy files from directory "Files" to EspoCRM files */
|
||||
if (!$this->copyFiles()) {
|
||||
throw new Error('Cannot copy files.');
|
||||
$this->throwErrorAndRemovePackage('Cannot copy files.');
|
||||
}
|
||||
$this->isCopied = true;
|
||||
|
||||
if (!$this->systemRebuild()) {
|
||||
throw new Error('Error occurred while EspoCRM rebuild.');
|
||||
$this->throwErrorAndRemovePackage('Error occurred while EspoCRM rebuild.');
|
||||
}
|
||||
|
||||
/* run before install script */
|
||||
@@ -78,4 +88,25 @@ class Install extends \Espo\Core\Upgrades\Actions\Base
|
||||
|
||||
$GLOBALS['log']->debug('Installation process ['.$processId.']: end run.');
|
||||
}
|
||||
|
||||
protected function restoreFiles()
|
||||
{
|
||||
$backupPath = $this->getPath('backupPath');
|
||||
|
||||
$res = true;
|
||||
if ($this->isCopied) {
|
||||
$res &= $this->copy(array($backupPath, self::FILES), '', true);
|
||||
$GLOBALS['log']->info('Restore: copy back');
|
||||
}
|
||||
|
||||
$res &= $this->getFileManager()->removeInDir($backupPath, true);
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
protected function throwErrorAndRemovePackage($errorMessage = '')
|
||||
{
|
||||
$this->restoreFiles();
|
||||
parent::throwErrorAndRemovePackage($errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,8 @@
|
||||
|
||||
namespace Espo\Core\Upgrades\Actions\Base;
|
||||
|
||||
use Espo\Core\Exceptions\Error;
|
||||
use Espo\Core\Exceptions\Error,
|
||||
Espo\Core\Utils\Util;
|
||||
|
||||
class Uninstall extends \Espo\Core\Upgrades\Actions\Base
|
||||
{
|
||||
@@ -41,14 +42,18 @@ class Uninstall extends \Espo\Core\Upgrades\Actions\Base
|
||||
/* run before install script */
|
||||
$this->runScript('beforeUninstall');
|
||||
|
||||
/* remove extension files, saved in fileList */
|
||||
if (!$this->deleteFiles()) {
|
||||
throw new Error('Permission denied to delete files.');
|
||||
}
|
||||
$backupPath = $this->getPath('backupPath');
|
||||
if (file_exists($backupPath)) {
|
||||
|
||||
/* copy core files */
|
||||
if (!$this->copyFiles()) {
|
||||
throw new Error('Cannot copy files.');
|
||||
/* remove extension files, saved in fileList */
|
||||
if (!$this->deleteFiles()) {
|
||||
throw new Error('Permission denied to delete files.');
|
||||
}
|
||||
|
||||
/* copy core files */
|
||||
if (!$this->copyFiles()) {
|
||||
throw new Error('Cannot copy files.');
|
||||
}
|
||||
}
|
||||
|
||||
if (!$this->systemRebuild()) {
|
||||
@@ -72,10 +77,25 @@ class Uninstall extends \Espo\Core\Upgrades\Actions\Base
|
||||
return $extensionEntity->get('fileList');
|
||||
}
|
||||
|
||||
protected function restoreFiles()
|
||||
{
|
||||
$packagePath = $this->getPath('packagePath');
|
||||
$filesPath = Util::concatPath($packagePath, self::FILES);
|
||||
|
||||
if (!file_exists($filesPath)) {
|
||||
$this->unzipArchive($packagePath);
|
||||
}
|
||||
|
||||
$res = $this->copy($filesPath, '', true);
|
||||
$res &= $this->getFileManager()->removeInDir($packagePath, true);
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
protected function copyFiles()
|
||||
{
|
||||
$backupPath = $this->getPath('backupPath');
|
||||
$res = $this->getFileManager()->copy(array($backupPath, self::FILES), '', true);
|
||||
$res = $this->copy(array($backupPath, self::FILES), '', true);
|
||||
|
||||
return $res;
|
||||
}
|
||||
@@ -86,10 +106,13 @@ class Uninstall extends \Espo\Core\Upgrades\Actions\Base
|
||||
* @param string $processId
|
||||
* @return string
|
||||
*/
|
||||
protected function getPath($name = 'packagePath', $isPackage = false)
|
||||
protected function getPackagePath($isPackage = false)
|
||||
{
|
||||
$name = ($name == 'packagePath') ? 'backupPath' : $name;
|
||||
return parent::getPath($name, $isPackage);
|
||||
if ($isPackage) {
|
||||
return $this->getPath('packagePath', $isPackage);
|
||||
}
|
||||
|
||||
return $this->getPath('backupPath');
|
||||
}
|
||||
|
||||
protected function deletePackageFiles()
|
||||
@@ -100,4 +123,10 @@ class Uninstall extends \Espo\Core\Upgrades\Actions\Base
|
||||
return $res;
|
||||
}
|
||||
|
||||
protected function throwErrorAndRemovePackage($errorMessage = '')
|
||||
{
|
||||
$this->restoreFiles();
|
||||
throw new Error($errorMessage);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -38,8 +38,8 @@ class Upload extends \Espo\Core\Upgrades\Actions\Base
|
||||
|
||||
$GLOBALS['log']->debug('Installation process ['.$processId.']: start upload the package.');
|
||||
|
||||
$packagePath = $this->getPath('packagePath');
|
||||
$packageArchivePath = $this->getPath('packagePath', true);
|
||||
$packagePath = $this->getPackagePath();
|
||||
$packageArchivePath = $this->getPackagePath(true);
|
||||
|
||||
if (!empty($data)) {
|
||||
list($prefix, $contents) = explode(',', $data);
|
||||
|
||||
@@ -58,12 +58,6 @@ class Delete extends \Espo\Core\Upgrades\Actions\Base\Delete
|
||||
throw new Error('Extension Entity not found.');
|
||||
}
|
||||
$this->setExtensionEntity($extensionEntity);
|
||||
|
||||
/** check if extension archive exsists */
|
||||
$packageArchivePath = $this->getPath('packagePath', true);
|
||||
if (!file_exists($packageArchivePath)) {
|
||||
throw new Error('Extension Archive doesn\'t exist.');
|
||||
}
|
||||
}
|
||||
|
||||
protected function afterRunAction()
|
||||
|
||||
@@ -51,11 +51,24 @@ class Install extends \Espo\Core\Upgrades\Actions\Base\Install
|
||||
$fileList = $this->getCopyFileList();
|
||||
$backupPath = $this->getPath('backupPath');
|
||||
|
||||
$res = $this->getFileManager()->copy('', array($backupPath, self::FILES), false, $fileList);
|
||||
$res = $this->copy('', array($backupPath, self::FILES), false, $fileList);
|
||||
|
||||
/** copy scripts files */
|
||||
$packagePath = $this->getPath('packagePath');
|
||||
$res &= $this->getFileManager()->copy(array($packagePath, self::SCRIPTS), array($backupPath, self::SCRIPTS), true);
|
||||
$packagePath = $this->getPackagePath();
|
||||
$res &= $this->copy(array($packagePath, self::SCRIPTS), array($backupPath, self::SCRIPTS), true);
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
protected function restoreFiles()
|
||||
{
|
||||
$res = true;
|
||||
if ($this->isCopied) {
|
||||
$extensionFileList = $this->getCopyFileList();
|
||||
$res &= $this->getFileManager()->remove($extensionFileList);
|
||||
}
|
||||
|
||||
$res &= parent::restoreFiles();
|
||||
|
||||
return $res;
|
||||
}
|
||||
@@ -125,7 +138,11 @@ class Install extends \Espo\Core\Upgrades\Actions\Base\Install
|
||||
protected function storeExtension()
|
||||
{
|
||||
$entityManager = $this->getEntityManager();
|
||||
$extensionEntity = $entityManager->getEntity('Extension');
|
||||
|
||||
$extensionEntity = $entityManager->getEntity('Extension', $this->getProcessId());
|
||||
if (!isset($extensionEntity)) {
|
||||
$extensionEntity = $entityManager->getEntity('Extension');
|
||||
}
|
||||
|
||||
$manifest = $this->getManifest();
|
||||
$fileList = $this->getCopyFileList();
|
||||
@@ -133,7 +150,6 @@ class Install extends \Espo\Core\Upgrades\Actions\Base\Install
|
||||
$data = array(
|
||||
'id' => $this->getProcessId(),
|
||||
'name' => $manifest['name'],
|
||||
'status' => self::ENABLED,
|
||||
'isInstalled' => true,
|
||||
'version' => $manifest['version'],
|
||||
'fileList' => $fileList,
|
||||
@@ -157,10 +173,26 @@ class Install extends \Espo\Core\Upgrades\Actions\Base\Install
|
||||
if (isset($extensionEntity)) {
|
||||
$comparedVersion = version_compare($manifest['version'], $extensionEntity->get('version'));
|
||||
if ($comparedVersion <= 0) {
|
||||
$this->throwErrorWithDetelePackage('You cannot install an older version of this extension.');
|
||||
$this->throwErrorAndRemovePackage('You cannot install an older version of this extension.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Throw an exception and remove package files.
|
||||
* Redeclared to prevent of deleting a package of installed extension.
|
||||
*
|
||||
* @param string $errorMessage [description]
|
||||
* @return [type] [description]
|
||||
*/
|
||||
protected function throwErrorAndRemovePackage($errorMessage = '')
|
||||
{
|
||||
if (!$this->isNew()) {
|
||||
throw new Error($errorMessage);
|
||||
}
|
||||
|
||||
return parent::throwErrorAndRemovePackage($errorMessage);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -58,12 +58,6 @@ class Uninstall extends \Espo\Core\Upgrades\Actions\Base\Uninstall
|
||||
throw new Error('Extension Entity not found.');
|
||||
}
|
||||
$this->setExtensionEntity($extensionEntity);
|
||||
|
||||
/** check if backup of the extension exsists */
|
||||
$backupPath = $this->getPath('backupPath');
|
||||
if (!file_exists($backupPath)) {
|
||||
throw new Error('Backup files don\'t exist.');
|
||||
}
|
||||
}
|
||||
|
||||
protected function afterRunAction()
|
||||
@@ -71,7 +65,6 @@ class Uninstall extends \Espo\Core\Upgrades\Actions\Base\Uninstall
|
||||
/** Set extension entity, isInstalled = false */
|
||||
$extensionEntity = $this->getExtensionEntity();
|
||||
|
||||
$extensionEntity->set('status', self::DISABLED);
|
||||
$extensionEntity->set('isInstalled', false);
|
||||
$this->getEntityManager()->saveEntity($extensionEntity);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user