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.