📄 install.php
📁 Path: /home/skhata/chandrasons.com/install.php
📊 Size: 14.79 KB
🔒 Perm: 0644
📝 MIME: text/x-php
<?php
/**
* ═══════════════════════════════════════════════════════════════════
* Chandra & Sons Pharma — cPanel Web Installer
*
* USAGE:
* 1. Upload the full project zip and extract into your cPanel domain folder
* 2. Open https://yourdomain.com/install.php in your browser
* 3. Fill in DB credentials and click Install
* 4. DELETE this file immediately after installation!
* ═══════════════════════════════════════════════════════════════════
*/
define('BASEPATH', __DIR__);
$step = $_POST['step'] ?? 'form';
$errors = [];
$success = [];
// ── helpers ──────────────────────────────────────────────────────────
function rchmod(string $path, int $dirMode, int $fileMode): void {
if (is_dir($path)) {
chmod($path, $dirMode);
foreach (scandir($path) as $item) {
if ($item === '.' || $item === '..') continue;
rchmod($path . DIRECTORY_SEPARATOR . $item, $dirMode, $fileMode);
}
} else {
chmod($path, $fileMode);
}
}
function genKey(): string {
return 'base64:' . base64_encode(random_bytes(32));
}
function writeEnv(array $cfg): void {
$tpl = file_get_contents(BASEPATH . '/.env.example');
$map = [
'your_db_name' => $cfg['db_name'],
'your_db_user' => $cfg['db_user'],
'your_db_password' => $cfg['db_pass'],
'https://chandrasons.com' => rtrim($cfg['app_url'], '/'),
'APP_KEY=' => 'APP_KEY=' . genKey(),
'APP_DEBUG=false' => 'APP_DEBUG=false',
'admin@chandrasons.com' => $cfg['admin_email'],
'Admin@1234' => $cfg['admin_pass'],
];
foreach ($map as $search => $replace) {
$tpl = str_replace($search, $replace, $tpl);
}
if (!empty($cfg['db_host'])) {
$tpl = preg_replace('/^DB_HOST=.*/m', 'DB_HOST=' . $cfg['db_host'], $tpl);
}
file_put_contents(BASEPATH . '/.env', $tpl);
}
function runArtisan(string $cmd): array {
$php = PHP_BINARY;
$art = BASEPATH . '/artisan';
$output = [];
$code = 0;
exec("$php $art $cmd 2>&1", $output, $code);
return ['ok' => $code === 0, 'out' => implode("\n", $output)];
}
// ── process install ───────────────────────────────────────────────────
if ($step === 'install') {
$cfg = [
'app_url' => trim($_POST['app_url'] ?? ''),
'db_host' => trim($_POST['db_host'] ?? 'localhost'),
'db_name' => trim($_POST['db_name'] ?? ''),
'db_user' => trim($_POST['db_user'] ?? ''),
'db_pass' => trim($_POST['db_pass'] ?? ''),
'admin_email'=> trim($_POST['admin_email']?? 'admin@chandrasons.com'),
'admin_pass' => trim($_POST['admin_pass'] ?? 'Admin@1234'),
];
// Validate
if (empty($cfg['app_url'])) $errors[] = 'App URL is required.';
if (empty($cfg['db_name'])) $errors[] = 'Database name is required.';
if (empty($cfg['db_user'])) $errors[] = 'Database user is required.';
if (strlen($cfg['admin_pass']) < 8) $errors[] = 'Admin password must be at least 8 characters.';
if (!$errors) {
// 1. Write .env
writeEnv($cfg);
$success[] = '✅ .env file created';
// 2. Set permissions
$writable = ['storage', 'bootstrap/cache'];
foreach ($writable as $dir) {
rchmod(BASEPATH . '/' . $dir, 0775, 0664);
}
$success[] = '✅ Folder permissions set (775/664)';
// 3. Create storage/app/public if missing
@mkdir(BASEPATH . '/storage/app/public', 0775, true);
@mkdir(BASEPATH . '/storage/framework/cache/data', 0775, true);
@mkdir(BASEPATH . '/storage/framework/sessions', 0775, true);
@mkdir(BASEPATH . '/storage/framework/views', 0775, true);
@mkdir(BASEPATH . '/storage/logs', 0775, true);
// 4. Clear cached config (stale cache would break migrate)
@unlink(BASEPATH . '/bootstrap/cache/config.php');
@unlink(BASEPATH . '/bootstrap/cache/routes-v7.php');
@unlink(BASEPATH . '/bootstrap/cache/packages.php');
@unlink(BASEPATH . '/bootstrap/cache/services.php');
$success[] = '✅ Bootstrap cache cleared';
// 5. Run migrations
$r = runArtisan('migrate --force');
if ($r['ok']) {
$success[] = '✅ Database migrated';
} else {
$errors[] = '❌ Migration failed: ' . $r['out'];
}
// 6. Run seeders
if (!$errors) {
$r = runArtisan('db:seed --force');
if ($r['ok']) {
$success[] = '✅ Database seeded (settings, services, brands, FAQs, admin user)';
} else {
$errors[] = '❌ Seeding failed: ' . $r['out'];
}
}
// 7. Create storage symlink
if (!$errors) {
if (is_link(BASEPATH . '/public/storage')) {
$success[] = '✅ Storage symlink already exists';
} else {
$r = runArtisan('storage:link');
if ($r['ok']) {
$success[] = '✅ Storage symlink created';
} else {
// Manual fallback
symlink(BASEPATH . '/storage/app/public', BASEPATH . '/public/storage');
$success[] = '✅ Storage symlink created (manual fallback)';
}
}
}
// 8. Cache config & routes
if (!$errors) {
runArtisan('config:cache');
runArtisan('route:cache');
runArtisan('view:clear');
$success[] = '✅ Config and route cache optimised';
}
}
}
// ── check requirements ─────────────────────────────────────────────────
$phpVer = PHP_VERSION;
$phpOk = version_compare($phpVer, '8.1.0', '>=');
$extChecks = ['pdo_mysql'=>'PDO MySQL','mbstring'=>'Mbstring','openssl'=>'OpenSSL',
'tokenizer'=>'Tokenizer','json'=>'JSON','ctype'=>'Ctype','xml'=>'XML',
'fileinfo'=>'FileInfo','bcmath'=>'BCMath'];
$extOk = [];
foreach ($extChecks as $ext => $label) {
$extOk[$label] = extension_loaded($ext);
}
$allOk = $phpOk && !in_array(false, $extOk, true);
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Chandra & Sons Pharma — Installer</title>
<style>
*{box-sizing:border-box;margin:0;padding:0}
body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;background:#F0F4F8;color:#1A2332;min-height:100vh;display:flex;align-items:flex-start;justify-content:center;padding:2rem 1rem}
.wrap{width:100%;max-width:680px}
.logo{text-align:center;margin-bottom:1.5rem}
.logo h1{font-size:1.5rem;font-weight:800;color:#0D7B8A}
.logo p{font-size:.85rem;color:#5A6A7A;margin-top:.25rem}
.card{background:white;border-radius:16px;padding:2rem;box-shadow:0 4px 24px rgba(0,0,0,.08);margin-bottom:1.5rem}
.card h2{font-size:1rem;font-weight:700;margin-bottom:1rem;color:#1A2332;padding-bottom:.5rem;border-bottom:1px solid #E2E8F0}
.req-row{display:flex;justify-content:space-between;align-items:center;padding:.4rem 0;border-bottom:1px solid #F5F7FA;font-size:.85rem}
.ok{color:#27AE60;font-weight:600}
.fail{color:#E31837;font-weight:600}
.warn{color:#F4A922;font-weight:600}
label{display:block;font-size:.8rem;font-weight:600;color:#5A6A7A;margin-bottom:.3rem;margin-top:1rem}
input{width:100%;padding:.6rem .8rem;border:1.5px solid #E2E8F0;border-radius:8px;font-size:.9rem;transition:border .2s}
input:focus{outline:none;border-color:#0D7B8A}
.grid2{display:grid;grid-template-columns:1fr 1fr;gap:1rem}
@media(max-width:500px){.grid2{grid-template-columns:1fr}}
.btn{display:block;width:100%;padding:.85rem;margin-top:1.5rem;background:#0D7B8A;color:white;border:none;border-radius:10px;font-size:1rem;font-weight:700;cursor:pointer;transition:background .2s}
.btn:hover{background:#0A5C67}
.btn:disabled{background:#ccc;cursor:not-allowed}
.alerts{margin-bottom:1.5rem}
.alert{padding:.75rem 1rem;border-radius:8px;margin-bottom:.5rem;font-size:.85rem;line-height:1.5}
.alert-ok{background:#E8F5E9;border:1px solid #A5D6A7;color:#2E7D32}
.alert-err{background:#FFEBEE;border:1px solid #EF9A9A;color:#B71C1C}
.alert-warn{background:#FFF8E1;border:1px solid #FFE082;color:#F57F17}
.done-box{text-align:center;padding:2rem}
.done-box h2{font-size:1.4rem;font-weight:800;color:#27AE60;margin-bottom:.5rem}
.done-box p{color:#5A6A7A;font-size:.9rem;margin-bottom:.75rem}
.done-box code{background:#F5F7FA;padding:.2rem .5rem;border-radius:4px;font-size:.8rem}
.badge{display:inline-block;padding:.2rem .6rem;border-radius:20px;font-size:.75rem;font-weight:700}
.badge-ok{background:#E8F5E9;color:#27AE60}
.badge-fail{background:#FFEBEE;color:#E31837}
.note{font-size:.78rem;color:#5A6A7A;margin-top:.4rem;font-style:italic}
</style>
</head>
<body>
<div class="wrap">
<div class="logo">
<h1>🏥 Chandra & Sons Pharma</h1>
<p>Web Installer — cPanel Shared Hosting</p>
</div>
<?php if ($step === 'install' && !$errors && count($success) > 3): ?>
<!-- SUCCESS STATE -->
<div class="card">
<div class="done-box">
<h2>🎉 Installation Complete!</h2>
<p>Your website is ready. Here's what was done:</p>
</div>
<?php foreach ($success as $s): ?>
<div class="alert alert-ok"><?= htmlspecialchars($s) ?></div>
<?php endforeach; ?>
<div class="alert alert-warn" style="margin-top:1rem">
⚠️ <strong>Security:</strong> Delete <code>install.php</code> from your server immediately!<br>
You can do this via cPanel File Manager or run: <code>rm install.php</code>
</div>
<div class="alert alert-ok" style="margin-top:.5rem">
🔑 Admin login: <code><?= htmlspecialchars($_POST['admin_email'] ?? 'admin@chandrasons.com') ?></code> / your chosen password<br>
Admin URL: <code><?= htmlspecialchars(rtrim($_POST['app_url'] ?? '', '/')) ?>/admin</code>
</div>
</div>
<?php else: ?>
<!-- REQUIREMENTS CHECK -->
<div class="card">
<h2>📋 Server Requirements</h2>
<div class="req-row">
<span>PHP Version (<?= $phpVer ?>)</span>
<span class="<?= $phpOk ? 'ok' : 'fail' ?>"><?= $phpOk ? '✅ OK' : '❌ Need 8.1+' ?></span>
</div>
<?php foreach ($extOk as $label => $loaded): ?>
<div class="req-row">
<span>PHP <?= $label ?></span>
<span class="<?= $loaded ? 'ok' : 'fail' ?>"><?= $loaded ? '✅ Loaded' : '❌ Missing' ?></span>
</div>
<?php endforeach; ?>
<div class="req-row">
<span>storage/ writable</span>
<span class="<?= is_writable(BASEPATH.'/storage') ? 'ok' : 'fail' ?>"><?= is_writable(BASEPATH.'/storage') ? '✅ OK' : '❌ Not writable' ?></span>
</div>
<div class="req-row">
<span>bootstrap/cache/ writable</span>
<span class="<?= is_writable(BASEPATH.'/bootstrap/cache') ? 'ok' : 'fail' ?>"><?= is_writable(BASEPATH.'/bootstrap/cache') ? '✅ OK' : '❌ Not writable' ?></span>
</div>
<div class="req-row">
<span>vendor/ present</span>
<span class="<?= is_dir(BASEPATH.'/vendor') ? 'ok' : 'fail' ?>"><?= is_dir(BASEPATH.'/vendor') ? '✅ OK' : '❌ Missing — upload vendor/' ?></span>
</div>
<div class="req-row">
<span>public/build/ present</span>
<span class="<?= is_dir(BASEPATH.'/public/build') ? 'ok' : 'fail' ?>"><?= is_dir(BASEPATH.'/public/build') ? '✅ OK' : '❌ Missing — upload public/build/' ?></span>
</div>
</div>
<?php if ($errors): ?>
<div class="alerts">
<?php foreach ($errors as $e): ?>
<div class="alert alert-err"><?= htmlspecialchars($e) ?></div>
<?php endforeach; ?>
</div>
<?php endif; ?>
<?php if ($success): ?>
<div class="alerts">
<?php foreach ($success as $s): ?>
<div class="alert alert-ok"><?= htmlspecialchars($s) ?></div>
<?php endforeach; ?>
</div>
<?php endif; ?>
<!-- INSTALL FORM -->
<div class="card">
<h2>⚙️ Installation Settings</h2>
<form method="POST">
<input type="hidden" name="step" value="install">
<label>Site URL (no trailing slash)</label>
<input type="url" name="app_url" value="https://chandrasons.com" placeholder="https://yourdomain.com" required>
<h2 style="margin-top:1.5rem;padding-top:1rem;border-top:1px solid #E2E8F0">🗄️ Database</h2>
<p class="note">Get these from cPanel → MySQL Databases</p>
<label>Database Host</label>
<input type="text" name="db_host" value="localhost" required>
<div class="grid2">
<div>
<label>Database Name</label>
<input type="text" name="db_name" placeholder="cpanelusername_dbname" required>
</div>
<div>
<label>Database User</label>
<input type="text" name="db_user" placeholder="cpanelusername_dbuser" required>
</div>
</div>
<label>Database Password</label>
<input type="password" name="db_pass" placeholder="Your database password">
<h2 style="margin-top:1.5rem;padding-top:1rem;border-top:1px solid #E2E8F0">👤 Admin Account</h2>
<div class="grid2">
<div>
<label>Admin Email</label>
<input type="email" name="admin_email" value="admin@chandrasons.com" required>
</div>
<div>
<label>Admin Password (min 8 chars)</label>
<input type="text" name="admin_pass" value="Admin@1234" required>
</div>
</div>
<button class="btn" type="submit" <?= !$allOk ? 'disabled title="Fix requirements above first"' : '' ?>>
<?= !$allOk ? '⚠️ Fix Requirements First' : '🚀 Install Now' ?>
</button>
</form>
</div>
<div class="card">
<h2>📖 After Installation</h2>
<div style="font-size:.83rem;color:#5A6A7A;line-height:1.8;">
<p>1. <strong>Delete install.php</strong> immediately for security</p>
<p>2. Log into <strong>/admin</strong> with your admin credentials</p>
<p>3. Go to <strong>Settings → General</strong> — update phone, address, social links</p>
<p>4. Go to <strong>Settings → SEO</strong> — add your Google Analytics ID</p>
<p>5. Go to <strong>Settings → Email</strong> — configure SMTP for enquiry emails</p>
<p>6. Upload real product photos and brand logos via the admin panel</p>
<p>7. Set up a cron job: <code>* * * * * php /path/to/artisan schedule:run</code></p>
</div>
</div>
<?php endif; ?>
</div>
</body>
</html>