270 lines
12 KiB
PHP
270 lines
12 KiB
PHP
<?php
|
|
require_once __DIR__.'/includes/boot.php';
|
|
if (authed()) go('/index.php');
|
|
if (setting('registration_enabled','1') !== '1') {
|
|
flash('Registration is currently disabled. Please check back later.','warning');
|
|
go('/login.php');
|
|
}
|
|
|
|
$pageTitle = 'Create Account — Discover Keyser WV';
|
|
$errors = [];
|
|
$businessOptions = qall("SELECT id,name,address FROM businesses WHERE is_active=1 ORDER BY name");
|
|
$tier = p('member_type', 'member') === 'business_owner' ? 'business_owner' : 'member';
|
|
|
|
if (isPost()) {
|
|
csrfCheck();
|
|
|
|
if (ps('website_url') !== '' || ps('confirm_email') !== '') {
|
|
flash('Account created! Welcome to Discover Keyser WV.','success');
|
|
go('/index.php');
|
|
}
|
|
|
|
$formTime = (int)p('_form_time', 0);
|
|
if ($formTime && (time() - $formTime) < 3) {
|
|
flash('Account created! Welcome to Discover Keyser WV.','success');
|
|
go('/index.php');
|
|
}
|
|
|
|
$tier = p('member_type', 'member') === 'business_owner' ? 'business_owner' : 'member';
|
|
$un = ps('username');
|
|
$em = ps('email');
|
|
$pw = ps('password');
|
|
$pw2 = ps('password2');
|
|
$tos = p('lawful_use', '');
|
|
|
|
$claimBizId = (int)p('claim_business_id');
|
|
$contactPhone = ps('contact_phone');
|
|
$claimBiz = null;
|
|
|
|
if (strlen($un) < 3) $errors[] = 'Username must be at least 3 characters.';
|
|
if (!preg_match('/^[a-zA-Z0-9_]+$/', $un)) $errors[] = 'Username may only contain letters, numbers, and underscores.';
|
|
if ($em && !filter_var($em, FILTER_VALIDATE_EMAIL)) $errors[] = 'Please enter a valid email address.';
|
|
if (strlen($pw) < 6) $errors[] = 'Password must be at least 6 characters.';
|
|
if ($pw !== $pw2) $errors[] = 'Passwords do not match.';
|
|
if ($tos !== '1') $errors[] = 'You must agree to use this service lawfully to create an account.';
|
|
if (!$errors && qval("SELECT id FROM users WHERE username=?", [$un])) $errors[] = 'That username is already taken. Please choose another.';
|
|
if (!$errors && $em && qval("SELECT id FROM users WHERE email=?", [$em])) $errors[] = 'That email address is already registered. Try signing in instead.';
|
|
|
|
$claimEdits = [
|
|
'description' => ps('claim_description'),
|
|
'address' => ps('claim_address'),
|
|
'phone' => ps('claim_public_phone'),
|
|
'email' => ps('claim_public_email'),
|
|
'website' => ps('claim_website'),
|
|
'video_url' => ps('claim_video_url'),
|
|
];
|
|
|
|
if ($tier === 'business_owner') {
|
|
if (!$claimBizId) {
|
|
$errors[] = 'Please select the business page you want to claim.';
|
|
} else {
|
|
$claimBiz = qone("SELECT * FROM businesses WHERE id=? AND is_active=1", [$claimBizId]);
|
|
if (!$claimBiz) $errors[] = 'Please select a valid listed business.';
|
|
}
|
|
if ($contactPhone === '' || strlen(preg_replace('/\D+/', '', $contactPhone)) < 7) {
|
|
$errors[] = 'Please enter a contact phone number for verification.';
|
|
}
|
|
if ($claimEdits['email'] !== '' && !filter_var($claimEdits['email'], FILTER_VALIDATE_EMAIL)) {
|
|
$errors[] = 'Please enter a valid public email edit.';
|
|
}
|
|
if (!validBusinessVideoUrl($claimEdits['video_url'])) {
|
|
$errors[] = 'Business videos must be a YouTube or Vimeo URL.';
|
|
}
|
|
}
|
|
|
|
if (!$errors) {
|
|
$id = qrun(
|
|
"INSERT INTO users(username,email,password)VALUES(?,?,?)",
|
|
[$un, $em ?: null, password_hash($pw, PASSWORD_BCRYPT)]
|
|
);
|
|
|
|
$submittedEdits = 0;
|
|
if ($tier === 'business_owner' && $claimBiz) {
|
|
qrun(
|
|
"INSERT INTO business_claim_requests(business_id,user_id,contact_phone)VALUES(?,?,?)",
|
|
[$claimBizId, $id, $contactPhone]
|
|
);
|
|
|
|
foreach ($claimEdits as $field => $newValue) {
|
|
if ($newValue === '') continue;
|
|
$oldValue = (string)($claimBiz[$field] ?? '');
|
|
if ($newValue === $oldValue) continue;
|
|
qrun(
|
|
"INSERT INTO business_edit_requests(business_id,user_id,field,old_value,new_value)VALUES(?,?,?,?,?)",
|
|
[$claimBizId, $id, $field, $oldValue, $newValue]
|
|
);
|
|
$submittedEdits++;
|
|
}
|
|
}
|
|
|
|
loginUser(qone("SELECT * FROM users WHERE id=?", [$id]));
|
|
|
|
if ($tier === 'business_owner' && $claimBiz) {
|
|
$msg = 'Your account is ready. Your claim for '.$claimBiz['name'].' is queued, and we will contact you at '.$contactPhone.' within a few business days for verification.';
|
|
if ($submittedEdits) $msg .= ' '.$submittedEdits.' proposed edit'.($submittedEdits !== 1 ? 's were' : ' was').' sent to admin review.';
|
|
flash($msg, 'success');
|
|
go('/dashboard.php');
|
|
}
|
|
|
|
flash('Welcome to Discover Keyser WV, '.$un.'!', 'success');
|
|
go('/index.php');
|
|
}
|
|
}
|
|
|
|
$ownerSelected = $tier === 'business_owner';
|
|
|
|
$footExtra = <<<HTML
|
|
<script>
|
|
(() => {
|
|
const radios = document.querySelectorAll('input[name="member_type"]');
|
|
const ownerFields = document.getElementById('ownerClaimFields');
|
|
const sync = () => {
|
|
const owner = document.querySelector('input[name="member_type"]:checked')?.value === 'business_owner';
|
|
ownerFields?.classList.toggle('is-open', owner);
|
|
ownerFields?.querySelectorAll('[data-owner-required]').forEach(el => {
|
|
if (owner) el.setAttribute('required', 'required');
|
|
else el.removeAttribute('required');
|
|
});
|
|
};
|
|
radios.forEach(r => r.addEventListener('change', sync));
|
|
sync();
|
|
})();
|
|
</script>
|
|
HTML;
|
|
|
|
include __DIR__.'/includes/header.php';
|
|
?>
|
|
|
|
<div class="signup-shell">
|
|
<div class="signup-intro">
|
|
<div class="eyebrow">JOIN KEYSER ONLINE</div>
|
|
<h1>Create Your Account</h1>
|
|
<p>Choose a community membership or start a verified business-owner claim for a page already listed in the directory.</p>
|
|
</div>
|
|
|
|
<?php if ($errors): ?>
|
|
<div class="err-box signup-errors"><?=implode('<br>', array_map('e', $errors))?></div>
|
|
<?php endif; ?>
|
|
|
|
<form method="POST" autocomplete="off" class="signup-card">
|
|
<?=csrfField()?>
|
|
<input type="hidden" name="_form_time" value="<?=time()?>">
|
|
|
|
<div class="hp-field" aria-hidden="true">
|
|
<label for="website_url">Leave this blank</label>
|
|
<input type="text" id="website_url" name="website_url" value="" tabindex="-1" autocomplete="off">
|
|
<label for="confirm_email">Do not fill</label>
|
|
<input type="email" id="confirm_email" name="confirm_email" value="" tabindex="-1" autocomplete="off">
|
|
</div>
|
|
|
|
<div class="tier-grid">
|
|
<label class="tier-card">
|
|
<input type="radio" name="member_type" value="member"<?=!$ownerSelected?' checked':''?>>
|
|
<span class="tier-kicker">Regular Member</span>
|
|
<span class="tier-title">Explore and contribute</span>
|
|
<span class="tier-copy">Rate businesses, submit events, report outdated listings, and keep up with Keyser.</span>
|
|
</label>
|
|
<label class="tier-card tier-card-owner">
|
|
<input type="radio" name="member_type" value="business_owner"<?=$ownerSelected?' checked':''?>>
|
|
<span class="tier-kicker">Business Owner</span>
|
|
<span class="tier-title">Claim a listed page</span>
|
|
<span class="tier-copy">Request ownership, send initial corrections, and add an optional YouTube or Vimeo video.</span>
|
|
</label>
|
|
</div>
|
|
|
|
<div class="signup-grid">
|
|
<div class="fg">
|
|
<label class="flabel" for="username">USERNAME *</label>
|
|
<input type="text" id="username" name="username" class="finput"
|
|
value="<?=e($_POST['username']??'')?>"
|
|
autocomplete="username" required autofocus pattern="[a-zA-Z0-9_]+" minlength="3">
|
|
<div class="fhint">Letters, numbers, underscores only. Min 3 characters.</div>
|
|
</div>
|
|
<div class="fg">
|
|
<label class="flabel" for="email">EMAIL ADDRESS <span style="font-weight:300;letter-spacing:0">(optional)</span></label>
|
|
<input type="email" id="email" name="email" class="finput"
|
|
value="<?=e($_POST['email']??'')?>"
|
|
autocomplete="email">
|
|
<div class="fhint">Used for account recovery and owner verification follow-up.</div>
|
|
</div>
|
|
<div class="fg">
|
|
<label class="flabel" for="password">PASSWORD *</label>
|
|
<input type="password" id="password" name="password" class="finput" autocomplete="new-password" required minlength="6">
|
|
</div>
|
|
<div class="fg">
|
|
<label class="flabel" for="password2">CONFIRM PASSWORD *</label>
|
|
<input type="password" id="password2" name="password2" class="finput" autocomplete="new-password" required minlength="6">
|
|
</div>
|
|
</div>
|
|
|
|
<div id="ownerClaimFields" class="owner-claim-fields<?=$ownerSelected?' is-open':''?>">
|
|
<div class="owner-claim-note">
|
|
<strong>Verification required.</strong> Select the business page you manage and provide a contact phone number. A site administrator will contact you within a few business days before the page is assigned to your account.
|
|
</div>
|
|
|
|
<div class="signup-grid">
|
|
<div class="fg">
|
|
<label class="flabel" for="claim_business_id">BUSINESS TO CLAIM *</label>
|
|
<select id="claim_business_id" name="claim_business_id" class="fselect" data-owner-required>
|
|
<option value="">Select a listed business</option>
|
|
<?php foreach ($businessOptions as $biz): ?>
|
|
<option value="<?=$biz['id']?>"<?=((int)($_POST['claim_business_id']??0)===(int)$biz['id'])?' selected':''?>>
|
|
<?=e($biz['name'])?><?= $biz['address'] ? ' — '.e($biz['address']) : '' ?>
|
|
</option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
</div>
|
|
<div class="fg">
|
|
<label class="flabel" for="contact_phone">CONTACT PHONE FOR VERIFICATION *</label>
|
|
<input type="tel" id="contact_phone" name="contact_phone" class="finput"
|
|
value="<?=e($_POST['contact_phone']??'')?>" placeholder="304-555-0123" data-owner-required>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="claim-edit-panel">
|
|
<div class="ibox-title">OPTIONAL FIRST EDITS</div>
|
|
<div class="signup-grid">
|
|
<div class="fg signup-wide">
|
|
<label class="flabel" for="claim_description">DESCRIPTION UPDATE</label>
|
|
<textarea id="claim_description" name="claim_description" class="ftextarea" placeholder="Share a corrected or refreshed business description."><?=e($_POST['claim_description']??'')?></textarea>
|
|
</div>
|
|
<div class="fg">
|
|
<label class="flabel" for="claim_address">PUBLIC ADDRESS</label>
|
|
<input type="text" id="claim_address" name="claim_address" class="finput" value="<?=e($_POST['claim_address']??'')?>">
|
|
</div>
|
|
<div class="fg">
|
|
<label class="flabel" for="claim_public_phone">PUBLIC PHONE</label>
|
|
<input type="text" id="claim_public_phone" name="claim_public_phone" class="finput" value="<?=e($_POST['claim_public_phone']??'')?>">
|
|
</div>
|
|
<div class="fg">
|
|
<label class="flabel" for="claim_public_email">PUBLIC EMAIL</label>
|
|
<input type="email" id="claim_public_email" name="claim_public_email" class="finput" value="<?=e($_POST['claim_public_email']??'')?>">
|
|
</div>
|
|
<div class="fg">
|
|
<label class="flabel" for="claim_website">WEBSITE</label>
|
|
<input type="text" id="claim_website" name="claim_website" class="finput" value="<?=e($_POST['claim_website']??'')?>" placeholder="example.com">
|
|
</div>
|
|
<div class="fg signup-wide">
|
|
<label class="flabel" for="claim_video_url">VIDEO URL</label>
|
|
<input type="url" id="claim_video_url" name="claim_video_url" class="finput" value="<?=e($_POST['claim_video_url']??'')?>" placeholder="YouTube or Vimeo URL">
|
|
<div class="fhint">Optional. Business owners may use YouTube or Vimeo.</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<label class="tos-check">
|
|
<input type="checkbox" name="lawful_use" value="1" <?=(!empty($_POST) && p('lawful_use')==='1') ? 'checked' : ''?> required>
|
|
<span class="tos-check-text">
|
|
<strong>I will only use this service lawfully.</strong>
|
|
I agree not to post false, misleading, defamatory, or harmful content, and I understand fraudulent business claims may be removed.
|
|
</span>
|
|
</label>
|
|
|
|
<button type="submit" class="btn btn-primary btn-block signup-submit">Create Account</button>
|
|
<p class="signin-link">Already have an account? <a href="/login.php">Sign in here</a></p>
|
|
</form>
|
|
</div>
|
|
|
|
<?php include __DIR__.'/includes/footer.php'; ?>
|