Merge branch 'develop' into add-statistics
This commit is contained in:
commit
ca6b01f447
9 changed files with 302 additions and 48 deletions
10
.htaccess
Normal file
10
.htaccess
Normal 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
33
src/api/url.php
Normal 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();
|
|
@ -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);
|
||||
|
|
|
@ -4,6 +4,7 @@ $(function() {
|
|||
fields: {
|
||||
email: 'email',
|
||||
password: ['minLength[6]', 'empty'],
|
||||
planet: ['minLength[3]', 'empty'],
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -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
85
src/classes/url.php
Normal 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;
|
||||
}
|
||||
}
|
|
@ -35,11 +35,14 @@ class Wishlist
|
|||
/**
|
||||
* Get Wishlist
|
||||
*/
|
||||
$this->data = $database->query('SELECT *
|
||||
$result = $database
|
||||
->query('SELECT *
|
||||
FROM `wishlists`
|
||||
WHERE `' . $column . '` = ' . $id_or_hash . ';')
|
||||
->fetch();
|
||||
|
||||
$this->data = $result ? $result : array();
|
||||
|
||||
/** Exists */
|
||||
if (isset($this->data['id'])) {
|
||||
$this->id = $this->data['id'];
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* register.php
|
||||
* Register a new user
|
||||
*
|
||||
* @author Jay Trees <github.jay@grandel.anonaddy.me>
|
||||
*/
|
||||
|
@ -9,24 +9,76 @@
|
|||
use wishthis\Page;
|
||||
|
||||
$page = new page(__FILE__, 'Register');
|
||||
$messages = array();
|
||||
|
||||
if (isset($_POST['email'], $_POST['password'])) {
|
||||
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,10 +86,18 @@ $page->navigation();
|
|||
?>
|
||||
<main>
|
||||
<div class="ui container">
|
||||
<div class="ui segment">
|
||||
<h1 class="ui header"><?= $page->title ?></h1>
|
||||
|
||||
<?= $page->messages($messages) ?>
|
||||
|
||||
<div class="ui segment">
|
||||
<form class="ui form" method="post">
|
||||
<div class="ui divided relaxed stackable two column grid">
|
||||
|
||||
<div class=" row">
|
||||
<div class="column">
|
||||
<h2 class="ui header">Account details</h2>
|
||||
|
||||
<div class="field">
|
||||
<label>Email</label>
|
||||
<input type="email" name="email" placeholder="john.doe@domain.tld" />
|
||||
|
@ -46,13 +106,36 @@ $page->navigation();
|
|||
<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 href="/?page=login">Login</a>
|
||||
<a class="ui tertiary button" href="/?page=login">Login</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</main>
|
||||
<?php
|
||||
|
|
Loading…
Reference in a new issue