You've already forked Atomcms-edit
398 lines
13 KiB
PowerShell
398 lines
13 KiB
PowerShell
<#
|
|
.SYNOPSIS
|
|
AtomCMS Auto Installer for Windows (XAMPP / WampServer)
|
|
.DESCRIPTION
|
|
Automates the full installation of AtomCMS on Windows.
|
|
Supports XAMPP and WampServer environments.
|
|
#>
|
|
|
|
$ErrorActionPreference = "Stop"
|
|
$Host.UI.RawUI.WindowTitle = "AtomCMS Installer"
|
|
|
|
$REPO_URL = "https://gitlab.epicnabbo.nl/RemcoEpic/atomcms-edit.git"
|
|
$DB_NAME = "habbo"
|
|
$DB_USER = "root"
|
|
$DB_PASS = ""
|
|
|
|
function Write-Logo {
|
|
Write-Host "╔══════════════════════════════════════════╗" -ForegroundColor Magenta
|
|
Write-Host "║ AtomCMS Auto Installer (Windows) ║" -ForegroundColor Magenta
|
|
Write-Host "╚══════════════════════════════════════════╝" -ForegroundColor Magenta
|
|
Write-Host ""
|
|
}
|
|
|
|
function Write-Step {
|
|
param([string]$Message)
|
|
Write-Host "[AtomCMS] $Message" -ForegroundColor Magenta
|
|
}
|
|
|
|
function Write-OK {
|
|
param([string]$Message)
|
|
Write-Host "[ OK ] $Message" -ForegroundColor Green
|
|
}
|
|
|
|
function Write-Info {
|
|
param([string]$Message)
|
|
Write-Host "[ INFO ] $Message" -ForegroundColor Cyan
|
|
}
|
|
|
|
function Write-Warn {
|
|
param([string]$Message)
|
|
Write-Host "[ WARN ] $Message" -ForegroundColor Yellow
|
|
}
|
|
|
|
function Write-Error {
|
|
param([string]$Message)
|
|
Write-Host "[FAILED] $Message" -ForegroundColor Red
|
|
exit 1
|
|
}
|
|
|
|
function Test-Admin {
|
|
$identity = [Security.Principal.WindowsIdentity]::GetCurrent()
|
|
$principal = New-Object Security.Principal.WindowsPrincipal($identity)
|
|
if (-not $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
|
|
Write-Warn "Not running as Administrator. Some operations may fail."
|
|
$continue = Read-Host "Continue anyway? (y/N)"
|
|
if ($continue -ne "y") { exit 1 }
|
|
}
|
|
}
|
|
|
|
function Find-Xampp {
|
|
$paths = @(
|
|
"C:\xampp",
|
|
"D:\xampp",
|
|
"E:\xampp",
|
|
"${env:ProgramFiles}\XAMPP",
|
|
"${env:ProgramFiles(x86)}\XAMPP"
|
|
)
|
|
foreach ($p in $paths) {
|
|
if (Test-Path "$p\php\php.exe") { return $p }
|
|
}
|
|
return $null
|
|
}
|
|
|
|
function Find-Wamp {
|
|
$paths = @(
|
|
"C:\wamp64",
|
|
"C:\wamp",
|
|
"D:\wamp64",
|
|
"D:\wamp"
|
|
)
|
|
foreach ($p in $paths) {
|
|
if (Test-Path "$p\bin\php\php8.?.?\php.exe") { return $p }
|
|
if (Test-Path "$p\bin\php\php8.??\php.exe") { return $p }
|
|
}
|
|
return $null
|
|
}
|
|
|
|
function Find-PHP {
|
|
$php = Get-Command "php.exe" -ErrorAction SilentlyContinue
|
|
if ($php) { return Split-Path $php.Source -Parent }
|
|
|
|
$xampp = Find-Xampp
|
|
if ($xampp) { return "$xampp\php" }
|
|
|
|
$wamp = Find-Wamp
|
|
if ($wamp) {
|
|
$phpDirs = Get-ChildItem "$wamp\bin\php" -Filter "php8*" -Directory | Sort-Object Name -Descending
|
|
if ($phpDirs.Count -gt 0) { return $phpDirs[0].FullName }
|
|
}
|
|
return $null
|
|
}
|
|
|
|
function Find-MySQL {
|
|
$mysql = Get-Command "mysql.exe" -ErrorAction SilentlyContinue
|
|
if ($mysql) { return Split-Path $mysql.Source -Parent }
|
|
|
|
$xampp = Find-Xampp
|
|
if ($xampp -and (Test-Path "$xampp\mysql\bin\mysql.exe")) { return "$xampp\mysql\bin" }
|
|
|
|
$wamp = Find-Wamp
|
|
if ($wamp -and (Test-Path "$wamp\bin\mariadb\*\bin\mysql.exe")) {
|
|
$dirs = Get-ChildItem "$wamp\bin\mariadb" -Directory | Sort-Object Name -Descending
|
|
if ($dirs.Count -gt 0) { return "$($dirs[0].FullName)\bin" }
|
|
}
|
|
return $null
|
|
}
|
|
|
|
function Find-Apache {
|
|
$xampp = Find-Xampp
|
|
if ($xampp -and (Test-Path "$xampp\apache\bin\httpd.exe")) { return "$xampp\apache" }
|
|
|
|
$wamp = Find-Wamp
|
|
if ($wamp -and (Test-Path "$wamp\bin\apache\*\bin\httpd.exe")) {
|
|
$dirs = Get-ChildItem "$wamp\bin\apache" -Directory | Sort-Object Name -Descending
|
|
if ($dirs.Count -gt 0) { return $dirs[0].FullName }
|
|
}
|
|
return $null
|
|
}
|
|
|
|
function Ensure-Tool {
|
|
param([string]$Name, [string]$CheckCommand, [string]$Url, [string]$InstallHint)
|
|
|
|
$found = Get-Command $CheckCommand -ErrorAction SilentlyContinue
|
|
if ($found) {
|
|
Write-OK "$Name is installed"
|
|
return $true
|
|
}
|
|
|
|
Write-Warn "$Name is not found."
|
|
if ($Url) {
|
|
Write-Info "Download from: $Url"
|
|
}
|
|
if ($InstallHint) {
|
|
Write-Info "$InstallHint"
|
|
}
|
|
return $false
|
|
}
|
|
|
|
function Install-Composer {
|
|
if (Get-Command "composer" -ErrorAction SilentlyContinue) {
|
|
Write-OK "Composer already installed"
|
|
return
|
|
}
|
|
Write-Step "Installing Composer..."
|
|
$installer = "$env:TEMP\composer-setup.php"
|
|
Invoke-WebRequest -Uri "https://getcomposer.org/installer" -OutFile $installer
|
|
php $installer --quiet --install-dir="$env:USERPROFILE\bin"
|
|
php -r "unlink('$installer');"
|
|
$env:Path += ";$env:USERPROFILE\bin"
|
|
[Environment]::SetEnvironmentVariable("Path", [Environment]::GetEnvironmentVariable("Path", "User") + ";$env:USERPROFILE\bin", "User")
|
|
Write-OK "Composer installed. You may need to restart your terminal."
|
|
}
|
|
|
|
function Clone-Project {
|
|
param([string]$TargetDir)
|
|
|
|
if (Test-Path "$TargetDir\artisan") {
|
|
Write-OK "Project already cloned at $TargetDir"
|
|
return $TargetDir
|
|
}
|
|
|
|
if (-not (Get-Command "git" -ErrorAction SilentlyContinue)) {
|
|
Write-Error "Git is not installed. Install Git for Windows: https://git-scm.com/download/win"
|
|
}
|
|
|
|
Write-Step "Cloning project..."
|
|
git clone $REPO_URL $TargetDir
|
|
Write-OK "Project cloned to $TargetDir"
|
|
return $TargetDir
|
|
}
|
|
|
|
function Configure-Env {
|
|
param([string]$ProjectDir)
|
|
|
|
Write-Step "Configuring environment..."
|
|
$envFile = "$ProjectDir\.env"
|
|
if (Test-Path $envFile) {
|
|
Write-Info ".env already exists, skipping"
|
|
return
|
|
}
|
|
|
|
Copy-Item "$ProjectDir\.env.example" $envFile
|
|
$dbPass = Read-Host "Database password (leave empty for root without password)"
|
|
|
|
(Get-Content $envFile) -replace 'DB_DATABASE=.*', "DB_DATABASE=$DB_NAME" | Set-Content $envFile
|
|
(Get-Content $envFile) -replace 'DB_USERNAME=.*', "DB_USERNAME=$DB_USER" | Set-Content $envFile
|
|
(Get-Content $envFile) -replace 'DB_PASSWORD=.*', "DB_PASSWORD=$dbPass" | Set-Content $envFile
|
|
|
|
Push-Location $ProjectDir
|
|
php artisan key:generate --quiet
|
|
Pop-Location
|
|
|
|
Write-OK ".env configured and APP_KEY generated"
|
|
}
|
|
|
|
function Create-Database {
|
|
param([string]$MySQLDir)
|
|
|
|
Write-Step "Creating database '$DB_NAME'..."
|
|
|
|
$mysqlExe = if ($MySQLDir) { "$MySQLDir\mysql.exe" } else { "mysql.exe" }
|
|
|
|
if ($DB_PASS) {
|
|
& $mysqlExe -u $DB_USER -p$DB_PASS -e "CREATE DATABASE IF NOT EXISTS `$DB_NAME` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;" 2>$null
|
|
} else {
|
|
& $mysqlExe -u $DB_USER -e "CREATE DATABASE IF NOT EXISTS `$DB_NAME` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;" 2>$null
|
|
}
|
|
|
|
if ($LASTEXITCODE -eq 0) {
|
|
Write-OK "Database '$DB_NAME' ready"
|
|
} else {
|
|
Write-Warn "Could not create database automatically."
|
|
Write-Info "Open phpMyAdmin (http://localhost/phpmyadmin) and create a database named '$DB_NAME' with charset utf8mb4_unicode_ci."
|
|
Read-Host "Press Enter after creating the database"
|
|
}
|
|
}
|
|
|
|
function Run-Migrations {
|
|
param([string]$ProjectDir)
|
|
|
|
Write-Step "Running migrations and seeders..."
|
|
Push-Location $ProjectDir
|
|
php artisan migrate --seed --force
|
|
Pop-Location
|
|
Write-OK "Migrations and seeders complete"
|
|
}
|
|
|
|
function Build-Assets {
|
|
param([string]$ProjectDir)
|
|
|
|
Write-Step "Building frontend assets..."
|
|
Push-Location $ProjectDir
|
|
yarn build:all
|
|
Pop-Location
|
|
Write-OK "Frontend assets built"
|
|
}
|
|
|
|
function Set-Permissions {
|
|
param([string]$ProjectDir)
|
|
|
|
Write-Step "Setting permissions..."
|
|
$folders = @("$ProjectDir\storage", "$ProjectDir\bootstrap\cache")
|
|
|
|
foreach ($folder in $folders) {
|
|
if (Test-Path $folder) {
|
|
try {
|
|
icacls $folder /grant "Everyone:F" /T /Q 2>$null
|
|
} catch {
|
|
Write-Warn "Could not set permissions on $folder. You may need to do this manually."
|
|
}
|
|
}
|
|
}
|
|
|
|
Write-OK "Permissions set"
|
|
}
|
|
|
|
function Configure-Apache {
|
|
param([string]$ApacheDir, [string]$ProjectDir)
|
|
|
|
Write-Step "Configuring Apache virtual host..."
|
|
|
|
$domain = Read-Host "Enter your domain name (e.g. localhost)"
|
|
$publicDir = "$ProjectDir\public".Replace("\", "/")
|
|
|
|
$vhost = @"
|
|
<VirtualHost *:80>
|
|
ServerName $domain
|
|
DocumentRoot "$publicDir"
|
|
|
|
<Directory "$publicDir">
|
|
Options Indexes FollowSymLinks
|
|
AllowOverride All
|
|
Require all granted
|
|
</Directory>
|
|
|
|
ErrorLog logs/atomcms-error.log
|
|
CustomLog logs/atomcms-access.log combined
|
|
</VirtualHost>
|
|
"@
|
|
|
|
if ($ApacheDir) {
|
|
$confFile = "$ApacheDir\conf\extra\httpd-vhosts.conf"
|
|
Add-Content -Path $confFile -Value "`n$vhost" -ErrorAction SilentlyContinue
|
|
Write-OK "Virtual host added to $confFile"
|
|
Write-Info "Make sure these lines are uncommented in httpd.conf:"
|
|
Write-Info " Include conf/extra/httpd-vhosts.conf"
|
|
Write-Info " LoadModule rewrite_module modules/mod_rewrite.so"
|
|
} else {
|
|
Write-Warn "Apache directory not found. Add this virtual host manually:"
|
|
Write-Host $vhost -ForegroundColor Gray
|
|
}
|
|
}
|
|
|
|
function Show-Summary {
|
|
param([string]$Domain)
|
|
|
|
Write-Host ""
|
|
Write-Host "╔══════════════════════════════════════════════════════════════╗" -ForegroundColor Green
|
|
Write-Host "║ AtomCMS is ready! ║" -ForegroundColor Green
|
|
Write-Host "║ ║" -ForegroundColor Green
|
|
Write-Host "║ Visit: http://$Domain ║" -ForegroundColor Green
|
|
Write-Host "║ Admin: http://$Domain/admin ║" -ForegroundColor Green
|
|
Write-Host "║ ║" -ForegroundColor Green
|
|
Write-Host "║ Run the repair tool for extra checks: ║" -ForegroundColor Green
|
|
Write-Host "║ php artisan atom:check --fix ║" -ForegroundColor Green
|
|
Write-Host "╚══════════════════════════════════════════════════════════════╝" -ForegroundColor Green
|
|
Write-Host ""
|
|
}
|
|
|
|
function Main {
|
|
Write-Logo
|
|
Test-Admin
|
|
|
|
# Check environment
|
|
$phpDir = Find-PHP
|
|
$mysqlDir = Find-MySQL
|
|
$apacheDir = Find-Apache
|
|
|
|
if (-not $phpDir) {
|
|
Write-Error "PHP not found. Install XAMPP (https://www.apachefriends.org/) or WampServer first."
|
|
}
|
|
|
|
# Add PHP and MySQL to PATH for this session
|
|
if ($phpDir) { $env:Path = "$phpDir;$env:Path" }
|
|
if ($mysqlDir) { $env:Path = "$mysqlDir;$env:Path" }
|
|
|
|
Write-OK "PHP found: $((Get-Command php).Source)"
|
|
if ($mysqlDir) { Write-OK "MySQL found: $mysqlDir" }
|
|
if ($apacheDir) { Write-OK "Apache found: $apacheDir" }
|
|
|
|
# Ensure required tools
|
|
Ensure-Tool -Name "Node.js" -CheckCommand "node" -Url "https://nodejs.org/" -InstallHint "Install Node.js LTS"
|
|
$hasYarn = Ensure-Tool -Name "Yarn" -CheckCommand "yarn" -Url "https://yarnpkg.com/getting-started/install" -InstallHint "Run: npm install -g yarn"
|
|
Ensure-Tool -Name "Git" -CheckCommand "git" -Url "https://git-scm.com/download/win" -InstallHint "Install Git for Windows"
|
|
|
|
if (-not $hasYarn) {
|
|
Write-Step "Installing Yarn via npm..."
|
|
npm install -g yarn
|
|
Write-OK "Yarn installed"
|
|
}
|
|
|
|
Install-Composer
|
|
|
|
# Where to install?
|
|
$defaultDir = if (Find-Xampp) { "$(Find-Xampp)\htdocs\atomcms" } else { "$env:USERPROFILE\atomcms" }
|
|
$projectDir = Read-Host "Installation directory [$defaultDir]"
|
|
if (-not $projectDir) { $projectDir = $defaultDir }
|
|
|
|
Clone-Project -TargetDir $projectDir
|
|
Configure-Env -ProjectDir $projectDir
|
|
|
|
# Install PHP deps
|
|
Write-Step "Installing PHP dependencies..."
|
|
Push-Location $projectDir
|
|
composer install --no-interaction --optimize-autoloader --no-dev
|
|
Pop-Location
|
|
Write-OK "PHP dependencies installed"
|
|
|
|
# Install Node deps
|
|
Write-Step "Installing Node dependencies..."
|
|
Push-Location $projectDir
|
|
yarn install --frozen-lockfile
|
|
Pop-Location
|
|
Write-OK "Node dependencies installed"
|
|
|
|
Create-Database -MySQLDir $mysqlDir
|
|
Run-Migrations -ProjectDir $projectDir
|
|
Build-Assets -ProjectDir $projectDir
|
|
Set-Permissions -ProjectDir $projectDir
|
|
|
|
$configureWeb = Read-Host "Configure Apache virtual host? (y/N)"
|
|
if ($configureWeb -eq "y") {
|
|
Configure-Apache -ApacheDir $apacheDir -ProjectDir $projectDir
|
|
}
|
|
|
|
# Finalize
|
|
Write-Step "Finalizing..."
|
|
Push-Location $projectDir
|
|
php artisan storage:link --force 2>$null
|
|
php artisan optimize:clear 2>$null
|
|
Pop-Location
|
|
|
|
$domain = Read-Host "Enter your domain/path to access the site (e.g. localhost/atomcms/public or your-domain.com)"
|
|
Show-Summary -Domain $domain
|
|
}
|
|
|
|
Main
|