checkServer();
if (!empty($errors)) {
echo strip_tags($errors) . PHP_EOL;
exit(1);
}
if ($argc <= 1 || in_array('--help', $argv) || in_array('-h', $argv)) {
echo "Evolution CMS Installer" . PHP_EOL;
echo "Usage: php install.php [options]" . PHP_EOL;
echo "Options:" . PHP_EOL;
echo " --list List available versions (branches and releases)" . PHP_EOL;
echo " --install=VERSION Install specific version (e.g., --install=\"tags/3.1.0\" or --install=\"heads/master\")" . PHP_EOL;
echo " --help, -h Show this help message" . PHP_EOL;
exit(0);
}
if (in_array('--list', $argv)) {
echo "Fetching available versions..." . PHP_EOL;
$branches = $installer->getBranches();
$releases = $installer->getReleases();
echo PHP_EOL . "Available releases:" . PHP_EOL;
foreach ($releases as $release) {
echo " tags/{$release['tag']} - {$release['name']}" . PHP_EOL;
}
echo PHP_EOL . "Available branches:" . PHP_EOL;
foreach ($branches as $branch) {
echo " heads/{$branch['tag']} - {$branch['name']}" . PHP_EOL;
}
exit(0);
}
$installVersion = null;
foreach ($argv as $arg) {
if (strpos($arg, '--install=') === 0) {
$installVersion = substr($arg, 10);
break;
}
}
if ($installVersion) {
echo "Installing Evolution CMS version: $installVersion" . PHP_EOL;
if ($installer->getArchive($installVersion)) {
echo "Installation completed successfully!" . PHP_EOL;
echo "Please navigate to the install directory to complete the setup." . PHP_EOL;
exit(0);
} else {
echo "Installation failed. Please check if the specified version exists." . PHP_EOL;
exit(1);
}
} else {
echo "No version specified. Use --install=VERSION to specify a version to install." . PHP_EOL;
exit(1);
}
}
if (!$isCli && !empty($_POST['tag']) && !$installer->getArchive($_POST['tag'])) {
print 'A non-existent tag was selected';
exit;
}
header('Content-Type: text/html; charset=utf-8');
class Installer
{
/**
* @var string
*/
protected $zipUrl = 'https://github.com/evocms-community/evolution/archive/refs/%s.zip';
/**
* @var string
*/
protected $apiUrl = 'https://api.github.com/repos/evocms-community/evolution/';
/**
* @return string
*/
public function checkServer()
{
$errors = [];
if (!extension_loaded('zip')) {
$errors[] = '
Cannot extract archives - ZIP extension is not enabled on this server.
';
}
if (!extension_loaded('curl')) {
$errors[] =
'
Cannot download files - CURL extension is not enabled on this server.
';
}
if (!is_writable(__DIR__)) {
$errors[] =
'
Cannot download files - The directory does not have write permission.
';
}
return implode($errors);
}
/**
* @param $url
*
* @return bool|string
*/
protected function curl($url)
{
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTPHEADER => [
'User-Agent: Evolution CE',
],
CURLOPT_VERBOSE => true,
CURLOPT_STDERR => $verbose = fopen('php://temp', 'w+')
]);
$result = curl_exec($ch);
if ($result === false) {
if (php_sapi_name() === 'cli') {
echo "Curl error: " . curl_error($ch) . PHP_EOL;
rewind($verbose);
$verboseLog = stream_get_contents($verbose);
echo "Verbose information:\n", htmlspecialchars($verboseLog), "\n";
}
}
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if (php_sapi_name() === 'cli') {
echo "HTTP response code: " . $httpCode . PHP_EOL;
}
curl_close($ch);
return $result;
}
/**
* @param $tag
*
* @return bool
*/
public function getArchive($tag)
{
$url = sprintf($this->zipUrl, $tag);
$tempName = '_temp' . md5(time());
$zipName = $tempName . '.zip';
$baseDir = str_replace('\\', DIRECTORY_SEPARATOR, __DIR__);
$tempDir = str_replace('\\', DIRECTORY_SEPARATOR, __DIR__) . DIRECTORY_SEPARATOR . $tempName;
if (php_sapi_name() === 'cli') {
echo "Downloading archive from $url..." . PHP_EOL;
}
$content = $this->curl($url);
if ($content === false) {
if (php_sapi_name() === 'cli') {
echo "Failed to download archive!" . PHP_EOL;
}
return false;
}
$result = file_put_contents($zipName, $content);
if ($result === false) {
if (php_sapi_name() === 'cli') {
echo "Failed to save archive to disk!" . PHP_EOL;
}
return false;
}
if (php_sapi_name() === 'cli') {
echo "Extracting files..." . PHP_EOL;
}
$zip = new ZipArchive();
if ($zip->open($baseDir . DIRECTORY_SEPARATOR . $zipName) !== true) {
if (php_sapi_name() === 'cli') {
echo "Failed to open zip archive!" . PHP_EOL;
}
return false;
}
$zip->extractTo($tempDir);
$zip->close();
if (is_file($baseDir . DIRECTORY_SEPARATOR . $zipName)) {
unlink($baseDir . DIRECTORY_SEPARATOR . $zipName);
}
$dir = '';
if ($handle = opendir($tempDir)) {
while ($name = readdir($handle)) {
if ($name === '.' || $name === '..') {
continue;
}
$dir = $name;
}
closedir($handle);
}
if (php_sapi_name() === 'cli') {
echo "Moving files to installation directory..." . PHP_EOL;
}
$this->moveFiles($tempDir . DIRECTORY_SEPARATOR . $dir, $baseDir);
$this->removeFiles($tempDir);
if (!php_sapi_name() === 'cli') {
header('Location: install/index.php');
unlink(__FILE__);
}
return true;
}
/**
* @param $dir
* @param $baseDir
*
* @return void
*/
protected function moveFiles($dir, $baseDir)
{
$dir = realpath($dir);
$baseDir = realpath($baseDir);
$iterator = new RecursiveDirectoryIterator($dir);
$files = new RecursiveIteratorIterator($iterator, RecursiveIteratorIterator::SELF_FIRST);
/**
* @var string $name
* @var SplFileInfo $file
*/
foreach ($files as $name => $file) {
$path = $baseDir . substr(dirname($name), strlen($dir));
$this->checkDir($path);
if ($file->isDir()) {
$checkDir = realpath($baseDir . substr($name, strlen($dir)));
$checkDir && $this->checkDir($checkDir);
}
if (is_writable($path) && $file->isFile()) {
rename($name, $path . '/' . basename($name));
}
}
}
/**
* @param string $folder
*
* @return void
*/
protected function checkDir($folder)
{
if (is_dir($folder)) {
return;
}
if (mkdir($folder) || is_dir($folder)) {
return;
}
throw new RuntimeException(
sprintf(
'Directory "%s" was not created',
$folder
)
);
}
/**
* @param $dir
*
* @return void
*/
protected function removeFiles($dir)
{
$iterator = new RecursiveDirectoryIterator($dir);
$files = new RecursiveIteratorIterator($iterator, RecursiveIteratorIterator::CHILD_FIRST);
/** @var SplFileInfo $file */
foreach ($files as $file) {
if ($file->getFilename() === '.' || $file->getFilename() === '..') {
continue;
}
if ($file->isDir()) {
rmdir($file->getRealPath());
} else {
unlink($file->getRealPath());
}
}
rmdir($dir);
}
/**
* Get available branches from GitHub API
*
* @return array
*/
public function getBranches()
{
$data = [];
$branches = json_decode($this->curl($this->apiUrl . 'branches'), true);
$ignore = [];
if (is_array($branches)) {
foreach ($branches as $branch) {
if (isset($branch['name']) && !in_array($branch['name'], $ignore)) {
$data[] = [
'tag' => $branch['name'],
'name' => $branch['name']
];
}
}
}
return $data;
}
/**
* Get available releases from GitHub API
*
* @return array
*/
public function getReleases()
{
$data = [];
$releases = json_decode($this->curl($this->apiUrl . 'releases'), true);
if (is_array($releases)) {
foreach ($releases as $release) {
if (isset($release['tag_name']) && isset($release['name'])) {
$data[] = [
'tag' => $release['tag_name'],
'name' => $release['name']
];
}
}
}
usort($data, function($a, $b) {
return version_compare($b['tag'], $a['tag']) * -1;
});
return $data;
}
}
if (!$isCli):
?>
EVO Installer
Evolution
Choose Evolution CMS version to install
checkServer()) {
echo $errors;
} else {
?>
Command Line Installation:
You can also install Evolution CMS using the command line:
php install.php --list - Show available versions
php install.php --install="tags/3.1.0" - Install specific release
php install.php --install="heads/master" - Install from specific branch
php install.php --help - Show help information
If you choose one of the Releases, that release will be installed. If you choose one of the Branches, the most recent DEV version in that branch will be installed.