2023-07-28 00:02:49 +08:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
declare(strict_types=1);
|
|
|
|
|
|
|
|
|
|
namespace SPC\store;
|
|
|
|
|
|
2023-08-20 19:51:45 +08:00
|
|
|
use SPC\exception\FileSystemException;
|
|
|
|
|
use SPC\exception\RuntimeException;
|
2023-07-28 00:02:49 +08:00
|
|
|
use SPC\exception\WrongUsageException;
|
|
|
|
|
|
2024-02-18 13:54:06 +08:00
|
|
|
class SourceManager
|
2023-07-28 00:02:49 +08:00
|
|
|
{
|
2023-08-20 19:51:45 +08:00
|
|
|
/**
|
|
|
|
|
* @throws WrongUsageException
|
|
|
|
|
* @throws FileSystemException
|
|
|
|
|
* @throws RuntimeException
|
|
|
|
|
*/
|
2025-03-31 16:37:24 +08:00
|
|
|
public static function initSource(?array $sources = null, ?array $libs = null, ?array $exts = null, bool $source_only = false): void
|
2023-07-28 00:02:49 +08:00
|
|
|
{
|
|
|
|
|
$sources_extracted = [];
|
|
|
|
|
// source check exist
|
|
|
|
|
if (is_array($sources)) {
|
|
|
|
|
foreach ($sources as $source) {
|
|
|
|
|
$sources_extracted[$source] = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// lib check source exist
|
|
|
|
|
if (is_array($libs)) {
|
|
|
|
|
foreach ($libs as $lib) {
|
|
|
|
|
// get source name for lib
|
|
|
|
|
$source = Config::getLib($lib, 'source');
|
|
|
|
|
$sources_extracted[$source] = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// ext check source exist
|
|
|
|
|
if (is_array($exts)) {
|
|
|
|
|
foreach ($exts as $ext) {
|
|
|
|
|
// get source name for ext
|
|
|
|
|
if (Config::getExt($ext, 'type') !== 'external') {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
$source = Config::getExt($ext, 'source');
|
|
|
|
|
$sources_extracted[$source] = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// start check
|
|
|
|
|
foreach ($sources_extracted as $source => $item) {
|
|
|
|
|
if (Config::getSource($source) === null) {
|
2023-10-14 11:22:46 +08:00
|
|
|
throw new WrongUsageException("Source [{$source}] does not exist, please check the name and correct it !");
|
2023-07-28 00:02:49 +08:00
|
|
|
}
|
2025-03-30 16:53:14 +08:00
|
|
|
// check source downloaded
|
2025-03-30 20:16:41 +08:00
|
|
|
$pre_built_name = Downloader::getPreBuiltLockName($source);
|
2025-06-18 14:05:43 +08:00
|
|
|
if ($source_only || LockFile::get($pre_built_name) === null) {
|
|
|
|
|
if (LockFile::get($source) === null) {
|
2025-03-30 16:53:14 +08:00
|
|
|
throw new WrongUsageException("Source [{$source}] not downloaded or not locked, you should download it first !");
|
|
|
|
|
}
|
|
|
|
|
$lock_name = $source;
|
|
|
|
|
} else {
|
|
|
|
|
$lock_name = $pre_built_name;
|
2023-07-28 00:02:49 +08:00
|
|
|
}
|
|
|
|
|
|
2025-06-18 14:05:43 +08:00
|
|
|
$lock_content = LockFile::get($lock_name);
|
|
|
|
|
|
2023-07-28 00:02:49 +08:00
|
|
|
// check source dir exist
|
2025-06-18 14:05:43 +08:00
|
|
|
$check = LockFile::getExtractPath($lock_name, SOURCE_PATH . '/' . $source);
|
|
|
|
|
// $check = $lock[$lock_name]['move_path'] === null ? (SOURCE_PATH . '/' . $source) : (SOURCE_PATH . '/' . $lock[$lock_name]['move_path']);
|
2023-07-28 00:02:49 +08:00
|
|
|
if (!is_dir($check)) {
|
2025-07-10 12:59:27 +08:00
|
|
|
logger()->debug("Extracting source [{$source}] to {$check} ...");
|
2025-06-18 14:05:43 +08:00
|
|
|
$filename = LockFile::getLockFullPath($lock_content);
|
|
|
|
|
FileSystem::extractSource($source, $lock_content['source_type'], $filename, $check);
|
|
|
|
|
LockFile::putLockSourceHash($lock_content, $check);
|
2025-06-14 16:09:48 +08:00
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
// if a lock file does not have hash, calculate with the current source (backward compatibility)
|
2025-06-18 14:05:43 +08:00
|
|
|
if (!isset($lock_content['hash'])) {
|
|
|
|
|
$hash = LockFile::getLockSourceHash($lock_content);
|
2023-10-15 15:45:34 +08:00
|
|
|
} else {
|
2025-06-18 14:05:43 +08:00
|
|
|
$hash = $lock_content['hash'];
|
2025-06-14 16:09:48 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// when source already extracted, detect if the extracted source hash is the same as the lock file one
|
|
|
|
|
if (file_exists("{$check}/.spc-hash") && FileSystem::readFile("{$check}/.spc-hash") === $hash) {
|
2025-07-10 12:59:27 +08:00
|
|
|
logger()->debug("Source [{$source}] already extracted in {$check}, skip !");
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ext imap was included in php < 8.4 which we should not extract,
|
|
|
|
|
// but since it's not simple to compare php version, for now we just skip it
|
|
|
|
|
if ($source === 'ext-imap') {
|
|
|
|
|
logger()->debug("Source [ext-imap] already extracted in {$check}, skip !");
|
2025-06-14 16:09:48 +08:00
|
|
|
continue;
|
2023-07-28 00:02:49 +08:00
|
|
|
}
|
2025-06-14 16:09:48 +08:00
|
|
|
|
|
|
|
|
// if not, remove the source dir and extract again
|
|
|
|
|
logger()->notice("Source [{$source}] hash mismatch, removing old source dir and extracting again ...");
|
2025-07-21 16:03:28 +07:00
|
|
|
if ($source === 'micro') {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2025-06-14 16:09:48 +08:00
|
|
|
FileSystem::removeDir($check);
|
2025-06-18 14:05:43 +08:00
|
|
|
$filename = LockFile::getLockFullPath($lock_content);
|
|
|
|
|
$move_path = LockFile::getExtractPath($lock_name, SOURCE_PATH . '/' . $source);
|
|
|
|
|
FileSystem::extractSource($source, $lock_content['source_type'], $filename, $move_path);
|
|
|
|
|
LockFile::putLockSourceHash($lock_content, $check);
|
2023-07-28 00:02:49 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|