This commit is contained in:
103
UpdateAssistant/library/Archive.php
Normal file
103
UpdateAssistant/library/Archive.php
Normal file
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
/**
|
||||
* Typecho update assistant.
|
||||
*
|
||||
* @package UpdateAssistant
|
||||
* @author mrgeneral
|
||||
* @version 1.0.1
|
||||
* @link https://www.chengxiaobai.cn
|
||||
*/
|
||||
|
||||
class Archive extends Base
|
||||
{
|
||||
protected function compress($archiveName, $targets, $workRootPath)
|
||||
{
|
||||
$archiveRealPath = rtrim($workRootPath, '/.\\') . DIRECTORY_SEPARATOR . 'archive' . DIRECTORY_SEPARATOR . 'back' . DIRECTORY_SEPARATOR . $archiveName . '.zip';
|
||||
|
||||
// cache
|
||||
if (is_file($archiveRealPath)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$archive = new ZipArchive();
|
||||
$archive->open($archiveRealPath, ZipArchive::CREATE);
|
||||
|
||||
foreach ($targets as $realPath => $realRootPath) {
|
||||
if (!is_dir($realPath)) {
|
||||
$archive->addFile($realPath, str_replace($realRootPath, '', $realPath));
|
||||
continue;
|
||||
}
|
||||
|
||||
$directoryIterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($realPath), RecursiveIteratorIterator::SELF_FIRST);
|
||||
|
||||
foreach ($directoryIterator as $fileInfo) {
|
||||
if (in_array($fileInfo->getFilename(), ['.', '..'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($fileInfo->isDir()) {
|
||||
$archive->addEmptyDir(str_replace($realRootPath, '', $fileInfo->getRealPath()));
|
||||
} else {
|
||||
$archive->addFile($fileInfo->getRealPath(), str_replace($realRootPath, '', $fileInfo->getRealPath()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$archive->close()) {
|
||||
throw new Exception('Compress failed!');
|
||||
}
|
||||
|
||||
return $archiveRealPath;
|
||||
}
|
||||
|
||||
protected function decompression($archiveName, $workRootPath)
|
||||
{
|
||||
$tmpPath = rtrim($workRootPath, '/.\\') . DIRECTORY_SEPARATOR . 'tmp' . DIRECTORY_SEPARATOR;
|
||||
$archiveRealPath = rtrim($workRootPath, '/.\\') . DIRECTORY_SEPARATOR . 'archive' . DIRECTORY_SEPARATOR . $archiveName . '.zip';
|
||||
$archive = new ZipArchive();
|
||||
|
||||
if ($archive->open($archiveRealPath) !== true) {
|
||||
throw new Exception('Open archive failed!');
|
||||
}
|
||||
|
||||
$this->clearPath($tmpPath);
|
||||
|
||||
$archive->extractTo($tmpPath);
|
||||
|
||||
if (!$archive->close()) {
|
||||
throw new Exception('Decompression failed!');
|
||||
}
|
||||
|
||||
foreach (scandir($tmpPath) as $item) {
|
||||
if (!in_array($item, ['.', '..']) && is_dir($tmpPath . $item)) {
|
||||
return $tmpPath . $item . DIRECTORY_SEPARATOR;
|
||||
}
|
||||
}
|
||||
|
||||
return $tmpPath;
|
||||
}
|
||||
|
||||
protected function clearPath($realPath)
|
||||
{
|
||||
if (!is_dir($realPath)) {
|
||||
return unlink($realPath);
|
||||
}
|
||||
|
||||
$directoryIterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($realPath), RecursiveIteratorIterator::CHILD_FIRST);
|
||||
|
||||
foreach ($directoryIterator as $fileInfo) {
|
||||
if (in_array($fileInfo->getFilename(), ['.', '..'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($fileInfo->isDir()) {
|
||||
$this->clearPath($fileInfo->getRealPath());
|
||||
rmdir($fileInfo->getRealPath());
|
||||
} elseif (substr($fileInfo->getPath(), -3) !== 'tmp') {
|
||||
unlink($fileInfo->getRealPath());
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
110
UpdateAssistant/library/Base.php
Normal file
110
UpdateAssistant/library/Base.php
Normal file
@@ -0,0 +1,110 @@
|
||||
<?php
|
||||
/**
|
||||
* Typecho update assistant.
|
||||
*
|
||||
* @package UpdateAssistant
|
||||
* @author mrgeneral
|
||||
* @version 1.0.1
|
||||
* @link https://www.chengxiaobai.cn
|
||||
*/
|
||||
|
||||
abstract class Base
|
||||
{
|
||||
protected static $instance;
|
||||
|
||||
protected $handler;
|
||||
|
||||
protected $defaultHeaders = [
|
||||
'User-Agent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3_CXB) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36',
|
||||
'Referer' => 'https://github.com/typecho/typecho',
|
||||
'Cache-Control' => 'max-age=0',
|
||||
];
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
if (!extension_loaded('zip')) {
|
||||
throw new Exception('Not found zip extension!');
|
||||
}
|
||||
|
||||
if (function_exists('curl_exec')) {
|
||||
$this->handler = 'curlHandler';
|
||||
} elseif (ini_get('allow_url_fopen')) {
|
||||
$this->handler = 'streamHandler';
|
||||
} else {
|
||||
throw new Exception('Requires cURL or set allow_url_fopen = 1 in your php.ini!');
|
||||
}
|
||||
}
|
||||
|
||||
protected static function getInstance()
|
||||
{
|
||||
if (static::$instance instanceof static) {
|
||||
return static::$instance;
|
||||
}
|
||||
|
||||
return static::$instance = new static;
|
||||
}
|
||||
|
||||
public static function __callStatic($name, $arguments)
|
||||
{
|
||||
return call_user_func_array([static::getInstance(), $name], $arguments);
|
||||
}
|
||||
|
||||
protected function curlHandler($url, $storedFileRealPath = '', $options = [], $headers = [])
|
||||
{
|
||||
$defaultOptions = [
|
||||
CURLOPT_FOLLOWLOCATION => true,
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_CONNECTTIMEOUT => 3,
|
||||
CURLOPT_TIMEOUT => 60,
|
||||
CURLOPT_HTTPHEADER => $this->buildHeaders(array_merge($this->defaultHeaders, $headers)),
|
||||
];
|
||||
|
||||
if (!empty($storedFileRealPath)) {
|
||||
$fileHandler = fopen($storedFileRealPath, 'wb+');
|
||||
$defaultOptions[CURLOPT_FILE] = $fileHandler;
|
||||
}
|
||||
|
||||
$curl = curl_init($url);
|
||||
curl_setopt_array($curl, $options + $defaultOptions);
|
||||
$result = curl_exec($curl);
|
||||
|
||||
if (curl_getinfo($curl, CURLINFO_HTTP_CODE) !== 200) {
|
||||
curl_close($curl);
|
||||
throw new Exception('Request failed, please try again!');
|
||||
}
|
||||
|
||||
curl_close($curl);
|
||||
|
||||
return empty($storedFileRealPath) ? $result : fclose($fileHandler);
|
||||
}
|
||||
|
||||
protected function streamHandler($url, $storedFileRealPath = '', $options = [], $headers = [])
|
||||
{
|
||||
$context = [
|
||||
'http' => [
|
||||
'header' => implode("\r\n", $this->buildHeaders(array_merge($this->defaultHeaders, $headers))),
|
||||
'protocol_version' => '1.1',
|
||||
'ignore_errors' => true,
|
||||
'timeout' => 60,
|
||||
'follow_location' => 5,
|
||||
],
|
||||
];
|
||||
|
||||
$streamHandler = fopen($url, 'rb', null, stream_context_create(array_merge($context, $options)));
|
||||
$result = empty($storedFileRealPath) ? stream_get_contents($streamHandler) : file_put_contents($storedFileRealPath, $streamHandler, LOCK_EX);
|
||||
fclose($streamHandler);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function buildHeaders($headers = [])
|
||||
{
|
||||
$result = [];
|
||||
|
||||
foreach ($headers as $name => $value) {
|
||||
$result[] = "$name: $value";
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
39
UpdateAssistant/library/Downloader.php
Normal file
39
UpdateAssistant/library/Downloader.php
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
/**
|
||||
* Typecho update assistant.
|
||||
*
|
||||
* @package UpdateAssistant
|
||||
* @author mrgeneral
|
||||
* @version 1.0.1
|
||||
* @link https://www.chengxiaobai.cn
|
||||
*/
|
||||
|
||||
class Downloader extends Base
|
||||
{
|
||||
protected function down($isDevelop, $archiveName, $workRootPath)
|
||||
{
|
||||
$downloadUrl = 'https://github.com/typecho/typecho/archive/master.zip';
|
||||
$archiveRealPath = rtrim($workRootPath, '/.\\') . DIRECTORY_SEPARATOR . 'archive' . DIRECTORY_SEPARATOR . $archiveName . '.zip';
|
||||
|
||||
// cache
|
||||
if (is_file($archiveRealPath)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!$isDevelop) {
|
||||
$content = $this->{$this->handler}('http://typecho.org/version.json');
|
||||
|
||||
if (empty($content)
|
||||
|| null === ($content = json_decode($content, true))
|
||||
|| empty($content['release'])
|
||||
|| empty($content['version'])
|
||||
) {
|
||||
throw new Exception('Fetch release version failed!');
|
||||
}
|
||||
|
||||
$downloadUrl = sprintf('https://github.com/typecho/typecho/archive/v%s-%s-release.zip', $content['release'], $content['version']);
|
||||
}
|
||||
|
||||
return $this->{$this->handler}($downloadUrl, $archiveRealPath);
|
||||
}
|
||||
}
|
||||
61
UpdateAssistant/library/Version.php
Normal file
61
UpdateAssistant/library/Version.php
Normal file
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
/**
|
||||
* Typecho update assistant.
|
||||
*
|
||||
* @package UpdateAssistant
|
||||
* @author mrgeneral
|
||||
* @version 1.0.1
|
||||
* @link https://www.chengxiaobai.cn
|
||||
*/
|
||||
|
||||
class Version extends Base
|
||||
{
|
||||
|
||||
protected function getVersion($isDevelop = true)
|
||||
{
|
||||
return $isDevelop ? $this->getDevelop() : $this->getRelease();
|
||||
}
|
||||
|
||||
protected function getDevelop()
|
||||
{
|
||||
$content = $this->{$this->handler}(
|
||||
'https://raw.githubusercontent.com/typecho/typecho/master/var/Typecho/Common.php',
|
||||
'',
|
||||
[],
|
||||
['Referer' => 'https://github.com/typecho/typecho/blob/master/var/Typecho/Common.php']
|
||||
);
|
||||
|
||||
if (empty($content) || !preg_match('/const VERSION = \'(\w.*)\';/', $content, $result)) {
|
||||
throw new Exception('Fetch develop version failed!');
|
||||
}
|
||||
|
||||
return $result[1];
|
||||
}
|
||||
|
||||
protected function getRelease()
|
||||
{
|
||||
$content = $this->{$this->handler}('http://typecho.org/version.json');
|
||||
|
||||
if (empty($content)
|
||||
|| null === ($content = json_decode($content, true))
|
||||
|| empty($content['release'])
|
||||
|| empty($content['version'])
|
||||
) {
|
||||
throw new Exception('Fetch release version failed!');
|
||||
}
|
||||
|
||||
return sprintf('%s/%s', $content['release'], $content['version']);
|
||||
}
|
||||
|
||||
protected function compare($currentVersion, $remoteVersion, $operator)
|
||||
{
|
||||
return version_compare(str_replace('/', '.', $currentVersion), str_replace('/', '.', $remoteVersion), $operator);
|
||||
}
|
||||
|
||||
protected function toString($version)
|
||||
{
|
||||
return implode(array_map(function ($subVersion) {
|
||||
return sprintf('%02s', $subVersion);
|
||||
}, explode('.', str_replace('/', '.', $version))));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user