refactor: 🚀 v2
This commit is contained in:
parent
a4dceb0da5
commit
026aea638f
@ -16,12 +16,18 @@ header, main, footer {
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
section {
|
||||
border: 1px solid #666;
|
||||
padding: 15px;
|
||||
margin: 10px 0;
|
||||
}
|
||||
.height-100-75 {
|
||||
height: calc(100% - 75px);
|
||||
}
|
||||
|
||||
#bookmark {
|
||||
background-color: #333;
|
||||
}
|
||||
.zfont {
|
||||
font-size: 0;
|
||||
}
|
||||
|
||||
#img {
|
||||
z-index: -1;
|
||||
|
||||
|
Before Width: | Height: | Size: 9.4 KiB After Width: | Height: | Size: 9.4 KiB |
227
index.php
227
index.php
@ -21,79 +21,87 @@ $alerts = [
|
||||
'danger' => []
|
||||
];
|
||||
|
||||
$data = ['img' => '', 'name' => '', 'url' => '', 'desc' => ''];
|
||||
|
||||
try {
|
||||
$data = Storage::get($id);
|
||||
}
|
||||
catch(Exception $ex) {
|
||||
$alerts['danger'][] = '❌ Error reading database';
|
||||
}
|
||||
if (empty($data)) {
|
||||
$data = [
|
||||
'img' => '',
|
||||
'name' => '',
|
||||
'url' => '',
|
||||
'desc' => ''
|
||||
];
|
||||
}
|
||||
|
||||
$img = $data['img'];
|
||||
// echo '<pre>'; print_r($img); echo '</pre>';
|
||||
$name = $data['name'];
|
||||
$url = $data['url'];
|
||||
$desc = $data['desc'];
|
||||
$gallery = [];
|
||||
if (file_exists("uppies/$id/gallery")) {
|
||||
foreach(scandir("uppies/$id/gallery") as $g) {
|
||||
if (in_array($g, ['.', '..', '.thumbs', '.DS_Store']))
|
||||
continue;
|
||||
$gallery[] = $g;
|
||||
}
|
||||
}
|
||||
|
||||
if ($_SERVER["REQUEST_METHOD"] === 'POST' && isset($_GET['upload'])) {
|
||||
http_response_code(202);
|
||||
$upload = htmlspecialchars($_GET['upload']);
|
||||
http_response_code(202); # 202 is abused for errors, because uikit requires 2xx responses
|
||||
|
||||
$targetDir = "uppies/";
|
||||
$targetDir = "uppies/${id}/${upload}/";
|
||||
$file = $_FILES["files"];
|
||||
$targetFile = $targetDir . basename($file["name"][0]);
|
||||
$imageFileType = strtolower(pathinfo($targetFile, PATHINFO_EXTENSION));
|
||||
$fileName = basename($file["name"][0]);
|
||||
|
||||
// Create the uploads directory if it doesn't exist
|
||||
if (!is_dir($targetDir)) {
|
||||
mkdir($targetDir, 0775, true);
|
||||
}
|
||||
|
||||
// Check if the file is actually an image
|
||||
$check = getimagesize($file["tmp_name"][0]);
|
||||
if ($check === false) {
|
||||
// check if the file is actually an image
|
||||
if (getimagesize($file["tmp_name"][0]) === false) {
|
||||
exit("❌ Error: File is not a valid image.");
|
||||
}
|
||||
|
||||
// Allow only specific image file formats
|
||||
$allowedTypes = ["jpg", "jpeg", "png", "gif"];
|
||||
if (!in_array($imageFileType, $allowedTypes)) {
|
||||
// allow only specific image extensions
|
||||
if (!in_array(strtolower(pathinfo($fileName, PATHINFO_EXTENSION)), ["psd", "tiff", "jpg", "jpeg", "png", "gif"])) {
|
||||
exit("❌ Error: Only JPG, JPEG, PNG and GIF files allowed.");
|
||||
}
|
||||
|
||||
// Limit file size (e.g., 5MB)
|
||||
if ($file["size"][0] > 100 * 1024 * 1024) {
|
||||
exit("❌ Error: File too large (max. 100 MB)");
|
||||
// limit file size
|
||||
if ($file["size"][0] > 200 * 1024 * 1024) {
|
||||
exit("❌ Error: File too large (max. 200 MB)");
|
||||
}
|
||||
|
||||
// generate destination file name
|
||||
$finalPath = $targetDir . $id . '.' . $imageFileType;
|
||||
|
||||
// Move uploaded file to the target directory
|
||||
if (move_uploaded_file($file["tmp_name"][0], $finalPath)) {
|
||||
if (move_uploaded_file($file["tmp_name"][0], $targetDir . $fileName)) {
|
||||
$data['img'] = $targetDir . $fileName;
|
||||
try {
|
||||
Storage::set_img($id, $id . '.' . $imageFileType);
|
||||
Storage::set($id, $data);
|
||||
}
|
||||
catch(Exception $ex) {
|
||||
exit("❌ Database error.");
|
||||
}
|
||||
|
||||
http_response_code(200);
|
||||
exit($finalPath);
|
||||
exit(($upload === 'avatar'? $targetDir : '') . $fileName);
|
||||
}
|
||||
else {
|
||||
exit("❌ Write Error.");
|
||||
}
|
||||
|
||||
exit("❌ General error saving the file.");
|
||||
exit("❌ General error.");
|
||||
}
|
||||
|
||||
else if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['desc']) && isset($_POST['name']) && isset($_POST['url'])) {
|
||||
$name = htmlspecialchars(trim($_POST['name']));
|
||||
$url = htmlspecialchars(trim($_POST['url']));
|
||||
$desc = htmlspecialchars(trim($_POST['desc']));
|
||||
$data['name'] = htmlspecialchars(trim($_POST['name']));
|
||||
$data['url'] = htmlspecialchars(trim($_POST['url']));
|
||||
$data['desc'] = htmlspecialchars(trim($_POST['desc']));
|
||||
|
||||
if (!empty($name) && !empty($desc) && !empty($url)) {
|
||||
if (!empty($data['name']) && !empty($data['desc']) && !empty($data['url'])) {
|
||||
try {
|
||||
Storage::set_data($id, $name, $url, $desc);
|
||||
Telegram::report("EF Conbook Artist Credits Submission\nname: $name\nurl: $url\ntext:\n$desc");
|
||||
Storage::set($id, $data);
|
||||
Telegram::report("EF Conbook Artist Credits Submission\nname: ". $data['name'] ."\nurl: ". $data['url'] ."\ntext:\n". $data['desc']);
|
||||
$alerts['success'][] = '✅ Entry saved';
|
||||
}
|
||||
catch(Exception $ex) {
|
||||
@ -116,14 +124,14 @@ else if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['desc']) && isset
|
||||
<meta name="author" content="The Eurofurence Conbook Team" />
|
||||
<meta name="rating" content="general" />
|
||||
|
||||
<link rel="shortcut icon" href="favicon.png">
|
||||
<link rel="shortcut icon" href="favicon.ico">
|
||||
|
||||
<meta property="og:image" content="img/ogp.jpg" />
|
||||
<meta property="og:image:secure_url" content="img/ogp.jpg" />
|
||||
<meta property="og:image:type" content="image/jpeg" />
|
||||
<meta property="og:image:width" content="344" />
|
||||
<meta property="og:image:height" content="247" />
|
||||
<meta property="og:image:alt" content="A dog on a cloud." />
|
||||
<meta property="og:image:alt" content="Conbook Art Credits" />
|
||||
<meta property="og:title" content="Conbook Art Credits" />
|
||||
<meta property="og:description" content="Submit Artist Credits to the Eurofurence Conbook Team" />
|
||||
<meta property="og:type" content="website" />
|
||||
@ -143,55 +151,75 @@ else if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['desc']) && isset
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<h1>Conbook Artist Credit Form</h1>
|
||||
<h1>Conbook Art Submission Form</h1>
|
||||
<p>
|
||||
Thank you for submitting art to the Eurofurence Conbook. In the event of your art making an appearance in the book, your are eligible to an entry in the artist credits.<br />
|
||||
Edit your entry below before <strong>the end of July</strong> to make sure you are credited appropriately.
|
||||
A place for you to submit art to the Eurofurence Conbook and provide crediting information.<br />
|
||||
<span uk-icon="clock"></span> Deadline: <strong>End of July</strong>!
|
||||
</p>
|
||||
|
||||
<p>Bookmark this page or save the following url to be able to edit your entry later:</p>
|
||||
<div class="uk-width-1-1 uk-grid-collapse" uk-grid>
|
||||
<div class="uk-width-3-4@m">
|
||||
<input type="text" id="bookmark" disabled value="<?= $bookmark ?>" class="uk-input" />
|
||||
</div>
|
||||
<div class="uk-width-1-4@m">
|
||||
<button type="button" id="copyUrl" class="uk-button uk-button-primary uk-width-1-1" title="✅ Copied">Copy to Clipboard</button>
|
||||
</div>
|
||||
</div>
|
||||
<p><span uk-icon="image"></span> Please make sure your images are large enough for DIN A4 printing. Don't worry about cropping or aspect ratio, we will adjust them into the layout ourselves.</p>
|
||||
</header>
|
||||
|
||||
<main class="uk-margin">
|
||||
<hr />
|
||||
<p>Please make sure your profile image is large enough for print. Don't worry about cropping or aspect ratio, it will be adjusted into the layout by us.</p>
|
||||
<section class="uk-child-width-1-2@m" uk-grid>
|
||||
<div>
|
||||
<div class="js-upload uk-placeholder uk-margin-top uk-position-relative">
|
||||
<div id="img"></div>
|
||||
<!-- <img id="img" src="" alt="No image uploaded yet" /> -->
|
||||
<span uk-icon="icon: cloud-upload"></span>
|
||||
<span class="uk-text-middle">Upload Your Profile Image<br />PNG, JPG or GIF<br />min. 500 x 500 @ 300 dpi<br /></span>
|
||||
<div uk-form-custom>
|
||||
<input type="file">
|
||||
<span class="uk-link">SELECT FILE</span>
|
||||
<main>
|
||||
<section>
|
||||
<h3>Personal Link</h3>
|
||||
<p>Bookmark or save it to edit your entry at a later time. Do not share it, unless with people you want to enable editing your information:</p>
|
||||
<div class="uk-width-1-1 uk-grid-collapse" uk-grid>
|
||||
<div class="uk-width-3-4@m">
|
||||
<input type="text" id="bookmark" disabled value="<?= $bookmark ?>" class="uk-input" />
|
||||
</div>
|
||||
<div class="uk-width-1-4@m">
|
||||
<button type="button" id="copyUrl" class="uk-button uk-button-primary uk-width-1-1" title="✅ Copied">Copy to Clipboard</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<progress id="js-progressbar" class="uk-progress" value="0" max="100" hidden></progress>
|
||||
<div class="uk-child-width-1-2@m uk-grid-small uk-grid-match" uk-grid>
|
||||
<div>
|
||||
<h3>Your Credits Entry</h3>
|
||||
<div class="upload-avatar uk-placeholder uk-position-relative">
|
||||
<div id="img"></div>
|
||||
<span uk-icon="icon: cloud-upload"></span>
|
||||
<span class="uk-text-middle">Upload Your Profile Image<br />PNG, JPG or GIF<br />min. 500 x 500 @ 300 dpi<br /></span>
|
||||
<div uk-form-custom>
|
||||
<input type="file">
|
||||
<span class="uk-link">SELECT FILE</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form action="" method="POST">
|
||||
<input type="text" name="name" id="name" maxlength="80" value="<?= $data['name'] ?>" placeholder="Your nickname (max. 80 characters)" class="uk-input" required />
|
||||
<input type="text" name="url" id="url" maxlength="256" value="<?= $data['url'] ?>" placeholder="Your gallery link / homepage (max. 256 characters)" class="uk-input uk-margin-top" required />
|
||||
<input type="text" name="desc" id="desc" maxlength="400" value="<?= $data['desc'] ?>" placeholder="Your description (max. 400 characters)" class="uk-input uk-margin-top" required />
|
||||
<input type="submit" value="Save" class="uk-button uk-button-primary uk-margin-top" />
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3>Your Contribution</h3>
|
||||
<div class="height-100-75 upload-gallery uk-placeholder uk-text-center">
|
||||
<span uk-icon="icon: cloud-upload"></span>
|
||||
<span class="uk-text-middle">Drop Your Contribution Here<br />PNG, PSD, TIFF, JPG or GIF<br />highest possible resolution, ideally 300 dpi<br /></span>
|
||||
<div uk-form-custom>
|
||||
<input type="file">
|
||||
<span class="uk-link">SELECT FILE</span>
|
||||
</div>
|
||||
<ul id="gallery" class="uk-text-left">
|
||||
<?php foreach ($gallery as $g) {
|
||||
// echo "<li>$g <a href=\"$bookmark&delete=$g\">[delete]</a></li>";
|
||||
echo "<li>$g </li>";
|
||||
}
|
||||
?>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<progress id="js-progressbar" class="uk-progress" value="0" max="100" hidden></progress>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<form action="" method="POST">
|
||||
<input type="text" name="name" id="name" maxlength="80" value="<?= $name ?>" placeholder="Your nickname (max. 80 characters)" class="uk-input uk-margin-top" />
|
||||
<input type="text" name="url" id="url" maxlength="256" value="<?= $url ?>" placeholder="Your gallery link / homepage (max. 256 characters)" class="uk-input uk-margin-top" />
|
||||
<input type="text" name="desc" id="desc" maxlength="400" value="<?= $desc ?>" placeholder="Your description (max. 400 characters)" class="uk-input uk-margin-top" />
|
||||
<input type="submit" value="Save" class="uk-button uk-button-primary uk-margin-top" />
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<footer>
|
||||
<hr />
|
||||
<p>If you need assistance, please contact <a href="https://help.eurofurence.org/contact/conbook" target="_blank">The Conbook Department</a>.</p>
|
||||
<p>Your input is being stored until September, then wiped. If you need assistance, please contact <a href="https://help.eurofurence.org/contact/conbook" target="_blank">The Conbook Department</a>.</p>
|
||||
</footer>
|
||||
|
||||
<script>
|
||||
@ -215,17 +243,17 @@ else if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['desc']) && isset
|
||||
?>
|
||||
</script>
|
||||
|
||||
<?php if ($img !== '') { ?>
|
||||
<?php if ($data['img'] !== '') { ?>
|
||||
<script>
|
||||
document.getElementById('img').style.backgroundImage = 'url(uppies/<?= $img ?>?' + new Date().getTime() + ')';
|
||||
document.getElementById('img').style.backgroundImage = 'url(<?= $data['img'] ?>?' + new Date().getTime() + ')';
|
||||
</script>
|
||||
<?php } ?>
|
||||
|
||||
<script>
|
||||
var bar = document.getElementById('js-progressbar');
|
||||
|
||||
UIkit.upload('.js-upload', {
|
||||
url: '<?= $bookmark ?>&upload',
|
||||
UIkit.upload('.upload-avatar', {
|
||||
url: '<?= $bookmark ?>&upload=avatar',
|
||||
|
||||
loadStart: function (e) {
|
||||
bar.removeAttribute('hidden');
|
||||
@ -245,7 +273,6 @@ else if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['desc']) && isset
|
||||
|
||||
completeAll: function (r) {
|
||||
if (r.status == 200) {
|
||||
console.log(r);
|
||||
document.getElementById('img').style.backgroundImage = 'url(' + r.responseText + '?' + new Date().getTime() + ')';
|
||||
UIkit.notification('✅ Image saved', 'success');
|
||||
}
|
||||
@ -258,6 +285,50 @@ else if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['desc']) && isset
|
||||
}, 1000);
|
||||
}
|
||||
});
|
||||
|
||||
UIkit.upload('.upload-gallery', {
|
||||
url: '<?= $bookmark ?>&upload=gallery',
|
||||
multiple: true,
|
||||
|
||||
loadStart: function (e) {
|
||||
bar.removeAttribute('hidden');
|
||||
bar.max = e.total;
|
||||
bar.value = e.loaded;
|
||||
},
|
||||
|
||||
progress: function (e) {
|
||||
bar.max = e.total;
|
||||
bar.value = e.loaded;
|
||||
},
|
||||
|
||||
loadEnd: function (e) {
|
||||
bar.max = e.total;
|
||||
bar.value = e.loaded;
|
||||
},
|
||||
|
||||
completeAll: function (r) {
|
||||
if (r.status == 200) {
|
||||
const li = document.createElement('li');
|
||||
li.innerText = r.responseText + ' ';
|
||||
|
||||
// const a = document.createElement('a');
|
||||
// a.href="<?= $bookmark ?>&delete=" + r.responseText;
|
||||
// a.innerText = '[delete]';
|
||||
// li.appendChild(a);
|
||||
|
||||
document.getElementById('gallery').appendChild(li);
|
||||
|
||||
UIkit.notification('✅ Image saved', 'success');
|
||||
}
|
||||
else {
|
||||
UIkit.notification(r.responseText, 'danger');
|
||||
}
|
||||
|
||||
setTimeout(function () {
|
||||
bar.setAttribute('hidden', 'hidden');
|
||||
}, 1000);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@ -21,10 +21,7 @@ class Storage {
|
||||
$db->exec("CREATE TABLE cache (
|
||||
id TEXT NOT NULL UNIQUE,
|
||||
mod DATATIME DEFAULT (DATETIME('now', 'localtime')),
|
||||
img TEXT,
|
||||
name TEXT,
|
||||
url TEXT,
|
||||
desc TEXT,
|
||||
data TEXT,
|
||||
PRIMARY KEY(id)
|
||||
);");
|
||||
}
|
||||
@ -38,7 +35,7 @@ class Storage {
|
||||
*/
|
||||
static public function get(string $id): array | bool {
|
||||
$db = Storage::init();
|
||||
$stmt = $db->prepare("SELECT name, url, desc, img FROM cache WHERE id=?;");
|
||||
$stmt = $db->prepare("SELECT data FROM cache WHERE id=?;");
|
||||
if (!$stmt || !$stmt->bindValue(1, $id, SQLITE3_TEXT)) {
|
||||
throw new Exception($db->lastErrorMsg());
|
||||
return false;
|
||||
@ -49,9 +46,9 @@ class Storage {
|
||||
return false;
|
||||
}
|
||||
while ($row = $cur->fetchArray()) {
|
||||
return ['img' => $row['img'], 'name' => $row['name'], 'url' => $row['url'], 'desc' => $row['desc']];
|
||||
return json_decode($row['data'], true);
|
||||
}
|
||||
return ['img' => '', 'name' => '', 'url' => '', 'desc' => ''];
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -61,7 +58,7 @@ class Storage {
|
||||
static public function getAll(): array {
|
||||
$db = Storage::init();
|
||||
$ret = [];
|
||||
$stmt = $db->prepare("SELECT id, img, name, url, desc FROM cache;");
|
||||
$stmt = $db->prepare("SELECT id, data FROM cache;");
|
||||
if (!$stmt) {
|
||||
throw new Exception($db->lastErrorMsg());
|
||||
return $ret;
|
||||
@ -72,7 +69,7 @@ class Storage {
|
||||
return $ret;
|
||||
}
|
||||
while ($row = $cur->fetchArray()) {
|
||||
$ret[$row['id']] = [$row['img'], $row['name'], $row['url'], $row['desc']];
|
||||
$ret[$row['id']] = json_decode($row['data'], true);
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
@ -83,20 +80,15 @@ class Storage {
|
||||
* @param array $data JSON-serializable data array to write to database.
|
||||
* @return bool Success indicator.
|
||||
*/
|
||||
static public function set_data(string $id, string $name, string $url, string $desc): bool {
|
||||
$db = Storage::init();
|
||||
$stmt = $db->prepare("INSERT INTO cache (id, name, url, desc) VALUES(?, ?, ?, ?) ON CONFLICT(id) DO UPDATE SET name=excluded.name, url=excluded.url, desc=excluded.desc, mod=excluded.mod;");
|
||||
if (!$stmt || !$stmt->bindValue(1, $id, SQLITE3_TEXT) || !$stmt->bindValue(2, $name, SQLITE3_TEXT) || !$stmt->bindValue(3, $url, SQLITE3_TEXT)|| !$stmt->bindValue(4, $desc, SQLITE3_TEXT) || !$stmt->execute()) {
|
||||
throw new Exception($db->lastErrorMsg());
|
||||
static public function set(string $id, array $data): bool {
|
||||
$db = Storage::init();
|
||||
$jdata = json_encode($data);
|
||||
if ($jdata === false) {
|
||||
throw new Exception(json_last_error_msg());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static public function set_img(string $id, string $img): bool {
|
||||
$db = Storage::init();
|
||||
$stmt = $db->prepare("INSERT INTO cache (id, img) VALUES(?, ?) ON CONFLICT(id) DO UPDATE SET img=excluded.img, mod=excluded.mod;");
|
||||
if (!$stmt || !$stmt->bindValue(1, $id, SQLITE3_TEXT) || !$stmt->bindValue(2, $img, SQLITE3_TEXT) || !$stmt->execute()) {
|
||||
$stmt = $db->prepare("INSERT INTO cache (id, data) VALUES(?, ?) ON CONFLICT(id) DO UPDATE SET data=excluded.data, mod=excluded.mod;");
|
||||
if (!$stmt || !$stmt->bindValue(1, $id, SQLITE3_TEXT) || !$stmt->bindValue(2, $jdata, SQLITE3_TEXT) || !$stmt->execute()) {
|
||||
throw new Exception($db->lastErrorMsg());
|
||||
return false;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user