* Fix bug#34221, install/disable/uninstall extension error.

This commit is contained in:
chaideqing
2023-05-25 09:21:11 +08:00
parent 232c0dd98c
commit 91cae60535
+99 -77
View File
@@ -19,7 +19,7 @@ class extensionModel extends model
/** /**
* The api root. * The api root.
* *
* @var string * @var string
* @access public * @access public
*/ */
public $apiRoot; public $apiRoot;
@@ -51,7 +51,7 @@ class extensionModel extends model
/** /**
* Fetch data from an api. * Fetch data from an api.
* *
* @param string $url * @param string $url
* @access public * @access public
* @return mixed * @return mixed
*/ */
@@ -88,8 +88,11 @@ class extensionModel extends model
/** /**
* Get extensions by some condition. * Get extensions by some condition.
* *
* @param string $type * @param string $type
* @param mixed $param * @param string $param
* @param int $recTotal
* @param int $recPerPage
* @param int $pageID
* @access public * @access public
* @return array|bool * @return array|bool
*/ */
@@ -112,9 +115,9 @@ class extensionModel extends model
/** /**
* Get versions for some extensions. * Get versions for some extensions.
* *
* @param string $extensions * @param string $extensions
* @access public * @access public
* @return array|bool * @return array|false
*/ */
public function getVersionsByAPI($extensions) public function getVersionsByAPI($extensions)
{ {
@@ -128,7 +131,7 @@ class extensionModel extends model
/** /**
* Check incompatible extension * Check incompatible extension
* *
* @param array $versions * @param array $versions
* @access public * @access public
* @return array * @return array
*/ */
@@ -144,7 +147,7 @@ class extensionModel extends model
/** /**
* Get extensions by status. * Get extensions by status.
* *
* @param string $status * @param string $status
* @access public * @access public
* @return array * @return array
*/ */
@@ -161,7 +164,7 @@ class extensionModel extends model
/** /**
* Get extension info from database. * Get extension info from database.
* *
* @param string $extension * @param string $extension
* @access public * @access public
* @return object * @return object
*/ */
@@ -173,7 +176,7 @@ class extensionModel extends model
/** /**
* Get info of an extension from the package file. * Get info of an extension from the package file.
* *
* @param string $extension * @param string $extension
* @access public * @access public
* @return object * @return object
*/ */
@@ -204,7 +207,7 @@ class extensionModel extends model
/** /**
* Parse extension's config file. * Parse extension's config file.
* *
* @param string $extension * @param string $extension
* @access public * @access public
* @return object * @return object
*/ */
@@ -245,7 +248,7 @@ class extensionModel extends model
/** /**
* Get the full path of the zip file of a extension. * Get the full path of the zip file of a extension.
* *
* @param string $extension * @param string $extension
* @access public * @access public
* @return string * @return string
*/ */
@@ -257,7 +260,7 @@ class extensionModel extends model
/** /**
* Get paths from an extension package. * Get paths from an extension package.
* *
* @param string $extension * @param string $extension
* @access public * @access public
* @return array * @return array
*/ */
@@ -290,7 +293,7 @@ class extensionModel extends model
/** /**
* Get all files from a package. * Get all files from a package.
* *
* @param string $extension * @param string $extension
* @access public * @access public
* @return array * @return array
*/ */
@@ -304,7 +307,7 @@ class extensionModel extends model
/** /**
* Get the extension's condition. * Get the extension's condition.
* *
* @param string $extenstion * @param string $extenstion
* @access public * @access public
* @return object * @return object
*/ */
@@ -330,7 +333,7 @@ class extensionModel extends model
/** /**
* Process license. If is opensource return the full text of it. * Process license. If is opensource return the full text of it.
* *
* @param string $license * @param string $license
* @access public * @access public
* @return string * @return string
*/ */
@@ -347,10 +350,10 @@ class extensionModel extends model
/** /**
* Get hook file for install or uninstall. * Get hook file for install or uninstall.
* *
* @param string $extension * @param string $extension
* @param string $hook preinstall|postinstall|preuninstall|postuninstall * @param string $hook preinstall|postinstall|preuninstall|postuninstall
* @access public * @access public
* @return string|bool * @return string|false
*/ */
public function getHookFile($extension, $hook) public function getHookFile($extension, $hook)
{ {
@@ -362,8 +365,8 @@ class extensionModel extends model
/** /**
* Get the install db file. * Get the install db file.
* *
* @param string $extension * @param string $extension
* @param string $method * @param string $method
* @access public * @access public
* @return string * @return string
*/ */
@@ -376,7 +379,7 @@ class extensionModel extends model
* Check the download path. * Check the download path.
* *
* @access public * @access public
* @return object the check result. * @return object the check result.
*/ */
public function checkDownloadPath() public function checkDownloadPath()
{ {
@@ -411,21 +414,21 @@ class extensionModel extends model
/** /**
* Check extension files. * Check extension files.
* *
* @param string $extension * @param string $extension
* @access public * @access public
* @return object the check result. * @return object the check result.
*/ */
public function checkExtensionPaths($extension) public function checkExtensionPaths($extension)
{ {
$return = new stdclass(); $checkResult = new stdclass();
$return->result = 'ok'; $checkResult->result = 'ok';
$return->errors = ''; $checkResult->errors = '';
$return->mkdirCommands = ''; $checkResult->mkdirCommands = '';
$return->chmodCommands = ''; $checkResult->chmodCommands = '';
$return->dirs2Created = array(); $checkResult->dirs2Created = array();
$appRoot = $this->app->getAppRoot(); $appRoot = $this->app->getAppRoot();
$paths = $this->getPathsFromPackage($extension); $paths = $this->getPathsFromPackage($extension);
foreach($paths as $path) foreach($paths as $path)
{ {
if($path == 'db' or $path == 'doc' or $path == 'hook') continue; if($path == 'db' or $path == 'doc' or $path == 'hook') continue;
@@ -434,38 +437,42 @@ class extensionModel extends model
{ {
if(!is_writable($path)) if(!is_writable($path))
{ {
$return->errors .= sprintf($this->lang->extension->errorTargetPathNotWritable, $path) . '<br />'; $checkResult->errors .= sprintf($this->lang->extension->errorTargetPathNotWritable, $path) . '<br />';
$return->chmodCommands .= "sudo chmod -R 777 $path<br />"; $checkResult->chmodCommands .= "sudo chmod -R 777 $path<br />";
} }
} }
else else
{ {
$parentDir = mb_substr($path, 0, strripos($path, '/')); $parentDir = mb_substr($path, 0, strripos($path, '/'));
if(!is_dir($path) and !mkdir($path, 0777, true))
{
$return->errors .= sprintf($this->lang->extension->errorTargetPathNotExists, $path) . '<br />';
$return->mkdirCommands .= "sudo mkdir -p $path<br />";
}
if(!is_writable($parentDir)) if(!is_writable($parentDir))
{ {
$return->errors .= sprintf($this->lang->extension->errorTargetPathNotWritable, $path) . '<br />'; $checkResult->errors .= sprintf($this->lang->extension->errorTargetPathNotWritable, $path) . '<br />';
$return->chmodCommands .= "sudo chmod -R 777 $path<br />"; $checkResult->chmodCommands .= "sudo chmod -R 777 $path<br />";
$checkResult->errors .= sprintf($this->lang->extension->errorTargetPathNotExists, $path) . '<br />';
$checkResult->mkdirCommands .= "sudo mkdir -p $path<br />";
} }
$return->dirs2Created[] = $path; else if(!mkdir($path, 0777, true))
{
$checkResult->errors .= sprintf($this->lang->extension->errorTargetPathNotExists, $path) . '<br />';
$checkResult->mkdirCommands .= "sudo mkdir -p $path<br />";
}
$checkResult->dirs2Created[] = $path;
} }
} }
if($return->errors) $return->result = 'fail'; if($checkResult->errors) $checkResult->result = 'fail';
$return->mkdirCommands = empty($return->mkdirCommands) ? '' : '<code>' . str_replace('/', DIRECTORY_SEPARATOR, $return->mkdirCommands) . '</code>';
$return->errors .= $this->lang->extension->executeCommands . $return->mkdirCommands; $checkResult->mkdirCommands = empty($checkResult->mkdirCommands) ? '' : '<code>' . str_replace('/', DIRECTORY_SEPARATOR, $checkResult->mkdirCommands) . '</code>';
if(PHP_OS == 'Linux') $return->errors .= empty($return->chmodCommands) ? '' : '<code>' . $return->chmodCommands . '</code>'; $checkResult->errors .= $this->lang->extension->executeCommands . $checkResult->mkdirCommands;
return $return; if(PHP_OS == 'Linux') $checkResult->errors .= empty($checkResult->chmodCommands) ? '' : '<code>' . $checkResult->chmodCommands . '</code>';
return $checkResult;
} }
/** /**
* Check the extension's version is compatibility for zentao version * Check the extension's version is compatibility for zentao version
* *
* @param string $version * @param string $version
* @access public * @access public
* @return bool * @return bool
*/ */
@@ -480,9 +487,7 @@ class extensionModel extends model
/** /**
* Check files in the package conflicts with exists files or not. * Check files in the package conflicts with exists files or not.
* *
* @param string $extension * @param string $extension
* @param string $type
* @param bool $isCheck
* @access public * @access public
* @return object * @return object
*/ */
@@ -508,7 +513,7 @@ class extensionModel extends model
/** /**
* Extract an extension. * Extract an extension.
* *
* @param string $extension * @param string $extension
* @access public * @access public
* @return object * @return object
*/ */
@@ -572,9 +577,9 @@ class extensionModel extends model
/** /**
* Remove an extension. * Remove an extension.
* *
* @param string $extension * @param string $extension
* @access public * @access public
* @return array the remove commands need executed manually. * @return array the remove commands need executed manually.
*/ */
public function removePackage($extension) public function removePackage($extension)
{ {
@@ -583,7 +588,7 @@ class extensionModel extends model
$dirs = json_decode($extension->dirs); $dirs = json_decode($extension->dirs);
$files = json_decode($extension->files); $files = json_decode($extension->files);
$appRoot = $this->app->getAppRoot(); $appRoot = $this->app->getAppRoot();
$removeCommands = array(); $commandTips = array();
/* Remove files first. */ /* Remove files first. */
if($files) if($files)
@@ -593,13 +598,18 @@ class extensionModel extends model
$file = $appRoot . $file; $file = $appRoot . $file;
if(!file_exists($file)) continue; if(!file_exists($file)) continue;
if(!is_writable($file) or @md5_file($file) != $savedMD5) $parentDir = mb_substr($file, 0, strripos($file, '/'));
if(!is_writable($file) || !is_writable($parentDir))
{ {
$removeCommands[] = PHP_OS == 'Linux' ? "rm -fr $file #changed" : "del $file :changed"; $commandTips[] = PHP_OS == 'Linux' ? "sudo rm -fr $file" : "del $file";
} }
elseif(!is_writable($file) or !@unlink($file)) elseif(@md5_file($file) != $savedMD5)
{ {
$removeCommands[] = PHP_OS == 'Linux' ? "rm -fr $file" : "del $file"; $commandTips[] = PHP_OS == 'Linux' ? "sudo rm -fr $file #changed" : "del $file :changed";
}
elseif(!@unlink($file))
{
$commandTips[] = PHP_OS == 'Linux' ? "sudo rm -fr $file" : "del $file";
} }
} }
} }
@@ -610,15 +620,25 @@ class extensionModel extends model
rsort($dirs); // remove from the lower level directory. rsort($dirs); // remove from the lower level directory.
foreach($dirs as $dir) foreach($dirs as $dir)
{ {
if(!is_dir($appRoot . $dir)) continue; $path = $appRoot . $dir;
if(!is_writable($appRoot . $dir) or !rmdir($appRoot . $dir)) $removeCommands[] = PHP_OS == 'Linux' ? "rm -fr $appRoot$dir" : "rmdir $appRoot$dir /s /q"; if(!is_dir($path)) continue;
$parentDir = mb_substr($path, 0, strripos($path, '/'));
if(!is_writable($path) || !is_writable($parentDir))
{
$commandTips[] = PHP_OS == 'Linux' ? "sudo rm -fr $appRoot$dir" : "rmdir $appRoot$dir /s /q";
}
elseif(!rmdir($appRoot . $dir))
{
$commandTips[] = PHP_OS == 'Linux' ? "sudo rm -fr $appRoot$dir" : "rmdir $appRoot$dir /s /q";
}
} }
} }
/* Clean model cache files. */ /* Clean model cache files. */
$this->cleanModelCache(); $this->cleanModelCache();
return $removeCommands; return $commandTips;
} }
/** /**
@@ -647,9 +667,9 @@ class extensionModel extends model
/** /**
* Erase an extension's package file. * Erase an extension's package file.
* *
* @param string $extension * @param string $extension
* @access public * @access public
* @return array the remove commands need executed manually. * @return array the remove commands need executed manually.
*/ */
public function erasePackage($extension) public function erasePackage($extension)
{ {
@@ -678,8 +698,8 @@ class extensionModel extends model
/** /**
* Judge need execute db install or not. * Judge need execute db install or not.
* *
* @param string $extension * @param string $extension
* @param string $method * @param string $method
* @access public * @access public
* @return bool * @return bool
*/ */
@@ -692,6 +712,7 @@ class extensionModel extends model
* Install the db. * Install the db.
* *
* @param int $extension * @param int $extension
* @param string $method
* @access public * @access public
* @return object * @return object
*/ */
@@ -732,9 +753,9 @@ class extensionModel extends model
/** /**
* Backup db when uninstall extension. * Backup db when uninstall extension.
* *
* @param string $extension * @param string $extension
* @access public * @access public
* @return bool|string * @return string|false
*/ */
public function backupDB($extension) public function backupDB($extension)
{ {
@@ -769,8 +790,8 @@ class extensionModel extends model
/** /**
* Save the extension to database. * Save the extension to database.
* *
* @param string $extension the extension code * @param string $extension the extension code
* @param string $type the extension type * @param string $type the extension type
* @access public * @access public
* @return void * @return void
*/ */
@@ -778,6 +799,7 @@ class extensionModel extends model
{ {
$code = $extension; $code = $extension;
$extension = $this->getInfoFromPackage($extension); $extension = $this->getInfoFromPackage($extension);
$extension->status = 'available'; $extension->status = 'available';
$extension->code = $code; $extension->code = $code;
$extension->type = empty($type) ? $extension->type : $type; $extension->type = empty($type) ? $extension->type : $type;
@@ -789,8 +811,8 @@ class extensionModel extends model
/** /**
* Update an extension. * Update an extension.
* *
* @param string $extension * @param string $extension
* @param array|object $data * @param array|object $data
* @access public * @access public
* @return int * @return int
*/ */
@@ -827,7 +849,7 @@ class extensionModel extends model
/** /**
* Check depends extension. * Check depends extension.
* *
* @param string $extension * @param string $extension
* @access public * @access public
* @return array * @return array
*/ */
@@ -850,11 +872,11 @@ class extensionModel extends model
/** /**
* Compare for limit data. * Compare for limit data.
* *
* @param string $version * @param string $version
* @param array $limit * @param array|string $limit
* @param string $type * @param string $type
* @access public * @access public
* @return void * @return bool
*/ */
public function compare4Limit($version, $limit, $type = 'between') public function compare4Limit($version, $limit, $type = 'between')
{ {
@@ -916,7 +938,7 @@ class extensionModel extends model
/** /**
* Get plugins that are about to expire or have expired. * Get plugins that are about to expire or have expired.
* *
* @param bool $category * @param bool $category
* @access public * @access public
* @return array * @return array
*/ */