Merge branch 'develop' into add-statistics

This commit is contained in:
grandeljay 2022-02-26 20:27:27 +01:00
commit ca6b01f447
9 changed files with 302 additions and 48 deletions

10
.htaccess Normal file
View file

@ -0,0 +1,10 @@
RewriteEngine On
# Wishlists
RewriteRule ^([a-z\-]+)/(\d+)$ /?page=$1&wishlist=$2 [QSA,L]
# Wishlist
RewriteRule ^wishlist/([a-z0-9]+)$ /?wishlist=$1 [QSA,L]
# Page
RewriteRule ^([a-z\-]+)$ /?page=$1 [QSA,L]

33
src/api/url.php Normal file
View file

@ -0,0 +1,33 @@
<?php
/**
* url.php
*
* @author Jay Trees <github.jay@grandel.anonaddy.me>
*/
use wishthis\URL;
$api = true;
$response = array(
'success' => false,
);
require '../../index.php';
switch ($_SERVER['REQUEST_METHOD']) {
case 'GET':
if (isset($_GET['url'])) {
$url = new URL(base64_decode($_GET['url']));
$response['data'] = array(
'url' => $url->getPretty()
);
$response['success'] = true;
}
break;
}
header('Content-type: application/json; charset=utf-8');
echo json_encode($response);
die();

View file

@ -10,7 +10,7 @@ if ('serviceWorker' in navigator) {
})
}
const urlParams = new URLSearchParams(window.location.search);
const urlParams = new URLSearchParams($_GET);
$(function() {
/**
@ -40,8 +40,8 @@ $(function() {
placeholder: 'No wishlist selected.'
})
if (urlParams.has('wishlist')) {
element.dropdown('set selected', urlParams.get('wishlist'));
if ($_GET.wishlist) {
element.dropdown('set selected', $_GET.wishlist);
} else {
if (response.results[0]) {
element.dropdown('set selected', response.results[0].value);

View file

@ -4,6 +4,7 @@ $(function() {
fields: {
email: 'email',
password: ['minLength[6]', 'empty'],
planet: ['minLength[3]', 'empty'],
}
});
});

View file

@ -17,8 +17,8 @@ $(function () {
placeholder: 'No wishlist selected.'
})
if (urlParams.has('wishlist')) {
element.dropdown('set selected', urlParams.get('wishlist'));
if ($_GET.wishlist) {
element.dropdown('set selected', $_GET.wishlist);
} else {
if (wishlists[0]) {
element.dropdown('set selected', wishlists[0].value);
@ -45,14 +45,26 @@ $(function () {
$('[name="wishlist_delete_id"]').val(wishlistValue);
if (wishlistValue) {
urlParams.set('wishlist', wishlistValue);
window.history.pushState({}, '', '/?' + urlParams.toString());
$_GET.wishlist = wishlistValue;
$('.wishlist-share').attr('href', '/?wishlist=' + wishlists[wishlistIndex].hash);
$('.button.wishlist-product-add').removeClass('disabled');
$('.button.wishlist-share').removeClass('disabled');
$('.wishlist-delete button').removeClass('disabled');
/** Update URL */
urlParams.set('wishlist', wishlistValue);
fetch('/src/api/url.php?url=' + btoa(urlParams.toString()), {
method: 'GET'
})
.then(response => response.json())
.then(response => {
if (response.success) {
window.history.pushState({}, '', response.data.url);
}
});
} else {
$('.button.wishlist-product-add').addClass('disabled');
$('.button.wishlist-share').addClass('disabled');

View file

@ -6,7 +6,7 @@
namespace wishthis;
use wishthis\User;
use wishthis\{User, URL};
class Page
{
@ -125,6 +125,17 @@ class Page
header('Location: /?page=power&required=' . $this->power);
die();
}
/**
* Redirect
*/
$url = new URL($_SERVER['QUERY_STRING']);
$redirect_to = $url->getPretty();
if ($redirect_to && $redirect_to !== $_SERVER['REQUEST_URI']) {
header('Location: ' . $redirect_to);
die();
}
}
public function header(): void
@ -157,12 +168,12 @@ class Page
/** Fomantic UI */
$stylesheetFomantic = 'semantic/dist/semantic.min.css';
$stylesheetFomanticModified = filemtime($stylesheetFomantic);
echo '<link rel="stylesheet" href="' . $stylesheetFomantic . '?m=' . $stylesheetFomanticModified . '" />';
echo '<link rel="stylesheet" type="text/css" href="/' . $stylesheetFomantic . '?m=' . $stylesheetFomanticModified . '" />';
/** Default */
$stylesheetDefault = 'src/assets/css/default.css';
$stylesheetDefaultModified = filemtime($stylesheetDefault);
echo '<link rel="stylesheet" href="' . $stylesheetDefault . '?m=' . $stylesheetDefaultModified . '" />';
echo '<link rel="stylesheet" type="text/css" href="/' . $stylesheetDefault . '?m=' . $stylesheetDefaultModified . '" />';
/** Page */
$stylesheetPage = 'src/assets/css/' . $this->name . '.css';
@ -170,27 +181,32 @@ class Page
if (file_exists($stylesheetPage)) {
$stylesheetPageModified = filemtime($stylesheetPage);
echo '<link rel="stylesheet" href="' . $stylesheetPage . '?m=' . $stylesheetPageModified . '" />';
echo '<link rel="stylesheet" type="text/css" href="/' . $stylesheetPage . '?m=' . $stylesheetPageModified . '" />';
}
/**
* Scripts
*/
?>
<script type="text/javascript">
var $_GET = JSON.parse('<?= isset($_GET) ? json_encode($_GET) : array() ?>');
</script>
<?php
/** jQuery */
$scriptjQuery = 'node_modules/jquery/dist/jquery.min.js';
$scriptjQueryModified = filemtime($scriptjQuery);
echo '<script defer src="' . $scriptjQuery . '?m=' . $scriptjQueryModified . '"></script>';
echo '<script defer src="/' . $scriptjQuery . '?m=' . $scriptjQueryModified . '"></script>';
/** Fomantic */
$scriptFomantic = 'semantic/dist/semantic.min.js';
$scriptFomanticModified = filemtime($scriptFomantic);
echo '<script defer src="' . $scriptFomantic . '?m=' . $scriptFomanticModified . '"></script>';
echo '<script defer src="/' . $scriptFomantic . '?m=' . $scriptFomanticModified . '"></script>';
/** Default */
$scriptDefault = 'src/assets/js/default.js';
$scriptDefaultModified = filemtime($scriptDefault);
echo '<script defer src="' . $scriptDefault . '?m=' . $scriptDefaultModified . '"></script>';
echo '<script defer src="/' . $scriptDefault . '?m=' . $scriptDefaultModified . '"></script>';
/** Page */
$scriptPage = 'src/assets/js/' . $this->name . '.js';
@ -198,7 +214,7 @@ class Page
if (file_exists($scriptPage)) {
$scriptPageModified = filemtime($scriptPage);
echo '<script defer src="' . $scriptPage . '?m=' . $scriptPageModified . '"></script>';
echo '<script defer src="/' . $scriptPage . '?m=' . $scriptPageModified . '"></script>';
}
?>
@ -321,4 +337,15 @@ class Page
</html>
<?php
}
public function messages(array $messages): string
{
$html = '';
foreach ($messages as $message) {
$html .= $message;
}
return $html;
}
}

85
src/classes/url.php Normal file
View file

@ -0,0 +1,85 @@
<?php
/**
* Returns the pretty version of a URL.
*
* @author Jay Trees <github.jay@grandel.anonaddy.me>
*/
namespace wishthis;
class URL
{
public function __construct(private string $url) {
}
public function getPretty(): string
{
$htaccess = explode(PHP_EOL, file_get_contents(ROOT . '/.htaccess'));
$pretty_url = '';
foreach ($htaccess as $index => $line) {
$parts = explode(chr(32), $line);
if (count($parts) >= 2) {
switch ($parts[0]) {
case 'RewriteRule':
$rewriteRule = $parts[1];
$rewriteRule = ltrim($rewriteRule, '^');
$rewriteRule = rtrim($rewriteRule, '$');
$target = $parts[2];
$keys = array_map(
function($item) {
return explode('=', $item)[0];
},
explode('&', parse_url($target, PHP_URL_QUERY))
);
$flags = explode(',', substr($parts[3], 1, -1)) ?? array();
$parameters_pairs = explode('&', parse_url($this->url, PHP_URL_PATH));
$parameters = array();
foreach ($parameters_pairs as $index => $pair) {
$parts = explode('=', $pair);
$key = $parts[0];
$value = $parts[1];
$parameters[$key] = $value;
}
preg_match_all('/\(.+?\)/', $rewriteRule, $regexes);
$countMatches = 0;
foreach ($regexes as $matches) {
foreach ($matches as $match) {
foreach ($parameters as $key => $value) {
if (
preg_match('/^' . $match . '$/', $value)
&& in_array($key, $keys)
&& count($parameters) === count($keys)
) {
$rewriteRule = str_replace($match, $value, $rewriteRule);
$countMatches++;
break;
}
}
}
if ($countMatches > 0 && $countMatches === count($matches)) {
$pretty_url = '/' . $rewriteRule;
if (in_array('L', $flags)) {
break 3;
}
}
}
break;
}
}
}
return $pretty_url;
}
}

View file

@ -35,10 +35,13 @@ class Wishlist
/**
* Get Wishlist
*/
$this->data = $database->query('SELECT *
FROM `wishlists`
WHERE `' . $column . '` = ' . $id_or_hash . ';')
->fetch();
$result = $database
->query('SELECT *
FROM `wishlists`
WHERE `' . $column . '` = ' . $id_or_hash . ';')
->fetch();
$this->data = $result ? $result : array();
/** Exists */
if (isset($this->data['id'])) {

View file

@ -1,32 +1,84 @@
<?php
/**
* register.php
* Register a new user
*
* @author Jay Trees <github.jay@grandel.anonaddy.me>
*/
use wishthis\Page;
$page = new page(__FILE__, 'Register');
$page = new page(__FILE__, 'Register');
$messages = array();
if (isset($_POST['email'], $_POST['password'])) {
$users = $database->query('SELECT * FROM `users`;')->fetchAll();
if (isset($_POST['email'], $_POST['password']) && !empty($_POST['planet'])) {
$users = $database->query('SELECT * FROM `users`;')->fetchAll();
$emails = array_map(
function($user) {
return $user['email'];
},
$users
);
if (0 === count($users)) {
$database->query('INSERT INTO `users`
(`email`, `password`, `power`) VALUES
("' . $_POST['email'] . '", "' . sha1($_POST['password']) . '", 100)
;');
} else {
$database->query('INSERT INTO `users`
(`email`, `password`) VALUES
("' . $_POST['email'] . '", "' . sha1($_POST['password']) . '")
;');
$isHuman = false;
$planet = strtolower($_POST['planet']);
$planetName = strtoupper($planet[0]) . substr($planet, 1);
$planets = array(
'mercury',
'venus',
'earth',
'mars',
'jupiter',
'saturn',
'uranus',
'neptune',
);
$not_planets = array(
'pluto',
'sun'
);
if (in_array($planet, array_merge($planets, $not_planets))) {
$isHuman = true;
}
header('Location: /?page=login');
die();
if (in_array($planet, $not_planets)) {
$messages[] = Page::warning('<strong>' . $planetName . '</strong> is not a planet but I\'ll let it slide, since only a human would make this kind of mistake.', 'Invalid planet');
}
if ($isHuman) {
if (0 === count($users)) {
$database->query('INSERT INTO `users`
(
`email`,
`password`,
`power`
) VALUES (
"' . $_POST['email'] . '",
"' . sha1($_POST['password']) . '",
100
)
;');
} else {
if (in_array($_POST['email'], $emails)) {
$messages[] = Page::error('An account with this email address already exists.', 'Invalid email address');
} else {
$database->query('INSERT INTO `users`
(
`email`,
`password`
) VALUES (
"' . $_POST['email'] . '",
"' . sha1($_POST['password']) . '"
)
;');
$messages[] = Page::success('Your account was successfully created.', 'Success');
}
}
} else {
$messages[] = Page::error('<strong>' . $planetName . '</strong> is not a planet in our solar system. Read this for more information: <a href="https://www.space.com/16080-solar-system-planets.html" target="_blank">Solar system planets: Order of the 8 (or 9) planets</a>', 'Invalid planet');
}
}
$page->header();
@ -34,25 +86,56 @@ $page->navigation();
?>
<main>
<div class="ui container">
<h1 class="ui header"><?= $page->title ?></h1>
<?= $page->messages($messages) ?>
<div class="ui segment">
<h1 class="ui header"><?= $page->title ?></h1>
<form class="ui form" method="post">
<div class="field">
<label>Email</label>
<input type="email" name="email" placeholder="john.doe@domain.tld" />
</div>
<div class="field">
<label>Password</label>
<input type="password" name="password" />
</div>
<div class="ui divided relaxed stackable two column grid">
<div class="ui error message"></div>
<div class=" row">
<div class="column">
<h2 class="ui header">Account details</h2>
<input class="ui primary button" type="submit" value="Register" />
<a href="/?page=login">Login</a>
<div class="field">
<label>Email</label>
<input type="email" name="email" placeholder="john.doe@domain.tld" />
</div>
<div class="field">
<label>Password</label>
<input type="password" name="password" />
</div>
</div>
<div class="column">
<h2 class="ui header">Authentication</h2>
<p>
Prove you are a Human, Lizard-person or Zuck-Like creature.
Please name a planet from our solar system.
</p>
<div class="field">
<label>Planet</label>
<input type="text" name="planet" />
</div>
<p>Robots are obivously from another solar system so this will keep them at bay.</p>
</div>
</div>
<div class="row">
<div class="column">
<div class="ui error message"></div>
<input class="ui primary button" type="submit" value="Register" />
<a class="ui tertiary button" href="/?page=login">Login</a>
</div>
</div>
</div>
</form>
</div>
</div>
</main>
<?php