1
0

Merge branch 'feature-Baseclass'

This commit is contained in:
Mike Schwörer 2020-01-20 17:46:10 +01:00
commit 9c8e61b203
Signed by: Mikescher
GPG Key ID: D3C7172E0A70F8CF
106 changed files with 4328 additions and 2536 deletions

4
.gitignore vendored
View File

@ -6,3 +6,7 @@ runtime/
**/.idea/tasks.xml **/.idea/tasks.xml
**/.idea/dataSources* **/.idea/dataSources*
config.php
www/dtest.php

View File

@ -1,7 +1,13 @@
<component name="InspectionProjectProfileManager"> <component name="InspectionProjectProfileManager">
<profile version="1.0" is_locked="false"> <profile version="1.0" is_locked="false">
<option name="myName" value="Project Default" /> <option name="myName" value="Project Default" />
<option name="myLocal" value="false" /> <inspection_tool class="DuplicatedCode" enabled="true" level="WEAK WARNING" enabled_by_default="true">
<Languages>
<language minSize="100" name="PHP" />
</Languages>
</inspection_tool>
<inspection_tool class="HtmlUnknownTarget" enabled="true" level="INFORMATION" enabled_by_default="true" />
<inspection_tool class="PhpUnhandledExceptionInspection" enabled="true" level="INFORMATION" enabled_by_default="true" />
<inspection_tool class="SpellCheckingInspection" enabled="false" level="TYPO" enabled_by_default="false"> <inspection_tool class="SpellCheckingInspection" enabled="false" level="TYPO" enabled_by_default="false">
<option name="processCode" value="true" /> <option name="processCode" value="true" />
<option name="processLiterals" value="true" /> <option name="processLiterals" value="true" />

6
.idea/jsLibraryMappings.xml generated Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="JavaScriptLibraryMappings">
<file url="file://$PROJECT_DIR$/www/data/javascript/admin.js" libraries="{jquery-latest}" />
</component>
</project>

View File

@ -34,7 +34,7 @@
<array /> <array />
</option> </option>
<option name="outputFromStdout" value="false" /> <option name="outputFromStdout" value="false" />
<option name="program" value="python" /> <option name="program" value="python3" />
<option name="runOnExternalChanges" value="true" /> <option name="runOnExternalChanges" value="true" />
<option name="scopeName" value="Project Files" /> <option name="scopeName" value="Project Files" />
<option name="trackOnlyRoot" value="true" /> <option name="trackOnlyRoot" value="true" />

View File

@ -8,5 +8,6 @@
</content> </content>
<orderEntry type="inheritedJdk" /> <orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="jquery-latest" level="application" />
</component> </component>
</module> </module>

View File

@ -2,27 +2,30 @@
import sys import sys
import os import os
from subprocess import call
import re import re
import subprocess import subprocess
def findnext(str, start, chr):
depth = 0
for i in range(start, len(str)):
if (str[i] == chr): return i;
def findclose(str, start): def findnext(strdata, start, searchchr):
depth = 0 depth = 0
for i in range(start, len(str)): for i in range(start, len(strdata)):
if (str[i] == '{'): depth = depth+1; if strdata[i] == searchchr: return i;
if (str[i] == '}'): depth = depth-1;
if (depth == 0): return i;
def countnl(str, start, end):
def findclose(strdata, start):
depth = 0
for i in range(start, len(strdata)):
if strdata[i] == '{': depth = depth + 1;
if strdata[i] == '}': depth = depth - 1;
if depth == 0: return i;
def countnl(strdata, start, end):
cnt = 0 cnt = 0
for i in range(start, end+1): for i in range(start, end + 1):
if (str[i] == '\n'): cnt = cnt+1; if strdata[i] == '\n': cnt = cnt + 1;
return cnt; return cnt
def comment_remover(text): def comment_remover(text):
def replacer(match): def replacer(match):
@ -31,30 +34,32 @@ def comment_remover(text):
return " " # note: a space and not an empty string return " " # note: a space and not an empty string
else: else:
return s return s
pattern = re.compile( pattern = re.compile(
r'//.*?$|/\*.*?\*/|\'(?:\\.|[^\\\'])*\'|"(?:\\.|[^\\"])*"', r'//.*?$|/\*.*?\*/|\'(?:\\.|[^\\\'])*\'|"(?:\\.|[^\\"])*"',
re.DOTALL | re.MULTILINE re.DOTALL | re.MULTILINE
) )
return re.sub(pattern, replacer, text) return re.sub(pattern, replacer, text)
fsource = str.replace(sys.argv[1], '\\', '/') # scss fsource = str.replace(sys.argv[1], '\\', '/') # scss
finput = str.replace(sys.argv[2], '\\', '/') # css finput = str.replace(sys.argv[2], '\\', '/') # css
foutput = str.replace(sys.argv[3], '\\', '/') # min.css foutput = str.replace(sys.argv[3], '\\', '/') # min.css
ftemp1 = '__temp_compresss_py_1.tmp.css'; ftemp1 = '__temp_compresss_py_1.tmp.css'
ftemp2 = '__temp_compresss_py_2.tmp.css'; ftemp2 = '__temp_compresss_py_2.tmp.css'
print('======== INPUT ========'); print('======== INPUT ========')
print(); print()
print(fsource); print(fsource)
print(finput); print(finput)
print(foutput); print(foutput)
print(); print()
print(); print()
print('======== DELETE OLD DATA ========'); print('======== DELETE OLD DATA ========')
if os.path.isfile(finput): if os.path.isfile(finput):
try: try:
os.remove(finput); os.remove(finput)
print(finput + ' deleted') print(finput + ' deleted')
except: except:
print(sys.exc_info()[0]) print(sys.exc_info()[0])
@ -62,18 +67,18 @@ else:
print(finput + ' does not exist') print(finput + ' does not exist')
if os.path.isfile(foutput): if os.path.isfile(foutput):
try: try:
os.remove(foutput); os.remove(foutput)
print(foutput + ' deleted') print(foutput + ' deleted')
except: except:
print(sys.exc_info()[0]) print(sys.exc_info()[0])
else: else:
print(foutput + ' does not exist') print(foutput + ' does not exist')
print(); print()
print(); print()
print('======== CALL SCSS ========')
print('======== CALL SCSS ========'); out = subprocess.run(['ruby', 'scss', '--style=expanded', '--no-cache', '--update', fsource + ':' + finput],
out = subprocess.run(['ruby', 'scss', '--style=expanded', '--no-cache', '--update', fsource + ':' + finput], stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout=subprocess.PIPE, stderr=subprocess.PIPE)
print('> scss.bat --style=expanded --no-cache --update ' + fsource + ':' + finput) print('> scss.bat --style=expanded --no-cache --update ' + fsource + ':' + finput)
print('STDOUT:') print('STDOUT:')
print(out.stdout.decode('utf-8')) print(out.stdout.decode('utf-8'))
@ -83,13 +88,13 @@ print(out.stderr.decode('utf-8'))
print('') print('')
print('') print('')
print('======== CLEANUP COMMENTS ========'); print('======== CLEANUP COMMENTS ========')
with open(finput, 'r') as tf: with open(finput, 'r') as tf:
data1 = tf.read() data1 = tf.read()
print(str(len(data1)) + ' characters read from ' + os.path.basename(finput)) print(str(len(data1)) + ' characters read from ' + os.path.basename(finput))
data1 = comment_remover(data1) data1 = comment_remover(data1)
print('Comments in css removed'); print('Comments in css removed')
with open(ftemp1, "w") as tf: with open(ftemp1, "w") as tf:
tf.write(data1) tf.write(data1)
@ -98,19 +103,19 @@ with open(ftemp1, "w") as tf:
print('') print('')
print('') print('')
print('======== CALL YUI ========')
print('======== CALL YUI ========'); out = subprocess.run(['java', '-jar', 'yuicompressor.jar', '--verbose', ftemp1, '-o', ftemp2], stdout=subprocess.PIPE,
out = subprocess.run(['java', '-jar', 'yuicompressor.jar', '--verbose', ftemp1, '-o', ftemp2], stdout=subprocess.PIPE, stderr=subprocess.PIPE) stderr=subprocess.PIPE)
print('> java -jar yuicompressor.jar --verbose "'+finput+'" -o "'+ftemp2+'"') print('> java -jar yuicompressor.jar --verbose "' + finput + '" -o "' + ftemp2 + '"')
print('STDOUT:'); print('STDOUT:')
print(out.stdout.decode('utf-8')) print(out.stdout.decode('utf-8'))
print('STDERR:'); print('STDERR:')
print(out.stderr.decode('utf-8')) print(out.stderr.decode('utf-8'))
print('') print('')
print('') print('')
print('======== READ ========'); print('======== READ ========')
with open(ftemp2, 'r') as tf: with open(ftemp2, 'r') as tf:
data = tf.read() data = tf.read()
print(str(len(data)) + ' characters read from ' + ftemp2) print(str(len(data)) + ' characters read from ' + ftemp2)
@ -118,11 +123,11 @@ with open(ftemp2, 'r') as tf:
print('') print('')
print('') print('')
print('======== REM ========'); print('======== REM ========')
try: try:
os.remove(ftemp1); os.remove(ftemp1)
print(ftemp1 + ' deleted') print(ftemp1 + ' deleted')
os.remove(ftemp2); os.remove(ftemp2)
print(ftemp2 + ' deleted') print(ftemp2 + ' deleted')
except: except:
print(sys.exc_info()[0]) print(sys.exc_info()[0])
@ -130,30 +135,29 @@ except:
print('') print('')
print('') print('')
print('======== REGEX ========'); print('======== REGEX ========')
data = re.sub(r'(\}*\})', '\g<1>\n', data); data = re.sub(r'(\}*\})', '\g<1>\n', data)
print('css data modified (1)') print('css data modified (1)')
print('') print('')
print('') print('')
print('======== MEDIA ========'); print('======== MEDIA ========')
ins = [] ins = []
for i in range(len(data)): for i in range(len(data)):
if data[i:].startswith('@media'): if data[i:].startswith('@media'):
copen = findnext(data, i, '{') copen = findnext(data, i, '{')
cclose = findclose(data, copen) cclose = findclose(data, copen)
if (countnl(data, copen, cclose) == 0): continue; if countnl(data, copen, cclose) == 0: continue;
ins.append( (copen+1, '\n\t') ) ins.append((copen + 1, '\n\t'))
for i in range(copen+1, cclose): for i2 in range(copen + 1, cclose):
if data[i] == '\n': if data[i2] == '\n':
tp =(i+1, '\t') tp = (i2 + 1, '\t')
ins.append( tp ) ins.append(tp)
ins.append((cclose, '\n')) ins.append((cclose, '\n'))
print('media query at idx:' + str(i) + ' formatted') print('media query at idx:' + str(i) + ' formatted')
@ -163,7 +167,7 @@ for (l, c) in reversed(ins):
print('') print('')
print('') print('')
print('======== WRITE ========'); print('======== WRITE ========')
with open(foutput, "w") as tf: with open(foutput, "w") as tf:
tf.write(data) tf.write(data)
print(str(len(data)) + ' characters written to ' + foutput) print(str(len(data)) + ' characters written to ' + foutput)
@ -171,12 +175,12 @@ with open(foutput, "w") as tf:
print('') print('')
print('') print('')
print('======== REMOVE MAP ========'); print('======== REMOVE MAP ========')
if os.path.isfile(finput + '.map'): if os.path.isfile(finput + '.map'):
try: try:
os.remove(finput + '.map'); os.remove(finput + '.map')
print(finput + '.map' + ' deleted') print(finput + '.map' + ' deleted')
except e: except Exception as e:
print(e) print(e)
else: else:
print(finput + '.map' + ' does not exist') print(finput + '.map' + ' does not exist')
@ -184,5 +188,4 @@ else:
print('') print('')
print('') print('')
print('Finished.') print('Finished.')

View File

@ -1,9 +1,9 @@
<?php <?php
require_once (__DIR__ . '/../internals/base.php'); require_once (__DIR__ . '/../internals/website.php');
require_once (__DIR__ . '/../internals/database.php');
require_once (__DIR__ . '/../internals/alephnoteStatistics.php');
Database::connect(); /** @var PageFrameOptions $FRAME_OPTIONS */ global $FRAME_OPTIONS;
/** @var URLRoute $ROUTE */ global $ROUTE;
/** @var Website $SITE */ global $SITE;
?> ?>
<div class="stripedtable_container"> <div class="stripedtable_container">
@ -20,7 +20,7 @@ Database::connect();
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<?php foreach (AlephNoteStatistics::getAllActiveEntriesOrdered() as $entry): ?> <?php foreach ($SITE->modules->AlephNoteStatistics()->getAllActiveEntriesOrdered() as $entry): ?>
<tr> <tr>
<td><?php echo $entry['ClientID']; ?></td> <td><?php echo $entry['ClientID']; ?></td>
<td><?php echo $entry['Version']; ?></td> <td><?php echo $entry['Version']; ?></td>

View File

@ -1,16 +1,17 @@
<?php <?php
require_once (__DIR__ . '/../internals/website.php');
global $API_OPTIONS; /** @var PageFrameOptions $FRAME_OPTIONS */ global $FRAME_OPTIONS;
/** @var URLRoute $ROUTE */ global $ROUTE;
/** @var Website $SITE */ global $SITE;
require_once (__DIR__ . '/../internals/base.php');
require_once (__DIR__ . '/../internals/database.php');
if (!isset($API_OPTIONS['name'])) httpDie(400, "Wrong parameters."); if (!isset($API_OPTIONS['name'])) { $FRAME_OPTIONS->forceResult(400, "Wrong parameters."); return; }
if (!isset($API_OPTIONS['clientid'])) httpDie(400, "Wrong parameters."); if (!isset($API_OPTIONS['clientid'])) { $FRAME_OPTIONS->forceResult(400, "Wrong parameters."); return; }
if (!isset($API_OPTIONS['version'])) httpDie(400, "Wrong parameters."); if (!isset($API_OPTIONS['version'])) { $FRAME_OPTIONS->forceResult(400, "Wrong parameters."); return; }
if (!isset($API_OPTIONS['providerstr'])) httpDie(400, "Wrong parameters."); if (!isset($API_OPTIONS['providerstr'])) { $FRAME_OPTIONS->forceResult(400, "Wrong parameters."); return; }
if (!isset($API_OPTIONS['providerid'])) httpDie(400, "Wrong parameters."); if (!isset($API_OPTIONS['providerid'])) { $FRAME_OPTIONS->forceResult(400, "Wrong parameters."); return; }
if (!isset($API_OPTIONS['notecount'])) httpDie(400, "Wrong parameters."); if (!isset($API_OPTIONS['notecount'])) { $FRAME_OPTIONS->forceResult(400, "Wrong parameters."); return; }
$nam = $API_OPTIONS['name']; $nam = $API_OPTIONS['name'];
$cid = $API_OPTIONS['clientid']; $cid = $API_OPTIONS['clientid'];
@ -22,9 +23,7 @@ $tnc = $API_OPTIONS['notecount'];
if ($nam !== 'AlephNote') print('{"success":false, "message":"Unknown AppName"}'); if ($nam !== 'AlephNote') print('{"success":false, "message":"Unknown AppName"}');
Database::connect(); $SITE->modules->Database()->sql_exec_prep('INSERT INTO an_statslog (ClientID, Version, ProviderStr, ProviderID, NoteCount) VALUES (:cid1, :ver1, :prv1, :pid1, :tnc1) ON DUPLICATE KEY UPDATE Version=:ver2,ProviderStr=:prv2,ProviderID=:pid2,NoteCount=:tnc2',
Database::sql_exec_prep('INSERT INTO an_statslog (ClientID, Version, ProviderStr, ProviderID, NoteCount) VALUES (:cid1, :ver1, :prv1, :pid1, :tnc1) ON DUPLICATE KEY UPDATE Version=:ver2,ProviderStr=:prv2,ProviderID=:pid2,NoteCount=:tnc2',
[ [
[':cid1', $cid, PDO::PARAM_STR], [':cid1', $cid, PDO::PARAM_STR],
[':ver1', $ver, PDO::PARAM_STR], [':ver1', $ver, PDO::PARAM_STR],

View File

@ -1,3 +1,9 @@
<?php <?php
require_once (__DIR__ . '/../internals/website.php');
echo "{}"; /** @var PageFrameOptions $FRAME_OPTIONS */ global $FRAME_OPTIONS;
/** @var URLRoute $ROUTE */ global $ROUTE;
/** @var Website $SITE */ global $SITE;
echo "{}";

View File

@ -1,11 +1,11 @@
<?php <?php
require_once (__DIR__ . '/../internals/website.php');
/** @var PageFrameOptions $FRAME_OPTIONS */ global $FRAME_OPTIONS;
/** @var URLRoute $ROUTE */ global $ROUTE;
/** @var Website $SITE */ global $SITE;
require_once (__DIR__ . '/../internals/base.php');
require_once (__DIR__ . '/../extern/egg/ExtendedGitGraph2.php');
require_once (__DIR__ . '/../internals/mikeschergitgraph.php');
set_time_limit(900); // 15min set_time_limit(900); // 15min
$v = MikescherGitGraph::create(); $v = $SITE->modules->ExtendedGitGraph()->updateCache();
$v->updateCache();

View File

@ -1,12 +1,12 @@
<?php <?php
require_once (__DIR__ . '/../internals/website.php');
require_once (__DIR__ . '/../internals/base.php'); /** @var PageFrameOptions $FRAME_OPTIONS */ global $FRAME_OPTIONS;
require_once (__DIR__ . '/../extern/egg/ExtendedGitGraph2.php'); /** @var URLRoute $ROUTE */ global $ROUTE;
require_once (__DIR__ . '/../internals/mikeschergitgraph.php'); /** @var Website $SITE */ global $SITE;
set_time_limit(900); // 15min set_time_limit(900); // 15min
$v = MikescherGitGraph::create(); $SITE->modules->ExtendedGitGraph()->update();
$v->update(); $SITE->modules->ExtendedGitGraph()->updateCache();
$v->updateCache();

View File

@ -1,10 +1,14 @@
<?php <?php
require_once (__DIR__ . '/../internals/website.php');
global $CONFIG; /** @var PageFrameOptions $FRAME_OPTIONS */ global $FRAME_OPTIONS;
/** @var URLRoute $ROUTE */ global $ROUTE;
/** @var Website $SITE */ global $SITE;
if ($CONFIG['extendedgitgraph']['output_file'])
if ($SITE->config['extendedgitgraph']['output_file'])
{ {
$lfile = $CONFIG['extendedgitgraph']['output_filepath']; $lfile = $SITE->config['extendedgitgraph']['output_filepath'];
if (file_exists($lfile)) if (file_exists($lfile))
{ {
@ -18,11 +22,11 @@ if ($CONFIG['extendedgitgraph']['output_file'])
echo '[[ FILE NOT FOUND ]]'; echo '[[ FILE NOT FOUND ]]';
} }
} }
else if ($CONFIG['extendedgitgraph']['output_file']) else if ($SITE->config['extendedgitgraph']['output_file'])
{ {
if (session_status() !== PHP_SESSION_ACTIVE) session_start(); if (session_status() !== PHP_SESSION_ACTIVE) session_start();
$svar = $CONFIG['extendedgitgraph']['session_var']; $svar = $SITE->config['extendedgitgraph']['session_var'];
if (isset($_GET['clear'])) if (key_exists($svar, $_SESSION)) $_SESSION[$svar] = ''; if (isset($_GET['clear'])) if (key_exists($svar, $_SESSION)) $_SESSION[$svar] = '';

View File

@ -1,16 +1,21 @@
<?php <?php
require_once (__DIR__ . '/../internals/website.php');
require_once (__DIR__ . '/../internals/base.php'); /** @var PageFrameOptions $FRAME_OPTIONS */ global $FRAME_OPTIONS;
require_once (__DIR__ . '/../internals/adventofcode.php'); /** @var URLRoute $ROUTE */ global $ROUTE;
/** @var Website $SITE */ global $SITE;
global $PARAM_AOCCALENDAR;
$PARAM_AOCCALENDAR =
[ if (!isset($API_OPTIONS['year'])) { $FRAME_OPTIONS->forceResult(400, "Wrong parameters."); return; }
'year' => intval($_GET['year']), if (!isset($API_OPTIONS['nav'])) { $FRAME_OPTIONS->forceResult(400, "Wrong parameters."); return; }
'nav' => boolval($_GET['nav']), if (!isset($API_OPTIONS['linkheader'])) { $FRAME_OPTIONS->forceResult(400, "Wrong parameters."); return; }
'linkheader' => boolval($_GET['linkheader']), if (!isset($API_OPTIONS['ajax'])) { $FRAME_OPTIONS->forceResult(400, "Wrong parameters."); return; }
'ajax' => boolval($_GET['ajax']),
'frame' => false, $year = intval($API_OPTIONS['year']);
'frameid' => strval($_GET['frameid']), $shownav = boolval($API_OPTIONS['nav']);
]; $linkheader = boolval($API_OPTIONS['linkheader']);
require (__DIR__ . '/../fragments/panel_aoc_calendar.php'); $ajax = boolval($API_OPTIONS['ajax']);
$frameid = strval($API_OPTIONS['frameid']);
echo $SITE->fragments->PanelAdventOfCodeCalendar($year, $shownav, $linkheader, $ajax, false, $frameid);

View File

@ -1,21 +1,21 @@
<?php <?php
require_once (__DIR__ . '/../internals/website.php');
global $API_OPTIONS; /** @var PageFrameOptions $FRAME_OPTIONS */ global $FRAME_OPTIONS;
/** @var URLRoute $ROUTE */ global $ROUTE;
/** @var Website $SITE */ global $SITE;
require_once (__DIR__ . '/../internals/base.php');
require_once (__DIR__ . '/../internals/programs.php');
require_once (__DIR__ . '/../internals/updateslog.php');
if (!isset($API_OPTIONS['name'])) httpDie(400, "Wrong parameters."); if (!isset($API_OPTIONS['name'])) { $FRAME_OPTIONS->forceResult(400, "Wrong parameters."); return; }
$name = $API_OPTIONS['name']; $name = $API_OPTIONS['name'];
$updatedata = Programs::listUpdateData(); $updatedata = $SITE->modules->UpdatesLog()->listUpdateData();
if (!array_key_exists($name, $updatedata)) httpError(404, 'Invalid Request - [Name] not found'); if (!array_key_exists($name, $updatedata)) { $FRAME_OPTIONS->forceResult(404, 'Invalid Request - [Name] not found'); return; }
$data = $updatedata[$name]; $data = $updatedata[$name];
UpdatesLog::insert($name, $data['version']); $SITE->modules->UpdatesLog()->insert($name, $data['version']);
print($name."<hr>".$data['version']."<hr>".$data['url']); print($name."<hr>".$data['version']."<hr>".$data['url']);

View File

@ -1,17 +1,17 @@
<?php <?php
require_once (__DIR__ . '/../internals/website.php');
global $API_OPTIONS; /** @var PageFrameOptions $FRAME_OPTIONS */ global $FRAME_OPTIONS;
global $OPTIONS; /** @var URLRoute $ROUTE */ global $ROUTE;
/** @var Website $SITE */ global $SITE;
require_once (__DIR__ . '/../internals/base.php');
require_once (__DIR__ . '/../internals/database.php');
if (!isset($API_OPTIONS['folder'])) httpDie(400, "Wrong parameters."); if (!isset($API_OPTIONS['folder'])) { $FRAME_OPTIONS->forceResult(400, "Wrong parameters."); return; }
if (!isset($API_OPTIONS['filename'])) httpDie(400, "Wrong parameters."); if (!isset($API_OPTIONS['filename'])) { $FRAME_OPTIONS->forceResult(400, "Wrong parameters."); return; }
$folder = $API_OPTIONS['folder']; $folder = $API_OPTIONS['folder'];
$filename = $API_OPTIONS['filename']; $filename = $API_OPTIONS['filename'];
$uri = $OPTIONS['uri']; $uri = $ROUTE->full_url;
$reltarget = "Backup/$folder/$filename"; $reltarget = "Backup/$folder/$filename";

View File

@ -1,21 +1,27 @@
<?php <?php
require_once (__DIR__ . '/../internals/website.php');
global $API_OPTIONS; /** @var PageFrameOptions $FRAME_OPTIONS */ global $FRAME_OPTIONS;
global $OPTIONS; /** @var URLRoute $ROUTE */ global $ROUTE;
/** @var Website $SITE */ global $SITE;
require_once (__DIR__ . '/../internals/base.php');
require_once (__DIR__ . '/../internals/database.php');
if (!isset($API_OPTIONS['target'])) httpDie(400, "Wrong parameters."); if (!isset($API_OPTIONS['target'])) { $FRAME_OPTIONS->forceResult(400, "Wrong parameters."); return; }
$hook = $API_OPTIONS['target']; $hook = $API_OPTIONS['target'];
$uri = $OPTIONS['uri']; $uri = $ROUTE->full_url;
$cmd = ""; $cmd = "";
if ($hook == 'website_mikescher') $cmd = 'git pull'; if ($hook == 'website_mikescher')
else if ($hook == 'griddominance') $cmd = 'update-gdapi'; $cmd = 'git pull';
else httpDie(400, "Unknown webhook: $hook"); else if ($hook == 'griddominance')
$cmd = 'update-gdapi';
else
{
$FRAME_OPTIONS->forceResult(400, "Unknown webhook: $hook");
return;
}
$std = shell_exec($cmd); $std = shell_exec($cmd);

View File

@ -1,4 +1,9 @@
<?php <?php
require_once (__DIR__ . '/../internals/website.php');
/** @var PageFrameOptions $FRAME_OPTIONS */ global $FRAME_OPTIONS;
/** @var URLRoute $ROUTE */ global $ROUTE;
/** @var Website $SITE */ global $SITE;
$ip = get_client_ip(); $ip = get_client_ip();

View File

@ -1,10 +1,10 @@
<?php <?php
require_once (__DIR__ . '/../internals/website.php');
global $OPTIONS; /** @var PageFrameOptions $FRAME_OPTIONS */ global $FRAME_OPTIONS;
/** @var URLRoute $ROUTE */ global $ROUTE;
/** @var Website $SITE */ global $SITE;
require_once (__DIR__ . '/../internals/base.php');
require_once (__DIR__ . '/../internals/books.php');
require_once (__DIR__ . '/../internals/programs.php');
echo '<!DOCTYPE html>'; echo '<!DOCTYPE html>';
echo '<html lang="en">'; echo '<html lang="en">';
@ -17,10 +17,10 @@ echo '<meta http-equiv="refresh" content="3; url=/admin; ?>" />';
echo '</head>'; echo '</head>';
echo '<body>'; echo '<body>';
foreach (Books::listAll() as $book) foreach ($SITE->modules->Books()->listAll() as $book)
{ {
echo 'Create preview for ' . $book['title'] . '<br/>' . "\n"; echo 'Create preview for ' . $book['title'] . '<br/>' . "\n";
Books::createPreview($book); $SITE->modules->Books()->createPreview($book);
} }
echo 'Finished.' . '<br/>' . "\n"; echo 'Finished.' . '<br/>' . "\n";

View File

@ -1,10 +1,10 @@
<?php <?php
require_once (__DIR__ . '/../internals/website.php');
global $OPTIONS; /** @var PageFrameOptions $FRAME_OPTIONS */ global $FRAME_OPTIONS;
/** @var URLRoute $ROUTE */ global $ROUTE;
/** @var Website $SITE */ global $SITE;
require_once (__DIR__ . '/../internals/base.php');
require_once (__DIR__ . '/../internals/books.php');
require_once (__DIR__ . '/../internals/programs.php');
echo '<!DOCTYPE html>'; echo '<!DOCTYPE html>';
echo '<html lang="en">'; echo '<html lang="en">';
@ -17,10 +17,10 @@ echo '<meta http-equiv="refresh" content="3;url=/admin;"/>';
echo '</head>'; echo '</head>';
echo '<body>'; echo '<body>';
foreach (Programs::listAll() as $prog) foreach ($SITE->modules->Programs()->listAll() as $prog)
{ {
echo 'Create preview for ' . $prog['name'] . '<br/>' . "\n"; echo 'Create preview for ' . $prog['name'] . '<br/>' . "\n";
Programs::createPreview($prog); $SITE->modules->Programs()->createPreview($prog);
} }
echo 'Finished.' . '<br/>' . "\n"; echo 'Finished.' . '<br/>' . "\n";

View File

@ -0,0 +1,14 @@
<?php
require_once (__DIR__ . '/../internals/website.php');
/** @var PageFrameOptions $FRAME_OPTIONS */ global $FRAME_OPTIONS;
/** @var URLRoute $ROUTE */ global $ROUTE;
/** @var Website $SITE */ global $SITE;
if (!isset($API_OPTIONS['filter'])) { $FRAME_OPTIONS->forceResult(400, "Wrong parameters."); return; }
$json = $SITE->modules->SelfTest()->run($API_OPTIONS['filter']);
echo json_encode($json);

View File

@ -1,10 +1,9 @@
<?php <?php
require_once (__DIR__ . '/../internals/base.php'); require_once (__DIR__ . '/../internals/website.php');
require_once (__DIR__ . '/../internals/database.php');
require_once (__DIR__ . '/../internals/updateslog.php');
Database::connect();
/** @var PageFrameOptions $FRAME_OPTIONS */ global $FRAME_OPTIONS;
/** @var URLRoute $ROUTE */ global $ROUTE;
/** @var Website $SITE */ global $SITE;
?> ?>
<div class="stripedtable_container" style="width: 100%;"> <div class="stripedtable_container" style="width: 100%;">
<table class="stripedtable"> <table class="stripedtable">
@ -16,7 +15,7 @@ Database::connect();
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<?php foreach (UpdatesLog::getEntries($_GET['ulname'], 512) as $entry): ?> <?php foreach ($SITE->modules->UpdatesLog()->getEntries($_GET['ulname'], 512) as $entry): ?>
<tr> <tr>
<td><?php echo $entry['ip']; ?></td> <td><?php echo $entry['ip']; ?></td>
<td><?php echo $entry['version']; ?></td> <td><?php echo $entry['version']; ?></td>

View File

@ -1,3 +1,4 @@
@charset "UTF-8";
/* 400px */ /* 400px */
body { body {
background-color: #EEEEEE; background-color: #EEEEEE;
@ -782,12 +783,6 @@ html, body {
text-align: left; text-align: left;
} }
.boxedcontent.alertbox {
background-color: #F52;
font-weight: bold;
text-align: center;
}
.egg_col_x5_0 { .egg_col_x5_0 {
fill: #eeeeee; fill: #eeeeee;
} }
@ -858,7 +853,7 @@ html, body {
min-width: 300px; min-width: 300px;
} }
.consistency_result_ok, .consistency_result_warn, .consistency_result_err { .consistency_result {
min-width: 400px; min-width: 400px;
color: #222222; color: #222222;
border: 1px solid #888; border: 1px solid #888;
@ -866,6 +861,10 @@ html, body {
margin: 1px 0; margin: 1px 0;
} }
.consistency_result:after {
content: " ";
}
.consistency_result_ok { .consistency_result_ok {
background: #00FF00; background: #00FF00;
} }
@ -878,6 +877,15 @@ html, body {
background: #FF0000; background: #FF0000;
} }
.consistency_result_intermed {
background: #EEEEEE;
}
.consistency_result_running {
background: #DDDDDD;
border: 1px solid #000;
}
.admincontent .boxedcontent hr { .admincontent .boxedcontent hr {
width: 95%; width: 95%;
height: 1px; height: 1px;
@ -887,6 +895,58 @@ html, body {
background: -webkit-radial-gradient(circle, rgba(0, 0, 0, 0.1) 0%, rgba(0, 0, 0, 0) 100%); background: -webkit-radial-gradient(circle, rgba(0, 0, 0, 0.1) 0%, rgba(0, 0, 0, 0) 100%);
} }
.admindberr {
color: #BB2222;
}
.boxedcontent.alertbox {
background-color: #FF4444;
color: #222222;
border: 1px solid #AA4444;
font-weight: bold;
text-align: center;
}
.boxedcontent.alertbox .bc_data {
padding-top: 2px;
padding-bottom: 2px;
}
.boxedcontent.warnbox {
background-color: #FFA726;
color: #333333;
border: 1px solid #444444;
font-weight: bold;
text-align: center;
}
.boxedcontent.warnbox .bc_data {
padding-top: 2px;
padding-bottom: 2px;
}
.boxedcontent.graybox {
background-color: #888888;
color: #222222;
border: 1px solid #444444;
font-weight: bold;
text-align: center;
}
.boxedcontent.graybox .bc_data {
padding-top: 2px;
padding-bottom: 2px;
}
.boxedcontent.successbox {
background-color: #168B00;
color: #222222;
border: 1px solid #444444;
font-weight: bold;
text-align: center;
}
.boxedcontent.successbox .bc_data {
padding-top: 2px;
padding-bottom: 2px;
}
/* 400px */ /* 400px */
#loginform div { #loginform div {
display: flex; display: flex;
@ -1900,6 +1960,7 @@ html, body {
/* 400px */ /* 400px */
.ev_master { .ev_master {
align-self: center; align-self: center;
width: 100%;
} }
@media (min-width: 851px) { @media (min-width: 851px) {
.ev_master { .ev_master {
@ -1918,6 +1979,17 @@ html, body {
text-align: center; text-align: center;
font-size: 25pt; font-size: 25pt;
} }
.ev_master .ev_statusmore {
color: #333333;
background-color: #BBBBBB;
text-align: left;
padding: 4px;
font-family: Consolas, Monaco, "Courier New", Menlo, monospace;
font-size: small;
overflow-x: auto;
white-space: nowrap;
width: 100%;
}
@media (max-width: 767px) { @media (max-width: 767px) {
.ev_master .ev_code { .ev_master .ev_code {
font-size: 75pt; font-size: 75pt;

View File

@ -1,4 +1,4 @@
body{background-color:#eee;color:#333;font-family:"Times New Roman",serif} @charset "UTF-8";body{background-color:#eee;color:#333;font-family:"Times New Roman",serif}
#content{padding-top:64px;display:flex;justify-content:center;line-height:1.4;flex-direction:column;align-items:center} #content{padding-top:64px;display:flex;justify-content:center;line-height:1.4;flex-direction:column;align-items:center}
.content-responsive{margin-left:auto;margin-right:auto} .content-responsive{margin-left:auto;margin-right:auto}
@media(max-width:767px){.content-responsive{width:95%;width:calc(100% - 20px);margin-left:auto;margin-right:auto}} @media(max-width:767px){.content-responsive{width:95%;width:calc(100% - 20px);margin-left:auto;margin-right:auto}}
@ -152,7 +152,6 @@ html,body{margin:0;padding:0;height:100%}
.about_circles{display:flex;flex-direction:column} .about_circles{display:flex;flex-direction:column}
.about_circles a{margin:5px 0} .about_circles a{margin:5px 0}
.about_circles .iconbutton_light span{text-align:left} .about_circles .iconbutton_light span{text-align:left}
.boxedcontent.alertbox{background-color:#F52;font-weight:bold;text-align:center}
.egg_col_x5_0{fill:#eee} .egg_col_x5_0{fill:#eee}
.egg_col_x5_1{fill:#6bcdff} .egg_col_x5_1{fill:#6bcdff}
.egg_col_x5_2{fill:#00a1f3} .egg_col_x5_2{fill:#00a1f3}
@ -168,11 +167,23 @@ html,body{margin:0;padding:0;height:100%}
.kvl_100 div span:first-child{min-width:100px} .kvl_100 div span:first-child{min-width:100px}
.kvl_200 div span:first-child{min-width:200px} .kvl_200 div span:first-child{min-width:200px}
.kvl_300 div span:first-child{min-width:300px} .kvl_300 div span:first-child{min-width:300px}
.consistency_result_ok,.consistency_result_warn,.consistency_result_err{min-width:400px;color:#222;border:1px solid #888;padding:0 5px;margin:1px 0} .consistency_result{min-width:400px;color:#222;border:1px solid #888;padding:0 5px;margin:1px 0}
.consistency_result:after{content:" "}
.consistency_result_ok{background:#0f0} .consistency_result_ok{background:#0f0}
.consistency_result_warn{background:#ff0} .consistency_result_warn{background:#ff0}
.consistency_result_err{background:red} .consistency_result_err{background:red}
.consistency_result_intermed{background:#eee}
.consistency_result_running{background:#ddd;border:1px solid #000}
.admincontent .boxedcontent hr{width:95%;height:1px;border:0;color:#FFFFFF00;background:-moz-radial-gradient(circle,rgba(0,0,0,0.1),rgba(0,0,0,0));background:-webkit-radial-gradient(circle,rgba(0,0,0,0.1) 0,rgba(0,0,0,0) 100%)} .admincontent .boxedcontent hr{width:95%;height:1px;border:0;color:#FFFFFF00;background:-moz-radial-gradient(circle,rgba(0,0,0,0.1),rgba(0,0,0,0));background:-webkit-radial-gradient(circle,rgba(0,0,0,0.1) 0,rgba(0,0,0,0) 100%)}
.admindberr{color:#b22}
.boxedcontent.alertbox{background-color:#f44;color:#222;border:1px solid #a44;font-weight:bold;text-align:center}
.boxedcontent.alertbox .bc_data{padding-top:2px;padding-bottom:2px}
.boxedcontent.warnbox{background-color:#ffa726;color:#333;border:1px solid #444;font-weight:bold;text-align:center}
.boxedcontent.warnbox .bc_data{padding-top:2px;padding-bottom:2px}
.boxedcontent.graybox{background-color:#888;color:#222;border:1px solid #444;font-weight:bold;text-align:center}
.boxedcontent.graybox .bc_data{padding-top:2px;padding-bottom:2px}
.boxedcontent.successbox{background-color:#168b00;color:#222;border:1px solid #444;font-weight:bold;text-align:center}
.boxedcontent.successbox .bc_data{padding-top:2px;padding-bottom:2px}
#loginform div{display:flex;flex-direction:column} #loginform div{display:flex;flex-direction:column}
#loginform div button{margin:10px 0;padding:0} #loginform div button{margin:10px 0;padding:0}
.loginerror{display:flex;background:#f44;color:#222;border:1px solid #a44;border-radius:2px;font-weight:bold;padding:0 5px;margin:5px 0 20px 0} .loginerror{display:flex;background:#f44;color:#222;border:1px solid #a44;border-radius:2px;font-weight:bold;padding:0 5px;margin:5px 0 20px 0}
@ -360,10 +371,11 @@ html,body{margin:0;padding:0;height:100%}
.wle_date{border-bottom:1px solid transparent;padding:2px;font-size:.8em;font-style:italic} .wle_date{border-bottom:1px solid transparent;padding:2px;font-size:.8em;font-style:italic}
.wle_title{font-weight:bold;font-size:1.2em;text-align:left;margin:2px 0 2px 10px} .wle_title{font-weight:bold;font-size:1.2em;text-align:left;margin:2px 0 2px 10px}
@media(max-width:767px){.wle_title{font-size:1.25em}} @media(max-width:767px){.wle_title{font-size:1.25em}}
.ev_master{align-self:center} .ev_master{align-self:center;width:100%}
@media(min-width:851px){.ev_master{padding-bottom:80px}} @media(min-width:851px){.ev_master{padding-bottom:80px}}
.ev_master .ev_code{color:#333;text-align:center;font-size:150pt;font-weight:500;font-family:Consolas,Monaco,"Courier New",Menlo,monospace} .ev_master .ev_code{color:#333;text-align:center;font-size:150pt;font-weight:500;font-family:Consolas,Monaco,"Courier New",Menlo,monospace}
.ev_master .ev_msg{color:#888;text-align:center;font-size:25pt} .ev_master .ev_msg{color:#888;text-align:center;font-size:25pt}
.ev_master .ev_statusmore{color:#333;background-color:#bbb;text-align:left;padding:4px;font-family:Consolas,Monaco,"Courier New",Menlo,monospace;font-size:small;overflow-x:auto;white-space:nowrap;width:100%}
@media(max-width:767px){ @media(max-width:767px){
.ev_master .ev_code{font-size:75pt} .ev_master .ev_code{font-size:75pt}
.ev_master .ev_msg{font-size:15pt} .ev_master .ev_msg{font-size:15pt}

View File

@ -112,12 +112,6 @@
} }
.boxedcontent.alertbox {
background-color: #F52;
font-weight: bold;
text-align: center;
}
@if $CFG_EGG_THEME == 'standard' @if $CFG_EGG_THEME == 'standard'
{ {
// ==== STANDARD ==== // ==== STANDARD ====

View File

@ -41,7 +41,7 @@
.kvl_200 div span:first-child { min-width: 200px; } .kvl_200 div span:first-child { min-width: 200px; }
.kvl_300 div span:first-child { min-width: 300px; } .kvl_300 div span:first-child { min-width: 300px; }
.consistency_result_ok, .consistency_result_warn, .consistency_result_err { .consistency_result {
min-width: 400px; min-width: 400px;
color: $COL_ADMIN_STATUS_FG; color: $COL_ADMIN_STATUS_FG;
border: $COL_ADMIN_STATUS_BORDER; border: $COL_ADMIN_STATUS_BORDER;
@ -49,9 +49,13 @@
margin: 1px 0; margin: 1px 0;
} }
.consistency_result:after { content: '\00a0' }
.consistency_result_ok { background: $COL_ADMIN_OK; } .consistency_result_ok { background: $COL_ADMIN_OK; }
.consistency_result_warn { background: $COL_ADMIN_WARN; } .consistency_result_warn { background: $COL_ADMIN_WARN; }
.consistency_result_err { background: $COL_ADMIN_ERROR; } .consistency_result_err { background: $COL_ADMIN_ERROR; }
.consistency_result_intermed { background: $COL_ADMIN_INTERMED; }
.consistency_result_running { background: $COL_ADMIN_RUNNING; border: $COL_ADMIN_STATUS_BORDER_ACTIVE; }
.admincontent .boxedcontent hr { .admincontent .boxedcontent hr {
@ -62,3 +66,53 @@
background: -moz-radial-gradient( circle, rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.0)); background: -moz-radial-gradient( circle, rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.0));
background: -webkit-radial-gradient(circle, rgba(0, 0, 0, 0.1) 0%,rgba(0, 0, 0, 0.0) 100%); background: -webkit-radial-gradient(circle, rgba(0, 0, 0, 0.1) 0%,rgba(0, 0, 0, 0.0) 100%);
} }
.admindberr { color: $COL_ADMIN_STATUS_DB_ERROR; }
.boxedcontent.alertbox {
background-color: $COL_TOAST_ERROR_BG;
color: $COL_TOAST_ERROR_FG;
border: $COL_TOAST_ERROR_BORDER;
font-weight: bold;
text-align: center;
.bc_data {
padding-top: 2px;
padding-bottom: 2px;
}
}
.boxedcontent.warnbox {
background-color: $COL_TOAST_WARN_BG;
color: $COL_TOAST_WARN_FG;
border: $COL_TOAST_WARN_BORDER;
font-weight: bold;
text-align: center;
.bc_data {
padding-top: 2px;
padding-bottom: 2px;
}
}
.boxedcontent.graybox {
background-color: $COL_TOAST_GRAY_BG;
color: $COL_TOAST_GRAY_FG;
border: $COL_TOAST_GRAY_BORDER;
font-weight: bold;
text-align: center;
.bc_data {
padding-top: 2px;
padding-bottom: 2px;
}
}
.boxedcontent.successbox {
background-color: $COL_TOAST_SUCCESS_BG;
color: $COL_TOAST_SUCCESS_FG;
border: $COL_TOAST_SUCCESS_BORDER;
font-weight: bold;
text-align: center;
.bc_data {
padding-top: 2px;
padding-bottom: 2px;
}
}

View File

@ -119,6 +119,18 @@ $COL_TOAST_ERROR_FG: #222222;
$COL_TOAST_ERROR_BG: #FF4444; $COL_TOAST_ERROR_BG: #FF4444;
$COL_TOAST_ERROR_BORDER: 1px solid #AA4444; $COL_TOAST_ERROR_BORDER: 1px solid #AA4444;
$COL_TOAST_WARN_FG: #333333;
$COL_TOAST_WARN_BG: #FFA726;
$COL_TOAST_WARN_BORDER: $LAYER1_BORDER;
$COL_TOAST_GRAY_FG: #222222;
$COL_TOAST_GRAY_BG: #888888;
$COL_TOAST_GRAY_BORDER: $LAYER1_BORDER;
$COL_TOAST_SUCCESS_FG: #222222;
$COL_TOAST_SUCCESS_BG: #168B00;
$COL_TOAST_SUCCESS_BORDER: $LAYER1_BORDER;
// ------------------------------------ // ------------------------------------
$COL_EULER_TIME_0_SAT: #00AA00; $COL_EULER_TIME_0_SAT: #00AA00;
@ -152,9 +164,14 @@ $AOC_DESCRIPTION_BG: #333333;
$COL_ADMIN_OK: #00FF00; $COL_ADMIN_OK: #00FF00;
$COL_ADMIN_WARN: #FFFF00; $COL_ADMIN_WARN: #FFFF00;
$COL_ADMIN_ERROR: #FF0000; $COL_ADMIN_ERROR: #FF0000;
$COL_ADMIN_INTERMED: #EEEEEE;
$COL_ADMIN_RUNNING: #DDDDDD;
$COL_ADMIN_STATUS_FG: #222222; $COL_ADMIN_STATUS_FG: #222222;
$COL_ADMIN_STATUS_BORDER: 1px solid #888; $COL_ADMIN_STATUS_BORDER: 1px solid #888;
$COL_ADMIN_STATUS_BORDER_ACTIVE: 1px solid #000;
$COL_ADMIN_STATUS_DB_ERROR: #BB2222;
// ------------------------------------ ------------------------------------ // ------------------------------------ ------------------------------------

View File

@ -3,6 +3,7 @@
.ev_master { .ev_master {
align-self: center; align-self: center;
width: 100%;
@include rdmedia_range(2,4) {padding-bottom: 80px;} @include rdmedia_range(2,4) {padding-bottom: 80px;}
@ -20,6 +21,20 @@
font-size: 25pt; font-size: 25pt;
} }
.ev_statusmore {
color: $LAYER1_FG;
background-color: $LAYER1_BG_DARKER;
text-align: left;
padding: 4px;
font-family: $FONT_CODE;
font-size: small;
overflow-x: auto;
white-space: nowrap;
width: 100%;
}
@include rdmedia(0) { @include rdmedia(0) {
.ev_code { font-size: 75pt; } .ev_code { font-size: 75pt; }
.ev_msg { font-size: 15pt; } .ev_msg { font-size: 15pt; }

View File

@ -70,3 +70,50 @@ function startAjaxReplace(target, url)
async: true async: true
}); });
} }
function refreshConsistencyDisplay(skip)
{
let i = 0;
for (let apibutton of $('.consistence_ajax_handler').toArray())
{
if (i++ !== skip) continue;
const filter = $(apibutton).data('filter');
$(apibutton).removeClass('consistency_result_intermed');
$(apibutton).addClass('consistency_result_running');
$.ajax('/api/site::selftest?filter=' + filter)
.done((data, status, xhr) =>
{
let json = JSON.parse(data);
$(apibutton).removeClass('consistency_result_intermed');
$(apibutton).removeClass('consistency_result_running');
if (json.result === 0) $(apibutton).addClass('consistency_result_ok');
if (json.result === 1) $(apibutton).addClass('consistency_result_warn');
if (json.result === 2) $(apibutton).addClass('consistency_result_err');
$(apibutton).text(json.message);
$(apibutton).attr('title', json.long);
setTimeout(() => refreshConsistencyDisplay(skip+1), 10);
})
.fail((xhr, status, err) =>
{
$(apibutton).removeClass('consistency_result_intermed');
$(apibutton).removeClass('consistency_result_running');
$(apibutton).addClass('consistency_result_err');
$(apibutton).text(err);
setTimeout(() => refreshConsistencyDisplay(skip+1), 10);
});
}
}
$(function()
{
setTimeout(() => refreshConsistencyDisplay(0), 200);
});

View File

@ -17,7 +17,7 @@ class Parsedown
{ {
# ~ # ~
const version = '1.6.0'; const version = '1.7.4';
# ~ # ~
@ -75,6 +75,32 @@ class Parsedown
protected $urlsLinked = true; protected $urlsLinked = true;
function setSafeMode($safeMode)
{
$this->safeMode = (bool) $safeMode;
return $this;
}
protected $safeMode;
protected $safeLinksWhitelist = array(
'http://',
'https://',
'ftp://',
'ftps://',
'mailto:',
'data:image/png;base64,',
'data:image/gif;base64,',
'data:image/jpeg;base64,',
'irc:',
'ircs:',
'git:',
'ssh:',
'news:',
'steam:',
);
# #
# Lines # Lines
# #
@ -342,8 +368,6 @@ class Parsedown
{ {
$text = $Block['element']['text']['text']; $text = $Block['element']['text']['text'];
$text = htmlspecialchars($text, ENT_NOQUOTES, 'UTF-8');
$Block['element']['text']['text'] = $text; $Block['element']['text']['text'] = $text;
return $Block; return $Block;
@ -354,7 +378,7 @@ class Parsedown
protected function blockComment($Line) protected function blockComment($Line)
{ {
if ($this->markupEscaped) if ($this->markupEscaped or $this->safeMode)
{ {
return; return;
} }
@ -396,7 +420,7 @@ class Parsedown
protected function blockFencedCode($Line) protected function blockFencedCode($Line)
{ {
if (preg_match('/^['.$Line['text'][0].']{3,}[ ]*([\w-]+)?[ ]*$/', $Line['text'], $matches)) if (preg_match('/^['.$Line['text'][0].']{3,}[ ]*([^`]+)?[ ]*$/', $Line['text'], $matches))
{ {
$Element = array( $Element = array(
'name' => 'code', 'name' => 'code',
@ -405,7 +429,21 @@ class Parsedown
if (isset($matches[1])) if (isset($matches[1]))
{ {
$class = 'language-'.$matches[1]; /**
* https://www.w3.org/TR/2011/WD-html5-20110525/elements.html#classes
* Every HTML element may have a class attribute specified.
* The attribute, if specified, must have a value that is a set
* of space-separated tokens representing the various classes
* that the element belongs to.
* [...]
* The space characters, for the purposes of this specification,
* are U+0020 SPACE, U+0009 CHARACTER TABULATION (tab),
* U+000A LINE FEED (LF), U+000C FORM FEED (FF), and
* U+000D CARRIAGE RETURN (CR).
*/
$language = substr($matches[1], 0, strcspn($matches[1], " \t\n\f\r"));
$class = 'language-'.$language;
$Element['attributes'] = array( $Element['attributes'] = array(
'class' => $class, 'class' => $class,
@ -457,8 +495,6 @@ class Parsedown
{ {
$text = $Block['element']['text']['text']; $text = $Block['element']['text']['text'];
$text = htmlspecialchars($text, ENT_NOQUOTES, 'UTF-8');
$Block['element']['text']['text'] = $text; $Block['element']['text']['text'] = $text;
return $Block; return $Block;
@ -547,6 +583,8 @@ class Parsedown
{ {
$Block['li']['text'] []= ''; $Block['li']['text'] []= '';
$Block['loose'] = true;
unset($Block['interrupted']); unset($Block['interrupted']);
} }
@ -595,6 +633,22 @@ class Parsedown
} }
} }
protected function blockListComplete(array $Block)
{
if (isset($Block['loose']))
{
foreach ($Block['element']['text'] as &$li)
{
if (end($li['text']) !== '')
{
$li['text'] []= '';
}
}
}
return $Block;
}
# #
# Quote # Quote
@ -678,7 +732,7 @@ class Parsedown
protected function blockMarkup($Line) protected function blockMarkup($Line)
{ {
if ($this->markupEscaped) if ($this->markupEscaped or $this->safeMode)
{ {
return; return;
} }
@ -997,7 +1051,7 @@ class Parsedown
# ~ # ~
# #
public function line($text) public function line($text, $nonNestables=array())
{ {
$markup = ''; $markup = '';
@ -1013,6 +1067,13 @@ class Parsedown
foreach ($this->InlineTypes[$marker] as $inlineType) foreach ($this->InlineTypes[$marker] as $inlineType)
{ {
# check to see if the current inline type is nestable in the current context
if ( ! empty($nonNestables) and in_array($inlineType, $nonNestables))
{
continue;
}
$Inline = $this->{'inline'.$inlineType}($Excerpt); $Inline = $this->{'inline'.$inlineType}($Excerpt);
if ( ! isset($Inline)) if ( ! isset($Inline))
@ -1034,6 +1095,13 @@ class Parsedown
$Inline['position'] = $markerPosition; $Inline['position'] = $markerPosition;
} }
# cause the new element to 'inherit' our non nestables
foreach ($nonNestables as $non_nestable)
{
$Inline['element']['nonNestables'][] = $non_nestable;
}
# the text that comes before the inline # the text that comes before the inline
$unmarkedText = substr($text, 0, $Inline['position']); $unmarkedText = substr($text, 0, $Inline['position']);
@ -1074,7 +1142,6 @@ class Parsedown
if (preg_match('/^('.$marker.'+)[ ]*(.+?)[ ]*(?<!'.$marker.')\1(?!'.$marker.')/s', $Excerpt['text'], $matches)) if (preg_match('/^('.$marker.'+)[ ]*(.+?)[ ]*(?<!'.$marker.')\1(?!'.$marker.')/s', $Excerpt['text'], $matches))
{ {
$text = $matches[2]; $text = $matches[2];
$text = htmlspecialchars($text, ENT_NOQUOTES, 'UTF-8');
$text = preg_replace("/[ ]*\n/", ' ', $text); $text = preg_replace("/[ ]*\n/", ' ', $text);
return array( return array(
@ -1193,6 +1260,7 @@ class Parsedown
$Element = array( $Element = array(
'name' => 'a', 'name' => 'a',
'handler' => 'line', 'handler' => 'line',
'nonNestables' => array('Url', 'Link'),
'text' => null, 'text' => null,
'attributes' => array( 'attributes' => array(
'href' => null, 'href' => null,
@ -1253,8 +1321,6 @@ class Parsedown
$Element['attributes']['title'] = $Definition['title']; $Element['attributes']['title'] = $Definition['title'];
} }
$Element['attributes']['href'] = str_replace(array('&', '<'), array('&amp;', '&lt;'), $Element['attributes']['href']);
return array( return array(
'extent' => $extent, 'extent' => $extent,
'element' => $Element, 'element' => $Element,
@ -1263,7 +1329,7 @@ class Parsedown
protected function inlineMarkup($Excerpt) protected function inlineMarkup($Excerpt)
{ {
if ($this->markupEscaped or strpos($Excerpt['text'], '>') === false) if ($this->markupEscaped or $this->safeMode or strpos($Excerpt['text'], '>') === false)
{ {
return; return;
} }
@ -1343,14 +1409,16 @@ class Parsedown
if (preg_match('/\bhttps?:[\/]{2}[^\s<]+\b\/*/ui', $Excerpt['context'], $matches, PREG_OFFSET_CAPTURE)) if (preg_match('/\bhttps?:[\/]{2}[^\s<]+\b\/*/ui', $Excerpt['context'], $matches, PREG_OFFSET_CAPTURE))
{ {
$url = $matches[0][0];
$Inline = array( $Inline = array(
'extent' => strlen($matches[0][0]), 'extent' => strlen($matches[0][0]),
'position' => $matches[0][1], 'position' => $matches[0][1],
'element' => array( 'element' => array(
'name' => 'a', 'name' => 'a',
'text' => $matches[0][0], 'text' => $url,
'attributes' => array( 'attributes' => array(
'href' => $matches[0][0], 'href' => $url,
), ),
), ),
); );
@ -1363,7 +1431,7 @@ class Parsedown
{ {
if (strpos($Excerpt['text'], '>') !== false and preg_match('/^<(\w+:\/{2}[^ >]+)>/i', $Excerpt['text'], $matches)) if (strpos($Excerpt['text'], '>') !== false and preg_match('/^<(\w+:\/{2}[^ >]+)>/i', $Excerpt['text'], $matches))
{ {
$url = str_replace(array('&', '<'), array('&amp;', '&lt;'), $matches[1]); $url = $matches[1];
return array( return array(
'extent' => strlen($matches[0]), 'extent' => strlen($matches[0]),
@ -1401,6 +1469,11 @@ class Parsedown
protected function element(array $Element) protected function element(array $Element)
{ {
if ($this->safeMode)
{
$Element = $this->sanitiseElement($Element);
}
$markup = '<'.$Element['name']; $markup = '<'.$Element['name'];
if (isset($Element['attributes'])) if (isset($Element['attributes']))
@ -1412,21 +1485,45 @@ class Parsedown
continue; continue;
} }
$markup .= ' '.$name.'="'.$value.'"'; $markup .= ' '.$name.'="'.self::escape($value).'"';
} }
} }
$permitRawHtml = false;
if (isset($Element['text'])) if (isset($Element['text']))
{
$text = $Element['text'];
}
// very strongly consider an alternative if you're writing an
// extension
elseif (isset($Element['rawHtml']))
{
$text = $Element['rawHtml'];
$allowRawHtmlInSafeMode = isset($Element['allowRawHtmlInSafeMode']) && $Element['allowRawHtmlInSafeMode'];
$permitRawHtml = !$this->safeMode || $allowRawHtmlInSafeMode;
}
if (isset($text))
{ {
$markup .= '>'; $markup .= '>';
if (!isset($Element['nonNestables']))
{
$Element['nonNestables'] = array();
}
if (isset($Element['handler'])) if (isset($Element['handler']))
{ {
$markup .= $this->{$Element['handler']}($Element['text']); $markup .= $this->{$Element['handler']}($text, $Element['nonNestables']);
}
elseif (!$permitRawHtml)
{
$markup .= self::escape($text, true);
} }
else else
{ {
$markup .= $Element['text']; $markup .= $text;
} }
$markup .= '</'.$Element['name'].'>'; $markup .= '</'.$Element['name'].'>';
@ -1485,10 +1582,77 @@ class Parsedown
return $markup; return $markup;
} }
protected function sanitiseElement(array $Element)
{
static $goodAttribute = '/^[a-zA-Z0-9][a-zA-Z0-9-_]*+$/';
static $safeUrlNameToAtt = array(
'a' => 'href',
'img' => 'src',
);
if (isset($safeUrlNameToAtt[$Element['name']]))
{
$Element = $this->filterUnsafeUrlInAttribute($Element, $safeUrlNameToAtt[$Element['name']]);
}
if ( ! empty($Element['attributes']))
{
foreach ($Element['attributes'] as $att => $val)
{
# filter out badly parsed attribute
if ( ! preg_match($goodAttribute, $att))
{
unset($Element['attributes'][$att]);
}
# dump onevent attribute
elseif (self::striAtStart($att, 'on'))
{
unset($Element['attributes'][$att]);
}
}
}
return $Element;
}
protected function filterUnsafeUrlInAttribute(array $Element, $attribute)
{
foreach ($this->safeLinksWhitelist as $scheme)
{
if (self::striAtStart($Element['attributes'][$attribute], $scheme))
{
return $Element;
}
}
$Element['attributes'][$attribute] = str_replace(':', '%3A', $Element['attributes'][$attribute]);
return $Element;
}
# #
# Static Methods # Static Methods
# #
protected static function escape($text, $allowQuotes = false)
{
return htmlspecialchars($text, $allowQuotes ? ENT_NOQUOTES : ENT_QUOTES, 'UTF-8');
}
protected static function striAtStart($string, $needle)
{
$len = strlen($needle);
if ($len > strlen($string))
{
return false;
}
else
{
return strtolower(substr($string, 0, $len)) === strtolower($needle);
}
}
static function instance($name = 'default') static function instance($name = 'default')
{ {
if (isset(self::$instances[$name])) if (isset(self::$instances[$name]))

View File

@ -17,13 +17,13 @@ class ParsedownExtra extends Parsedown
{ {
# ~ # ~
const version = '0.7.0'; const version = '0.8.1';
# ~ # ~
function __construct() function __construct()
{ {
if (parent::version < '1.5.0') if (version_compare(parent::version, '1.7.4') < 0)
{ {
throw new Exception('ParsedownExtra requires a later version of Parsedown'); throw new Exception('ParsedownExtra requires a later version of Parsedown');
} }
@ -206,6 +206,10 @@ class ParsedownExtra extends Parsedown
{ {
$Block = parent::blockHeader($Line); $Block = parent::blockHeader($Line);
if (! isset($Block)) {
return null;
}
if (preg_match('/[ #]*{('.$this->regexAttribute.'+)}[ ]*$/', $Block['element']['text'], $matches, PREG_OFFSET_CAPTURE)) if (preg_match('/[ #]*{('.$this->regexAttribute.'+)}[ ]*$/', $Block['element']['text'], $matches, PREG_OFFSET_CAPTURE))
{ {
$attributeString = $matches[1][0]; $attributeString = $matches[1][0];
@ -238,6 +242,10 @@ class ParsedownExtra extends Parsedown
{ {
$Block = parent::blockSetextHeader($Line, $Block); $Block = parent::blockSetextHeader($Line, $Block);
if (! isset($Block)) {
return null;
}
if (preg_match('/[ ]*{('.$this->regexAttribute.'+)}[ ]*$/', $Block['element']['text'], $matches, PREG_OFFSET_CAPTURE)) if (preg_match('/[ ]*{('.$this->regexAttribute.'+)}[ ]*$/', $Block['element']['text'], $matches, PREG_OFFSET_CAPTURE))
{ {
$attributeString = $matches[1][0]; $attributeString = $matches[1][0];
@ -302,6 +310,10 @@ class ParsedownExtra extends Parsedown
{ {
$Link = parent::inlineLink($Excerpt); $Link = parent::inlineLink($Excerpt);
if (! isset($Link)) {
return null;
}
$remainder = substr($Excerpt['text'], $Link['extent']); $remainder = substr($Excerpt['text'], $Link['extent']);
if (preg_match('/^[ ]*{('.$this->regexAttribute.'+)}/', $remainder, $matches)) if (preg_match('/^[ ]*{('.$this->regexAttribute.'+)}/', $remainder, $matches))
@ -420,7 +432,7 @@ class ParsedownExtra extends Parsedown
$Element['text'][1]['text'] []= array( $Element['text'][1]['text'] []= array(
'name' => 'li', 'name' => 'li',
'attributes' => array('id' => 'fn:'.$definitionId), 'attributes' => array('id' => 'fn:'.$definitionId),
'text' => "\n".$text."\n", 'rawHtml' => "\n".$text."\n",
); );
} }

View File

@ -69,9 +69,7 @@ class EGGDatabase
public function sql_query_assoc(string $query) public function sql_query_assoc(string $query)
{ {
$r = $this->pdo->query($query)->fetchAll(PDO::FETCH_ASSOC); return $this->pdo->query($query)->fetchAll(PDO::FETCH_ASSOC);
return $r;
} }
public function sql_query_assoc_prep(string $query, array $params) public function sql_query_assoc_prep(string $query, array $params)
@ -84,9 +82,7 @@ class EGGDatabase
} }
$stmt->execute(); $stmt->execute();
$r = $stmt->fetchAll(PDO::FETCH_ASSOC); return $stmt->fetchAll(PDO::FETCH_ASSOC);
return $r;
} }
public function sql_exec_prep(string $query, array $params) public function sql_exec_prep(string $query, array $params)

View File

@ -227,7 +227,7 @@ abstract class StandardGitConnection implements IRemoteSource
$target = $branch->Head; $target = $branch->Head;
$next_sha = [ $branch->HeadFromAPI ]; $next_sha = [ $branch->HeadFromAPI ];
$visited = [ $branch->HeadFromAPI ]; $visited = [ ];
$json = $this->queryCommits($repo->Name, $branch->Name, $next_sha[0]); $json = $this->queryCommits($repo->Name, $branch->Name, $next_sha[0]);
@ -257,6 +257,7 @@ abstract class StandardGitConnection implements IRemoteSource
if (count($newcommits) === 0) if (count($newcommits) === 0)
{ {
$this->logger->proclog("Found no new commits for: [" . $this->name . "|" . $repo->Name . "|" . $branch->Name . "] (HEAD at {" . substr($branch->HeadFromAPI, 0, 8) . "})"); $this->logger->proclog("Found no new commits for: [" . $this->name . "|" . $repo->Name . "|" . $branch->Name . "] (HEAD at {" . substr($branch->HeadFromAPI, 0, 8) . "})");
if ($branch->HeadFromAPI !== $branch->Head) $db->setBranchHead($branch, $branch->HeadFromAPI);
return []; return [];
} }
@ -295,7 +296,11 @@ abstract class StandardGitConnection implements IRemoteSource
$db->deleteAllCommits($branch); $db->deleteAllCommits($branch);
if (count($newcommits) === 0) return []; if (count($newcommits) === 0)
{
if ($branch->HeadFromAPI !== $branch->Head) $db->setBranchHead($branch, $branch->HeadFromAPI);
return [];
}
$db->insertNewCommits($this->name, $repo, $branch, $newcommits); $db->insertNewCommits($this->name, $repo, $branch, $newcommits);
$db->setBranchHead($branch, $branch->HeadFromAPI); $db->setBranchHead($branch, $branch->HeadFromAPI);

View File

@ -1,8 +1,17 @@
<?php <?php
require_once (__DIR__ . '/../internals/base.php'); require_once (__DIR__ . '/../internals/website.php');
require_once (__DIR__ . '/../internals/blog.php');
require_once (__DIR__ . '/../internals/adventofcode.php'); /** @var PageFrameOptions $FRAME_OPTIONS */ global $FRAME_OPTIONS;
require_once (__DIR__ . '/../internals/ParsedownCustom.php'); /** @var URLRoute $ROUTE */ global $ROUTE;
/** @var Website $SITE */ global $SITE;
global $FRAGMENT_PARAM;
/** @var array $parameter */
$parameter = $FRAGMENT_PARAM;
?>
<?php
$post = $parameter['blogpost'];
$year = $post['extras']['aoc:year']; $year = $post['extras']['aoc:year'];
@ -11,7 +20,7 @@ $year = $post['extras']['aoc:year'];
<div class="boxedcontent blogcontent_plain"> <div class="boxedcontent blogcontent_plain">
<div style="position: relative;"> <div style="position: relative;">
<a href="<?php echo AdventOfCode::getGithubLink($year); ?>" style="position: absolute; top: 0; right: 0; border: 0;"> <a href="<?php echo $SITE->modules->AdventOfCode()->getGithubLink($year); ?>" style="position: absolute; top: 0; right: 0; border: 0;">
<img src="/data/images/blog/github_band.png" alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png"> <img src="/data/images/blog/github_band.png" alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png">
</a> </a>
</div> </div>
@ -21,16 +30,8 @@ $year = $post['extras']['aoc:year'];
</div> </div>
<div class="bc_data"> <div class="bc_data">
<?php <?php $SITE->renderMarkdown($SITE->modules->Blog()->getPostFragment($post)); ?>
$pd = new ParsedownCustom();
echo $pd->text(Blog::getPostFragment($post));
?>
<br/> <br/>
<?php <?php echo $SITE->fragments->PanelAdventOfCodeCalendar($year, true, false, false); ?>
global $PARAM_AOCCALENDAR;
$PARAM_AOCCALENDAR = ['year' => $year, 'nav'=>true, 'linkheader'=>false, 'ajax'=>false];
require (__DIR__ . '/../fragments/panel_aoc_calendar.php')
?>
</div> </div>
</div> </div>

View File

@ -1,23 +1,28 @@
<?php <?php
require_once (__DIR__ . '/../internals/base.php'); require_once (__DIR__ . '/../internals/website.php');
require_once (__DIR__ . '/../internals/blog.php');
require_once (__DIR__ . '/../internals/adventofcode.php');
require_once (__DIR__ . '/../internals/ParsedownCustom.php');
/** @var PageFrameOptions $FRAME_OPTIONS */ global $FRAME_OPTIONS;
/** @var URLRoute $ROUTE */ global $ROUTE;
/** @var Website $SITE */ global $SITE;
global $FRAGMENT_PARAM;
/** @var array $parameter */
$parameter = $FRAGMENT_PARAM;
?>
<?php
$post = $parameter['blogpost'];
$subview = $parameter['subview'];
$year = $post['extras']['aoc:year']; $year = $post['extras']['aoc:year'];
$subview = $OPTIONS['subview'];
$day = AdventOfCode::getDayFromStrIdent($year, $subview);
if ($day === NULL) httpError(404, 'AdventOfCode entry not found');
$pd = new ParsedownCustom();
$day = $SITE->modules->AdventOfCode()->getDayFromStrIdent($year, $subview);
if ($day === NULL) { $FRAME_OPTIONS->forceResult(404, 'AdventOfCode entry not found'); return; }
?> ?>
<div class="boxedcontent base_markdown"> <div class="boxedcontent base_markdown">
<div style="position: relative;"> <div style="position: relative;">
<a href="<?php echo AdventOfCode::getGithubLink($year); ?>" style="position: absolute; top: 0; right: 0; border: 0;"> <a href="<?php echo $SITE->modules->AdventOfCode()->getGithubLink($year); ?>" style="position: absolute; top: 0; right: 0; border: 0;">
<img src="/data/images/blog/github_band.png" alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png"> <img src="/data/images/blog/github_band.png" alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png">
</a> </a>
</div> </div>
@ -43,7 +48,7 @@ $pd = new ParsedownCustom();
<b>Part <?php echo $i; ?>:</b> <b>Part <?php echo $i; ?>:</b>
<div class="bc_aoc_solution_parent"> <div class="bc_aoc_solution_parent">
<div class="bc_aoc_solution_code"> <div class="bc_aoc_solution_code">
<pre><code class="<?php echo AdventOfCode::getLanguageCSS($day) ?>"><?php echo htmlspecialchars(AdventOfCode::getSolutionCode($day, $i-1)); ?></code></pre> <pre><code class="<?php echo $SITE->modules->AdventOfCode()->getLanguageCSS($day) ?>"><?php echo htmlspecialchars($SITE->modules->AdventOfCode()->getSolutionCode($day, $i-1)); ?></code></pre>
</div> </div>
<div class="bc_aoc_solution_value"><b>Result:</b> <?php echo $day['solutions'][$i-1]; ?></div> <div class="bc_aoc_solution_value"><b>Result:</b> <?php echo $day['solutions'][$i-1]; ?></div>
</div> </div>
@ -51,12 +56,12 @@ $pd = new ParsedownCustom();
<?php endfor; ?> <?php endfor; ?>
<?php includeAdditionalScript("/data/javascript/prism.js", 'defer'); ?> <?php $FRAME_OPTIONS->addScript("/data/javascript/prism.js", true); ?>
<?php includeAdditionalStylesheet("/data/rawcss/prism.css"); ?> <?php $FRAME_OPTIONS->addStylesheet("/data/rawcss/prism.css"); ?>
<div class="pagination"> <div class="pagination">
<?php <?php
$assocdays = AdventOfCode::listSingleYearAssociative($year); $assocdays = $SITE->modules->AdventOfCode()->listSingleYearAssociative($year);
echo "<div class='pagAny'>"; echo "<div class='pagAny'>";
for($i=0; $i < 25; $i++) for($i=0; $i < 25; $i++)

View File

@ -1,11 +1,18 @@
<?php <?php
require_once (__DIR__ . '/../internals/base.php'); require_once (__DIR__ . '/../internals/website.php');
require_once (__DIR__ . '/../internals/blog.php');
require_once (__DIR__ . '/../internals/euler.php');
require_once (__DIR__ . '/../extern/Parsedown.php');
$problems = Euler::listAll(); /** @var PageFrameOptions $FRAME_OPTIONS */ global $FRAME_OPTIONS;
/** @var URLRoute $ROUTE */ global $ROUTE;
/** @var Website $SITE */ global $SITE;
global $FRAGMENT_PARAM;
/** @var array $parameter */
$parameter = $FRAGMENT_PARAM;
?>
<?php
$post = $parameter['blogpost'];
$problems = $SITE->modules->Euler()->listAll();
?> ?>
<div class="boxedcontent blogcontent_euler base_markdown"> <div class="boxedcontent blogcontent_euler base_markdown">

View File

@ -1,18 +1,23 @@
<?php <?php
require_once (__DIR__ . '/../internals/base.php'); require_once (__DIR__ . '/../internals/website.php');
require_once (__DIR__ . '/../internals/blog.php');
require_once (__DIR__ . '/../internals/euler.php');
require_once (__DIR__ . '/../internals/ParsedownCustom.php');
$subview = $OPTIONS['subview']; /** @var PageFrameOptions $FRAME_OPTIONS */ global $FRAME_OPTIONS;
/** @var URLRoute $ROUTE */ global $ROUTE;
/** @var Website $SITE */ global $SITE;
$euler = Euler::listAll(); global $FRAGMENT_PARAM;
$problem = Euler::getEulerProblemFromStrIdent($subview); /** @var array $parameter */
$parameter = $FRAGMENT_PARAM;
?>
if ($problem === NULL) httpError(404, 'Project Euler entry not found'); <?php
$post = $parameter['blogpost'];
$subview = $parameter['subview'];
$pd = new ParsedownCustom(); $euler = $SITE->modules->Euler()->listAll();
$problem = $SITE->modules->Euler()->getEulerProblemFromStrIdent($subview);
if ($problem === NULL) { $FRAME_OPTIONS->forceResult(404, 'Project Euler entry not found'); return; }
$arr = []; $arr = [];
$max = 0; $max = 0;
@ -42,28 +47,19 @@ $max = ceil($max / 20) * 20;
<div class="bce_header"><h1><a href="<?php echo $problem['url_euler']; ?>">Problem <?php echo $problem['number3']; ?></a>: <?php echo htmlspecialchars($problem['title']); ?></h1></div> <div class="bce_header"><h1><a href="<?php echo $problem['url_euler']; ?>">Problem <?php echo $problem['number3']; ?></a>: <?php echo htmlspecialchars($problem['title']); ?></h1></div>
<b>Description:</b> <b>Description:</b>
<div class="bce_description"><?php echo $pd->text(file_get_contents($problem['file_description'])); ?></div> <div class="bce_description"><?php echo $SITE->renderMarkdown(file_get_contents($problem['file_description'])); ?></div>
<br/> <br/>
<b>Solution:</b> <b>Solution:</b>
<?php <?php
global $PARAM_BEFUNGE93RUNNER; echo $SITE->fragments->WidgetBefunge93(file_get_contents($problem['file_code']), $problem['url_raw'], !$problem['abbreviated'], $problem['steps'] < 15000 ? 1 : ($problem['steps'] < 500000 ? 2 : 3), false);
$PARAM_BEFUNGE93RUNNER =
[
'code' => file_get_contents($problem['file_code']),
'url' => $problem['url_raw'],
'interactive' => !$problem['abbreviated'],
'speed' => $problem['steps'] < 15000 ? 1 : ($problem['steps'] < 500000 ? 2 : 3),
'editable' => false,
];
echo require (__DIR__ . '/../fragments/widget_befunge93.php');
if ($problem['abbreviated']) echo '<i>This program is too big to display/execute here, click [download] to get the full program. </i><br/>'; if ($problem['abbreviated']) echo '<i>This program is too big to display/execute here, click [download] to get the full program. </i><br/>';
?> ?>
<br/> <br/>
<b>Explanation:</b> <b>Explanation:</b>
<div class="bce_explanation"><?php echo $pd->text(file_get_contents($problem['file_explanation'])); ?></div> <div class="bce_explanation"><?php echo $SITE->renderMarkdown(file_get_contents($problem['file_explanation'])); ?></div>
<br/> <br/>
<table class="notable"> <table class="notable">

View File

@ -1,7 +1,17 @@
<?php <?php
require_once (__DIR__ . '/../internals/base.php'); require_once (__DIR__ . '/../internals/website.php');
require_once (__DIR__ . '/../internals/blog.php');
require_once (__DIR__ . '/../internals/ParsedownCustom.php'); /** @var PageFrameOptions $FRAME_OPTIONS */ global $FRAME_OPTIONS;
/** @var URLRoute $ROUTE */ global $ROUTE;
/** @var Website $SITE */ global $SITE;
global $FRAGMENT_PARAM;
/** @var array $parameter */
$parameter = $FRAGMENT_PARAM;
?>
<?php
$post = $parameter['blogpost'];
?> ?>
<div class="boxedcontent blogcontent_markdown base_markdown"> <div class="boxedcontent blogcontent_markdown base_markdown">
@ -11,10 +21,7 @@ require_once (__DIR__ . '/../internals/ParsedownCustom.php');
</div> </div>
<div class="bc_data"> <div class="bc_data">
<?php <?php echo $SITE->renderMarkdown($SITE->modules->Blog()->getPostFragment($post)); ?>
$pd = new ParsedownCustom();
echo $pd->text(Blog::getPostFragment($post));
?>
</div> </div>
</div> </div>

View File

@ -1,6 +1,17 @@
<?php <?php
require_once (__DIR__ . '/../internals/base.php'); require_once (__DIR__ . '/../internals/website.php');
require_once (__DIR__ . '/../internals/blog.php');
/** @var PageFrameOptions $FRAME_OPTIONS */ global $FRAME_OPTIONS;
/** @var URLRoute $ROUTE */ global $ROUTE;
/** @var Website $SITE */ global $SITE;
global $FRAGMENT_PARAM;
/** @var array $parameter */
$parameter = $FRAGMENT_PARAM;
?>
<?php
$post = $parameter['blogpost'];
?> ?>
<div class="boxedcontent blogcontent_plain"> <div class="boxedcontent blogcontent_plain">
@ -10,7 +21,7 @@ require_once (__DIR__ . '/../internals/blog.php');
</div> </div>
<div class="bc_data"> <div class="bc_data">
<?php echo nl2br(htmlspecialchars(Blog::getPostFragment($post))); ?> <?php echo nl2br(htmlspecialchars($SITE->modules->Blog()->getPostFragment($post))); ?>
</div> </div>
</div> </div>

View File

@ -1,4 +0,0 @@
<div id="footerdiv" class="content-responsive">
<hr />
made with vanilla PHP and MySQL<span class="footerspan2">, no frameworks, no bootstrap, no unnecessary* javascript</span>
</div>

View File

@ -1,19 +0,0 @@
<div id="headerdiv">
<div class="logowrapper">
<a href="/"><img class="logo" src="/data/images/logo.png" alt="Mikescher.com Logo" /></a>
</div>
<div class="tabrow">
<a class="tab <?php if ($HEADER_ACTIVE === 'home') echo 'tab_active'; ?>" href="/">Home</a>
<a class="tab <?php if ($HEADER_ACTIVE === 'euler') echo 'tab_active'; ?>" href="/blog/1/Project_Euler_with_Befunge">Project Euler</a>
<a class="tab <?php if ($HEADER_ACTIVE === 'blog') echo 'tab_active'; ?>" href="/blog">Blog</a>
<a class="tab <?php if ($HEADER_ACTIVE === 'programs') echo 'tab_active'; ?>" href="/programs">Programs</a>
<a class="tab <?php if ($HEADER_ACTIVE === 'webapps') echo 'tab_active'; ?>" href="/webapps">Tools</a>
<?php if (isLoggedInByCookie()): ?><a class="tab tab_admin" href="/admin">Admin</a><?php endif; ?>
<a class="tab <?php if ($HEADER_ACTIVE === 'about') echo 'tab_active'; ?>" href="/about">About</a>
<div class="tab_split" ></div>
<?php if (isLoggedInByCookie()): ?><a class="tab tab_logout" href="/logout"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="-8 0 40 32"><path d="m 18,24 0,4 -14,0 0,-24 14,0 0,4 4,0 0,-8 -22,0 0,32 22,0 0,-8 z m -6,-4.003 0,-8 12,0 0,-4 8,8 -8,8 0,-4 z"></path></svg></a><?php endif; ?>
<a class="tab tab_github" href="https://github.com/Mikescher/">Github</a>
</div>
</div>

View File

@ -1,22 +1,28 @@
<?php <?php
require_once(__DIR__ . '/../internals/adventofcode.php'); require_once (__DIR__ . '/../internals/website.php');
$years = AdventOfCode::listYears(); /** @var PageFrameOptions $FRAME_OPTIONS */ global $FRAME_OPTIONS;
$year = end($years); /** @var URLRoute $ROUTE */ global $ROUTE;
/** @var Website $SITE */ global $SITE;
global $FRAGMENT_PARAM;
/** @var array $parameter */
$parameter = $FRAGMENT_PARAM;
?>
<?php
$years = $SITE->modules->AdventOfCode()->listYears();
$year = intval(end($years));
?> ?>
<div class="index_pnl_base"> <div class="index_pnl_base">
<div class="index_pnl_header"> <div class="index_pnl_header">
<a href="<?php echo AdventOfCode::getURLForYear($year); ?>">Advent of Code</a> <a href="<?php echo $SITE->modules->AdventOfCode()->getURLForYear($year); ?>">Advent of Code</a>
</div> </div>
<div class="index_pnl_content"> <div class="index_pnl_content">
<?php <?php echo $SITE->fragments->PanelAdventOfCodeCalendar($year, true, true, true); ?>
global $PARAM_AOCCALENDAR;
$PARAM_AOCCALENDAR = ['year' => $year, 'nav'=>true, 'linkheader'=>true, 'ajax'=>true];
require (__DIR__ . '/../fragments/panel_aoc_calendar.php')
?>
</div> </div>

View File

@ -1,19 +1,28 @@
<?php <?php
require_once (__DIR__ . '/../internals/website.php');
global $PARAM_AOCCALENDAR; /** @var PageFrameOptions $FRAME_OPTIONS */ global $FRAME_OPTIONS;
/** @var URLRoute $ROUTE */ global $ROUTE;
/** @var Website $SITE */ global $SITE;
$year = $PARAM_AOCCALENDAR['year']; global $FRAGMENT_PARAM;
$shownav = $PARAM_AOCCALENDAR['nav']; /** @var array $parameter */
$linkheader = $PARAM_AOCCALENDAR['linkheader']; $parameter = $FRAGMENT_PARAM;
$ajax = $PARAM_AOCCALENDAR['ajax']; ?>
$frame = isset($PARAM_AOCCALENDAR['frame']) ? $PARAM_AOCCALENDAR['frame'] : true;
$frameid = isset($PARAM_AOCCALENDAR['frameid']) ? $PARAM_AOCCALENDAR['frameid'] : ('aoc_frame_' . getRandomToken(16));
$assocdays = AdventOfCode::listSingleYearAssociative($year); <?php
$prev_year = $shownav ? AdventOfCode::getPrevYear($year) : null; $year = $parameter['year'];
$next_year = $shownav ? AdventOfCode::getNextYear($year) : null; $shownav = $parameter['nav'];
$linkheader = $parameter['linkheader'];
$ajax = $parameter['ajax'];
$frame = $parameter['frame'];
$frameid = $parameter['frameid'];
if ($ajax) includeAdditionalScript("/data/javascript/aoc_panel_interactive.js", 'defer', true); $assocdays = $SITE->modules->AdventOfCode()->listSingleYearAssociative($year);
$prev_year = $shownav ? $SITE->modules->AdventOfCode()->getPrevYear($year) : null;
$next_year = $shownav ? $SITE->modules->AdventOfCode()->getNextYear($year) : null;
if ($ajax) $FRAME_OPTIONS->addScript("/data/javascript/aoc_panel_interactive.js", true);
?> ?>
@ -26,14 +35,14 @@ if ($ajax) includeAdditionalScript("/data/javascript/aoc_panel_interactive.js",
if ($ajax) if ($ajax)
echo '<a href="javascript:void();" onclick="javascript:changeAOCPanel(' . $prev_year . ', ' . ($shownav?'true':'false') . ', ' . ($linkheader?'true':'false') . ', ' . ($ajax?'true':'false') . ', \'' . $frameid . '\')" class="aoc_calendar_header_link aoc_prev" >&lt;</a>'; echo '<a href="javascript:void();" onclick="javascript:changeAOCPanel(' . $prev_year . ', ' . ($shownav?'true':'false') . ', ' . ($linkheader?'true':'false') . ', ' . ($ajax?'true':'false') . ', \'' . $frameid . '\')" class="aoc_calendar_header_link aoc_prev" >&lt;</a>';
else else
echo '<a href="' . AdventOfCode::getURLForYear($prev_year) . '" class="aoc_calendar_header_link aoc_prev" >&lt;</a>'; echo '<a href="' . $SITE->modules->AdventOfCode()->getURLForYear($prev_year) . '" class="aoc_calendar_header_link aoc_prev" >&lt;</a>';
} }
else else
{ {
echo '<a href="#" class="aoc_calendar_header_link aoc_prev aoc_link_hidden" >&lt;</a>'; echo '<a href="#" class="aoc_calendar_header_link aoc_prev aoc_link_hidden" >&lt;</a>';
} }
if ($linkheader) echo '<span class="aoc_calendar_header_title"><a href="' . AdventOfCode::getURLForYear($year) . '">'.$year.'</a></span>'; if ($linkheader) echo '<span class="aoc_calendar_header_title"><a href="' . $SITE->modules->AdventOfCode()->getURLForYear($year) . '">'.$year.'</a></span>';
else echo '<span class="aoc_calendar_header_title">'.$year.'</span>'; else echo '<span class="aoc_calendar_header_title">'.$year.'</span>';
if ($next_year !== null) if ($next_year !== null)
@ -41,7 +50,7 @@ if ($ajax) includeAdditionalScript("/data/javascript/aoc_panel_interactive.js",
if ($ajax) if ($ajax)
echo '<a href="javascript:void();" onclick="javascript:changeAOCPanel(' . $next_year . ', ' . ($shownav?'true':'false') . ', ' . ($linkheader?'true':'false') . ', ' . ($ajax?'true':'false') . ', \'' . $frameid . '\')" class="aoc_calendar_header_link aoc_next" >&gt;</a>'; echo '<a href="javascript:void();" onclick="javascript:changeAOCPanel(' . $next_year . ', ' . ($shownav?'true':'false') . ', ' . ($linkheader?'true':'false') . ', ' . ($ajax?'true':'false') . ', \'' . $frameid . '\')" class="aoc_calendar_header_link aoc_next" >&gt;</a>';
else else
echo '<a href="' . AdventOfCode::getURLForYear($next_year) . '" class="aoc_calendar_header_link aoc_next" >&gt;</a>'; echo '<a href="' . $SITE->modules->AdventOfCode()->getURLForYear($next_year) . '" class="aoc_calendar_header_link aoc_next" >&gt;</a>';
} }
else else
{ {

View File

@ -1,7 +1,17 @@
<?php <?php
require_once(__DIR__ . '/../internals/blog.php'); require_once (__DIR__ . '/../internals/website.php');
$allposts = Blog::listAllNewestFirst(); /** @var PageFrameOptions $FRAME_OPTIONS */ global $FRAME_OPTIONS;
/** @var URLRoute $ROUTE */ global $ROUTE;
/** @var Website $SITE */ global $SITE;
global $FRAGMENT_PARAM;
/** @var array $parameter */
$parameter = $FRAGMENT_PARAM;
?>
<?php
$allposts = $SITE->modules->Blog()->listAllNewestFirst();
?> ?>
<div class="index_pnl_base"> <div class="index_pnl_base">

View File

@ -1,7 +1,17 @@
<?php <?php
require_once(__DIR__ . '/../internals/books.php'); require_once (__DIR__ . '/../internals/website.php');
$allbooks = Books::listAllNewestFirst(); /** @var PageFrameOptions $FRAME_OPTIONS */ global $FRAME_OPTIONS;
/** @var URLRoute $ROUTE */ global $ROUTE;
/** @var Website $SITE */ global $SITE;
global $FRAGMENT_PARAM;
/** @var array $parameter */
$parameter = $FRAGMENT_PARAM;
?>
<?php
$allbooks = $SITE->modules->Books()->listAllNewestFirst();
?> ?>
<div class="index_pnl_base"> <div class="index_pnl_base">

View File

@ -1,7 +1,17 @@
<?php <?php
require_once(__DIR__ . '/../internals/euler.php'); require_once (__DIR__ . '/../internals/website.php');
$euler = Euler::listAll(); /** @var PageFrameOptions $FRAME_OPTIONS */ global $FRAME_OPTIONS;
/** @var URLRoute $ROUTE */ global $ROUTE;
/** @var Website $SITE */ global $SITE;
global $FRAGMENT_PARAM;
/** @var array $parameter */
$parameter = $FRAGMENT_PARAM;
?>
<?php
$data = $SITE->modules->Euler()->listAll();
$RATING_CLASSES = ['euler_pnl_celltime_perfect', 'euler_pnl_celltime_good', 'euler_pnl_celltime_ok', 'euler_pnl_celltime_bad', 'euler_pnl_celltime_fail']; $RATING_CLASSES = ['euler_pnl_celltime_perfect', 'euler_pnl_celltime_good', 'euler_pnl_celltime_ok', 'euler_pnl_celltime_bad', 'euler_pnl_celltime_fail'];
?> ?>
@ -18,7 +28,7 @@
$arr = []; $arr = [];
$max = 0; $max = 0;
foreach ($euler as $problem) foreach ($data as $problem)
{ {
$max = max($max, $problem['number']); $max = max($max, $problem['number']);
$arr[$problem['number']] = $problem; $arr[$problem['number']] = $problem;

View File

@ -1,7 +1,17 @@
<?php <?php
require_once(__DIR__ . '/../internals/programs.php'); require_once (__DIR__ . '/../internals/website.php');
$allprograms = Programs::listAllNewestFirst(); /** @var PageFrameOptions $FRAME_OPTIONS */ global $FRAME_OPTIONS;
/** @var URLRoute $ROUTE */ global $ROUTE;
/** @var Website $SITE */ global $SITE;
global $FRAGMENT_PARAM;
/** @var array $parameter */
$parameter = $FRAGMENT_PARAM;
?>
<?php
$allprograms = $SITE->modules->Programs()->listAllNewestFirst();
?> ?>
<div class="index_pnl_base"> <div class="index_pnl_base">

View File

@ -1,15 +1,23 @@
<?php <?php
require_once (__DIR__ . '/../internals/base.php'); require_once (__DIR__ . '/../internals/website.php');
global $PARAM_BEFUNGE93RUNNER; /** @var PageFrameOptions $FRAME_OPTIONS */ global $FRAME_OPTIONS;
/** @var URLRoute $ROUTE */ global $ROUTE;
/** @var Website $SITE */ global $SITE;
$code = $PARAM_BEFUNGE93RUNNER['code']; global $FRAGMENT_PARAM;
$url = $PARAM_BEFUNGE93RUNNER['url']; /** @var array $parameter */
$interactive = $PARAM_BEFUNGE93RUNNER['interactive']; $parameter = $FRAGMENT_PARAM;
$initspeed = $PARAM_BEFUNGE93RUNNER['speed'];
$editable = $PARAM_BEFUNGE93RUNNER['editable'];
function fmtBef($str) {
$code = $parameter['code'];
$url = $parameter['url'];
$interactive = $parameter['interactive'];
$initspeed = $parameter['speed'];
$editable = $parameter['editable'];
function fmtBef($str)
{
$str = htmlspecialchars($str); $str = htmlspecialchars($str);
$str = str_replace("\r", "", $str); $str = str_replace("\r", "", $str);
$str = join("\n", array_map(function($p){return rtrim($p);}, explode("\n", $str))); $str = join("\n", array_map(function($p){return rtrim($p);}, explode("\n", $str)));
@ -23,7 +31,8 @@ function fmtBef($str) {
$result = ''; $result = '';
if ($interactive) { if ($interactive)
{
$speed_attr = ''; $speed_attr = '';
if (isset($initspeed) && $initspeed != NULL && $initspeed>0) $speed_attr = ' data-b93rnr_initialspeed="'.$initspeed.'" '; if (isset($initspeed) && $initspeed != NULL && $initspeed>0) $speed_attr = ' data-b93rnr_initialspeed="'.$initspeed.'" ';
$code_attr = ''; $code_attr = '';
@ -58,7 +67,7 @@ if ($interactive) {
$result .= ' </div>' . "\n"; $result .= ' </div>' . "\n";
$result .= '</div>' . "\n"; $result .= '</div>' . "\n";
includeAdditionalScript("/data/javascript/blogpost_bef93runner.js"); $FRAME_OPTIONS->addScript("/data/javascript/blogpost_bef93runner.js", false);
} }
else else
{ {
@ -72,4 +81,4 @@ else
$result .= '</div>' . "\n"; $result .= '</div>' . "\n";
} }
return $result; echo $result;

View File

@ -1,15 +1,25 @@
<?php <?php
require_once (__DIR__ . '/../internals/base.php'); require_once (__DIR__ . '/../internals/website.php');
/** @var PageFrameOptions $FRAME_OPTIONS */ global $FRAME_OPTIONS;
/** @var URLRoute $ROUTE */ global $ROUTE;
/** @var Website $SITE */ global $SITE;
global $FRAGMENT_PARAM;
/** @var array $parameter */
$parameter = $FRAGMENT_PARAM;
$codeLeft = $parameter['code_left'];
$codeRight = $parameter['code_right'];
global $PARAM_CODE_LEFT;
global $PARAM_CODE_RIGHT;
$result = ''; $result = '';
$result .= '<div class="bfjoust_runner_owner">' . "\n"; $result .= '<div class="bfjoust_runner_owner">' . "\n";
$result .= ' <div class="hsplit">' . "\n"; $result .= ' <div class="hsplit">' . "\n";
$result .= ' <textarea class="hsplit_1 source" id="source_1">' . htmlspecialchars($PARAM_CODE_LEFT) . '</textarea>' . "\n"; $result .= ' <textarea class="hsplit_1 source" id="source_1">' . htmlspecialchars($codeLeft) . '</textarea>' . "\n";
$result .= ' <textarea class="hsplit_2 source" id="source_2">' . htmlspecialchars($PARAM_CODE_RIGHT) . '</textarea>' . "\n"; $result .= ' <textarea class="hsplit_2 source" id="source_2">' . htmlspecialchars($codeRight) . '</textarea>' . "\n";
$result .= ' </div>' . "\n"; $result .= ' </div>' . "\n";
$result .= ' <div id="commandpanel">' . "\n"; $result .= ' <div id="commandpanel">' . "\n";
@ -35,6 +45,6 @@ $result .= '</div>' . "\n";
$result .= '' . "\n"; $result .= '' . "\n";
includeAdditionalScript("/data/javascript/blogpost_BFJoustBot_script.js"); $FRAME_OPTIONS->addScript('/data/javascript/blogpost_BFJoustBot_script.js', false);
return $result; echo $result;

9
www/frames/api_frame.php Normal file
View File

@ -0,0 +1,9 @@
<?php
require_once (__DIR__ . '/../internals/website.php');
/** @var PageFrameOptions $FRAME_OPTIONS */ global $FRAME_OPTIONS;
/** @var URLRoute $ROUTE */ global $ROUTE;
/** @var Website $SITE */ global $SITE;
print($FRAME_OPTIONS->raw);

View File

@ -0,0 +1,69 @@
<!DOCTYPE html>
<?php
require_once (__DIR__ . '/../internals/website.php');
/** @var PageFrameOptions $FRAME_OPTIONS */ global $FRAME_OPTIONS;
/** @var URLRoute $ROUTE */ global $ROUTE;
/** @var Website $SITE */ global $SITE;
?>
<html lang="en">
<head>
<meta charset="utf-8">
<?php
if ($FRAME_OPTIONS->title !== '' && $FRAME_OPTIONS->title !== null)
echo '<title>' . htmlspecialchars('Mikescher.com - ' . $FRAME_OPTIONS->title) . '</title>';
else if ($FRAME_OPTIONS->title === '')
echo '<title>Mikescher.com</title>';
else
echo '';
?>
<meta name="google-site-verification" content="pZOhmjeJcQbRMNa8xRLam4dwJ2oYwMwISY1lRKreSSs"/>
<link rel="icon" type="image/png" href="/data/images/favicon.png"/>
<?php
if ($FRAME_OPTIONS->canonical_url !== null) echo '<link rel="canonical" href="'.$FRAME_OPTIONS->canonical_url.'"/>' . "\n";
foreach ($FRAME_OPTIONS->stylesheets as $cssfile) echo '<link rel="stylesheet" href="' . $cssfile . '"/>' . "\n";
foreach ($FRAME_OPTIONS->scripts as $scriptfile)
{
if ($scriptfile[1]) echo '<script src="' . $scriptfile[0] . '" defer></script>' . "\n";
else echo '<script src="' . $scriptfile[0] . '" type="text/javascript" ></script>' . "\n";
}
?>
</head>
<body>
<div id="mastercontainer">
<div id="headerdiv">
<div class="logowrapper">
<a href="/"><img class="logo" src="/data/images/logo.png" alt="Mikescher.com Logo" /></a>
</div>
<div class="tabrow">
<a class="tab <?php if ($FRAME_OPTIONS->activeHeader === 'home') echo 'tab_active'; ?>" href="/">Home</a>
<a class="tab <?php if ($FRAME_OPTIONS->activeHeader === 'euler') echo 'tab_active'; ?>" href="/blog/1/Project_Euler_with_Befunge">Project Euler</a>
<a class="tab <?php if ($FRAME_OPTIONS->activeHeader === 'blog') echo 'tab_active'; ?>" href="/blog">Blog</a>
<a class="tab <?php if ($FRAME_OPTIONS->activeHeader === 'programs') echo 'tab_active'; ?>" href="/programs">Programs</a>
<a class="tab <?php if ($FRAME_OPTIONS->activeHeader === 'webapps') echo 'tab_active'; ?>" href="/webapps">Tools</a>
<?php if ($SITE->isLoggedInByCookie()): ?><a class="tab tab_admin" href="/admin">Admin</a><?php endif; ?>
<a class="tab <?php if ($FRAME_OPTIONS->activeHeader === 'about') echo 'tab_active'; ?>" href="/about">About</a>
<div class="tab_split" ></div>
<?php if ($SITE->isLoggedInByCookie()): ?><a class="tab tab_logout" href="/logout"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="-8 0 40 32"><path d="m 18,24 0,4 -14,0 0,-24 14,0 0,4 4,0 0,-8 -22,0 0,32 22,0 0,-8 z m -6,-4.003 0,-8 12,0 0,-4 8,8 -8,8 0,-4 z"></path></svg></a><?php endif; ?>
<a class="tab tab_github" href="https://github.com/Mikescher/">Github</a>
</div>
</div>
<div id="content" class="<?php echo join(' ', $FRAME_OPTIONS->contentCSSClasses); ?>">
<?php echo $FRAME_OPTIONS->raw; ?>
</div>
<div id="footerdiv" class="content-responsive">
<hr />
made with vanilla PHP and MySQL<span class="footerspan2">, no frameworks, no bootstrap, no unnecessary* javascript</span>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,52 @@
<!DOCTYPE html>
<?php
require_once (__DIR__ . '/../internals/website.php');
/** @var PageFrameOptions $FRAME_OPTIONS */ global $FRAME_OPTIONS;
/** @var URLRoute $ROUTE */ global $ROUTE;
/** @var Website $SITE */ global $SITE;
?>
<html lang="en">
<head>
<meta charset="utf-8">
<title><?php echo ($FRAME_OPTIONS->title !== '') ? htmlspecialchars('Mikescher.com - ' . $FRAME_OPTIONS->title) : 'Mikescher.com'; ?></title>
<meta name="google-site-verification" content="pZOhmjeJcQbRMNa8xRLam4dwJ2oYwMwISY1lRKreSSs"/>
<link rel="icon" type="image/png" href="/data/images/favicon.png"/>
<link rel="stylesheet" href="/data/css/styles.css" />
</head>
<body>
<div id="mastercontainer">
<div id="headerdiv">
<div class="logowrapper">
<a href="/"><img class="logo" src="/data/images/logo.png" alt="Mikescher.com Logo" /></a>
</div>
<div class="tabrow">
<a class="tab" href="/">Home</a>
<a class="tab" href="/blog/1/Project_Euler_with_Befunge">Project Euler</a>
<a class="tab" href="/blog">Blog</a>
<a class="tab" href="/programs">Programs</a>
<a class="tab" href="/webapps">Tools</a>
<a class="tab" href="/about">About</a>
<div class="tab_split" ></div>
<a class="tab tab_github" href="https://github.com/Mikescher/">Github</a>
</div>
</div>
<div id="content" class="<?php echo join(' ', $FRAME_OPTIONS->contentCSSClasses); ?>">
<?php echo $FRAME_OPTIONS->raw; ?>
</div>
<div id="footerdiv" class="content-responsive">
<hr />
made with vanilla PHP and MySQL<span class="footerspan2">, no frameworks, no bootstrap, no unnecessary* javascript</span>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,9 @@
<?php
require_once (__DIR__ . '/../internals/website.php');
/** @var PageFrameOptions $FRAME_OPTIONS */ global $FRAME_OPTIONS;
/** @var URLRoute $ROUTE */ global $ROUTE;
/** @var Website $SITE */ global $SITE;
// echo nothing

View File

@ -1,213 +1,85 @@
<?php <?php
require_once (__DIR__ . '/internals/base.php'); require_once (__DIR__ . '/internals/website.php');
$site = new Website();
$site->init();
$URL_RULES = $URL_RULES =
[ [
[ 'url' => [], 'target' => 'pages/main.php', 'options' => [], ], [ 'url' => [], 'target' => 'main.php', 'options' => [ 'http' ], 'parameter' => [ ], ],
[ 'url' => ['index'], 'target' => 'pages/main.php', 'options' => [], ], [ 'url' => ['index'], 'target' => 'main.php', 'options' => [ 'http' ], 'parameter' => [ ], ],
[ 'url' => ['index.php'], 'target' => 'pages/main.php', 'options' => [], ], [ 'url' => ['index.php'], 'target' => 'main.php', 'options' => [ 'http' ], 'parameter' => [ ], ],
[ 'url' => ['msmain', 'index'], 'target' => 'pages/main.php', 'options' => [], ], [ 'url' => ['msmain', 'index'], 'target' => 'main.php', 'options' => [ 'http' ], 'parameter' => [ ], ],
[ 'url' => ['about'], 'target' => 'pages/about.php', 'options' => [], ], [ 'url' => ['about'], 'target' => 'about.php', 'options' => [ 'http' ], 'parameter' => [ ], ],
[ 'url' => ['msmain', 'about'], 'target' => 'pages/about.php', 'options' => [], ], [ 'url' => ['msmain', 'about'], 'target' => 'about.php', 'options' => [ 'http' ], 'parameter' => [ ], ],
[ 'url' => ['login'], 'target' => 'pages/login.php', 'options' => [ 'login_target' => '/' ], ], [ 'url' => ['login'], 'target' => 'login.php', 'options' => [ 'http' ], 'parameter' => [ 'login_target' => '/' ], ],
[ 'url' => ['logout'], 'target' => 'pages/logout.php', 'options' => [ 'logout_target' => '/' ], ], [ 'url' => ['logout'], 'target' => 'logout.php', 'options' => [ 'http' ], 'parameter' => [ 'logout_target' => '/' ], ],
[ 'url' => ['programs'], 'target' => 'pages/programs_list.php', 'options' => [ 'categoryfilter' => '' ], ], [ 'url' => ['programs'], 'target' => 'programs_list.php', 'options' => [ 'http' ], 'parameter' => [ 'categoryfilter' => '' ], ],
[ 'url' => ['programs', 'index'], 'target' => 'pages/programs_list.php', 'options' => [ 'categoryfilter' => '%GET%' ], ], [ 'url' => ['programs', 'index'], 'target' => 'programs_list.php', 'options' => [ 'http' ], 'parameter' => [ 'categoryfilter' => '%GET%' ], ],
[ 'url' => ['programs', 'index'], 'target' => 'pages/programs_list.php', 'options' => [ 'categoryfilter' => '' ], ], [ 'url' => ['programs', 'index'], 'target' => 'programs_list.php', 'options' => [ 'http' ], 'parameter' => [ 'categoryfilter' => '' ], ],
[ 'url' => ['programs', 'cat', '?{categoryfilter}'], 'target' => 'pages/programs_list.php', 'options' => [ 'categoryfilter' => '%URL%' ], ], [ 'url' => ['programs', 'cat', '?{categoryfilter}'], 'target' => 'programs_list.php', 'options' => [ 'http' ], 'parameter' => [ 'categoryfilter' => '%URL%' ], ],
[ 'url' => ['downloads', 'details.php'], 'target' => 'pages/programs_list.php', 'options' => [ 'categoryfilter' => '' ], ], [ 'url' => ['downloads', 'details.php'], 'target' => 'programs_list.php', 'options' => [ 'http' ], 'parameter' => [ 'categoryfilter' => '' ], ],
[ 'url' => ['downloads', 'downloads.php'], 'target' => 'pages/programs_list.php', 'options' => [ 'categoryfilter' => '' ], ], [ 'url' => ['downloads', 'downloads.php'], 'target' => 'programs_list.php', 'options' => [ 'http' ], 'parameter' => [ 'categoryfilter' => '' ], ],
[ 'url' => ['programs', 'view', '?{id}'], 'target' => 'pages/programs_view.php', 'options' => [ 'id' => '%URL%' ], ], [ 'url' => ['programs', 'view', '?{id}'], 'target' => 'programs_view.php', 'options' => [ 'http' ], 'parameter' => [ 'id' => '%URL%' ], ],
[ 'url' => ['programs', 'view'], 'target' => 'pages/programs_view.php', 'options' => [ 'id' => '%GET%' ], ], [ 'url' => ['programs', 'view'], 'target' => 'programs_view.php', 'options' => [ 'http' ], 'parameter' => [ 'id' => '%GET%' ], ],
[ 'url' => ['downloads', '?{id}'], 'target' => 'pages/programs_download.php', 'options' => [ 'id' => '%URL%' ], ], [ 'url' => ['downloads', '?{id}'], 'target' => 'programs_download.php', 'options' => [ 'http' ], 'parameter' => [ 'id' => '%URL%' ], ],
[ 'url' => ['programs', 'download', '?{id}'], 'target' => 'pages/programs_download.php', 'options' => [ 'id' => '%URL%' ], ], [ 'url' => ['programs', 'download', '?{id}'], 'target' => 'programs_download.php', 'options' => [ 'http' ], 'parameter' => [ 'id' => '%URL%' ], ],
[ 'url' => ['programs', 'download'], 'target' => 'pages/programs_download.php', 'options' => [ 'id' => '%GET%' ], ], [ 'url' => ['programs', 'download'], 'target' => 'programs_download.php', 'options' => [ 'http' ], 'parameter' => [ 'id' => '%GET%' ], ],
[ 'url' => ['books'], 'target' => 'pages/books_list.php', 'options' => [], ], [ 'url' => ['books'], 'target' => 'books_list.php', 'options' => [ 'http' ], 'parameter' => [ ], ],
[ 'url' => ['books', 'list'], 'target' => 'pages/books_list.php', 'options' => [], ], [ 'url' => ['books', 'list'], 'target' => 'books_list.php', 'options' => [ 'http' ], 'parameter' => [ ], ],
[ 'url' => ['books', 'view', '?{id}'], 'target' => 'pages/books_view.php', 'options' => [ 'id' => '%GET%' ], ], [ 'url' => ['books', 'view', '?{id}'], 'target' => 'books_view.php', 'options' => [ 'http' ], 'parameter' => [ 'id' => '%GET%' ], ],
[ 'url' => ['books', 'view', '?{id}', '*'], 'target' => 'pages/books_view.php', 'options' => [ 'id' => '%URL%' ], ], [ 'url' => ['books', 'view', '?{id}', '*'], 'target' => 'books_view.php', 'options' => [ 'http' ], 'parameter' => [ 'id' => '%URL%' ], ],
[ 'url' => ['update.php'], 'target' => 'pages/api.php', 'options' => [ '_opt' => 'http', 'cmd' => 'progs::updatecheck' ], ], [ 'url' => ['update.php'], 'target' => 'api.php', 'options' => [ 'http', 'api' ], 'parameter' => [ 'cmd' => 'progs::updatecheck' ], ],
[ 'url' => ['update.php', '?{Name}'], 'target' => 'pages/api.php', 'options' => [ '_opt' => 'http', 'cmd' => 'progs::updatecheck' ], ], [ 'url' => ['update.php', '?{Name}'], 'target' => 'api.php', 'options' => [ 'http', 'api' ], 'parameter' => [ 'cmd' => 'progs::updatecheck' ], ],
[ 'url' => ['update'], 'target' => 'pages/api.php', 'options' => [ '_opt' => 'http', 'cmd' => 'progs::updatecheck' ], ], [ 'url' => ['update'], 'target' => 'api.php', 'options' => [ 'http', 'api' ], 'parameter' => [ 'cmd' => 'progs::updatecheck' ], ],
[ 'url' => ['update', '?{Name}'], 'target' => 'pages/api.php', 'options' => [ '_opt' => 'http', 'cmd' => 'progs::updatecheck' ], ], [ 'url' => ['update', '?{Name}'], 'target' => 'api.php', 'options' => [ 'http', 'api' ], 'parameter' => [ 'cmd' => 'progs::updatecheck' ], ],
[ 'url' => ['update2'], 'target' => 'pages/api.php', 'options' => [ '_opt' => 'http', 'cmd' => 'progs::updatecheck' ], ], [ 'url' => ['update2'], 'target' => 'api.php', 'options' => [ 'http', 'api' ], 'parameter' => [ 'cmd' => 'progs::updatecheck' ], ],
[ 'url' => ['api', 'update'], 'target' => 'pages/api.php', 'options' => [ '_opt' => 'http', 'cmd' => 'progs::updatecheck' ], ], [ 'url' => ['api', 'update'], 'target' => 'api.php', 'options' => [ 'http', 'api' ], 'parameter' => [ 'cmd' => 'progs::updatecheck' ], ],
[ 'url' => ['api', 'update', '?{Name}'], 'target' => 'pages/api.php', 'options' => [ '_opt' => 'http', 'cmd' => 'progs::updatecheck' ], ], [ 'url' => ['api', 'update', '?{Name}'], 'target' => 'api.php', 'options' => [ 'http', 'api' ], 'parameter' => [ 'cmd' => 'progs::updatecheck' ], ],
[ 'url' => ['api', 'test'], 'target' => 'pages/api.php', 'options' => [ '_opt' => 'http', 'cmd' => 'base::test' ], ], [ 'url' => ['api', 'test'], 'target' => 'api.php', 'options' => [ 'http', 'api' ], 'parameter' => [ 'cmd' => 'base::test' ], ],
[ 'url' => ['api', 'setselfadress'], 'target' => 'pages/api.php', 'options' => [ '_opt' => 'http', 'cmd' => 'server::setselfaddress' ], ], [ 'url' => ['api', 'setselfadress'], 'target' => 'api.php', 'options' => [ 'http', 'api' ], 'parameter' => [ 'cmd' => 'server::setselfaddress' ], ],
[ 'url' => ['api', 'statsping'], 'target' => 'pages/api.php', 'options' => [ '_opt' => 'http', 'cmd' => 'alephnote::statsping' ], ], [ 'url' => ['api', 'statsping'], 'target' => 'api.php', 'options' => [ 'http', 'api' ], 'parameter' => [ 'cmd' => 'alephnote::statsping' ], ],
[ 'url' => ['api', 'webhook', '?{target}'], 'target' => 'pages/api.php', 'options' => [ '_opt' => 'http', 'cmd' => 'server::gitwebhook' ], ], [ 'url' => ['api', 'webhook', '?{target}'], 'target' => 'api.php', 'options' => [ 'http', 'api' ], 'parameter' => [ 'cmd' => 'server::gitwebhook' ], ],
[ 'url' => ['api', 'backupupload'], 'target' => 'pages/api.php', 'options' => [ '_opt' => 'http', 'cmd' => 'server::backupupload' ], ], [ 'url' => ['api', 'backupupload'], 'target' => 'api.php', 'options' => [ 'http', 'api' ], 'parameter' => [ 'cmd' => 'server::backupupload' ], ],
[ 'url' => ['api', '?{cmd}'], 'target' => 'pages/api.php', 'options' => [ 'cmd' => '%URL%' ], ], [ 'url' => ['api', '?{cmd}'], 'target' => 'api.php', 'options' => [ 'api' ], 'parameter' => [ 'cmd' => '%URL%' ], ],
[ 'url' => ['admin'], 'target' => 'pages/admin.php', 'options' => [ '_opt' => 'password'], ], [ 'url' => ['admin'], 'target' => 'admin.php', 'options' => [ 'password' ], 'parameter' => [ ] ],
[ 'url' => ['blog'], 'target' => 'pages/blog_list.php', 'options' => [], ], [ 'url' => ['blog'], 'target' => 'blog_list.php', 'options' => [ ], 'parameter' => [ ], ],
[ 'url' => ['log'], 'target' => 'pages/blog_list.php', 'options' => [], ], [ 'url' => ['log'], 'target' => 'blog_list.php', 'options' => [ ], 'parameter' => [ ], ],
[ 'url' => ['blogpost', 'index'], 'target' => 'pages/blog_list.php', 'options' => [], ], [ 'url' => ['blogpost', 'index'], 'target' => 'blog_list.php', 'options' => [ ], 'parameter' => [ ], ],
[ 'url' => ['blog', '?{id}'], 'target' => 'pages/blog_view.php', 'options' => [ 'id' => '%URL%', 'subview' => '' ], ], [ 'url' => ['blog', '?{id}'], 'target' => 'blog_view.php', 'options' => [ ], 'parameter' => [ 'id' => '%URL%', 'subview' => '' ], ],
[ 'url' => ['blog', '?{id}'], 'target' => 'pages/blog_view.php', 'options' => [ 'id' => '%URL%', 'subview' => '' ], ], [ 'url' => ['blog', '?{id}', '?{name}'], 'target' => 'blog_view.php', 'options' => [ ], 'parameter' => [ 'id' => '%URL%', 'subview' => '' ], ],
[ 'url' => ['blog', '?{id}', '?{name}'], 'target' => 'pages/blog_view.php', 'options' => [ 'id' => '%URL%', 'subview' => '' ], ], [ 'url' => ['blog', '?{id}', '?{name}', '?{subview}'], 'target' => 'blog_view.php', 'options' => [ ], 'parameter' => [ 'id' => '%URL%', 'subview' => '%URL%' ], ],
[ 'url' => ['blog', '?{id}', '?{name}', '?{subview}'], 'target' => 'pages/blog_view.php', 'options' => [ 'id' => '%URL%', 'subview' => '%URL%' ], ], [ 'url' => ['log', '?{id}'], 'target' => 'blog_view.php', 'options' => [ ], 'parameter' => [ 'id' => '%URL%', 'subview' => '' ], ],
[ 'url' => ['log', '?{id}'], 'target' => 'pages/blog_view.php', 'options' => [ 'id' => '%URL%', 'subview' => '' ], ], [ 'url' => ['log', '?{id}', '?{name}'], 'target' => 'blog_view.php', 'options' => [ ], 'parameter' => [ 'id' => '%URL%', 'subview' => '' ], ],
[ 'url' => ['log', '?{id}'], 'target' => 'pages/blog_view.php', 'options' => [ 'id' => '%URL%', 'subview' => '' ], ], [ 'url' => ['log', '?{id}', '?{name}', '?{subview}'], 'target' => 'blog_view.php', 'options' => [ ], 'parameter' => [ 'id' => '%URL%', 'subview' => '%URL%' ], ],
[ 'url' => ['log', '?{id}', '?{name}'], 'target' => 'pages/blog_view.php', 'options' => [ 'id' => '%URL%', 'subview' => '' ], ], [ 'url' => ['blogpost', 'view'], 'target' => 'blog_view.php', 'options' => [ ], 'parameter' => [ 'id' => '%GET%', 'subview' => '' ], ],
[ 'url' => ['log', '?{id}', '?{name}', '?{subview}'], 'target' => 'pages/blog_view.php', 'options' => [ 'id' => '%URL%', 'subview' => '%URL%' ], ],
[ 'url' => ['blogpost', 'view'], 'target' => 'pages/blog_view.php', 'options' => [ 'id' => '%GET%', 'subview' => '' ], ],
[ 'url' => ['webapps'], 'target' => 'pages/webapps_list.php', 'options' => [], ], [ 'url' => ['webapps'], 'target' => 'webapps_list.php', 'options' => [ ], 'parameter' => [ ], ],
[ 'url' => ['highscores', 'list.php'], 'target' => 'pages/highscores_listentries.php', 'options' => [ '_opt' => 'http', 'gameid' => '%GET%' ], ], [ 'url' => ['highscores', 'list.php'], 'target' => 'highscores_listentries.php', 'options' => [ 'http' ], 'parameter' => [ 'gameid' => '%GET%' ], ],
[ 'url' => ['highscores', 'list'], 'target' => 'pages/highscores_listentries.php', 'options' => [ '_opt' => 'http', 'gameid' => '%GET%' ], ], [ 'url' => ['highscores', 'list'], 'target' => 'highscores_listentries.php', 'options' => [ 'http' ], 'parameter' => [ 'gameid' => '%GET%' ], ],
[ 'url' => ['highscores', 'listentries'], 'target' => 'pages/highscores_listentries.php', 'options' => [ '_opt' => 'http', 'gameid' => '%GET%' ], ], [ 'url' => ['highscores', 'listentries'], 'target' => 'highscores_listentries.php', 'options' => [ 'http' ], 'parameter' => [ 'gameid' => '%GET%' ], ],
[ 'url' => ['highscores', 'list.php'], 'target' => 'pages/highscores_listgames.php', 'options' => [ '_opt' => 'http' ], ], [ 'url' => ['highscores', 'list.php'], 'target' => 'highscores_listgames.php', 'options' => [ 'http' ], 'parameter' => [ ], ],
[ 'url' => ['highscores', 'list'], 'target' => 'pages/highscores_listgames.php', 'options' => [ '_opt' => 'http' ], ], [ 'url' => ['highscores', 'list'], 'target' => 'highscores_listgames.php', 'options' => [ 'http' ], 'parameter' => [ ], ],
[ 'url' => ['highscores', 'listgames'], 'target' => 'pages/highscores_listgames.php', 'options' => [ '_opt' => 'http' ], ], [ 'url' => ['highscores', 'listgames'], 'target' => 'highscores_listgames.php', 'options' => [ 'http' ], 'parameter' => [ ], ],
[ 'url' => ['highscores', 'insert.php'], 'target' => 'pages/highscores_insert.php', 'options' => [ '_opt' => 'http', 'gameid' => '%GET%', 'check' => '%GET%', 'name' => '%GET%', 'rand' => '%GET%', 'points' => '%GET%' ], ], [ 'url' => ['highscores', 'insert.php'], 'target' => 'highscores_insert.php', 'options' => [ 'http' ], 'parameter' => [ 'gameid' => '%GET%', 'check' => '%GET%', 'name' => '%GET%', 'rand' => '%GET%', 'points' => '%GET%' ], ],
[ 'url' => ['highscores', 'insert'], 'target' => 'pages/highscores_insert.php', 'options' => [ '_opt' => 'http', 'gameid' => '%GET%', 'check' => '%GET%', 'name' => '%GET%', 'rand' => '%GET%', 'points' => '%GET%' ], ], [ 'url' => ['highscores', 'insert'], 'target' => 'highscores_insert.php', 'options' => [ 'http' ], 'parameter' => [ 'gameid' => '%GET%', 'check' => '%GET%', 'name' => '%GET%', 'rand' => '%GET%', 'points' => '%GET%' ], ],
[ 'url' => ['highscores', 'update.php'], 'target' => 'pages/highscores_update.php', 'options' => [ '_opt' => 'http', 'gameid' => '%GET%', 'check' => '%GET%', 'name' => '%GET%', 'rand' => '%GET%', 'points' => '%GET%', 'nameid' => '%GET%' ], ], [ 'url' => ['highscores', 'update.php'], 'target' => 'highscores_update.php', 'options' => [ 'http' ], 'parameter' => [ 'gameid' => '%GET%', 'check' => '%GET%', 'name' => '%GET%', 'rand' => '%GET%', 'points' => '%GET%', 'nameid' => '%GET%' ], ],
[ 'url' => ['highscores', 'update'], 'target' => 'pages/highscores_update.php', 'options' => [ '_opt' => 'http', 'gameid' => '%GET%', 'check' => '%GET%', 'name' => '%GET%', 'rand' => '%GET%', 'points' => '%GET%', 'nameid' => '%GET%' ], ], [ 'url' => ['highscores', 'update'], 'target' => 'highscores_update.php', 'options' => [ 'http' ], 'parameter' => [ 'gameid' => '%GET%', 'check' => '%GET%', 'name' => '%GET%', 'rand' => '%GET%', 'points' => '%GET%', 'nameid' => '%GET%' ], ],
[ 'url' => ['highscores', 'list_top50.php'], 'target' => 'pages/highscores_top50.php', 'options' => [ '_opt' => 'http', 'gameid' => '%GET%' ], ], [ 'url' => ['highscores', 'list_top50.php'], 'target' => 'highscores_top50.php', 'options' => [ 'http' ], 'parameter' => [ 'gameid' => '%GET%' ], ],
[ 'url' => ['highscores', 'list_top50'], 'target' => 'pages/highscores_top50.php', 'options' => [ '_opt' => 'http', 'gameid' => '%GET%' ], ], [ 'url' => ['highscores', 'list_top50'], 'target' => 'highscores_top50.php', 'options' => [ 'http' ], 'parameter' => [ 'gameid' => '%GET%' ], ],
[ 'url' => ['highscores', 'getNewID.php'], 'target' => 'pages/highscores_newid.php', 'options' => [ '_opt' => 'http', 'gameid' => '%GET%' ], ], [ 'url' => ['highscores', 'getNewID.php'], 'target' => 'highscores_newid.php', 'options' => [ 'http' ], 'parameter' => [ 'gameid' => '%GET%' ], ],
[ 'url' => ['highscores', 'newid'], 'target' => 'pages/highscores_newid.php', 'options' => [ '_opt' => 'http', 'gameid' => '%GET%' ], ], [ 'url' => ['highscores', 'newid'], 'target' => 'highscores_newid.php', 'options' => [ 'http' ], 'parameter' => [ 'gameid' => '%GET%' ], ],
[ 'url' => ['404'], 'target' => 'pages/error_404.php', 'options' => [], ],
]; ];
//############################################################################# $site->serve($URL_RULES);
try {
InitPHP();
if (isProd())
$requri = $_SERVER['REQUEST_URI'];
else
$requri = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : 'localhost:80/';
$parse = parse_url($requri);
$path = isset($parse['path']) ? $parse['path'] : '';
$pathparts = preg_split('@/@', $path, NULL, PREG_SPLIT_NO_EMPTY);
$partcount = count($pathparts);
global $OPTIONS;
global $HEADER_ACTIVE;
$HEADER_ACTIVE = 'none';
foreach ($URL_RULES as $rule)
{
if ($partcount !== count($rule['url'])) continue;
$urlparams = [];
$ctrlOpt = key_exists('_opt', $rule['options']) ? explode('|', $rule['options']['_opt']) : [];
$target = $rule['target'];
$match = true;
for($i = 0; $i < $partcount; $i++)
{
$comp = $rule['url'][$i];
if (startsWith($comp, '?{') && endsWith($comp, '}'))
{
$ident = substr($comp, 2, strlen($comp)-3);
$urlparams[$ident] = $pathparts[$i];
}
else if ($comp === '*')
{
// ok
}
else
{
if (strtolower($comp) !== strtolower($pathparts[$i])) { $match = false; break; }
}
}
if (!$match) continue;
$opt = [ 'controllerOptions' => $ctrlOpt, 'uri' => $requri ];
foreach($rule['options'] as $optname => $optvalue)
{
$value = $optvalue;
if ($value === '%GET%')
{
if (!isset($_GET[$optname])) { $match = false; break; }
$value = $_GET[$optname];
}
else if ($value === '%POST%')
{
if (!isset($_POST[$optname])) { $match = false; break; }
$value = $_POST[$optname];
}
else if ($value === '%URL%')
{
if (!isset($urlparams[$optname])) { $match = false; break; }
$value = urldecode($urlparams[$optname]);
}
$opt[strtolower($optname)] = $value;
}
$opt['_urlparams'] = [];
foreach ($urlparams as $name => $value) $opt['_urlparams'][strtolower($name)] = urldecode($value);
if (!$match) continue;
if (in_array('disabled', $ctrlOpt)) continue;
if (in_array('password', $ctrlOpt))
{
if (!isLoggedInByCookie())
{
$opt['login_target'] = $path;
$target = 'pages/login.php';
}
}
$is_http = (!isset($_SERVER['HTTPS'])) || empty($_SERVER['HTTPS']) || $_SERVER['HTTPS'] == "off";
if (isProd() && $is_http && !in_array('http', $ctrlOpt))
{
ob_clean();
$redirect = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
header('HTTP/1.1 301 Moved Permanently');
header('Location: ' . $redirect);
exit();
}
$OPTIONS = $opt;
/** @noinspection PhpIncludeInspection */
include $target;
return;
}
{
// [404] - Page Not Found
$OPTIONS = [];
httpError('404', 'Page not found');
return;
}
} catch (Exception $e) {
if (isProd())
{
sendExceptionMail($e);
httpError('500 ', 'Internal server error');
}
else
{
if (isset($e->xdebug_message)) echo '<table class="xdebug-error xe-uncaught-exception" dir="ltr" border="1" cellspacing="0" cellpadding="1">'.$e->xdebug_message.'</table>';
else echo nl2br($e);
}
}
//TODO euler insert+show 32bit | 64bit mode //TODO euler insert+show 32bit | 64bit mode
//TODO support for different color schemes //TODO support for different color schemes

View File

@ -1 +0,0 @@
config.php

View File

@ -1,26 +0,0 @@
<?php if(count(get_included_files()) ==1) exit("Direct access not permitted.");
require_once (__DIR__ . '/../internals/database.php');
class AlephNoteStatistics
{
public static function getTotalUserCount()
{
return Database::sql_query_num('SELECT COUNT(*) FROM an_statslog WHERE NoteCount>0');
}
public static function getUserCountFromLastVersion()
{
return Database::sql_query_num('SELECT COUNT(*) FROM an_statslog WHERE NoteCount>0 GROUP BY Version ORDER BY INET_ATON(Version) DESC LIMIT 1');
}
public static function getActiveUserCount($days)
{
return Database::sql_query_num('SELECT COUNT(*) FROM an_statslog WHERE NoteCount>0 AND LastChanged > NOW() - INTERVAL '.$days.' DAY');
}
public static function getAllActiveEntriesOrdered()
{
return Database::sql_query_assoc('SELECT * FROM an_statslog WHERE NoteCount>0 ORDER BY LastChanged DESC');
}
}

View File

@ -1,422 +0,0 @@
<?php if(count(get_included_files()) ==1) exit("Direct access not permitted.");
global $CONFIG;
$CONFIG = require 'config.php';
global $CSS_BASE;
$CSS_BASE = ($CONFIG['prod']) ? ('/data/css/styles.min.css') : ('/data/css/styles.css');
global $ADDITIONAL_SCRIPTS;
global $ADDITIONAL_STYLESHEETS;
$ADDITIONAL_SCRIPTS = [];
$ADDITIONAL_STYLESHEETS = [];
function InitPHP() {
set_error_handler("exception_error_handler"); // errors as exceptions for global catch
ob_start(); // buffer outpt so it can be discarded in httpError
}
function exception_error_handler($severity, $message, $file, $line) {
if (!(error_reporting() & $severity)) {
// This error code is not included in error_reporting
return;
}
throw new ErrorException($message, 0, $severity, $file, $line);
}
function startsWith($haystack, $needle)
{
$length = strlen($needle);
return (substr($haystack, 0, $length) === $needle);
}
function endsWith($haystack, $needle)
{
$length = strlen($needle);
return $length === 0 || (substr($haystack, -$length) === $needle);
}
function httpError($errorcode, $message)
{
ob_clean();
http_response_code($errorcode);
global $OPTIONS;
$OPTIONS = [ 'code' => $errorcode, 'message' => $message ];
require (__DIR__ . '/../pages/errorview.php');
die();
}
function httpDie($errorcode, $message)
{
ob_flush();
http_response_code($errorcode);
die($message);
}
function destructiveUrlEncode($str) {
$str = str_replace(' ', '_', $str);
$str = str_replace('+', '_', $str);
$str = str_replace(':', '_', $str);
$str = str_replace('.', '', $str);
return urlencode($str);
}
function formatMilliseconds($millis)
{
if ($millis < 1000)
{
return $millis . 'ms';
}
else if ($millis < 10 * 1000)
{
return number_format($millis / (1000), 2) . 's';
}
else if ($millis < 60 * 1000)
{
return floor($millis / (1000)) . 's';
}
else if ($millis < 10 * 60 * 1000)
{
return floor($millis / (60 * 1000)) . 'min ' . floor(($millis % (60 * 1000)) / 1000) . 's';
}
else if ($millis < 60 * 60 * 1000)
{
return floor($millis / (60 * 1000)) . 'min';
}
else if ($millis < 10 * 60 * 60 * 1000)
{
return number_format($millis / (60 * 60 * 1000), 2) . ' hours';
}
else
{
return floor($millis / (60 * 60 * 1000)) . ' hours';
}
}
function includeAdditionalScript($script, $attr='', $printImmediately = false) {
global $ADDITIONAL_SCRIPTS;
if (in_array($script, $ADDITIONAL_SCRIPTS)) return false;
if ($printImmediately) {
$ADDITIONAL_SCRIPTS[$script] = ['src' => $script, 'attr' => $attr, 'consumed' => true];
echo '<script src="'.$script.'" type="text/javascript" '.$attr.'></script>';
return true;
} else {
$ADDITIONAL_SCRIPTS[$script] = ['src' => $script, 'attr' => $attr, 'consumed' => false];
return true;
}
}
function includeAdditionalStylesheet($sheet, $attr='', $printImmediately = false) {
global $ADDITIONAL_STYLESHEETS;
if (in_array($sheet, $ADDITIONAL_STYLESHEETS)) return false;
if ($printImmediately) {
$ADDITIONAL_STYLESHEETS[$sheet] = ['src' => $sheet, 'attr' => $attr, 'consumed' => true];
echo '<link rel="stylesheet" href="' . $sheet . '" '.$attr.'/>';
return true;
} else {
$ADDITIONAL_STYLESHEETS[$sheet] = ['src' => $sheet, 'attr' => $attr, 'consumed' => false];
return true;
}
}
function printHeaderCSS() {
global $CSS_BASE;
includeAdditionalStylesheet($CSS_BASE, '', true);
}
function printAdditionalScripts() {
global $ADDITIONAL_SCRIPTS;
foreach ($ADDITIONAL_SCRIPTS as $d) {
if ($d['consumed']) continue;
echo '<script src="' . $d['src'] . '" type="text/javascript" ' . $d['attr'] . '></script>';
$d['consumed'] = true;
}
}
function printAdditionalStylesheets() {
global $ADDITIONAL_STYLESHEETS;
foreach ($ADDITIONAL_STYLESHEETS as $d) {
if ($d['consumed']) continue;
echo '<link rel="stylesheet" href="' . $d['src'] . '" ' . $d['attr'] . '/>';
$d['consumed'] = true;
}
}
function isProd() {
global $CONFIG;
return $CONFIG['prod'];
}
function convertCountryToFlag($country) {
$country = trim(strtolower($country));
if ($country === 'italy') return '/data/images/flags/013-italy.svg';
if ($country === 'china') return '/data/images/flags/034-china.svg';
if ($country === 'japan') return '/data/images/flags/063-japan.svg';
if ($country === 'un') return '/data/images/flags/082-united-nations.svg';
if ($country === 'south korea') return '/data/images/flags/094-south-korea.svg';
if ($country === 'spain') return '/data/images/flags/128-spain.svg';
if ($country === 'norway') return '/data/images/flags/143-norway.svg';
if ($country === 'Czech') return '/data/images/flags/149-czech-republic.svg';
if ($country === 'germany') return '/data/images/flags/162-germany.svg';
if ($country === 'sweden') return '/data/images/flags/184-sweden.svg';
if ($country === 'france') return '/data/images/flags/195-france.svg';
if ($country === 'switzerland') return '/data/images/flags/205-switzerland.svg';
if ($country === 'england') return '/data/images/flags/216-england.svg';
if ($country === 'usa') return '/data/images/flags/226-united-states.svg';
if ($country === 'america') return '/data/images/flags/226-united-states.svg';
if ($country === 'canada') return '/data/images/flags/243-canada.svg';
if ($country === 'russia') return '/data/images/flags/248-russia.svg';
if ($country === 'eu') return '/data/images/flags/259-european-union.svg';
if ($country === 'uk') return '/data/images/flags/260-united-kingdom.svg';
return null;
}
function convertLanguageToFlag($lang) {
$lang = trim(strtolower($lang));
if ($lang === 'italian') return '/data/images/flags/013-italy.svg';
if ($lang === 'english') return '/data/images/flags/226-united-states.svg';
if ($lang === 'french') return '/data/images/flags/195-france.svg';
if ($lang === 'german') return '/data/images/flags/162-germany.svg';
if ($lang === 'spanish') return '/data/images/flags/128-spain.svg';
return null;
}
function setLoginCookie($user, $pass)
{
$expires = time() + (24*60*60); // 24h
$hash = hash('sha256', $user . ';' . $pass . ';' . gmdate('Y-m-d'));
setcookie('mikescher_auth', $hash, $expires);
}
function isLoggedInByCookie()
{
static $_loginCache = null;
if ($_loginCache !== null) return $_loginCache;
global $CONFIG;
if (key_exists('mikescher_auth', $_COOKIE))
{
if (strlen($_COOKIE['mikescher_auth']) !== 64) return $_loginCache = false;
$auth = hash('sha256', $CONFIG['admin_username'] . ';' . $CONFIG['admin_password'] . ';' . gmdate('Y-m-d'));
if ($auth === $_COOKIE['mikescher_auth']) return $_loginCache = true;
}
return $_loginCache = false;
}
function clearLoginCookie()
{
setcookie("mikescher_auth", "", time()+30);
}
/**
* easy image resize function
* @author http://www.nimrodstech.com/php-image-resize/
* @param string $file - file name to resize
* @param int $width - new image width
* @param int $height - new image height
* @param boolean $proportional - keep image proportional, default is no
* @param string $output - name of the new file (include path if needed)
* @return boolean|resource
*/
function smart_resize_image($file, $width = 0, $height = 0, $proportional, $output)
{
if ( $height <= 0 && $width <= 0 ) return false;
if ( $file === null) return false;
# Setting defaults and meta
$info = getimagesize($file);
$image = '';
$final_width = 0;
$final_height = 0;
list($width_old, $height_old) = $info;
$cropHeight = $cropWidth = 0;
# Calculating proportionality
if ($proportional) {
if ($width == 0) $factor = $height/$height_old;
elseif ($height == 0) $factor = $width/$width_old;
else $factor = min( $width / $width_old, $height / $height_old );
$final_width = round( $width_old * $factor );
$final_height = round( $height_old * $factor );
}
else {
$final_width = ( $width <= 0 ) ? $width_old : $width;
$final_height = ( $height <= 0 ) ? $height_old : $height;
$widthX = $width_old / $width;
$heightX = $height_old / $height;
$x = min($widthX, $heightX);
$cropWidth = ($width_old - $width * $x) / 2;
$cropHeight = ($height_old - $height * $x) / 2;
}
# Loading image to memory according to type
switch ( $info[2] ) {
case IMAGETYPE_JPEG: $image = imagecreatefromjpeg($file); break;
case IMAGETYPE_GIF: $image = imagecreatefromgif($file); break;
case IMAGETYPE_PNG: $image = imagecreatefrompng($file); break;
default: return false;
}
# This is the resizing/resampling/transparency-preserving magic
$image_resized = imagecreatetruecolor( $final_width, $final_height );
if ( ($info[2] == IMAGETYPE_GIF) || ($info[2] == IMAGETYPE_PNG) ) {
$transparency = imagecolortransparent($image);
$palletsize = imagecolorstotal($image);
if ($transparency >= 0 && $transparency < $palletsize) {
$transparent_color = imagecolorsforindex($image, $transparency);
$transparency = imagecolorallocate($image_resized, $transparent_color['red'], $transparent_color['green'], $transparent_color['blue']);
imagefill($image_resized, 0, 0, $transparency);
imagecolortransparent($image_resized, $transparency);
}
elseif ($info[2] == IMAGETYPE_PNG) {
imagealphablending($image_resized, false);
$color = imagecolorallocatealpha($image_resized, 0, 0, 0, 127);
imagefill($image_resized, 0, 0, $color);
imagesavealpha($image_resized, true);
}
}
imagecopyresampled($image_resized, $image, 0, 0, $cropWidth, $cropHeight, $final_width, $final_height, $width_old - 2 * $cropWidth, $height_old - 2 * $cropHeight);
# Preparing a method of providing result
switch ( strtolower($output) ) {
case 'browser':
$mime = image_type_to_mime_type($info[2]);
header("Content-type: $mime");
$output = NULL;
break;
case 'file':
$output = $file;
break;
case 'return':
return $image_resized;
break;
default:
break;
}
# Writing image according to type to the output destination and image quality
switch ( $info[2] ) {
case IMAGETYPE_GIF: imagegif($image_resized, $output); break;
case IMAGETYPE_JPEG: imagejpeg($image_resized, $output, 100); break;
case IMAGETYPE_PNG:
$quality = 9 - (int)((0.9*100)/10.0);
imagepng($image_resized, $output, $quality);
break;
default: return false;
}
return true;
}
/**
* @param string $file - file name to resize
* @param int $width - new image width
* @param int $height - new image height
* @param string $output - name of the new file (include path if needed)
*/
function magick_resize_image($file, $width, $height, $output)
{
list($width_old, $height_old) = getimagesize($file);
if ($width == 0) $factor = $height/$height_old;
elseif ($height == 0) $factor = $width/$width_old;
else $factor = min( $width / $width_old, $height / $height_old );
$final_width = round( $width_old * $factor );
$final_height = round( $height_old * $factor );
$cmd = 'convert "' . $file . '" -strip -resize ' . $final_width . 'x' . $final_height . ' "' . $output . '"';
shell_exec($cmd);
}
function sendMail($subject, $content, $to, $from) {
mail($to, $subject, $content, 'From: ' . $from);
}
function ParamServerOrUndef($idx) {
return isset($_SERVER[$idx]) ? $_SERVER[$idx] : 'NOT_SET';
}
/**
* @param Exception $e
*/
function sendExceptionMail($e)
{
try {
$subject = "Server has encountered an Error at " . date("Y-m-d H:i:s") . "] ";
$content = "";
$content .= 'HTTP_HOST: ' . ParamServerOrUndef('HTTP_HOST') . "\n";
$content .= 'REQUEST_URI: ' . ParamServerOrUndef('REQUEST_URI') . "\n";
$content .= 'TIME: ' . date('Y-m-d H:i:s') . "\n";
$content .= 'REMOTE_ADDR: ' . ParamServerOrUndef('REMOTE_ADDR') . "\n";
$content .= 'HTTP_X_FORWARDED_FOR: ' . ParamServerOrUndef('HTTP_X_FORWARDED_FOR') . "\n";
$content .= 'HTTP_USER_AGENT: ' . ParamServerOrUndef('HTTP_USER_AGENT') . "\n";
$content .= 'MESSAGE:' . "\n" . $e->getMessage() . "\n";
$content .= 'CODE:' . "\n" . $e->getCode() . "\n";
$content .= 'TRACE:' . "\n" . $e->getTraceAsString() . "\n";
$content .= '$_GET:' . "\n" . print_r($_GET, true) . "\n";
$content .= '$_POST:' . "\n" . print_r($_POST, true) . "\n";
$content .= '$_FILES:' . "\n" . print_r($_FILES, true) . "\n";
sendMail($subject, $content, 'virtualadmin@mikescher.de', 'webserver-error@mikescher.com');
}
catch (Exception $e)
{
//
}
}
function get_client_ip() {
if (getenv('HTTP_CLIENT_IP')) return getenv('HTTP_CLIENT_IP');
else if(getenv('HTTP_X_FORWARDED_FOR')) return getenv('HTTP_X_FORWARDED_FOR');
else if(getenv('HTTP_X_FORWARDED')) return getenv('HTTP_X_FORWARDED');
else if(getenv('HTTP_FORWARDED_FOR')) return getenv('HTTP_FORWARDED_FOR');
else if(getenv('HTTP_FORWARDED')) return getenv('HTTP_FORWARDED');
else if(getenv('REMOTE_ADDR')) return getenv('REMOTE_ADDR');
else if (isset($_SERVER['HTTP_CLIENT_IP'])) return $_SERVER['HTTP_CLIENT_IP'];
else if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])) return $_SERVER['HTTP_X_FORWARDED_FOR'];
else if(isset($_SERVER['HTTP_X_FORWARDED'])) return $_SERVER['HTTP_X_FORWARDED'];
else if(isset($_SERVER['HTTP_FORWARDED_FOR'])) return $_SERVER['HTTP_FORWARDED_FOR'];
else if(isset($_SERVER['HTTP_FORWARDED'])) return $_SERVER['HTTP_FORWARDED'];
else if(isset($_SERVER['REMOTE_ADDR'])) return $_SERVER['REMOTE_ADDR'];
else return 'UNKNOWN';
}
function getRandomToken($length = 32)
{
try
{
if(!isset($length) || intval($length) <= 8 ) $length = 32;
if (function_exists('random_bytes')) return bin2hex(random_bytes($length));
if (function_exists('mcrypt_create_iv')) return bin2hex(mcrypt_create_iv($length, MCRYPT_DEV_URANDOM));
if (function_exists('openssl_random_pseudo_bytes')) return bin2hex(openssl_random_pseudo_bytes($length));
}
catch (Exception $e) { throw new InvalidArgumentException($e); }
throw new InvalidArgumentException("No random");
}

View File

@ -1,113 +0,0 @@
<?php if(count(get_included_files()) ==1) exit("Direct access not permitted.");
class Database
{
/* @var PDO $PDO */
public static $PDO = NULL;
public static function connect()
{
global $CONFIG;
if (self::$PDO !== NULL) return;
$dsn = "mysql:host=" . $CONFIG['host'] . ";dbname=" . $CONFIG['database'] . ";charset=utf8";
$opt = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
];
self::$PDO = new PDO($dsn, $CONFIG['user'], $CONFIG['password'], $opt);
}
public static function tryconnect()
{
try {
self::connect();
return true;
} catch (exception $e) {
return false;
}
}
public static function sql_query_num($query)
{
$r = self::$PDO->query($query)->fetch(PDO::FETCH_NUM)[0];
return $r;
}
public static function sql_query_num_prep($query, $params)
{
$stmt = self::$PDO->prepare($query);
foreach ($params as $p)
{
if (strpos($query, $p[0]) !== FALSE) $stmt->bindValue($p[0], $p[1], $p[2]);
}
$stmt->execute();
$r = $stmt->fetch(PDO::FETCH_NUM)[0];
return $r;
}
public static function sql_query_assoc($query)
{
$r = self::$PDO->query($query)->fetchAll(PDO::FETCH_ASSOC);
return $r;
}
public static function sql_query_assoc_prep($query, $params)
{
$stmt = self::$PDO->prepare($query);
foreach ($params as $p)
{
if (strpos($query, $p[0]) !== FALSE) $stmt->bindValue($p[0], $p[1], $p[2]);
}
$stmt->execute();
$r = $stmt->fetchAll(PDO::FETCH_ASSOC);
return $r;
}
public static function sql_query_single($query)
{
$r = self::$PDO->query($query)->fetch(PDO::FETCH_ASSOC);
return $r;
}
public static function sql_query_single_prep($query, $params)
{
$stmt = self::$PDO->prepare($query);
foreach ($params as $p)
{
if (strpos($query, $p[0]) !== FALSE) $stmt->bindValue($p[0], $p[1], $p[2]);
}
$stmt->execute();
$r = $stmt->fetch(PDO::FETCH_ASSOC);
return $r;
}
public static function sql_exec_prep($query, $params)
{
$stmt = self::$PDO->prepare($query);
foreach ($params as $p)
{
if (strpos($query, $p[0]) !== FALSE) $stmt->bindValue($p[0], $p[1], $p[2]);
}
$stmt->execute();
return $stmt->rowCount();
}
}

132
www/internals/fragments.php Normal file
View File

@ -0,0 +1,132 @@
<?php
class Fragments
{
private function evalFragment($name, $url, $params)
{
try
{
ob_start();
{
global $FRAGMENT_PARAM;
$FRAGMENT_PARAM = $params;
/** @noinspection PhpIncludeInspection */
include (__DIR__ . '/../fragments/' . $url);
}
return ob_get_contents();
}
finally
{
ob_end_clean();
}
}
public function PanelEuler()
{
return $this->evalFragment('PanelEuler', 'panel_euler.php', [ ]);
}
public function PanelPrograms()
{
return $this->evalFragment('PanelPrograms', 'panel_programs.php', [ ]);
}
public function PanelBlog()
{
return $this->evalFragment('PanelBlog', 'panel_blog.php', [ ]);
}
public function PanelBooks()
{
return $this->evalFragment('PanelBooks', 'panel_books.php', [ ]);
}
public function PanelAdventOfCode()
{
return $this->evalFragment('PanelAdventOfCode', 'panel_aoc.php', [ ]);
}
public function PanelAdventOfCodeCalendar(int $year, bool $shownav, bool $linkheader, bool $ajax, bool $frame=true, $frameid=null)
{
return $this->evalFragment('PanelAdventOfCodeCalendar', 'panel_aoc_calendar.php',
[
'year' => $year,
'nav' => $shownav,
'linkheader' => $linkheader,
'ajax' => $ajax,
'frame' => $frame,
'frameid' => ($frameid == null) ? ('aoc_frame_' . getRandomToken(16)) : $frameid,
]);
}
public function BlogviewPlain(array $blogpost)
{
return $this->evalFragment('BlogviewPlain', 'blogview_plain.php',
[
'blogpost' => $blogpost,
]);
}
public function BlogviewMarkdown(array $blogpost)
{
return $this->evalFragment('BlogviewMarkdown', 'blogview_markdown.php',
[
'blogpost' => $blogpost,
]);
}
public function BlogviewEulerList(array $blogpost)
{
return $this->evalFragment('BlogviewEulerList', 'blogview_euler_list.php',
[
'blogpost' => $blogpost,
]);
}
public function BlogviewEulerSingle(array $blogpost, string $subview)
{
return $this->evalFragment('BlogviewEulerSingle', 'blogview_euler_single.php',
[
'blogpost' => $blogpost,
'subview' => $subview,
]);
}
public function BlogviewAdventOfCodeList(array $blogpost)
{
return $this->evalFragment('BlogviewAdventOfCodeList', 'blogview_aoc_list.php',
[
'blogpost' => $blogpost,
]);
}
public function BlogviewAdventOfCodeSingle(array $blogpost, string $subview)
{
return $this->evalFragment('BlogviewAdventOfCodeSingle', 'blogview_aoc_single.php',
[
'blogpost' => $blogpost,
'subview' => $subview,
]);
}
public function WidgetBefunge93(string $code, string $url, bool $interactive, int $speed, bool $editable)
{
return $this->evalFragment('WidgetBefunge93', 'widget_befunge93.php',
[
'code' => $code,
'url' => $url,
'interactive' => $interactive,
'speed' => $speed,
'editable' => $editable,
]);
}
public function WidgetBFJoust(string $codeLeft, string $codeRight)
{
return $this->evalFragment('WidgetBFJoust', 'widget_bfjoust.php',
[
'code_left' => $codeLeft,
'code_right' => $codeRight,
]);
}
}

View File

@ -1,102 +0,0 @@
<?php if(count(get_included_files()) ==1) exit("Direct access not permitted.");
require_once (__DIR__ . '/../internals/database.php');
class Highscores
{
public static function generateChecksum($rand, $player, $playerid, $points, $gamesalt)
{
if ($playerid >= 0)
return md5($rand . $player . $playerid . $points . $gamesalt);
else
return md5($rand . $player . $points . $gamesalt);
}
public static function insert($gameid, $points, $name, $playerid, $check, $time, $ip)
{
return Database::sql_exec_prep('INSERT INTO highscoreentries (GAME_ID, POINTS, PLAYER, PLAYERID, CHECKSUM, TIMESTAMP, IP) VALUES (:gid, :p, :pn, :pid, :cs, :ts, :ip)',
[
[':gid', $gameid, PDO::PARAM_INT],
[':p', $points, PDO::PARAM_INT],
[':pn', $name, PDO::PARAM_STR],
[':pid', $playerid, PDO::PARAM_INT],
[':cs', $check, PDO::PARAM_STR],
[':ts', $time, PDO::PARAM_STR],
[':ip', $ip, PDO::PARAM_STR],
]);
}
public static function update($gameid, $points, $name, $playerid, $check, $time, $ip)
{
return Database::sql_exec_prep('UPDATE highscoreentries SET POINTS = :p, PLAYER = :pn, CHECKSUM = :cs, IP = :ip, TIMESTAMP = :ts WHERE GAME_ID = :gid AND PLAYERID = :pid',
[
[':gid', $gameid, PDO::PARAM_INT],
[':p', $points, PDO::PARAM_INT],
[':pn', $name, PDO::PARAM_STR],
[':pid', $playerid, PDO::PARAM_INT],
[':cs', $check, PDO::PARAM_STR],
[':ts', $time, PDO::PARAM_STR],
[':ip', $ip, PDO::PARAM_STR],
]);
}
public static function getGameByID($gameid)
{
return Database::sql_query_single_prep('SELECT * FROM highscoregames WHERE ID = :id',
[
[ ':id', $gameid, PDO::PARAM_INT ],
]);
}
public static function getOrderedEntriesFromGame($gameid, $limit = null)
{
$sql = 'SELECT * FROM highscoreentries WHERE GAME_ID = :id ORDER BY POINTS DESC';
if ($limit !== null) $sql .= " LIMIT $limit";
return Database::sql_query_assoc_prep($sql,
[
[ ':id', $gameid, PDO::PARAM_INT ]
]);
}
public static function getNewestEntriesFromGame($gameid, $limit = null)
{
$sql = 'SELECT * FROM highscoreentries WHERE GAME_ID = :id ORDER BY TIMESTAMP DESC';
if ($limit !== null) $sql .= " LIMIT $limit";
return Database::sql_query_assoc_prep($sql,
[
[ ':id', $gameid, PDO::PARAM_INT ]
]);
}
public static function getEntryCountFromGame($gameid)
{
return Database::sql_query_num_prep('SELECT COUNT(*) FROM highscoreentries WHERE GAME_ID = :id',
[
[ ':id', $gameid, PDO::PARAM_INT ]
]);
}
public static function getAllGames()
{
return Database::sql_query_assoc('SELECT * FROM highscoregames');
}
public static function getNextPlayerID($gameid)
{
return Database::sql_query_num_prep('SELECT MAX(PLAYERID)+1 AS NID FROM highscoreentries WHERE GAME_ID = :gid',
[
[ ':id', $gameid, PDO::PARAM_INT ]
]);
}
public static function getSpecificScore($gameid, $playerid)
{
return Database::sql_query_single_prep('SELECT * FROM highscoreentries WHERE GAME_ID = :gid AND PLAYERID = :pid',
[
[ ':gid', $gameid, PDO::PARAM_INT ],
[ ':pid', $playerid, PDO::PARAM_INT ],
]);
}
}

View File

@ -0,0 +1,6 @@
<?php
interface IWebsiteModule
{
public function checkConsistency();
}

View File

@ -1,45 +0,0 @@
<?php if(count(get_included_files()) ==1) exit("Direct access not permitted.");
require_once (__DIR__ . '/../internals/base.php');
require_once (__DIR__ . '/../extern/egg/ExtendedGitGraph2.php');
class MikescherGitGraph
{
/**
* @return ExtendedGitGraph2
* @throws Exception
*/
public static function create()
{
global $CONFIG;
return new ExtendedGitGraph2($CONFIG['extendedgitgraph']);
}
public static function getPathRenderedData()
{
return __DIR__ . '/../dynamic/egg/cache_fullrenderer.html';
}
/**
* @return string|null
* @throws Exception
*/
public static function get()
{
$d = self::create()->loadFromCache();
if ($d === null) return "";
return $d;
}
public static function checkConsistency()
{
$p = self::getPathRenderedData();
if (!file_exists($p)) return ['result'=>'err', 'message' => 'Rendered data not found'];
if (filemtime($p) < time()-(24*60*60)) return ['result'=>'warn', 'message' => 'Rendered data is older than 1 day'];
return ['result'=>'ok', 'message' => ''];
}
}

99
www/internals/modules.php Normal file
View File

@ -0,0 +1,99 @@
<?php
require_once 'website.php';
class Modules
{
/** @var Database|null */ private $database = null;
/** @var AdventOfCode|null */ private $adventOfCode = null;
/** @var Blog|null */ private $blog = null;
/** @var Books|null */ private $books = null;
/** @var Euler|null */ private $euler = null;
/** @var Programs|null */ private $programs = null;
/** @var AlephNoteStatistics|null */ private $anstats = null;
/** @var UpdatesLog|null */ private $updateslog = null;
/** @var WebApps|null */ private $webapps = null;
/** @var MikescherGitGraph|null */ private $extendedgitgraph = null;
/** @var Highscores|null */ private $highscores = null;
/** @var SelfTest|null */ private $selftest = null;
/** @var Website */
private $site;
public function __construct(Website $site)
{
$this->site = $site;
}
public function Database()
{
if ($this->database === null) { require_once 'modules/database.php'; $this->database = new Database($this->site); }
return $this->database;
}
public function AdventOfCode(): AdventOfCode
{
if ($this->adventOfCode === null) { require_once 'modules/adventofcode.php'; $this->adventOfCode = new AdventOfCode(); }
return $this->adventOfCode;
}
public function Blog(): Blog
{
if ($this->blog === null) { require_once 'modules/blog.php'; $this->blog = new Blog(); }
return $this->blog;
}
public function Books(): Books
{
if ($this->books === null) { require_once 'modules/books.php'; $this->books = new Books($this->site); }
return $this->books;
}
public function Euler(): Euler
{
if ($this->euler === null) { require_once 'modules/euler.php'; $this->euler = new Euler(); }
return $this->euler;
}
public function Programs(): Programs
{
if ($this->programs === null) { require_once 'modules/programs.php'; $this->programs = new Programs(); }
return $this->programs;
}
public function AlephNoteStatistics(): AlephNoteStatistics
{
if ($this->anstats === null) { require_once 'modules/alephnoteStatistics.php'; $this->anstats = new AlephNoteStatistics($this->site); }
return $this->anstats;
}
public function UpdatesLog(): UpdatesLog
{
if ($this->updateslog === null) { require_once 'modules/updateslog.php'; $this->updateslog = new UpdatesLog($this->site); }
return $this->updateslog;
}
public function WebApps(): WebApps
{
if ($this->webapps === null) { require_once 'modules/webapps.php'; $this->webapps = new WebApps(); }
return $this->webapps;
}
public function ExtendedGitGraph(): MikescherGitGraph
{
if ($this->extendedgitgraph === null) { require_once 'modules/mikeschergitgraph.php'; $this->extendedgitgraph = new MikescherGitGraph($this->site); }
return $this->extendedgitgraph;
}
public function Highscores(): Highscores
{
if ($this->highscores === null) { require_once 'modules/highscores.php'; $this->highscores = new Highscores($this->site); }
return $this->highscores;
}
public function SelfTest(): SelfTest
{
if ($this->selftest === null) { require_once 'modules/selftest.php'; $this->selftest = new SelfTest(); }
return $this->selftest;
}
}

View File

@ -1,6 +1,6 @@
<?php <?php
class AdventOfCode class AdventOfCode implements IWebsiteModule
{ {
const YEARS = const YEARS =
[ [
@ -23,48 +23,60 @@ class AdventOfCode
'ts' => ['ext'=>'ts', 'css'=>'language-typescript', 'name'=>'Typescript'], 'ts' => ['ext'=>'ts', 'css'=>'language-typescript', 'name'=>'Typescript'],
]; ];
public static function listAllFromAllYears() /** @var array */
private $staticData;
public function __construct()
{ {
$all = require (__DIR__ . '/../statics/aoc/__all.php'); $this->load();
}
private function load()
{
$all = require (__DIR__ . '/../../statics/aoc/__all.php');
array_walk($all, function(&$value, $year) { array_walk($value, function (&$innervalue) use ($year) { $innervalue = self::readSingle($year, $innervalue); }); }); array_walk($all, function(&$value, $year) { array_walk($value, function (&$innervalue) use ($year) { $innervalue = self::readSingle($year, $innervalue); }); });
return $all; $this->staticData = $all;
} }
public static function listSingleYear($year) public function listAllFromAllYears()
{ {
$all = require (__DIR__ . '/../statics/aoc/__all.php'); return $this->staticData;
$result = $all[$year];
array_walk($result, function(&$value) use ($year) { $value = self::readSingle($year, $value); });
return $result;
} }
public static function listSingleYearAssociative($year) public function listAllDays()
{ {
$all = self::listSingleYear($year); $r = [];
foreach ($this->staticData as $yeardata) foreach ($yeardata as $year => $daydata) $r []= $daydata;
return $this->staticData;
}
public function listSingleYear($year)
{
return $this->staticData[$year];
}
public function listSingleYearAssociative($year)
{
$all = $this->listSingleYear($year);
$result = array_fill(0, 25, null); $result = array_fill(0, 25, null);
foreach ($all as $d) foreach ($all as $d)
{ {
$result[$d['day']-1] = $d; $result[$d['day'] - 1] = $d;
} }
return $result; return $result;
} }
public static function listYears() public function listYears()
{ {
$all = require (__DIR__ . '/../statics/aoc/__all.php'); return array_keys($this->staticData);
return array_keys($all);
} }
public static function readSingle($year, $a) private static function readSingle($year, $a)
{ {
$yeardata = self::YEARS[$year]; $yeardata = self::YEARS[$year];
@ -76,16 +88,17 @@ class AdventOfCode
$a['url_aoc'] = $yeardata['url-aoc'] . $a['day']; // adventofcode.com/{year}/day/{day} $a['url_aoc'] = $yeardata['url-aoc'] . $a['day']; // adventofcode.com/{year}/day/{day}
$a['file_challenge'] = (__DIR__ . '/../statics/aoc/'.$year.'/'.$n2p.'_challenge.txt'); $a['file_challenge'] = (__DIR__ . '/../../statics/aoc/'.$year.'/'.$n2p.'_challenge.txt');
$a['file_input'] = (__DIR__ . '/../statics/aoc/'.$year.'/'.$n2p.'_input.txt'); $a['file_input'] = (__DIR__ . '/../../statics/aoc/'.$year.'/'.$n2p.'_input.txt');
$a['year'] = $year;
$a['date'] = $year . '-' . 12 . '-' . $n2p; $a['date'] = $year . '-' . 12 . '-' . $n2p;
$solutionfiles = []; $solutionfiles = [];
for ($i=1; $i <= $a['parts']; $i++) for ($i=1; $i <= $a['parts']; $i++)
{ {
$solutionfiles []= (__DIR__ . '/../statics/aoc/' . $year . '/' . $n2p . '_solution-' . $i . '.' . self::LANGUAGES[$a['language']]['ext']); $solutionfiles []= (__DIR__ . '/../../statics/aoc/' . $year . '/' . $n2p . '_solution-' . $i . '.' . self::LANGUAGES[$a['language']]['ext']);
} }
$a['file_solutions'] = $solutionfiles; $a['file_solutions'] = $solutionfiles;
@ -93,7 +106,7 @@ class AdventOfCode
return $a; return $a;
} }
public static function getDayFromStrIdent($year, $ident) public function getDayFromStrIdent($year, $ident)
{ {
$e = explode('-', $ident, 2); // day-xxx $e = explode('-', $ident, 2); // day-xxx
if (count($e)!==2) return null; if (count($e)!==2) return null;
@ -104,25 +117,25 @@ class AdventOfCode
return self::getSingleDay($year, $i); return self::getSingleDay($year, $i);
} }
public static function getSingleDay($year, $day) public function getSingleDay($year, $day)
{ {
foreach (self::listSingleYear($year) as $aocd) { foreach ($this->listSingleYear($year) as $aocd) {
if ($aocd['day'] == $day) return $aocd; if ($aocd['day'] == $day) return $aocd;
} }
return null; return null;
} }
public static function getGithubLink($year) public function getGithubLink($year)
{ {
return self::YEARS['' . $year]['github']; return self::YEARS['' . $year]['github'];
} }
public static function getURLForYear($year) public function getURLForYear($year)
{ {
return '/blog/' . self::YEARS[''.$year]['blog-id'] . '/Advent_of_Code_' . $year . '/'; return '/blog/' . self::YEARS[''.$year]['blog-id'] . '/Advent_of_Code_' . $year . '/';
} }
public static function getPrevYear($year) public function getPrevYear($year)
{ {
$last = null; $last = null;
foreach (self::YEARS as $y => $d) foreach (self::YEARS as $y => $d)
@ -133,7 +146,7 @@ class AdventOfCode
return null; return null;
} }
public static function getNextYear($year) public function getNextYear($year)
{ {
$found = false; $found = false;
foreach (self::YEARS as $y => $d) foreach (self::YEARS as $y => $d)
@ -144,12 +157,12 @@ class AdventOfCode
return null; return null;
} }
public static function getLanguageCSS($data) public function getLanguageCSS($data)
{ {
return self::LANGUAGES[$data['language']]['css']; return self::LANGUAGES[$data['language']]['css'];
} }
public static function getSolutionCode($data, $i) public function getSolutionCode($data, $i)
{ {
$raw = file_get_contents($data['file_solutions'][$i]); $raw = file_get_contents($data['file_solutions'][$i]);
@ -165,11 +178,13 @@ class AdventOfCode
return $raw; return $raw;
} }
public static function checkConsistency() public function checkConsistency()
{ {
$warn = null; $warn = null;
foreach (self::listAllFromAllYears() as $year => $yd) $this->load();
foreach ($this->listAllFromAllYears() as $year => $yd)
{ {
$daylist = []; $daylist = [];
$titlelist = []; $titlelist = [];

View File

@ -0,0 +1,37 @@
<?php
class AlephNoteStatistics implements IWebsiteModule
{
/** @var Website */
private $site;
public function __construct(Website $site)
{
$this->site = $site;
}
public function getTotalUserCount()
{
return $this->site->modules->Database()->sql_query_num('SELECT COUNT(*) FROM an_statslog WHERE NoteCount>0');
}
public function getUserCountFromLastVersion()
{
return $this->site->modules->Database()->sql_query_num('SELECT COUNT(*) FROM an_statslog WHERE NoteCount>0 GROUP BY Version ORDER BY INET_ATON(Version) DESC LIMIT 1');
}
public function getActiveUserCount($days)
{
return $this->site->modules->Database()->sql_query_num('SELECT COUNT(*) FROM an_statslog WHERE NoteCount>0 AND LastChanged > NOW() - INTERVAL '.$days.' DAY');
}
public function getAllActiveEntriesOrdered()
{
return $this->site->modules->Database()->sql_query_assoc('SELECT * FROM an_statslog WHERE NoteCount>0 ORDER BY LastChanged DESC');
}
public function checkConsistency()
{
return ['result'=>'ok', 'message' => ''];
}
}

View File

@ -1,12 +1,20 @@
<?php <?php
class Blog class Blog implements IWebsiteModule
{ {
public static function listAll() /** @var array */
{ private $staticData;
$all = require (__DIR__ . '/../statics/blog/__all.php');
return array_map('self::readSingle', $all); public function __construct()
{
$this->load();
}
private function load()
{
$all = require (__DIR__ . '/../../statics/blog/__all.php');
$this->staticData = array_map(function($a){return self::readSingle($a);}, $all);
} }
private static function readSingle($d) private static function readSingle($d)
@ -18,31 +26,42 @@ class Blog
$d['canonical'] = "https://www.mikescher.com" . $d['url']; $d['canonical'] = "https://www.mikescher.com" . $d['url'];
$d['file_fragment'] = __DIR__ . '/../statics/blog/' . $d['fragment']; $d['file_fragment'] = __DIR__ . '/../../statics/blog/' . $d['fragment'];
if (!array_key_exists('extras', $d)) $d['extras'] = []; if (!array_key_exists('extras', $d)) $d['extras'] = [];
return $d; return $d;
} }
public static function listAllNewestFirst() public function listAll()
{ {
$data = self::listAll(); return $this->staticData;
}
public function listAllNewestFirst()
{
$data = $this->staticData;
usort($data, function($a, $b) { return strcasecmp($b['date'], $a['date']); }); usort($data, function($a, $b) { return strcasecmp($b['date'], $a['date']); });
return $data; return $data;
} }
public static function getBlogpost($id) public function getBlogpost($id)
{ {
foreach (self::listAll() as $post) { foreach ($this->staticData as $post) {
if ($post['id'] == $id) return $post; if ($post['id'] == $id) return $post;
} }
return null; return null;
} }
public static function getFullBlogpost($id, $subview, &$error) /**
* @param string $id
* @param string $subview
* @param string $error
* @return array|null
*/
public function getFullBlogpost($id, $subview, &$error)
{ {
$post = self::getBlogpost($id); $post = $this->getBlogpost($id);
if ($post === null) { $error="Blogpost not found"; return null; } if ($post === null) { $error="Blogpost not found"; return null; }
$post['issubview'] = false; $post['issubview'] = false;
@ -51,8 +70,7 @@ class Blog
$eulerproblem = null; $eulerproblem = null;
if ($isSubEuler) if ($isSubEuler)
{ {
require_once(__DIR__ . '/../internals/euler.php'); $eulerproblem = Website::inst()->modules->Euler()->getEulerProblemFromStrIdent($subview);
$eulerproblem = Euler::getEulerProblemFromStrIdent($subview);
if ($eulerproblem === null) { $error="Project Euler entry not found"; return null; } if ($eulerproblem === null) { $error="Project Euler entry not found"; return null; }
$post['submodel'] = $eulerproblem; $post['submodel'] = $eulerproblem;
$post['issubview'] = true; $post['issubview'] = true;
@ -62,8 +80,7 @@ class Blog
$adventofcodeday = null; $adventofcodeday = null;
if ($isSubAdventOfCode) if ($isSubAdventOfCode)
{ {
require_once(__DIR__ . '/../internals/adventofcode.php'); $adventofcodeday = Website::inst()->modules->AdventOfCode()->getDayFromStrIdent($post['extras']['aoc:year'], $subview);
$adventofcodeday = AdventOfCode::getDayFromStrIdent($post['extras']['aoc:year'], $subview);
if ($adventofcodeday === null) { $error="AdventOfCode entry not found"; return null; } if ($adventofcodeday === null) { $error="AdventOfCode entry not found"; return null; }
$post['submodel'] = $adventofcodeday; $post['submodel'] = $adventofcodeday;
$post['issubview'] = true; $post['issubview'] = true;
@ -79,16 +96,18 @@ class Blog
} }
public static function getPostFragment($post) public function getPostFragment($post)
{ {
return file_get_contents($post['file_fragment']); return file_get_contents($post['file_fragment']);
} }
public static function checkConsistency() public function checkConsistency()
{ {
$keys = []; $keys = [];
foreach (self::listAll() as $post) $this->load();
foreach ($this->staticData as $post)
{ {
if (in_array($post['id'], $keys)) return ['result'=>'err', 'message' => 'Duplicate key ' . $post['id']]; if (in_array($post['id'], $keys)) return ['result'=>'err', 'message' => 'Duplicate key ' . $post['id']];
$keys []= $post['id']; $keys []= $post['id'];

View File

@ -1,10 +1,27 @@
<?php if(count(get_included_files()) ==1) exit("Direct access not permitted."); <?php
require_once __DIR__ . '/base.php'; class Books implements IWebsiteModule
class Books
{ {
public static function readSingle($a) /** @var Website */
private $site;
/** @var array */
private $staticData;
public function __construct(Website $site)
{
$this->site = $site;
$this->load();
}
private function load()
{
$all = require (__DIR__ . '/../../statics/books/__all.php');
$this->staticData = array_map(function($a){return self::readSingle($a);}, $all);
}
private static function readSingle($a)
{ {
$a['imgfront_url'] = '/data/images/book_img/' . $a['id'] . '_front.png'; $a['imgfront_url'] = '/data/images/book_img/' . $a['id'] . '_front.png';
$a['imgfront_path'] = __DIR__ . '/../data/images/book_img/' . $a['id'] . '_front.png'; $a['imgfront_path'] = __DIR__ . '/../data/images/book_img/' . $a['id'] . '_front.png';
@ -23,7 +40,7 @@ class Books
for ($i=1; $i <= $a['imagecount']; $i++) for ($i=1; $i <= $a['imagecount']; $i++)
{ {
$a['extraimages_urls'] []= '/data/images/book_img/' . $a['id'] . '_img' . $i . '.jpg'; $a['extraimages_urls'] []= '/data/images/book_img/' . $a['id'] . '_img' . $i . '.jpg';
$a['extraimages_paths'] []= __DIR__ . '/../data/images/book_img/' . $a['id'] . '_img' . $i . '.jpg'; $a['extraimages_paths'] []= __DIR__ . '/../../data/images/book_img/' . $a['id'] . '_img' . $i . '.jpg';
} }
$a['book_count'] = is_array($a['pdf']) ? count($a['pdf']) : 1; $a['book_count'] = is_array($a['pdf']) ? count($a['pdf']) : 1;
@ -31,27 +48,27 @@ class Books
return $a; return $a;
} }
public static function listAll() public function listAll()
{ {
$all = require (__DIR__ . '/../statics/books/__all.php'); return $this->staticData;
return array_map('self::readSingle', $all);
} }
public static function listAllNewestFirst() public function listAllNewestFirst()
{ {
$data = self::listAll(); $data = $this->staticData;
usort($data, function($a, $b) { return strcasecmp($b['date'], $a['date']); }); usort($data, function($a, $b) { return strcasecmp($b['date'], $a['date']); });
return $data; return $data;
} }
public static function checkConsistency() public function checkConsistency()
{ {
$warn = null; $warn = null;
$this->load();
$ids = []; $ids = [];
foreach (self::listAll() as $prog) foreach ($this->staticData as $prog)
{ {
if (in_array($prog['id'], $ids)) return ['result'=>'err', 'message' => 'Duplicate id ' . $prog['id']]; if (in_array($prog['id'], $ids)) return ['result'=>'err', 'message' => 'Duplicate id ' . $prog['id']];
$ids []= $prog['id']; $ids []= $prog['id'];
@ -79,7 +96,7 @@ class Books
return ['result'=>'ok', 'message' => '']; return ['result'=>'ok', 'message' => ''];
} }
public static function checkThumbnails() public function checkThumbnails()
{ {
foreach (self::listAll() as $book) foreach (self::listAll() as $book)
{ {
@ -89,21 +106,19 @@ class Books
return ['result'=>'ok', 'message' => '']; return ['result'=>'ok', 'message' => ''];
} }
public static function createPreview($prog) public function createPreview($prog)
{ {
global $CONFIG;
$src = $prog['imgfront_path']; $src = $prog['imgfront_path'];
$dst = $prog['preview_path']; $dst = $prog['preview_path'];
if ($CONFIG['use_magick']) if ($this->site->config['use_magick'])
magick_resize_image($src, 200, 0, $dst); magick_resize_image($src, 200, 0, $dst);
else else
smart_resize_image($src, 200, 0, true, $dst); smart_resize_image($src, 200, 0, true, $dst);
} }
public static function getBook($id) public function getBook($id)
{ {
foreach (self::listAll() as $book) { foreach (self::listAll() as $book) {
if ($book['id'] == $id) return $book; if ($book['id'] == $id) return $book;
@ -111,7 +126,7 @@ class Books
return null; return null;
} }
public static function getRepositoryHost($book) public function getRepositoryHost($book)
{ {
$r = $book['repository']; $r = $book['repository'];
if (startsWith($r, "http://")) $r = substr($r, strlen("http://")); if (startsWith($r, "http://")) $r = substr($r, strlen("http://"));

View File

@ -0,0 +1,99 @@
<?php
class Database implements IWebsiteModule
{
/* @var PDO $pdo */
private $pdo = NULL;
public function __construct(Website $site)
{
$this->connect($site->config);
}
private function connect(array $config)
{
$dsn = "mysql:host=" . $config['host'] . ";dbname=" . $config['database'] . ";charset=utf8";
$opt =
[
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
];
$this->pdo = new PDO($dsn, $config['user'], $config['password'], $opt);
}
public function sql_query_num($query)
{
return $this->pdo->query($query)->fetch(PDO::FETCH_NUM)[0];
}
public function sql_query_num_prep($query, $params)
{
$stmt = $this->pdo->prepare($query);
foreach ($params as $p)
{
if (strpos($query, $p[0]) !== FALSE) $stmt->bindValue($p[0], $p[1], $p[2]);
}
$stmt->execute();
return $stmt->fetch(PDO::FETCH_NUM)[0];
}
public function sql_query_assoc($query)
{
return $this->pdo->query($query)->fetchAll(PDO::FETCH_ASSOC);
}
public function sql_query_assoc_prep($query, $params)
{
$stmt = $this->pdo->prepare($query);
foreach ($params as $p)
{
if (strpos($query, $p[0]) !== FALSE) $stmt->bindValue($p[0], $p[1], $p[2]);
}
$stmt->execute();
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
public function sql_query_single($query)
{
return $this->pdo->query($query)->fetch(PDO::FETCH_ASSOC);
}
public function sql_query_single_prep($query, $params)
{
$stmt = $this->pdo->prepare($query);
foreach ($params as $p)
{
if (strpos($query, $p[0]) !== FALSE) $stmt->bindValue($p[0], $p[1], $p[2]);
}
$stmt->execute();
return $stmt->fetch(PDO::FETCH_ASSOC);
}
public function sql_exec_prep($query, $params)
{
$stmt = $this->pdo->prepare($query);
foreach ($params as $p)
{
if (strpos($query, $p[0]) !== FALSE) $stmt->bindValue($p[0], $p[1], $p[2]);
}
$stmt->execute();
return $stmt->rowCount();
}
public function checkConsistency()
{
return ['result'=>'ok', 'message' => ''];
}
}

View File

@ -1,8 +1,23 @@
<?php if(count(get_included_files()) ==1) exit("Direct access not permitted."); <?php
class Euler class Euler implements IWebsiteModule
{ {
public static function readSingle($a) /** @var array */
private $staticData;
public function __construct()
{
$this->load();
}
private function load()
{
$all = require (__DIR__ . '/../../statics/euler/__all.php');
$this->staticData = array_map(function($a){return self::readSingle($a);}, $all);
}
private static function readSingle($a)
{ {
$n3p = str_pad($a['number'], 3, '0', STR_PAD_LEFT); $n3p = str_pad($a['number'], 3, '0', STR_PAD_LEFT);
$a['number3'] = $n3p; $a['number3'] = $n3p;
@ -18,40 +33,14 @@ class Euler
$a['url_raw'] = 'https://raw.githubusercontent.com/Mikescher/Project-Euler_Befunge/master/processed/Euler_Problem-' . $n3p . '.b93'; $a['url_raw'] = 'https://raw.githubusercontent.com/Mikescher/Project-Euler_Befunge/master/processed/Euler_Problem-' . $n3p . '.b93';
$a['url_github'] = 'https://github.com/Mikescher/Project-Euler_Befunge'; $a['url_github'] = 'https://github.com/Mikescher/Project-Euler_Befunge';
$a['file_description'] = (__DIR__ . '/../statics/euler/Euler_Problem-'.$n3p.'_description.md'); $a['file_description'] = (__DIR__ . '/../../statics/euler/Euler_Problem-'.$n3p.'_description.md');
$a['file_code'] = (__DIR__ . '/../statics/euler/Euler_Problem-'.$n3p.'.b93'); $a['file_code'] = (__DIR__ . '/../../statics/euler/Euler_Problem-'.$n3p.'.b93');
$a['file_explanation'] = (__DIR__ . '/../statics/euler/Euler_Problem-'.$n3p.'_explanation.md'); $a['file_explanation'] = (__DIR__ . '/../../statics/euler/Euler_Problem-'.$n3p.'_explanation.md');
return $a; return $a;
} }
public static function listAll() private static function rateTime($problem)
{
$all = require (__DIR__ . '/../statics/euler/__all.php');
return array_map('self::readSingle', $all);
}
public static function getEulerProblemFromStrIdent($ident)
{
$e = explode('-', $ident, 2); // problem-xxx
if (count($e)!==2) return null;
$i = intval($e[1], 10);
if ($i == 0) return null;
return self::getEulerProblem($i);
}
public static function getEulerProblem($num)
{
foreach (self::listAll() as $ep) {
if ($ep['number'] == $num) return $ep;
}
return null;
}
public static function rateTime($problem)
{ {
if ($problem['time'] < 100) // < 100ms if ($problem['time'] < 100) // < 100ms
return 0; return 0;
@ -68,14 +57,40 @@ class Euler
return 4; return 4;
} }
public static function checkConsistency() public function listAll()
{
return $this->staticData;
}
public function getEulerProblemFromStrIdent($ident)
{
$e = explode('-', $ident, 2); // problem-xxx
if (count($e)!==2) return null;
$i = intval($e[1], 10);
if ($i == 0) return null;
return self::getEulerProblem($i);
}
public function getEulerProblem($num)
{
foreach (self::listAll() as $ep) {
if ($ep['number'] == $num) return $ep;
}
return null;
}
public function checkConsistency()
{ {
$warn = null; $warn = null;
$this->load();
$numbers = []; $numbers = [];
$realname = []; $realname = [];
foreach (self::listAll() as $ep) foreach ($this->staticData as $ep)
{ {
if (in_array($ep['number'], $numbers)) return ['result'=>'err', 'message' => 'Duplicate number ' . $ep['number']]; if (in_array($ep['number'], $numbers)) return ['result'=>'err', 'message' => 'Duplicate number ' . $ep['number']];
$numbers []= $ep['number']; $numbers []= $ep['number'];

View File

@ -0,0 +1,113 @@
<?php
class Highscores implements IWebsiteModule
{
/** @var Website */
private $site;
public function __construct(Website $site)
{
$this->site = $site;
}
public function generateChecksum($rand, $player, $playerid, $points, $gamesalt)
{
if ($playerid >= 0)
return md5($rand . $player . $playerid . $points . $gamesalt);
else
return md5($rand . $player . $points . $gamesalt);
}
public function insert($gameid, $points, $name, $playerid, $check, $time, $ip)
{
return $this->site->modules->Database()->sql_exec_prep('INSERT INTO highscoreentries (GAME_ID, POINTS, PLAYER, PLAYERID, CHECKSUM, TIMESTAMP, IP) VALUES (:gid, :p, :pn, :pid, :cs, :ts, :ip)',
[
[':gid', $gameid, PDO::PARAM_INT],
[':p', $points, PDO::PARAM_INT],
[':pn', $name, PDO::PARAM_STR],
[':pid', $playerid, PDO::PARAM_INT],
[':cs', $check, PDO::PARAM_STR],
[':ts', $time, PDO::PARAM_STR],
[':ip', $ip, PDO::PARAM_STR],
]);
}
public function update($gameid, $points, $name, $playerid, $check, $time, $ip)
{
return $this->site->modules->Database()->sql_exec_prep('UPDATE highscoreentries SET POINTS = :p, PLAYER = :pn, CHECKSUM = :cs, IP = :ip, TIMESTAMP = :ts WHERE GAME_ID = :gid AND PLAYERID = :pid',
[
[':gid', $gameid, PDO::PARAM_INT],
[':p', $points, PDO::PARAM_INT],
[':pn', $name, PDO::PARAM_STR],
[':pid', $playerid, PDO::PARAM_INT],
[':cs', $check, PDO::PARAM_STR],
[':ts', $time, PDO::PARAM_STR],
[':ip', $ip, PDO::PARAM_STR],
]);
}
public function getGameByID($gameid)
{
return $this->site->modules->Database()->sql_query_single_prep('SELECT * FROM highscoregames WHERE ID = :id',
[
[ ':id', $gameid, PDO::PARAM_INT ],
]);
}
public function getOrderedEntriesFromGame($gameid, $limit = null)
{
$sql = 'SELECT * FROM highscoreentries WHERE GAME_ID = :id ORDER BY POINTS DESC';
if ($limit !== null) $sql .= " LIMIT $limit";
return $this->site->modules->Database()->sql_query_assoc_prep($sql,
[
[ ':id', $gameid, PDO::PARAM_INT ]
]);
}
public function getNewestEntriesFromGame($gameid, $limit = null)
{
$sql = 'SELECT * FROM highscoreentries WHERE GAME_ID = :id ORDER BY TIMESTAMP DESC';
if ($limit !== null) $sql .= " LIMIT $limit";
return $this->site->modules->Database()->sql_query_assoc_prep($sql,
[
[ ':id', $gameid, PDO::PARAM_INT ]
]);
}
public function getEntryCountFromGame($gameid)
{
return $this->site->modules->Database()->sql_query_num_prep('SELECT COUNT(*) FROM highscoreentries WHERE GAME_ID = :id',
[
[ ':id', $gameid, PDO::PARAM_INT ]
]);
}
public function getAllGames()
{
return $this->site->modules->Database()->sql_query_assoc('SELECT * FROM highscoregames');
}
public function getNextPlayerID($gameid)
{
return $this->site->modules->Database()->sql_query_num_prep('SELECT MAX(PLAYERID)+1 AS NID FROM highscoreentries WHERE GAME_ID = :gid',
[
[ ':id', $gameid, PDO::PARAM_INT ]
]);
}
public function getSpecificScore($gameid, $playerid)
{
return $this->site->modules->Database()->sql_query_single_prep('SELECT * FROM highscoreentries WHERE GAME_ID = :gid AND PLAYERID = :pid',
[
[ ':gid', $gameid, PDO::PARAM_INT ],
[ ':pid', $playerid, PDO::PARAM_INT ],
]);
}
public function checkConsistency()
{
return ['result'=>'ok', 'message' => ''];
}
}

View File

@ -0,0 +1,51 @@
<?php
require_once (__DIR__ . '/../../extern/egg/ExtendedGitGraph2.php');
class MikescherGitGraph implements IWebsiteModule
{
/** @var ExtendedGitGraph2 */
private $extgitgraph;
/** @noinspection PhpUnhandledExceptionInspection */
public function __construct(Website $site)
{
$this->extgitgraph = new ExtendedGitGraph2($site->config['extendedgitgraph']);
}
public function getPathRenderedData()
{
return __DIR__ . '/../../dynamic/egg/cache_fullrenderer.html';
}
public function update()
{
return $this->extgitgraph->update();
}
public function updateCache()
{
return $this->extgitgraph->updateCache();
}
/**
* @return string|null
*/
public function get()
{
$d = $this->extgitgraph->loadFromCache();
if ($d === null) return "";
return $d;
}
public function checkConsistency()
{
$p = $this->getPathRenderedData();
if (!file_exists($p)) return ['result'=>'err', 'message' => 'Rendered data not found'];
if (filemtime($p) < time()-(24*60*60)) return ['result'=>'warn', 'message' => 'Rendered data is older than 1 day'];
return ['result'=>'ok', 'message' => ''];
}
}

View File

@ -1,8 +1,6 @@
<?php if(count(get_included_files()) ==1) exit("Direct access not permitted."); <?php
require_once __DIR__ . '/base.php'; class Programs implements IWebsiteModule
class Programs
{ {
const PROG_LANGS = [ 'Java', 'C#', 'Delphi', 'PHP', 'C++' ]; const PROG_LANGS = [ 'Java', 'C#', 'Delphi', 'PHP', 'C++' ];
@ -33,15 +31,30 @@ class Programs
'Mozilla-2.0' => 'https://choosealicense.com/licenses/mpl-2.0/', 'Mozilla-2.0' => 'https://choosealicense.com/licenses/mpl-2.0/',
]; ];
public static function readSingle($a) /** @var array */
private $staticData;
public function __construct()
{
$this->load();
}
private function load()
{
$all = require (__DIR__ . '/../../statics/programs/__all.php');
$this->staticData = array_map(function($a){return self::readSingle($a);}, $all);
}
private static function readSingle($a)
{ {
$a['mainimage_url'] = '/data/images/program_img/' . $a['internal_name'] . '.png'; $a['mainimage_url'] = '/data/images/program_img/' . $a['internal_name'] . '.png';
$a['mainimage_path'] = __DIR__ . '/../data/images/program_img/' . $a['internal_name'] . '.png'; $a['mainimage_path'] = __DIR__ . '/../../data/images/program_img/' . $a['internal_name'] . '.png';
$a['preview_url'] = '/data/dynamic/progprev_' . $a['internal_name'] . '.png'; $a['preview_url'] = '/data/dynamic/progprev_' . $a['internal_name'] . '.png';
$a['preview_path'] = __DIR__ . '/../data/dynamic/progprev_' . $a['internal_name'] . '.png'; $a['preview_path'] = __DIR__ . '/../../data/dynamic/progprev_' . $a['internal_name'] . '.png';
$a['file_longdescription'] = (__DIR__ . '/../statics/programs/' . $a['internal_name'] . '_description.md'); $a['file_longdescription'] = (__DIR__ . '/../../statics/programs/' . $a['internal_name'] . '_description.md');
$a['url'] = '/programs/view/' . $a['internal_name']; $a['url'] = '/programs/view/' . $a['internal_name'];
@ -55,49 +68,41 @@ class Programs
foreach ($a['extra_images'] as $fn) foreach ($a['extra_images'] as $fn)
{ {
$a['extraimages_urls'] []= '/data/images/program_img/' . $fn; $a['extraimages_urls'] []= '/data/images/program_img/' . $fn;
$a['extraimages_paths'] []= __DIR__ . '/../data/images/program_img/' . $fn; $a['extraimages_paths'] []= __DIR__ . '/../../data/images/program_img/' . $fn;
} }
} }
return $a; return $a;
} }
public static function listAll() public function listAll()
{ {
$all = require (__DIR__ . '/../statics/programs/__all.php'); return $this->staticData;
return array_map('self::readSingle', $all);
} }
public static function listAllNewestFirst($filter = '') public function listAllNewestFirst($filter = '')
{ {
$data = self::listAll(); $data = $this->staticData;
usort($data, function($a, $b) { return strcasecmp($b['add_date'], $a['add_date']); }); usort($data, function($a, $b) { return strcasecmp($b['add_date'], $a['add_date']); });
if ($filter !== '') $data = array_filter($data, function($a) use($filter) { return strtolower($a['category']) === strtolower($filter); }); if ($filter !== '') $data = array_filter($data, function($a) use($filter) { return strtolower($a['category']) === strtolower($filter); });
return $data; return $data;
} }
public static function listUpdateData() public function getProgramByInternalName($id)
{ {
$a = require (__DIR__ . '/../statics/updates/_all.php'); foreach ($this->staticData as $prog) {
return $a;
}
public static function getProgramByInternalName($id)
{
foreach (self::listAll() as $prog) {
if (strcasecmp($prog['internal_name'], $id) === 0) return $prog; if (strcasecmp($prog['internal_name'], $id) === 0) return $prog;
if ($prog['internal_name_alt'] !== null && strcasecmp($prog['internal_name_alt'], $id) === 0) return $prog; if ($prog['internal_name_alt'] !== null && strcasecmp($prog['internal_name_alt'], $id) === 0) return $prog;
} }
return null; return null;
} }
public static function getProgramDescription($prog) public function getProgramDescription($prog)
{ {
return file_get_contents($prog['file_longdescription']); return file_get_contents($prog['file_longdescription']);
} }
public static function urlComparator($a, $b) private static function urlComparator($a, $b)
{ {
$na = 0; $na = 0;
$nb = 0; $nb = 0;
@ -118,10 +123,10 @@ class Programs
} }
public static function getURLs($prog) public function getURLs($prog)
{ {
$urls = $prog['urls']; $urls = $prog['urls'];
uksort($urls, 'self::urlComparator'); uksort($urls, function($a,$b){return self::urlComparator($a,$b);});
$result = []; $result = [];
foreach ($urls as $fulltype => $urldata) foreach ($urls as $fulltype => $urldata)
@ -178,29 +183,31 @@ class Programs
return $result; return $result;
} }
public static function getLicenseUrl($license) public function getLicenseUrl($license)
{ {
return self::LICENSES[$license]; return self::LICENSES[$license];
} }
public static function getDirectDownloadURL($prog) public function getDirectDownloadURL($prog)
{ {
return '/data/binaries/'.$prog['internal_name'].'.zip'; return '/data/binaries/'.$prog['internal_name'].'.zip';
} }
public static function getDirectDownloadPath($prog) public function getDirectDownloadPath($prog)
{ {
return (__DIR__ . '/../data/binaries/'.$prog['internal_name'].'.zip'); return (__DIR__ . '/../../data/binaries/'.$prog['internal_name'].'.zip');
} }
public static function checkConsistency() public function checkConsistency()
{ {
$warn = null; $warn = null;
$this->load();
$intname = []; $intname = [];
$realname = []; $realname = [];
foreach (self::listAll() as $prog) foreach ($this->staticData as $prog)
{ {
if (in_array($prog['internal_name'], $intname)) return ['result'=>'err', 'message' => 'Duplicate internal_name ' . $prog['name']]; if (in_array($prog['internal_name'], $intname)) return ['result'=>'err', 'message' => 'Duplicate internal_name ' . $prog['name']];
$intname []= $prog['internal_name']; $intname []= $prog['internal_name'];
@ -216,7 +223,7 @@ class Programs
if (strpos($prog['internal_name'], ' ') !== FALSE) return ['result'=>'err', 'message' => 'Internal name contains spaces ' . $prog['name']]; if (strpos($prog['internal_name'], ' ') !== FALSE) return ['result'=>'err', 'message' => 'Internal name contains spaces ' . $prog['name']];
foreach (explode('|', $prog['ui_language']) as $lang) if (convertLanguageToFlag($lang) === null) return ['result'=>'err', 'message' => 'Unknown ui-lang ' . $prog['name']];; foreach (explode('|', $prog['ui_language']) as $lang) if ($this->convertLanguageToFlag($lang) === null) return ['result'=>'err', 'message' => 'Unknown ui-lang ' . $prog['name']];
if (!in_array($prog['prog_language'], self::PROG_LANGS)) return ['result'=>'err', 'message' => 'Unknown prog-lang ' . $prog['name']]; if (!in_array($prog['prog_language'], self::PROG_LANGS)) return ['result'=>'err', 'message' => 'Unknown prog-lang ' . $prog['name']];
@ -225,11 +232,11 @@ class Programs
if ($prog['license'] !== null && !array_key_exists($prog['license'], self::LICENSES)) return ['result'=>'err', 'message' => 'Unknown license ' . $prog['name']]; if ($prog['license'] !== null && !array_key_exists($prog['license'], self::LICENSES)) return ['result'=>'err', 'message' => 'Unknown license ' . $prog['name']];
$isdl = false; $isdl = false;
foreach (self::getURLs($prog) as $xurl) foreach ($this->getURLs($prog) as $xurl)
{ {
if (!in_array($xurl['type'], self::URL_ORDER)) return ['result'=>'err', 'message' => 'Unknown url ' . $xurl['type']]; if (!in_array($xurl['type'], self::URL_ORDER)) return ['result'=>'err', 'message' => 'Unknown url ' . $xurl['type']];
if ($xurl['type']==='download' && $xurl['isdirect'] && !file_exists(self::getDirectDownloadPath($prog))) return ['result'=>'err', 'message' => 'Direct download not found ' . $prog['name']]; if ($xurl['type']==='download' && $xurl['isdirect'] && !file_exists($this->getDirectDownloadPath($prog))) return ['result'=>'err', 'message' => 'Direct download not found ' . $prog['name']];
if ($xurl['type']==='download' || $xurl['type']==='playstore' || $xurl['type']==='itunesstore') $isdl = true; if ($xurl['type']==='download' || $xurl['type']==='playstore' || $xurl['type']==='itunesstore') $isdl = true;
} }
@ -242,7 +249,7 @@ class Programs
foreach ($prog['extraimages_paths'] as $eipath) foreach ($prog['extraimages_paths'] as $eipath)
{ {
if (!file_exists($eipath)) return ['result'=>'err', 'message' => 'Extra-Image not found ' . $prog['title_short']]; if (!file_exists($eipath)) return ['result'=>'err', 'message' => 'Extra-Image not found ' . $prog['name'], 'long' => $eipath];
} }
} }
@ -250,9 +257,9 @@ class Programs
return ['result'=>'ok', 'message' => '']; return ['result'=>'ok', 'message' => ''];
} }
public static function checkThumbnails() public function checkThumbnails()
{ {
foreach (self::listAll() as $prog) foreach ($this->staticData as $prog)
{ {
if (!file_exists($prog['preview_path'])) return ['result'=>'err', 'message' => 'Preview not found ' . $prog['name']]; if (!file_exists($prog['preview_path'])) return ['result'=>'err', 'message' => 'Preview not found ' . $prog['name']];
} }
@ -260,16 +267,26 @@ class Programs
return ['result'=>'ok', 'message' => '']; return ['result'=>'ok', 'message' => ''];
} }
public static function createPreview($prog) public function createPreview($prog)
{ {
global $CONFIG;
$src = $prog['mainimage_path']; $src = $prog['mainimage_path'];
$dst = $prog['preview_path']; $dst = $prog['preview_path'];
if ($CONFIG['use_magick']) if (Website::inst()->config['use_magick'])
magick_resize_image($src, 250, 0, $dst); magick_resize_image($src, 250, 0, $dst);
else else
smart_resize_image($src, 250, 0, true, $dst); smart_resize_image($src, 250, 0, true, $dst);
} }
public function convertLanguageToFlag($lang) {
$lang = trim(strtolower($lang));
if ($lang === 'italian') return '/data/images/flags/013-italy.svg';
if ($lang === 'english') return '/data/images/flags/226-united-states.svg';
if ($lang === 'french') return '/data/images/flags/195-france.svg';
if ($lang === 'german') return '/data/images/flags/162-germany.svg';
if ($lang === 'spanish') return '/data/images/flags/128-spain.svg';
return null;
}
} }

View File

@ -0,0 +1,644 @@
<?php
class SelfTest implements IWebsiteModule
{
private const STATUS_ERROR = 2;
private const STATUS_WARN = 1;
private const STATUS_OK = 0;
private const DISPLAY_NAMES =
[
'web::main' => 'Website (http)',
'web::programs' => 'Programs (http)',
'web::books' => 'Books (http)',
'web::blog' => 'Blog (http)',
'web::webapps' => 'WebApps (http)',
'web::euler' => 'Project Euler (http)',
'web::aoc' => 'Advent of Code (http)',
'api::default' => 'API',
'api::highscore' => 'Highscores API',
'modules::database' => 'Database',
'modules::blog' => 'Blog (data)',
'modules::euler' => 'Project Euler (data)',
'modules::books' => 'Books (data)',
'modules::extgitgraph' => 'ExtendedGitGraph (data)',
'modules::programs' => 'Programs (data)',
'modules::adventofcode' => 'Advent of Code (data)',
'modules::anstatistics' => 'AlephNote Stats (data)',
'modules::updateslog' => 'Program Updates (data)',
'modules::webapps' => 'Webapps (data)',
'modules::highscores' => 'Highscores (data)',
'backend::git' => 'Git Repository'
];
private $methods = [];
public function __construct()
{
$this->init();
}
private function init()
{
$this->addMethodPathStatus("web::main::index-1", 200, '');
$this->addMethodPathStatus("web::main::index-2", 200, '/index');
$this->addMethodPathStatus("web::main::index-3", 200, '/index.php');
$this->addMethodPathStatus("web::main::index-4", 200, '/msmain/index');
$this->addMethodPathStatus("web::main::about-1", 200, '/about');
$this->addMethodPathStatus("web::main::about-2", 200, '/msmain/about');
$this->addMethodPathStatus("web::main::login-1", 200, '/login');
$this->addMethodPathStatus("web::main::404-1", 404, '/asdf');
$this->addHTTPSRedirect( "web::main::redirect-1", '');
$this->addHTTPSRedirect( "web::main::redirect-2", '/about');
$this->addHTTPSRedirect( "web::main::redirect-3", '/about');
$this->addMethodPathStatus( "web::programs::programs-list-1", 200, '/programs');
$this->addMethodPathStatus( "web::programs::programs-list-2", 200, '/programs/index');
$this->addMethodPathStatus( "web::programs::programs-list-3", 200, '/downloads/details.php');
$this->addMethodPathStatus( "web::programs::programs-list-4", 200, '/downloads/downloads.php');
$this->addMethodMultiPathStatus("web::programs::programs-filtered-1", 200, '/programs/index?categoryfilter={0}', function(){ return array_key_map_unique(Website::inst()->modules->Programs()->listAll(), 'category'); });
$this->addMethodMultiPathStatus("web::programs::programs-filtered-2", 200, '/programs/cat/{0}', function(){ return array_key_map_unique(Website::inst()->modules->Programs()->listAll(), 'category'); });
$this->addMethodMultiPathStatus("web::programs::programs-show-1", 200, '/programs/view/{0}', function(){ return array_key_map(Website::inst()->modules->Programs()->listAll(), 'internal_name'); });
$this->addMethodMultiPathStatus("web::programs::programs-show-2", 200, '/programs/view?id={0}', function(){ return array_key_map(Website::inst()->modules->Programs()->listAll(), 'internal_name'); });
$this->addMethodMultiPathStatus("web::programs::programs-show-3", 200, '{0}', function(){ return array_key_map(Website::inst()->modules->Programs()->listAll(), 'url'); });
$this->addMethodMultiPathStatus("web::programs::programs-download-1", 301, '/downloads/{0}', function(){ return array_key_map(Website::inst()->modules->Programs()->listAll(), 'internal_name'); });
$this->addMethodMultiPathStatus("web::programs::programs-download-2", 301, '/programs/download/{0}', function(){ return array_key_map(Website::inst()->modules->Programs()->listAll(), 'internal_name'); });
$this->addMethodMultiPathStatus("web::programs::programs-download-3", 301, '/programs/download?id={0}', function(){ return array_key_map(Website::inst()->modules->Programs()->listAll(), 'internal_name'); });
$this->addMethodPathStatus( "web::programs::programs-404-1", 404, '/programs/view/asdf_not_found');
$this->addMethodPathStatus( "web::programs::programs-404-2", 404, '/programs/download/asdf_not_found');
$this->addMethodExtProgLinks( "web::programs::programs-ext-links");
$this->addMethodPathStatus( "web::books::books-list-1", 200, '/books');
$this->addMethodPathStatus( "web::books::books-list-2", 200, '/books/list');
$this->addMethodMultiPathStatus("web::books::books-show-1", 200, '/books/view/{0}', function(){ return array_key_map(Website::inst()->modules->Books()->listAll(), 'id'); });
$this->addMethodMultiPathStatus("web::books::books-show-2", 200, '{0}', function(){ return array_key_map(Website::inst()->modules->Books()->listAll(), 'url'); });
$this->addMethodPathStatus( "web::books::books-404-1", 404, '/books/view/asdf/not_found');
$this->addMethodPathStatus( "web::blog::blog-list-1", 200, '/blog');
$this->addMethodPathStatus( "web::blog::blog-list-2", 200, '/log');
$this->addMethodPathStatus( "web::blog::blog-list-3", 200, '/blogpost/index');
$this->addMethodMultiPathStatus("web::blog::blog-show-1", 200, '/blog/{0}', function(){ return array_key_map(Website::inst()->modules->Blog()->listAll(), 'id'); });
$this->addMethodMultiPathStatus("web::blog::blog-show-2", 200, '/log/{0}', function(){ return array_key_map(Website::inst()->modules->Blog()->listAll(), 'id'); });
$this->addMethodMultiPathStatus("web::blog::blog-show-3", 200, '/blogpost/view?id={0}', function(){ return array_key_map(Website::inst()->modules->Blog()->listAll(), 'id'); });
$this->addMethodMultiPathStatus("web::blog::blog-show-4", 200, '{0}', function(){ return array_key_map(Website::inst()->modules->Blog()->listAll(), 'url'); });
$this->addMethodPathStatus( "web::blog::blog-404-1", 404, '/blog/999999');
$this->addMethodPathStatus( "web::blog::blog-404-2", 404, '/blog/999999/Notfound');
$this->addMethodPathStatus( "web::blog::blog-404-3", 404, '/blog/asdf');
$this->addMethodPathStatus("web::webapps::webapps-list-1", 200, '/webapps');
$this->addMethodPathStatus( "web::euler::euler-list-1", 200, '/blog/1/Project_Euler_with_Befunge');
$this->addMethodMultiPathStatus("web::euler::euler-show-1", 200, '{0}', function(){ return array_key_map(Website::inst()->modules->Euler()->listAll(), 'url'); });
$this->addMethodPathStatus( "web::euler::euler-404-1", 404, '/blog/1/Project_Euler_with_Befunge/problem-A');
$this->addMethodPathStatus( "web::euler::euler-404-2", 404, '/blog/1/Project_Euler_with_Befunge/problem-99999');
$this->addMethodPathStatus( "web::euler::euler-404-3", 404, '/blog/1/Project_Euler_with_Befunge/asdf');
$this->addMethodMultiPathStatus("web::aoc::aoc-list-1", 200, '{0}', function(){ return array_map(function($x){return Website::inst()->modules->AdventOfCode()->getURLForYear($x);},Website::inst()->modules->AdventOfCode()->listYears()); });
$this->addMethodMultiPathStatus("web::aoc::aoc-show-1", 200, '{0}', function(){ return array_key_map(Website::inst()->modules->AdventOfCode()->listAllDays(), 'url'); });
$this->addMethodPathStatus( "web::aoc::aoc-404-1", 404, '/blog/25/Advent_of_Code_2017/day-26');
$this->addMethodPathStatus( "web::aoc::aoc-404-2", 404, '/blog/23/Advent_of_Code_2018/day-27');
$this->addMethodPathStatus( "web::aoc::aoc-404-3", 404, '/blog/24/Advent_of_Code_2019/day-28');
$this->addCheckConsistency("modules::database::database-check-consistency", function(){ return Website::inst()->modules->Database(); });
$this->addCheckConsistency("modules::blog::blog-check-consistency", function(){ return Website::inst()->modules->Blog(); });
$this->addCheckConsistency("modules::euler::euler-check-consistency", function(){ return Website::inst()->modules->Euler(); });
$this->addCheckConsistency("modules::books::books-check-consistency", function(){ return Website::inst()->modules->Books(); });
$this->addCheckConsistency("modules::extgitgraph::extgitgraph-check-consistency", function(){ return Website::inst()->modules->ExtendedGitGraph(); });
$this->addCheckConsistency("modules::programs::programs-check-consistency", function(){ return Website::inst()->modules->Programs(); });
$this->addCheckConsistency("modules::books::books-check-consistency", function(){ return Website::inst()->modules->Books(); });
$this->addCheckConsistency("modules::adventofcode::adventofcode-check-consistency", function(){ return Website::inst()->modules->AdventOfCode(); });
$this->addCheckConsistency("modules::anstatistics::anstatistics-check-consistency", function(){ return Website::inst()->modules->AlephNoteStatistics(); });
$this->addCheckConsistency("modules::updateslog::updateslog-check-consistency", function(){ return Website::inst()->modules->UpdatesLog(); });
$this->addCheckConsistency("modules::webapps::webapps-check-consistency", function(){ return Website::inst()->modules->WebApps(); });
$this->addCheckConsistency("modules::highscores::highscores-check-consistency", function(){ return Website::inst()->modules->Highscores(); });
$ajaxsecret = Website::inst()->config['ajax_secret'];
$this->addMethodPathResponse( "api::default::base-test-2", 200, '{}', '/api/test');
$this->addMethodPathResponse( "api::default::base-test-4", 200, '{}', '/api/base::test');
$this->addMethodMultiPathStatus("api::default::updatecheck-1", 200, '/update.php?name={0}', function(){ return array_keys(Website::inst()->modules->UpdatesLog()->listUpdateData()); });
$this->addMethodMultiPathStatus("api::default::updatecheck-2", 200, '/update.php/{0}', function(){ return array_keys(Website::inst()->modules->UpdatesLog()->listUpdateData()); });
$this->addMethodMultiPathStatus("api::default::updatecheck-3", 200, '/update?name={0}', function(){ return array_keys(Website::inst()->modules->UpdatesLog()->listUpdateData()); });
$this->addMethodMultiPathStatus("api::default::updatecheck-4", 200, '/update/{0}', function(){ return array_keys(Website::inst()->modules->UpdatesLog()->listUpdateData()); });
$this->addMethodMultiPathStatus("api::default::updatecheck-5", 200, '/update2?name={0}', function(){ return array_keys(Website::inst()->modules->UpdatesLog()->listUpdateData()); });
$this->addMethodMultiPathStatus("api::default::updatecheck-6", 200, '/api/update?name={0}', function(){ return array_keys(Website::inst()->modules->UpdatesLog()->listUpdateData()); });
$this->addMethodMultiPathStatus("api::default::updatecheck-7", 200, '/api/update/{0}', function(){ return array_keys(Website::inst()->modules->UpdatesLog()->listUpdateData()); });
$this->addMethodPathStatus( "api::default::egg-status", 200, "/api/extendedgitgraph::status?ajax_secret=$ajaxsecret");
$this->addMethodPathStatus( "api::default::an-show", 200, "/api/alephnote::show?ajax_secret=$ajaxsecret");
$this->addMethodPathStatus( "api::default::updates-show", 200, "/api/updates::show?ajax_secret=$ajaxsecret");
$this->addMethodPathStatus( "api::default::aoc-ajax", 200, "/api/html::panel_aoc_calendar");
$this->addMethodPathStatus( "api::default::404-1", 404, '/api/update/no_prog_xx');
$this->addMethodPathStatus( "api::default::404-2", 404, '/api/asdf::notfound');
$this->addMethodPathStatus( "api::highscore::listgames-1", 200, "/highscores/list.php");
$this->addMethodPathStatus( "api::highscore::listgames-2", 200, "/highscores/list");
$this->addMethodPathStatus( "api::highscore::listgames-3", 200, "/highscores/listgames");
$this->addMethodMultiPathStatus("api::highscore::listentries-1", 200, "/highscores/list.php?gameid={0}", function(){ return [1,2,3,4,5,6]; });
$this->addMethodMultiPathStatus("api::highscore::listentries-2", 200, "/highscores/list?gameid={0}", function(){ return [1,2,3,4,5,6]; });
$this->addMethodMultiPathStatus("api::highscore::listentries-3", 200, "/highscores/listentries?gameid={0}", function(){ return [1,2,3,4,5,6]; });
$this->addMethodMultiPathStatus("api::highscore::top50-1", 200, "/highscores/list_top50.php?gameid={0}", function(){ return [1,2,3,4,5,6]; });
$this->addMethodMultiPathStatus("api::highscore::top50-2", 200, "/highscores/list_top50?gameid={0}", function(){ return [1,2,3,4,5,6]; });
$this->addMethodGitStatusCheck("backend::git::git-status");
}
/** @noinspection PhpUnhandledExceptionInspection */
public function listMethodGroups()
{
$data = [];
foreach ($this->methods as $method)
{
$parts = explode('::', $method['name']);
if (count($parts) !== 3) throw new Exception();
$data []= ($parts[0] . '::' . $parts[1]);
}
$data = array_unique($data);
$result = [];
foreach ($data as $d)
{
$result []=
[
'name' => key_exists($d, self::DISPLAY_NAMES) ? self::DISPLAY_NAMES[$d] : $d,
'filter' => $d.'::*',
'base' => $d
];
}
sort($result);
return $result;
}
private function addMethodPathStatus(string $name, int $status, string $path)
{
$this->methods []=
[
'name' => $name,
'func' => function() use ($name, $path, $status)
{
$xname = explode('::', $name)[2];
try
{
if (!Website::inst()->isProd()) return
[
'result' => self::STATUS_WARN,
'message' => '{'.$xname.'} not executed: curl requests in dev mode prohibited',
'long' => null,
'exception' => null,
];
$r = curl_http_request($_SERVER['HTTP_HOST'] . $path);
if ($r['statuscode'] === $status) return
[
'result' => self::STATUS_OK,
'message' => "{".$xname."} succeeded",
'long' => null,
'exception' => null,
];
return
[
'result' => self::STATUS_ERROR,
'message' => '{'.$xname.'} failed: Request returned wrong statuscode',
'long' => 'Wrong HTTP Statuscode (Expected: ['.$status.']; Found: ['.$r['statuscode'].'])' . "\n" . "Response:\n" . $r['output'] . "\nError [" . $r['errnum'] . "]:\n" . $r['errstr'],
'exception' => null,
];
}
catch (Exception $e)
{
return
[
'result' => self::STATUS_ERROR,
'message' => "{$xname} failed: " . $e->getMessage(),
'long' => str_max_len($e->getMessage(), 48),
'exception' => $e,
];
}
}
];
}
private function addMethodMultiPathStatus(string $name, int $status, string $path, Closure $supplier)
{
$this->methods []=
[
'name' => $name,
'func' => function() use ($name, $path, $status, $supplier)
{
$xname = explode('::', $name)[2];
try
{
if (!Website::inst()->isProd()) return
[
'result' => self::STATUS_WARN,
'message' => '{'.$xname.'} not executed: curl requests in dev mode prohibited',
'long' => null,
'exception' => null,
];
$supdata = $supplier();
$message = '';
$count = 0;
foreach ($supdata as $d)
{
$r = curl_http_request($_SERVER['HTTP_HOST'] . str_replace('{0}', $d, $path));
$count++;
if ($r['statuscode'] === $status) { $message .= "{".$xname."} succeeded" . "\n"; continue; }
return
[
'result' => self::STATUS_ERROR,
'message' => '{'.$xname.'} failed: Request returned wrong statuscode',
'long' => 'Wrong HTTP Statuscode (Expected: ['.$status.']; Found: ['.$r['statuscode'].'])' . "\n" . "Response:\n" . $r['output'] . "\nError [" . $r['errnum'] . "]:\n" . $r['errstr'],
'exception' => null,
];
}
return
[
'result' => self::STATUS_OK,
'message' => "$count requests succeeded\n" . $message,
'long' => null,
'exception' => null,
];
}
catch (Exception $e)
{
return
[
'result' => self::STATUS_ERROR,
'message' => "{$xname} failed: " . $e->getMessage(),
'long' => str_max_len($e->getMessage(), 48),
'exception' => $e,
];
}
}
];
}
private function addCheckConsistency(string $name, Closure $moduleSupplier)
{
$this->methods []=
[
'name' => $name,
'func' => function() use ($name, $moduleSupplier)
{
try
{
/** @var IWebsiteModule $module */
$module = $moduleSupplier();
$consistency = $module->checkConsistency();
if ($consistency['result'] === 'err') return
[
'result' => self::STATUS_ERROR,
'message' => $consistency['message'],
'long' => isset($consistency['long']) ? $consistency['long'] : null,
'exception' => null,
];
if ($consistency['result'] === 'warn') return
[
'result' => self::STATUS_WARN,
'message' => $consistency['message'],
'long' => isset($consistency['long']) ? $consistency['long'] : null,
'exception' => null,
];
if ($consistency['result'] === 'ok') return
[
'result' => self::STATUS_OK,
'message' => 'OK',
'long' => isset($consistency['long']) ? $consistency['long'] : null,
'exception' => null,
];
throw new Exception("Unknown result: " . print_r($consistency, true));
}
catch (Exception $e)
{
return
[
'result' => self::STATUS_ERROR,
'message' => str_max_len($e->getMessage(), 48),
'long' => formatException($e),
'exception' => $e,
];
}
}
];
}
private function addMethodPathResponse(string $name, int $status, string $json_expected, string $path)
{
$this->methods []=
[
'name' => $name,
'func' => function() use ($name, $path, $status, $json_expected)
{
$xname = explode('::', $name)[2];
try
{
if (!Website::inst()->isProd()) return
[
'result' => self::STATUS_WARN,
'message' => '{'.$xname.'} not executed: curl requests in dev mode prohibited',
'long' => null,
'exception' => null,
];
$r = curl_http_request($_SERVER['HTTP_HOST'] . $path);
if ($r['statuscode'] !== $status)
{
return
[
'result' => self::STATUS_ERROR,
'message' => '{'.$xname.'} failed: Request returned wrong statuscode',
'long' => 'Wrong HTTP Statuscode (Expected: ['.$status.']; Found: ['.$r['statuscode'].'])' . "\n" . "Response:\n" . $r['output'] . "\nError [" . $r['errnum'] . "]:\n" . $r['errstr'],
'exception' => null,
];
}
if (json_encode(json_decode($r['output'])) == json_encode(json_decode($json_expected)))
{
return
[
'result' => self::STATUS_ERROR,
'message' => '{'.$xname.'} failed: Request returned wrong statuscode',
'long' => "Wrong HTTP Response\nExpected:\n$json_expected\nFound:\n".$r['output'] . "\n" . "HTTP Statuscode:\n" . $r['statuscode'] . "\nError [" . $r['errnum'] . "]:\n" . $r['errstr'],
'exception' => null,
];
}
return
[
'result' => self::STATUS_OK,
'message' => "{".$xname."} succeeded",
'long' => null,
'exception' => null,
];
}
catch (Exception $e)
{
return
[
'result' => self::STATUS_ERROR,
'message' => "{$xname} failed: " . $e->getMessage(),
'long' => str_max_len($e->getMessage(), 48),
'exception' => $e,
];
}
}
];
}
private function addMethodGitStatusCheck(string $name)
{
$this->methods []=
[
'name' => $name,
'func' => function() use ($name)
{
$xname = explode('::', $name)[2];
try
{
if (!Website::inst()->isProd()) return
[
'result' => self::STATUS_WARN,
'message' => '{'.$xname.'} not executed in dev mode',
'long' => null,
'exception' => null,
];
$r = exec('git rev-parse --abbrev-ref HEAD');
$ok = (strpos($r, 'Your branch is up to date with') !== false) && (strpos($r, 'nothing to commit, working tree clean') !== false);
if (!$ok)
{
return
[
'result' => self::STATUS_ERROR,
'message' => "{$xname} failed",
'long' => $r,
'exception' => null,
];
}
else
{
return
[
'result' => self::STATUS_OK,
'message' => "{".$xname."} succeeded",
'long' => $r,
'exception' => null,
];
}
}
catch (Exception $e)
{
return
[
'result' => self::STATUS_ERROR,
'message' => "{$xname} failed: " . $e->getMessage(),
'long' => str_max_len($e->getMessage(), 48),
'exception' => $e,
];
}
}
];
}
private function addMethodExtProgLinks(string $name)
{
$this->methods []=
[
'name' => $name,
'func' => function() use ($name)
{
$xname = explode('::', $name)[2];
if (!Website::inst()->isProd()) return
[
'result' => self::STATUS_WARN,
'message' => '{'.$xname.'} not executed: curl requests in dev mode prohibited',
'long' => null,
'exception' => null,
];
try
{
$message = '';
$count = 0;
foreach (Website::inst()->modules->Programs()->listAll() as $prog)
{
foreach ($prog['urls'] as $urlobj)
{
$url = $urlobj;
if (is_array($urlobj)) $url = $urlobj['url'];
$r = curl_http_request($url);
$count++;
if ($r['statuscode'] === 200) { $message .= "[".$prog['name']."] Request to '$url' succeeded" . "\n"; continue; }
return
[
'result' => self::STATUS_ERROR,
'message' => '['.$prog['name'].'] failed: Request to returned wrong statuscode',
'long' => 'Wrong HTTP Statuscode from "'.$url.'"' . "\nExpected: [200]\nFound: [".$r['statuscode'].']' . "\n" . "Response:\n" . $r['output'] . "\nError [" . $r['errnum'] . "]:\n" . $r['errstr'],
'exception' => null,
];
}
}
return
[
'result' => self::STATUS_OK,
'message' => "$count requests succeeded\n" . $message,
'long' => null,
'exception' => null,
];
}
catch (Exception $e)
{
return
[
'result' => self::STATUS_ERROR,
'message' => "{$xname} failed: " . $e->getMessage(),
'long' => str_max_len($e->getMessage(), 48),
'exception' => $e,
];
}
}
];
}
private function addHTTPSRedirect(string $name, string $path)
{
$this->methods []=
[
'name' => $name,
'func' => function() use ($name, $path)
{
$xname = explode('::', $name)[2];
try
{
if (!Website::inst()->isProd()) return
[
'result' => self::STATUS_WARN,
'message' => '{'.$xname.'} not executed: curl requests in dev mode prohibited',
'long' => null,
'exception' => null,
];
$host = parse_url($_SERVER['HTTP_HOST'], PHP_URL_HOST);
$port = parse_url($_SERVER['HTTP_HOST'], PHP_URL_PORT);
$url1 = 'http://' . $host . ':' . $port . $path;
$url2 = 'https://' . $host . ':' . $port . $path;
$r = curl_http_request($url1);
if ($r['statuscode'] !== 310)
{
return
[
'result' => self::STATUS_ERROR,
'message' => '{'.$xname.'} failed: Request returned wrong statuscode',
'long' => 'Wrong HTTP Statuscode (Expected: [200]; Found: ['.$r['statuscode'].'])' . "\n" . "Response:\n" . $r['output'] . "\n" . "Redirect:\n" . $r['redirect'] . "\nError [" . $r['errnum'] . "]:\n" . $r['errstr'],
'exception' => null,
];
}
if ($r['redirect'] !== $url2)
{
return
[
'result' => self::STATUS_ERROR,
'message' => '{'.$xname.'} failed: Request returned wrong redirect',
'long' => 'Wrong Redirect URL (Expected: ['.$url2.']; Found: ['.$r['redirect'].'])' . "\n" . "Response:\n" . $r['output'] . "\n" . "Redirect:\n" . $r['redirect'] . "\nError [" . $r['errnum'] . "]:\n" . $r['errstr'],
'exception' => null,
];
}
return
[
'result' => self::STATUS_OK,
'message' => "{".$xname."} succeeded",
'long' => null,
'exception' => null,
];
}
catch (Exception $e)
{
return
[
'result' => self::STATUS_ERROR,
'message' => "{$xname} failed: " . $e->getMessage(),
'long' => str_max_len($e->getMessage(), 48),
'exception' => $e,
];
}
}
];
}
public function run($filter)
{
$rex = '/^' . str_replace('*', '([^:]*)', $filter) . '$/';
$fullmessage = '';
$fullwarnmessage = '';
$warnings = 0;
$count = 0;
foreach ($this->methods as $method)
{
if (!preg_match($rex, $method['name'])) continue;
$r = $method['func']();
if ($r['result'] === self::STATUS_ERROR) return $r;
if ($r['result'] === self::STATUS_WARN) { $warnings++; $fullwarnmessage .= $r['message'] . "\n"; }
$fullmessage .= $r['message'] . "\n";
$count++;
}
if ($warnings > 0)
{
return
[
'result' => self::STATUS_WARN,
'message' => "$warnings/$count methods had warnings",
'long' => $fullwarnmessage,
'exception' => null,
];
}
if ($count === 0) return
[
'result' => self::STATUS_WARN,
'message' => "No methods matched filter",
'long' => null,
'exception' => null,
];
return
[
'result' => self::STATUS_OK,
'message' => "OK",
'long' => "$count methods succeeded\n\n" . $fullmessage,
'exception' => null,
];
}
public function checkConsistency()
{
return ['result'=>'ok', 'message' => ''];
}
}

View File

@ -0,0 +1,80 @@
<?php
class UpdatesLog implements IWebsiteModule
{
/** @var Website */
private $site;
/** @var array */
private $staticData;
public function __construct(Website $site)
{
$this->site = $site;
$this->load();
}
private function load()
{
$all = require (__DIR__ . '/../../statics/updates/__all.php');
$this->staticData = array_map(function($a){return self::readSingle($a);}, $all);
}
private static function readSingle($d)
{
return $d;
}
public function listUpdateData()
{
return $this->staticData;
}
public function insert($name, $version)
{
$ip = get_client_ip();
$ippath = (__DIR__ . '/../../dynamic/self_ip_address.auto.cfg');
$self_ip = file_exists($ippath) ? file_get_contents($ippath) : 'N/A';
if ($self_ip === $ip) $ip = "self";
$this->site->modules->Database()->sql_exec_prep("INSERT INTO updateslog (programname, ip, version, date) VALUES (:pn, :ip, :vn, NOW())",
[
[':pn', $name, PDO::PARAM_STR],
[':ip', $ip, PDO::PARAM_STR],
[':vn', $version, PDO::PARAM_STR],
]);
}
public function listProgramsInformation()
{
return $this->site->modules->Database()->sql_query_assoc('SELECT programname AS name, Count(*) as count_total, MAX(date) AS last_query, (SELECT COUNT(*) FROM updateslog AS u1 WHERE u1.programname=u0.programname AND NOW() - INTERVAL 7 DAY < u1.date) AS count_week FROM updateslog AS u0 GROUP BY programname');
}
public function getEntries($name, $limit)
{
return $this->site->modules->Database()->sql_query_assoc_prep('SELECT * FROM updateslog WHERE programname = :pn ORDER BY date DESC LIMIT :lt',
[
[':pn', $name, PDO::PARAM_STR],
[':lt', $limit, PDO::PARAM_INT],
]);
}
public function checkConsistency()
{
$warn = null;
$this->load();
foreach ($this->staticData as $name => $data)
{
if (!key_exists('version', $data)) return ['result'=>'err', 'message' => 'Missing value [version]'];
if (!key_exists('url', $data)) return ['result'=>'err', 'message' => 'Missing value [url]'];
}
if ($warn != null) return $warn;
return ['result'=>'ok', 'message' => ''];
}
}

View File

@ -0,0 +1,49 @@
<?php
class WebApps implements IWebsiteModule
{
/** @var array */
private $staticData;
public function __construct()
{
$this->load();
}
private function load()
{
$all = require (__DIR__ . '/../../statics/webapps/__all.php');
$this->staticData = array_map(function($a){return self::readSingle($a);}, $all);
}
private static function readSingle($a)
{
return $a;
}
public function listAllNewestFirst()
{
$data = $this->staticData;
usort($data, function($a, $b) { return strcasecmp($b['date'], $a['date']); });
return $data;
}
public function checkConsistency()
{
$warn = null;
$this->load();
$ids = [];
foreach ($this->staticData as $prog)
{
if (in_array($prog['id'], $ids)) return ['result'=>'err', 'message' => 'Duplicate id ' . $prog['id']];
$ids []= $prog['id'];
}
if ($warn != null) return $warn;
return ['result'=>'ok', 'message' => ''];
}
}

View File

@ -0,0 +1,86 @@
<?php
class PageFrameOptions
{
/** @var string */
public $raw;
/** @var string */
public $title = 'Mikescher.com';
/** @var int */
public $statuscode = 200;
/** @var bool */
public $force_404 = false;
/** @var string */
public $force_404_message = '';
/** @var bool */
public $force_redirect = false;
/** @var string */
public $force_redirect_url = '';
/** @var string */
public $frame = 'default_frame.php';
/** @var string */
public $contentType = null;
/** @var string */
public $activeHeader = null;
/** @var string */
public $canonical_url = null;
/** @var string[] */
public $contentCSSClasses = [ 'content-responsive' ];
/** @var array */
public $stylesheets = [];
/** @var array */
public $scripts = [];
public function addStylesheet(string $url)
{
foreach ($this->stylesheets as $css) if ($css === $url) return;
$this->stylesheets []= $url;
}
public function addScript(string $url, bool $defer = false)
{
foreach ($this->scripts as &$script)
{
if ($script[0] === $url)
{
if (!$defer && $script[1]) $script[1] = false; // upgrade from defered to immediate script
return;
}
}
$this->scripts []= [ $url, $defer ];
}
public function setForced404(string $err)
{
$this->force_404 = true;
$this->force_404_message = $err;
}
public function setForcedRedirect(string $url)
{
$this->force_redirect = true;
$this->force_redirect_url = $url;
}
public function forceResult(int $statuscode, string $content)
{
$this->statuscode = $statuscode;
ob_clean();
echo $content;
}
}

View File

@ -1,6 +1,5 @@
<?php <?php
require_once (__DIR__ . '/../internals/base.php');
require_once (__DIR__ . '/../extern/Parsedown.php'); require_once (__DIR__ . '/../extern/Parsedown.php');
require_once (__DIR__ . '/../extern/ParsedownExtra.php'); require_once (__DIR__ . '/../extern/ParsedownExtra.php');
@ -68,29 +67,14 @@ class ParsedownCustom extends ParsedownExtra
protected function handleBFJoust(array $Element) protected function handleBFJoust(array $Element)
{ {
global $PARAM_CODE_LEFT; $split = preg_split("/-{16,}/", $Element['text']);
global $PARAM_CODE_RIGHT;
$split = preg_split("/\-{16,}/", $Element['text']); return Website::inst()->fragments->WidgetBFJoust(trim($split[0]), trim($split[1]));
$PARAM_CODE_LEFT = trim($split[0]);
$PARAM_CODE_RIGHT = trim($split[1]);
return require (__DIR__ . '/../fragments/widget_bfjoust.php');
} }
protected function handleBef93(array $Element) protected function handleBef93(array $Element)
{ {
global $PARAM_BEFUNGE93RUNNER; return Website::inst()->fragments->WidgetBefunge93($Element['text'], '', $Element['b93_interactive'], $Element['b93_speed'], $Element['b93_editable']);
$PARAM_BEFUNGE93RUNNER =
[
'code' => $Element['text'],
'url' => '',
'interactive' => $Element['b93_interactive'],
'speed' => $Element['b93_speed'],
'editable' => $Element['b93_editable'],
];
return require (__DIR__ . '/../fragments/widget_befunge93.php');
} }
protected function blockTable($Line, array $Block = null) protected function blockTable($Line, array $Block = null)

View File

@ -0,0 +1,113 @@
<?php
require_once "website.php";
class RuleEngine
{
/**
* @param Website $site
* @param array $urlConfig
* @return URLRoute
*/
public static function findRoute(Website $site, array $urlConfig): URLRoute
{
if ($site->isProd())
$requri = $_SERVER['REQUEST_URI'];
else
$requri = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : 'localhost:80/';
$parse = parse_url($requri);
$path = isset($parse['path']) ? $parse['path'] : '';
$pathparts = preg_split('@/@', $path, NULL, PREG_SPLIT_NO_EMPTY);
$partcount = count($pathparts);
foreach ($urlConfig as $rule)
{
$route = self::testRule($site, $rule, $requri, $pathparts, $partcount);
if ($route === null) continue;
if ($route->needsAdminLogin && !$site->isLoggedInByCookie()) return URLRoute::getLoginRoute($route, $requri);
return $route;
}
return URLRoute::getNotFoundRoute($requri);
}
private static function testRule(Website $site, array $rule, string $requri, array $pathparts, int $partcount)
{
if ($partcount !== count($rule['url'])) return null;
$urlparams = [];
$match = true;
for($i = 0; $i < $partcount; $i++)
{
$comp = $rule['url'][$i];
if (startsWith($comp, '?{') && endsWith($comp, '}'))
{
$ident = substr($comp, 2, strlen($comp)-3);
$urlparams[$ident] = $pathparts[$i];
}
else if ($comp === '*')
{
if (!isset($urlparams['*'])) $urlparams['*'] = [];
$urlparams['*'] []= $pathparts[$i];
}
else
{
if (strtolower($comp) !== strtolower($pathparts[$i])) { $match = false; break; }
}
}
if (!$match) return null;
$route = new URLRoute($rule['target'], $requri);
foreach($rule['parameter'] as $optname => $optvalue)
{
$value = $optvalue;
if ($value === '%GET%')
{
if (!isset($_GET[$optname])) { $match = false; break; }
$value = $_GET[$optname];
}
else if ($value === '%POST%')
{
if (!isset($_POST[$optname])) { $match = false; break; }
$value = $_POST[$optname];
}
else if ($value === '%URL%')
{
if (!isset($urlparams[$optname])) { $match = false; break; }
$value = urldecode($urlparams[$optname]);
}
$route->parameter[strtolower($optname)] = $value;
}
if (!$match) return null;
$route->urlParameter = $urlparams;
$ctrlOpt = $rule['options'];
if (in_array('disabled', $ctrlOpt)) return null;
if (in_array('api', $ctrlOpt)) $route->isAPI = true;
if (isset($ctrlOpt['method']) && $_SERVER["REQUEST_METHOD"] !== $ctrlOpt['method']) return null;
$route->needsAdminLogin = isset($ctrlOpt['password']);
if ($site->isProd() && isHTTPRequest() && !in_array('http', $ctrlOpt))
{
// enforce https
$redirect = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
header('HTTP/1.1 301 Moved Permanently');
header('Location: ' . $redirect);
exit();
}
return $route;
}
}

View File

@ -1,40 +0,0 @@
<?php if(count(get_included_files()) ==1) exit("Direct access not permitted.");
require_once (__DIR__ . '/../internals/database.php');
class UpdatesLog
{
public static function insert($name, $version)
{
$ip = get_client_ip();
$ippath = __DIR__ . '/../dynamic/self_ip_address.auto.cfg';
$self_ip = file_exists($ippath) ? file_get_contents($ippath) : 'N/A';
if ($self_ip === $ip) $ip = "self";
Database::connect();
Database::sql_exec_prep("INSERT INTO updateslog (programname, ip, version, date) VALUES (:pn, :ip, :vn, NOW())",
[
[':pn', $name, PDO::PARAM_STR],
[':ip', $ip, PDO::PARAM_STR],
[':vn', $version, PDO::PARAM_STR],
]);
}
public static function listProgramsInformation()
{
Database::connect();
return Database::sql_query_assoc('SELECT programname AS name, Count(*) as count_total, MAX(date) AS last_query, (SELECT COUNT(*) FROM updateslog AS u1 WHERE u1.programname=u0.programname AND NOW() - INTERVAL 7 DAY < u1.date) AS count_week FROM updateslog AS u0 GROUP BY programname');
}
public static function getEntries($name, $limit)
{
Database::connect();
return Database::sql_query_assoc_prep('SELECT * FROM updateslog WHERE programname = :pn ORDER BY date DESC LIMIT :lt',
[
[':pn', $name, PDO::PARAM_STR],
[':lt', $limit, PDO::PARAM_INT],
]);
}
}

112
www/internals/urlroute.php Normal file
View File

@ -0,0 +1,112 @@
<?php
require_once "website.php";
class URLRoute
{
/** @var string */
public $targetpath;
/** @var string */
public $full_url;
/** @var array */
public $parameter;
/** @var int */
public $needsAdminLogin;
/** @var array */
public $urlParameter;
/** @var bool */
public $isAPI;
public function __construct(string $target, string $url)
{
$this->targetpath = (__DIR__ . '/../pages/' . $target);
$this->full_url = $url;
$this->parameter = [];
$this->needsAdminLogin = false;
$this->urlParameter = [];
$this->isAPI = false;
}
/**
* @param Website $site
* @return PageFrameOptions
*/
public function get(Website $site): PageFrameOptions
{
$pfo = new PageFrameOptions();
$pfo->addStylesheet($site->isProd() ? ('/data/css/styles.min.css') : ('/data/css/styles.css'));
return $this->getDirect($site, $pfo);
}
/**
* @param Website $site
* @param PageFrameOptions $pfo
* @return PageFrameOptions
*/
public function getDirect(Website $site, PageFrameOptions $pfo): PageFrameOptions
{
try
{
ob_start();
global $ROUTE;
global $FRAME_OPTIONS;
global $SITE;
$ROUTE = $this;
$FRAME_OPTIONS = $pfo;
$SITE = $site;
/** @noinspection PhpIncludeInspection */
require $this->targetpath;
$FRAME_OPTIONS->raw = ob_get_contents();
return $FRAME_OPTIONS;
}
finally
{
ob_end_clean();
}
}
/**
* @param URLRoute $route
* @param string $requri
* @return URLRoute
*/
public static function getLoginRoute(URLRoute $route, string $requri): URLRoute
{
$r = new URLRoute('login.php', $requri);
$r->parameter = [ 'login_target' => $route->full_url ];
return $r;
}
/**
* @param string $requri
* @return URLRoute
*/
public static function getNotFoundRoute(string $requri): URLRoute
{
$r = new URLRoute('error_notfound.php', $requri);
$r->parameter = [];
return $r;
}
/**
* @param string $requri
* @return URLRoute
*/
public static function getServerErrorRoute(string $requri): URLRoute
{
$r = new URLRoute('error_servererror.php', $requri);
$r->parameter = [];
return $r;
}
}

287
www/internals/utils.php Normal file
View File

@ -0,0 +1,287 @@
<?php
function startsWith($haystack, $needle)
{
$length = strlen($needle);
return (substr($haystack, 0, $length) === $needle);
}
function endsWith($haystack, $needle)
{
$length = strlen($needle);
return $length === 0 || (substr($haystack, -$length) === $needle);
}
function destructiveUrlEncode($str)
{
$str = str_replace(' ', '_', $str);
$str = str_replace('+', '_', $str);
$str = str_replace(':', '_', $str);
$str = str_replace('.', '', $str);
return urlencode($str);
}
function formatMilliseconds($millis)
{
if ($millis < 1000)
{
return $millis . 'ms';
}
else if ($millis < 10 * 1000)
{
return number_format($millis / (1000), 2) . 's';
}
else if ($millis < 60 * 1000)
{
return floor($millis / (1000)) . 's';
}
else if ($millis < 10 * 60 * 1000)
{
return floor($millis / (60 * 1000)) . 'min ' . floor(($millis % (60 * 1000)) / 1000) . 's';
}
else if ($millis < 60 * 60 * 1000)
{
return floor($millis / (60 * 1000)) . 'min';
}
else if ($millis < 10 * 60 * 60 * 1000)
{
return number_format($millis / (60 * 60 * 1000), 2) . ' hours';
}
else
{
return floor($millis / (60 * 60 * 1000)) . ' hours';
}
}
/**
* easy image resize function
* @author http://www.nimrodstech.com/php-image-resize/
* @param string $file - file name to resize
* @param int $width - new image width
* @param int $height - new image height
* @param boolean $proportional - keep image proportional, default is no
* @param string $output - name of the new file (include path if needed)
* @return boolean|resource
*/
function smart_resize_image($file, $width, $height, $proportional, $output)
{
if ( $height <= 0 && $width <= 0 ) return false;
if ( $file === null) return false;
# Setting defaults and meta
$info = getimagesize($file);
$image = '';
$final_width = 0;
$final_height = 0;
list($width_old, $height_old) = $info;
$cropHeight = $cropWidth = 0;
# Calculating proportionality
if ($proportional) {
if ($width == 0) $factor = $height/$height_old;
elseif ($height == 0) $factor = $width/$width_old;
else $factor = min( $width / $width_old, $height / $height_old );
$final_width = round( $width_old * $factor );
$final_height = round( $height_old * $factor );
}
else {
$final_width = ( $width <= 0 ) ? $width_old : $width;
$final_height = ( $height <= 0 ) ? $height_old : $height;
$widthX = $width_old / $width;
$heightX = $height_old / $height;
$x = min($widthX, $heightX);
$cropWidth = ($width_old - $width * $x) / 2;
$cropHeight = ($height_old - $height * $x) / 2;
}
# Loading image to memory according to type
switch ( $info[2] ) {
case IMAGETYPE_JPEG: $image = imagecreatefromjpeg($file); break;
case IMAGETYPE_GIF: $image = imagecreatefromgif($file); break;
case IMAGETYPE_PNG: $image = imagecreatefrompng($file); break;
default: return false;
}
# This is the resizing/resampling/transparency-preserving magic
$image_resized = imagecreatetruecolor( $final_width, $final_height );
if ( ($info[2] == IMAGETYPE_GIF) || ($info[2] == IMAGETYPE_PNG) ) {
$transparency = imagecolortransparent($image);
$palletsize = imagecolorstotal($image);
if ($transparency >= 0 && $transparency < $palletsize) {
$transparent_color = imagecolorsforindex($image, $transparency);
$transparency = imagecolorallocate($image_resized, $transparent_color['red'], $transparent_color['green'], $transparent_color['blue']);
imagefill($image_resized, 0, 0, $transparency);
imagecolortransparent($image_resized, $transparency);
}
elseif ($info[2] == IMAGETYPE_PNG) {
imagealphablending($image_resized, false);
$color = imagecolorallocatealpha($image_resized, 0, 0, 0, 127);
imagefill($image_resized, 0, 0, $color);
imagesavealpha($image_resized, true);
}
}
imagecopyresampled($image_resized, $image, 0, 0, $cropWidth, $cropHeight, $final_width, $final_height, $width_old - 2 * $cropWidth, $height_old - 2 * $cropHeight);
# Preparing a method of providing result
switch ( strtolower($output) ) {
case 'browser':
$mime = image_type_to_mime_type($info[2]);
header("Content-type: $mime");
$output = NULL;
break;
case 'file':
$output = $file;
break;
case 'return':
return $image_resized;
break;
default:
break;
}
# Writing image according to type to the output destination and image quality
switch ( $info[2] ) {
case IMAGETYPE_GIF: imagegif($image_resized, $output); break;
case IMAGETYPE_JPEG: imagejpeg($image_resized, $output, 100); break;
case IMAGETYPE_PNG:
$quality = 9 - (int)((0.9*100)/10.0);
imagepng($image_resized, $output, $quality);
break;
default: return false;
}
return true;
}
/**
* @param string $file - file name to resize
* @param int $width - new image width
* @param int $height - new image height
* @param string $output - name of the new file (include path if needed)
*/
function magick_resize_image($file, $width, $height, $output)
{
list($width_old, $height_old) = getimagesize($file);
if ($width == 0) $factor = $height/$height_old;
elseif ($height == 0) $factor = $width/$width_old;
else $factor = min( $width / $width_old, $height / $height_old );
$final_width = round( $width_old * $factor );
$final_height = round( $height_old * $factor );
$cmd = 'convert "' . $file . '" -strip -resize ' . $final_width . 'x' . $final_height . ' "' . $output . '"';
shell_exec($cmd);
}
function sendMail($subject, $content, $to, $from)
{
mail($to, $subject, $content, 'From: ' . $from);
}
function get_client_ip() {
if (getenv('HTTP_CLIENT_IP')) return getenv('HTTP_CLIENT_IP');
else if(getenv('HTTP_X_FORWARDED_FOR')) return getenv('HTTP_X_FORWARDED_FOR');
else if(getenv('HTTP_X_FORWARDED')) return getenv('HTTP_X_FORWARDED');
else if(getenv('HTTP_FORWARDED_FOR')) return getenv('HTTP_FORWARDED_FOR');
else if(getenv('HTTP_FORWARDED')) return getenv('HTTP_FORWARDED');
else if(getenv('REMOTE_ADDR')) return getenv('REMOTE_ADDR');
else if (isset($_SERVER['HTTP_CLIENT_IP'])) return $_SERVER['HTTP_CLIENT_IP'];
else if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])) return $_SERVER['HTTP_X_FORWARDED_FOR'];
else if(isset($_SERVER['HTTP_X_FORWARDED'])) return $_SERVER['HTTP_X_FORWARDED'];
else if(isset($_SERVER['HTTP_FORWARDED_FOR'])) return $_SERVER['HTTP_FORWARDED_FOR'];
else if(isset($_SERVER['HTTP_FORWARDED'])) return $_SERVER['HTTP_FORWARDED'];
else if(isset($_SERVER['REMOTE_ADDR'])) return $_SERVER['REMOTE_ADDR'];
else return 'UNKNOWN';
}
function getRandomToken($length = 32)
{
try
{
if(!isset($length) || intval($length) <= 8 ) $length = 32;
if (function_exists('random_bytes')) return bin2hex(random_bytes($length));
if (function_exists('mcrypt_create_iv')) return bin2hex(mcrypt_create_iv($length, MCRYPT_DEV_URANDOM));
if (function_exists('openssl_random_pseudo_bytes')) return bin2hex(openssl_random_pseudo_bytes($length));
}
catch (Exception $e) { throw new InvalidArgumentException($e); }
throw new InvalidArgumentException("No random");
}
function isHTTPRequest()
{
return (!isset($_SERVER['HTTPS'])) || empty($_SERVER['HTTPS']) || $_SERVER['HTTPS'] == "off";
}
function str_max_len(string $str, int $max)
{
if (strlen($str) < $max) return $str;
return substr($str, 0, $max-3)."...";
}
function formatException($e)
{
if ($e === null) return "NULL";
if ($e instanceof Exception)
{
$r = '';
$r .= $e->getMessage() . "\n\n";
$r .= $e->getFile() . "\n\n";
$r .= str_replace(dirname(__DIR__), '.', $e->getTraceAsString()) . "\n\n";
if (isset($e->xdebug_message))
{
$xdbg = $e->xdebug_message;
$xdbg = str_replace('<br />', "\n", $xdbg);
$xdbg = str_replace('<br/>', "\n", $xdbg);
$xdbg = str_replace('<br>', "\n", $xdbg);
$xdbg = str_replace('><', "> <", $xdbg);
$xdbg = strip_tags($xdbg);
$xdbg = htmlspecialchars($xdbg);
$r .= $xdbg . "\n";
}
return $r;
}
return 'object';
}
function array_key_map_unique(array $array, string $key)
{
$r = [];
foreach ($array as $d) if (!in_array($d[$key], $r)) $r []= $d[$key];
return $r;
}
function array_key_map(array $array, string $key)
{
$r = [];
foreach ($array as $d) $r []= $d[$key];
return $r;
}
function curl_http_request($url)
{
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
$output = curl_exec($ch);
$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$redirect = curl_getinfo($ch, CURLINFO_REDIRECT_URL);
$errnum = curl_errno( $ch );
$errmsg = curl_error( $ch );
curl_close($ch);
return [ 'output'=>$output, 'statuscode'=>$httpcode, 'redirect'=>$redirect, 'erronum'=>$errnum, 'errorstr'=>$errmsg ];
}

View File

@ -1,25 +0,0 @@
<?php
class WebApps
{
public static function listAll()
{
$all = require (__DIR__ . '/../statics/webapps/__all.php');
return array_map('self::readSingle', $all);
}
public static function readSingle($a)
{
return $a;
}
public static function listAllNewestFirst()
{
$data = self::listAll();
usort($data, function($a, $b) { return strcasecmp($b['date'], $a['date']); });
return $data;
}
}

216
www/internals/website.php Normal file
View File

@ -0,0 +1,216 @@
<?php
require_once 'ruleengine.php';
require_once 'urlroute.php';
require_once 'pageframeoptions.php';
require_once 'iwebsitemodule.php';
require_once 'modules.php';
require_once 'fragments.php';
require_once 'utils.php';
class Website
{
/** @var Website */
private static $instance;
/** @var array */
public $config;
/** @var bool|null */
private $isLoggedIn = null;
/** @var Modules */
public $modules;
/** @var Fragments */
public $fragments;
public function init()
{
set_error_handler("exception_error_handler"); // errors as exceptions for global catch
try
{
$this->config = require (__DIR__ . "/../config.php");
if (!$this->config['prod'])
{
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
}
$this->modules = new Modules($this);
$this->fragments = new Fragments();
self::$instance = $this;
}
catch (exception $e)
{
$this->serveServerError("Initialization failed", formatException($e), null);
}
}
public static function inst()
{
return self::$instance;
}
public function serve($rules)
{
try
{
$route = RuleEngine::findRoute($this, $rules);
$result = $route->get($this);
if ($result->force_redirect)
{
header('Location: ' . $result->force_redirect_url);
exit();
}
if ($result->force_404)
{
$this->serveCustom404($route->full_url, $result, $result->force_404_message);
exit();
}
$this->output($result, $route);
}
catch (Exception $e)
{
$this->serveServerError("Internal Server Error", formatException($e), null);
}
}
private function serveCustom404(string $uri, PageFrameOptions $frameOpt, string $message)
{
try
{
$frameOpt->statuscode = 404;
$frameOpt->title = 'Page not found';
$route = URLRoute::getNotFoundRoute($uri);
$route->parameter['message'] = $message;
$result = $route->getDirect($this, $frameOpt);
$this->output($result, $route);
}
catch (Exception $e)
{
$this->serveServerError("Internal Server Error", formatException($e), null);
}
exit();
}
/**
* @param string $message
* @param string|null $debugInfo
* @param PageFrameOptions|null $frameOpt
*/
private function serveServerError(string $message, $debugInfo, $frameOpt)
{
try
{
if ($frameOpt === null) $frameOpt = new PageFrameOptions();
$frameOpt->statuscode = 500;
$frameOpt->title = 'Internal Server Error';
$frameOpt->frame = 'error_frame.php';
$route = URLRoute::getServerErrorRoute($_SERVER['REQUEST_URI']);
$route->parameter['message'] = $message;
$route->parameter['debuginfo'] = $debugInfo;
$result = $route->getDirect($this, $frameOpt);
$this->output($result, $route);
}
catch (Exception $e)
{
http_response_code(500);
die('Internal Server Error');
}
exit();
}
private function output(PageFrameOptions $pfo, URLRoute $route)
{
if ($pfo->contentType !== null) header('Content-Type: ' . $pfo->contentType);
http_response_code($pfo->statuscode);
global $ROUTE;
global $FRAME_OPTIONS;
global $SITE;
$ROUTE = $route;
$FRAME_OPTIONS = $pfo;
$SITE = $this;
/** @noinspection PhpIncludeInspection */
require __DIR__ . '/../frames/' . $FRAME_OPTIONS->frame;
}
/**
* @return bool
*/
public function isProd()
{
if ($this->config == null) return true;
return $this->config['prod'];
}
public function isLoggedInByCookie()
{
if ($this->isLoggedIn !== null) return $this->isLoggedIn;
if (key_exists('mikescher_auth', $_COOKIE))
{
if (strlen($_COOKIE['mikescher_auth']) !== 64) return ($this->isLoggedIn = false);
$auth = hash('sha256', $this->config['admin_username'] . ';' . $this->config['admin_password'] . ';' . gmdate('Y-m-d'));
if ($auth === $_COOKIE['mikescher_auth']) return ($this->isLoggedIn = true);
}
return ($this->isLoggedIn = false);
}
function setLoginCookie($user, $pass)
{
$expires = time() + (24*60*60); // 24h
$hash = hash('sha256', $user . ';' . $pass . ';' . gmdate('Y-m-d'));
setcookie('mikescher_auth', $hash, $expires);
}
function clearLoginCookie()
{
setcookie("mikescher_auth", "", time()+30);
}
public function renderMarkdown(string $txt)
{
require_once 'parsedowncustom.php';
$pd = new ParsedownCustom();
return $pd->text($txt);
}
}
/**
* @param $severity
* @param $message
* @param $file
* @param $line
* @throws ErrorException
*/
function exception_error_handler($severity, $message, $file, $line) {
// This error code is not included in error_reporting
if (!(error_reporting() & $severity)) return;
throw new ErrorException($message, 0, $severity, $file, $line);
}

View File

@ -1,26 +1,18 @@
<!DOCTYPE html>
<html lang="en">
<?php <?php
require_once (__DIR__ . '/../internals/base.php'); require_once (__DIR__ . '/../internals/website.php');
require_once (__DIR__ . '/../internals/mikeschergitgraph.php');
global $OPTIONS; /** @var PageFrameOptions $FRAME_OPTIONS */ global $FRAME_OPTIONS;
/** @var URLRoute $ROUTE */ global $ROUTE;
/** @var Website $SITE */ global $SITE;
?> ?>
<head>
<meta charset="utf-8">
<title>Mikescher.com - About</title>
<link rel="icon" type="image/png" href="/data/images/favicon.png"/>
<link rel="canonical" href="https://www.mikescher.com/about"/>
<?php printHeaderCSS(); ?>
<?php includeAdditionalScript("/data/javascript/extendedgitgraph.js", 'defer', true) ?>
</head>
<body>
<div id="mastercontainer">
<?php $HEADER_ACTIVE = 'about'; include (__DIR__ . '/../fragments/header.php'); ?> <?php
$FRAME_OPTIONS->title = 'About';
$FRAME_OPTIONS->canonical_url = 'https://www.mikescher.com/about';
$FRAME_OPTIONS->activeHeader = 'about';
?>
<div id="content" class="content-responsive"> <div class="aboutcontent">
<div class="aboutcontent">
<div class="contentheader"><h1>About mikescher.com</h1><hr/></div> <div class="contentheader"><h1>About mikescher.com</h1><hr/></div>
@ -35,7 +27,6 @@ global $OPTIONS;
<p>This is my personal homepage, I use it to upload programs I have written, web serials I have style-setted and sometimes for a little bit of blogging.</p> <p>This is my personal homepage, I use it to upload programs I have written, web serials I have style-setted and sometimes for a little bit of blogging.</p>
<p>Its mostly just a collection of stuff I wanted to put only, but I guess thats the core of most personal homepages</p> <p>Its mostly just a collection of stuff I wanted to put only, but I guess thats the core of most personal homepages</p>
</div> </div>
</div> </div>
@ -47,7 +38,10 @@ global $OPTIONS;
<div class="bc_data about_egg_container"> <div class="bc_data about_egg_container">
<?php print(MikescherGitGraph::get()); ?> <?php
$FRAME_OPTIONS->addScript('/data/javascript/extendedgitgraph.js', true);
echo $SITE->modules->ExtendedGitGraph()->get();
?>
</div> </div>
@ -101,14 +95,4 @@ global $OPTIONS;
</div> </div>
</div>
</div>
<?php include (__DIR__ . '/../fragments/footer.php'); ?>
</div> </div>
<?php printAdditionalScripts(); ?>
<?php printAdditionalStylesheets(); ?>
</body>
</html>

View File

@ -1,56 +1,25 @@
<!DOCTYPE html>
<html lang="en">
<?php <?php
require_once (__DIR__ . '/../internals/base.php'); require_once (__DIR__ . '/../internals/website.php');
require_once (__DIR__ . '/../internals/highscores.php');
require_once (__DIR__ . '/../internals/alephnoteStatistics.php');
require_once (__DIR__ . '/../internals/blog.php');
require_once (__DIR__ . '/../internals/euler.php');
require_once (__DIR__ . '/../internals/adventofcode.php');
require_once (__DIR__ . '/../internals/highscores.php');
require_once (__DIR__ . '/../internals/mikeschergitgraph.php');
require_once (__DIR__ . '/../internals/programs.php');
require_once (__DIR__ . '/../internals/books.php');
require_once (__DIR__ . '/../internals/updateslog.php');
$connected = Database::tryconnect(); /** @var PageFrameOptions $FRAME_OPTIONS */ global $FRAME_OPTIONS;
/** @var URLRoute $ROUTE */ global $ROUTE;
/** @var Website $SITE */ global $SITE;
?>
$consistency_blog = Blog::checkConsistency(); <?php
$consistency_prog = Programs::checkConsistency(); $FRAME_OPTIONS->title = 'Admin';
$consistency_euler = Euler::checkConsistency(); $FRAME_OPTIONS->canonical_url = 'https://www.mikescher.com/admin';
$consistency_books = Books::checkConsistency(); $FRAME_OPTIONS->activeHeader = 'admin';
$consistency_egg = MikescherGitGraph::checkConsistency();
$consistency_progimg = Programs::checkThumbnails(); $FRAME_OPTIONS->addScript('https://code.jquery.com/jquery-latest.min.js', true);
$consistency_bookimg = Books::checkThumbnails(); $FRAME_OPTIONS->addScript('/data/javascript/admin.js', true);
$consistency_aoc = AdventOfCode::checkConsistency();
$connected = true; try { $SITE->modules->Database(); } catch (Exception $e) { $connected = false; }
?> ?>
<?php
function dumpConsistency($c) { <div class="admincontent">
if ($c['result']==='ok') echo "<span class='consistency_result_ok'>OK</span>";
else if ($c['result']==='warn') echo "<span class='consistency_result_warn'>".$c['message']."</span>";
else echo "<span class='consistency_result_err'>".$c['message']."</span>";
}
?>
<head>
<meta charset="utf-8">
<title>Mikescher.com - Admin</title>
<link rel="icon" type="image/png" href="/data/images/favicon.png"/>
<link rel="canonical" href="https://www.mikescher.com/about"/>
<?php printHeaderCSS(); ?>
<?php includeAdditionalScript("https://code.jquery.com/jquery-latest.min.js", '', true) ?>
<?php includeAdditionalScript("/data/javascript/admin.js", 'defer', true) ?>
</head>
<body>
<div id="mastercontainer">
<?php $HEADER_ACTIVE = 'admin'; include (__DIR__ . '/../fragments/header.php'); ?>
<div id="content" class="content-responsive">
<div class="admincontent">
<div class="contentheader"><h1>Admin</h1><hr/></div> <div class="contentheader"><h1>Admin</h1><hr/></div>
@ -60,6 +29,12 @@ function dumpConsistency($c) {
</div> </div>
<?php endif; ?> <?php endif; ?>
<?php if (!$SITE->isProd()): ?>
<div class="boxedcontent warnbox">
<div class="bc_data">Website runs in /dev/ mode</div>
</div>
<?php endif; ?>
<!-- - - - - - - - - - - - - - - - - - - - - --> <!-- - - - - - - - - - - - - - - - - - - - - -->
<div class="boxedcontent"> <div class="boxedcontent">
@ -80,19 +55,13 @@ function dumpConsistency($c) {
<div class="bc_data"> <div class="bc_data">
<div class="keyvaluelist kvl_200"> <div class="keyvaluelist kvl_200">
<div><span>Program thumbnails:</span> <?php dumpConsistency($consistency_progimg); ?></div> <?php foreach ($SITE->modules->SelfTest()->listMethodGroups() as $group): ?>
<div><span>ExtendedGitGraph:</span> <?php dumpConsistency($consistency_egg); ?></div> <div><span><?php echo $group['name']; ?></span><span class='consistency_result consistency_result_intermed consistence_ajax_handler' data-filter="<?php echo $group['filter']; ?>">&nbsp;</span></div>
<div><span>Book thumbnails:</span> <?php dumpConsistency($consistency_bookimg); ?></div> <?php endforeach; ?>
<div><span>Blog data:</span> <?php dumpConsistency($consistency_blog); ?></div>
<div><span>Euler data:</span> <?php dumpConsistency($consistency_euler); ?></div>
<div><span>AdventOfCode data:</span> <?php dumpConsistency($consistency_aoc); ?></div>
<div><span>Programs data:</span> <?php dumpConsistency($consistency_prog); ?></div>
<div><span>Books data:</span> <?php dumpConsistency($consistency_books); ?></div>
</div> </div>
<br/> <br/>
<a class="button" href="/api/site::createProgramThumbnails">Update Program Thumbnails</a> <a class="button" href="/api/site::createProgramThumbnails">Update Program Thumbnails</a>
<a class="button" href="/api/site::createBookThumbnails">Update Book Thumbnails</a> <a class="button" href="/api/site::createBookThumbnails">Update Book Thumbnails</a>
</div> </div>
</div> </div>
@ -122,8 +91,8 @@ function dumpConsistency($c) {
<div class="bc_data"> <div class="bc_data">
<textarea class="egg_ajaxOutput" id="egg_ajaxOutput" readonly="readonly"></textarea> <textarea class="egg_ajaxOutput" id="egg_ajaxOutput" readonly="readonly"></textarea>
<a class="button" href="javascript:startAjaxRefresh('<?php echo $CONFIG['ajax_secret'] ?>')">Update</a> <a class="button" href="javascript:startAjaxRefresh('<?php echo $SITE->config['ajax_secret'] ?>')">Update</a>
<a class="button" href="javascript:startAjaxRedraw('<?php echo $CONFIG['ajax_secret'] ?>')">Redraw</a> <a class="button" href="javascript:startAjaxRedraw('<?php echo $SITE->config['ajax_secret'] ?>')">Redraw</a>
</div> </div>
@ -137,16 +106,16 @@ function dumpConsistency($c) {
<?php if ($connected): ?> <?php if ($connected): ?>
<div class="bc_data"> <div class="bc_data">
<div class="keyvaluelist kvl_200"> <div class="keyvaluelist kvl_200">
<div><span>Total users:</span> <span><?php echo AlephNoteStatistics::getTotalUserCount(); ?></span></div> <div><span>Total users:</span> <span><?php echo $SITE->modules->AlephNoteStatistics()->getTotalUserCount(); ?></span></div>
<div><span>Users on latest version:</span> <span><?php echo AlephNoteStatistics::getUserCountFromLastVersion(); ?></span></div> <div><span>Users on latest version:</span> <span><?php echo $SITE->modules->AlephNoteStatistics()->getUserCountFromLastVersion(); ?></span></div>
<div><span>Active users:</span> <span><?php echo AlephNoteStatistics::getActiveUserCount(32); ?></span></div> <div><span>Active users:</span> <span><?php echo $SITE->modules->AlephNoteStatistics()->getActiveUserCount(32); ?></span></div>
</div> </div>
<br/> <br/>
<div id="an_ajax_target"></div> <div id="an_ajax_target"></div>
<a class="button" href="javascript:startAjaxReplace('#an_ajax_target', '/api/alephnote::show?secret=<?php echo $CONFIG['ajax_secret'] ?>')">Show</a> <a class="button" href="javascript:startAjaxReplace('#an_ajax_target', '/api/alephnote::show?secret=<?php echo $SITE->config['ajax_secret'] ?>')">Show</a>
</div> </div>
<?php else: ?> <?php else: ?>
<div class="bc_data keyvaluelist">Database not connected.</div> <div class="bc_data keyvaluelist admindberr">Database not connected.</div>
<?php endif; ?> <?php endif; ?>
</div> </div>
@ -157,11 +126,11 @@ function dumpConsistency($c) {
<div class="bc_header">Statics</div> <div class="bc_header">Statics</div>
<div class="bc_data keyvaluelist kvl_200"> <div class="bc_data keyvaluelist kvl_200">
<div><span>Blog entries:</span> <span><?php echo count(Blog::listAll()); ?></span></div> <div><span>Blog entries:</span> <span><?php echo count($SITE->modules->Blog()->listAll()); ?></span></div>
<div><span>Book entries:</span> <span><?php echo count(Books::listAll()); ?></span></div> <div><span>Book entries:</span> <span><?php echo count($SITE->modules->Books()->listAll()); ?></span></div>
<div><span>Euler entries:</span> <span><?php echo count(Euler::listAll()); ?></span></div> <div><span>Euler entries:</span> <span><?php echo count($SITE->modules->Euler()->listAll()); ?></span></div>
<div><span>Program entries:</span> <span><?php echo count(Programs::listAll()); ?></span></div> <div><span>Program entries:</span> <span><?php echo count($SITE->modules->Programs()->listAll()); ?></span></div>
<div><span>Update entries:</span> <span><?php echo count(Programs::listUpdateData()); ?></span></div> <div><span>Update entries:</span> <span><?php echo count($SITE->modules->UpdatesLog()->listUpdateData()); ?></span></div>
</div> </div>
</div> </div>
@ -172,8 +141,8 @@ function dumpConsistency($c) {
<?php if ($connected): ?> <?php if ($connected): ?>
<div class="bc_data keyvaluelist kvl_300"> <div class="bc_data keyvaluelist kvl_300">
<?php foreach (UpdatesLog::listProgramsInformation() as $info): ?> <?php foreach ($SITE->modules->UpdatesLog()->listProgramsInformation() as $info): ?>
<div><span><?php echo '[' . $info['name'] . '] Count:' ?></span> <span><a href="javascript:startAjaxReplace('#ul_ajax_target', '/api/updates::show?secret=<?php echo $CONFIG['ajax_secret'] ?>&ulname=<?php echo $info['name'] ?>')"><?php echo $info['count_total']; ?></a></span></div> <div><span><?php echo '[' . $info['name'] . '] Count:' ?></span> <span><a href="javascript:startAjaxReplace('#ul_ajax_target', '/api/updates::show?secret=<?php echo $SITE->config['ajax_secret'] ?>&ulname=<?php echo $info['name'] ?>')"><?php echo $info['count_total']; ?></a></span></div>
<div><span><?php echo '[' . $info['name'] . '] Last query:' ?></span> <span><?php echo $info['last_query']; ?></span></div> <div><span><?php echo '[' . $info['name'] . '] Last query:' ?></span> <span><?php echo $info['last_query']; ?></span></div>
<div><span><?php echo '[' . $info['name'] . '] Count (1 week):' ?></span> <span><?php echo $info['count_week']; ?></span></div> <div><span><?php echo '[' . $info['name'] . '] Count (1 week):' ?></span> <span><?php echo $info['count_week']; ?></span></div>
<hr /> <hr />
@ -182,7 +151,7 @@ function dumpConsistency($c) {
<div id="ul_ajax_target"></div> <div id="ul_ajax_target"></div>
</div> </div>
<?php else: ?> <?php else: ?>
<div class="bc_data keyvaluelist">Database not connected.</div> <div class="bc_data keyvaluelist admindberr">Database not connected.</div>
<?php endif; ?> <?php endif; ?>
</div> </div>
@ -194,14 +163,14 @@ function dumpConsistency($c) {
<?php if ($connected): ?> <?php if ($connected): ?>
<div class="bc_data keyvaluelist kvl_300"> <div class="bc_data keyvaluelist kvl_300">
<?php foreach (Highscores::getAllGames() as $game): ?> <?php foreach ($SITE->modules->Highscores()->getAllGames() as $game): ?>
<div><span><?php echo '[' . $game['NAME'] . '] Entries:' ?></span> <span><a href="/highscores/list?gameid=<?php echo $game['ID']; ?>"><?php echo Highscores::getEntryCountFromGame($game['ID']); ?></a></span></div> <div><span><?php echo '[' . $game['NAME'] . '] Entries:' ?></span> <span><a href="/highscores/list?gameid=<?php echo $game['ID']; ?>"><?php echo $SITE->modules->Highscores()->getEntryCountFromGame($game['ID']); ?></a></span></div>
<div><span><?php echo '[' . $game['NAME'] . '] Highscore:' ?></span> <span><?php <div><span><?php echo '[' . $game['NAME'] . '] Highscore:' ?></span> <span><?php
$hs = Highscores::getOrderedEntriesFromGame($game['ID'], 1)[0]; $hs = $SITE->modules->Highscores()->getOrderedEntriesFromGame($game['ID'], 1)[0];
echo $hs['POINTS'] . ' (' . $hs['PLAYER'] . ') @ ' . $hs['TIMESTAMP']; echo $hs['POINTS'] . ' (' . $hs['PLAYER'] . ') @ ' . $hs['TIMESTAMP'];
?></span></div> ?></span></div>
<div><span><?php echo '[' . $game['NAME'] . '] Last Update:' ?></span> <span><?php echo Highscores::getNewestEntriesFromGame($game['ID'], 1)[0]['TIMESTAMP']; ?></span></div> <div><span><?php echo '[' . $game['NAME'] . '] Last Update:' ?></span> <span><?php echo $SITE->modules->Highscores()->getNewestEntriesFromGame($game['ID'], 1)[0]['TIMESTAMP']; ?></span></div>
<hr /> <hr />
@ -209,7 +178,7 @@ function dumpConsistency($c) {
</div> </div>
<?php else: ?> <?php else: ?>
<div class="bc_data keyvaluelist">Database not connected.</div> <div class="bc_data keyvaluelist admindberr">Database not connected.</div>
<?php endif; ?> <?php endif; ?>
</div> </div>
@ -220,7 +189,7 @@ function dumpConsistency($c) {
<div class="bc_header">Configuration</div> <div class="bc_header">Configuration</div>
<div class="bc_data keyvaluelist kvl_200"> <div class="bc_data keyvaluelist kvl_200">
<?php <?php
foreach ($CONFIG as $key => $value) foreach ($SITE->config as $key => $value)
{ {
if ($key === 'extendedgitgraph') continue; if ($key === 'extendedgitgraph') continue;
@ -237,7 +206,7 @@ function dumpConsistency($c) {
<div class="bc_header">Configuration['extendedgitgraph']</div> <div class="bc_header">Configuration['extendedgitgraph']</div>
<div class="bc_data keyvaluelist kvl_200"> <div class="bc_data keyvaluelist kvl_200">
<?php <?php
foreach ($CONFIG['extendedgitgraph'] as $key => $value) foreach ($SITE->config['extendedgitgraph'] as $key => $value)
{ {
if (is_array($value)) if (is_array($value))
echo '<div><span>' . $key . '</span> <span style="white-space: pre">' . json_encode($value, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) . '</span></div>' . "\n"; echo '<div><span>' . $key . '</span> <span style="white-space: pre">' . json_encode($value, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) . '</span></div>' . "\n";
@ -248,14 +217,4 @@ function dumpConsistency($c) {
</div> </div>
</div> </div>
</div>
</div>
<?php include (__DIR__ . '/../fragments/footer.php'); ?>
</div> </div>
<?php printAdditionalScripts(); ?>
<?php printAdditionalStylesheets(); ?>
</body>
</html>

View File

@ -1,8 +1,15 @@
<?php <?php
require_once (__DIR__ . '/../internals/website.php');
global $OPTIONS; /** @var PageFrameOptions $FRAME_OPTIONS */ global $FRAME_OPTIONS;
/** @var URLRoute $ROUTE */ global $ROUTE;
/** @var Website $SITE */ global $SITE;
$FRAME_OPTIONS->title = null;
$FRAME_OPTIONS->canonical_url = null;
$FRAME_OPTIONS->activeHeader = null;
$FRAME_OPTIONS->frame = 'api_frame.php';
require_once (__DIR__ . '/../internals/base.php');
$API_COMMANDS = $API_COMMANDS =
[ [
@ -12,6 +19,7 @@ $API_COMMANDS =
'site::createprogramthumbnails' => [ 'src' => __DIR__.'/../commands/site_createProgramThumbnails.php', 'auth' => 'admin' ], 'site::createprogramthumbnails' => [ 'src' => __DIR__.'/../commands/site_createProgramThumbnails.php', 'auth' => 'admin' ],
'site::createbookthumbnails' => [ 'src' => __DIR__.'/../commands/site_createBookThumbnails.php', 'auth' => 'admin' ], 'site::createbookthumbnails' => [ 'src' => __DIR__.'/../commands/site_createBookThumbnails.php', 'auth' => 'admin' ],
'site::selftest' => [ 'src' => __DIR__.'/../commands/site_selftest.php', 'auth' => 'admin' ],
'server::setselfaddress' => [ 'src' => __DIR__.'/../commands/server_setselfaddress.php', 'auth' => 'none' ], 'server::setselfaddress' => [ 'src' => __DIR__.'/../commands/server_setselfaddress.php', 'auth' => 'none' ],
'server::gitwebhook' => [ 'src' => __DIR__.'/../commands/server_gitwebhook.php', 'auth' => 'webhook_secret' ], 'server::gitwebhook' => [ 'src' => __DIR__.'/../commands/server_gitwebhook.php', 'auth' => 'webhook_secret' ],
@ -29,7 +37,7 @@ $API_COMMANDS =
'html::panel_aoc_calendar' => [ 'src' => __DIR__.'/../commands/html_panel-aoc-calendar.php', 'auth' => 'none' ], 'html::panel_aoc_calendar' => [ 'src' => __DIR__.'/../commands/html_panel-aoc-calendar.php', 'auth' => 'none' ],
]; ];
$cmd = strtolower($OPTIONS['cmd']); $cmd = strtolower($ROUTE->parameter['cmd']);
if (!array_key_exists($cmd, $API_COMMANDS)) if (!array_key_exists($cmd, $API_COMMANDS))
{ {
@ -58,7 +66,9 @@ if (!array_key_exists($cmd, $API_COMMANDS))
print(" ::::::`:::::;' / / `# \n"); print(" ::::::`:::::;' / / `# \n");
print(" \n"); print(" \n");
print(" \n"); print(" \n");
httpDie(400, 'Wrong command.');
$FRAME_OPTIONS->forceResult(400, 'Wrong command.');
return;
} }
$config = $API_COMMANDS[$cmd]; $config = $API_COMMANDS[$cmd];
@ -66,17 +76,17 @@ $config = $API_COMMANDS[$cmd];
$secret = isset($_GET['secret']) ? $_GET['secret'] : ''; $secret = isset($_GET['secret']) ? $_GET['secret'] : '';
if ($config['auth'] === 'webhook_secret' && $secret !== $CONFIG['webhook_secret']) httpDie(401, 'Unauthorized.'); if ($config['auth'] === 'webhook_secret' && $secret !== $SITE->config['webhook_secret']) { $FRAME_OPTIONS->forceResult(401, "Unauthorized."); return; }
if ($config['auth'] === 'ajax_secret' && $secret !== $CONFIG['ajax_secret']) httpDie(401, 'Unauthorized.'); if ($config['auth'] === 'ajax_secret' && $secret !== $SITE->config['ajax_secret']) { $FRAME_OPTIONS->forceResult(401, "Unauthorized."); return; }
if ($config['auth'] === 'upload_secret' && $secret !== $CONFIG['upload_secret']) httpDie(401, 'Unauthorized.'); if ($config['auth'] === 'upload_secret' && $secret !== $SITE->config['upload_secret']) { $FRAME_OPTIONS->forceResult(401, "Unauthorized."); return; }
if ($config['auth'] === 'admin' && !isLoggedInByCookie()) httpDie(401, 'Unauthorized.'); if ($config['auth'] === 'admin' && !$SITE->isLoggedInByCookie()) { $FRAME_OPTIONS->forceResult(401, "Unauthorized."); return; }
global $API_OPTIONS; global $API_OPTIONS;
$API_OPTIONS = []; $API_OPTIONS = [];
foreach ($_GET as $k => $v) $API_OPTIONS[strtolower($k)] = $v; foreach ($_GET as $k => $v) $API_OPTIONS[strtolower($k)] = $v;
foreach ($OPTIONS['_urlparams'] as $k => $v) $API_OPTIONS[strtolower($k)] = $v; foreach ($ROUTE->urlParameter as $k => $v) $API_OPTIONS[strtolower($k)] = $v;
try try
{ {
@ -85,15 +95,16 @@ try
} }
catch (exception $e) catch (exception $e)
{ {
print("API Command failed with exception");
print($e);
$content = $content =
"REQUEST: " . var_export($_REQUEST) . "\r\n\r\n" . "REQUEST: " . var_export($_REQUEST) . "\r\n\r\n" .
"IP: " . get_client_ip() . "\r\n\r\n" . "IP: " . get_client_ip() . "\r\n\r\n" .
"ERROR: " . $e . "\r\n\r\n"; "ERROR: " . $e . "\r\n\r\n";
if (isProd()) sendMail("Website API call failed", $content, 'virtualadmin@mikescher.de', 'webserver-info@mikescher.com'); if ($SITE->isProd()) sendMail("Website API call failed", $content, 'virtualadmin@mikescher.de', 'webserver-info@mikescher.com');
httpDie(500, 'Error.'); $msg = "Error.";
if (!$SITE->isProd()) $msg = "Error.\n" . "API Command failed with exception.\n" . $e;
$FRAME_OPTIONS->forceResult(500, $msg);
return;
} }

View File

@ -1,27 +1,20 @@
<!DOCTYPE html>
<html lang="en">
<?php <?php
require_once (__DIR__ . '/../internals/base.php'); require_once (__DIR__ . '/../internals/website.php');
require_once (__DIR__ . '/../internals/blog.php');
$allposts = Blog::listAllNewestFirst();
/** @var PageFrameOptions $FRAME_OPTIONS */ global $FRAME_OPTIONS;
/** @var URLRoute $ROUTE */ global $ROUTE;
/** @var Website $SITE */ global $SITE;
?> ?>
<head>
<meta charset="utf-8">
<title>Mikescher.com - Blog</title>
<link rel="icon" type="image/png" href="/data/images/favicon.png"/>
<link rel="canonical" href="https://www.mikescher.com/blog"/>
<?php printHeaderCSS(); ?>
</head>
<body>
<div id="mastercontainer">
<?php $HEADER_ACTIVE='blog'; include (__DIR__ . '/../fragments/header.php'); ?> <?php
$FRAME_OPTIONS->title = 'Blog';
$FRAME_OPTIONS->canonical_url = 'https://www.mikescher.com/blog';
$FRAME_OPTIONS->activeHeader = 'blog';
<div id="content" class="content-responsive"> $allposts = $SITE->modules->Blog()->listAllNewestFirst();
?>
<div class="blockcontent"> <div class="blockcontent">
<div class="contentheader"><h1>Blogposts and other stuff</h1><hr/></div> <div class="contentheader"><h1>Blogposts and other stuff</h1><hr/></div>
@ -42,14 +35,4 @@ $allposts = Blog::listAllNewestFirst();
?> ?>
</div> </div>
</div>
</div> </div>
<?php include (__DIR__ . '/../fragments/footer.php'); ?>
</div>
<?php printAdditionalScripts(); ?>
<?php printAdditionalStylesheets(); ?>
</body>
</html>

View File

@ -1,72 +1,55 @@
<!DOCTYPE html>
<html lang="en">
<?php <?php
require_once (__DIR__ . '/../internals/base.php'); require_once (__DIR__ . '/../internals/website.php');
require_once (__DIR__ . '/../internals/blog.php');
/** @var PageFrameOptions $FRAME_OPTIONS */ global $FRAME_OPTIONS;
$id = $OPTIONS['id']; /** @var URLRoute $ROUTE */ global $ROUTE;
$subview = $OPTIONS['subview']; /** @var Website $SITE */ global $SITE;
$post = Blog::getFullBlogpost($id, $subview, $err);
if ($post === null) httpError(404, $err);
?>
<head>
<meta charset="utf-8">
<title>Mikescher.com - <?php echo htmlspecialchars($post['title']); ?></title>
<link rel="icon" type="image/png" href="/data/images/favicon.png"/>
<?php printHeaderCSS(); ?>
<?php echo '<link rel="canonical" href="' . $post['canonical'] . '"/>'; ?>
</head>
<body>
<div id="mastercontainer">
<?php
if ($post['type'] == 'euler') $HEADER_ACTIVE = 'euler';
else if ($post['type'] == 'euler' && $post['issubview']) $HEADER_ACTIVE = 'aoc';
else $HEADER_ACTIVE = 'blog';
include (__DIR__ . '/../fragments/header.php');
?> ?>
<div id="content" class="content-responsive"> <?php
$id = $ROUTE->parameter['id'];
$subview = $ROUTE->parameter['subview'];
<div class="blockcontent"> $post = $SITE->modules->Blog()->getFullBlogpost($id, $subview, $err);
if ($post === null) { $FRAME_OPTIONS->setForced404($err); return; }
$FRAME_OPTIONS->title = $post['title'];
$FRAME_OPTIONS->canonical_url = $post['canonical'];
if ($post['type'] == 'euler')
$FRAME_OPTIONS->activeHeader = 'euler';
else if ($post['type'] == 'euler' && $post['issubview'])
$FRAME_OPTIONS->activeHeader = 'aoc';
else
$FRAME_OPTIONS->activeHeader = 'blog';
?>
<div class="blockcontent">
<div class="contentheader"><h1><?php echo htmlspecialchars($post['title']); ?></h1><hr/></div> <div class="contentheader"><h1><?php echo htmlspecialchars($post['title']); ?></h1><hr/></div>
<?php <?php
if ($post['type'] === 'plain') { if ($post['type'] === 'plain')
{
include (__DIR__ . '/../fragments/blogview_plain.php'); echo $SITE->fragments->BlogviewPlain($post);
}
} elseif ($post['type'] === 'markdown') { elseif ($post['type'] === 'markdown')
{
include (__DIR__ . '/../fragments/blogview_markdown.php'); echo $SITE->fragments->BlogviewMarkdown($post);
}
} elseif ($post['type'] === 'euler') { elseif ($post['type'] === 'euler')
{
if ($subview === '') include (__DIR__ . '/../fragments/blogview_euler_list.php'); if ($subview === '') echo $SITE->fragments->BlogviewEulerList($post);
else include (__DIR__ . '/../fragments/blogview_euler_single.php'); else echo $SITE->fragments->BlogviewEulerSingle($post, $subview);
}
} elseif ($post['type'] === 'aoc') { elseif ($post['type'] === 'aoc')
{
if ($subview === '') include (__DIR__ . '/../fragments/blogview_aoc_list.php'); if ($subview === '') echo $SITE->fragments->BlogviewAdventOfCodeList($post);
else include (__DIR__ . '/../fragments/blogview_aoc_single.php'); else echo $SITE->fragments->BlogviewAdventOfCodeSingle($post, $subview);
} }
?> ?>
</div>
</div> </div>
<?php include (__DIR__ . '/../fragments/footer.php'); ?>
</div>
<?php printAdditionalScripts(); ?>
<?php printAdditionalStylesheets(); ?>
</body>
</html>

View File

@ -1,27 +1,20 @@
<!DOCTYPE html>
<html lang="en">
<?php <?php
require_once (__DIR__ . '/../internals/base.php'); require_once (__DIR__ . '/../internals/website.php');
require_once (__DIR__ . '/../internals/books.php');
$allbooks = Books::listAllNewestFirst();
/** @var PageFrameOptions $FRAME_OPTIONS */ global $FRAME_OPTIONS;
/** @var URLRoute $ROUTE */ global $ROUTE;
/** @var Website $SITE */ global $SITE;
?> ?>
<head>
<meta charset="utf-8">
<title>Mikescher.com - Converted Books</title>
<link rel="icon" type="image/png" href="/data/images/favicon.png"/>
<link rel="canonical" href="https://www.mikescher.com/books"/>
<?php printHeaderCSS(); ?>
</head>
<body>
<div id="mastercontainer">
<?php $HEADER_ACTIVE = 'books'; include (__DIR__ . '/../fragments/header.php'); ?> <?php
$FRAME_OPTIONS->title = 'Converted Books';
$FRAME_OPTIONS->canonical_url = 'https://www.mikescher.com/books';
$FRAME_OPTIONS->activeHeader = 'books';
<div id="content" class="content-responsive"> $allbooks = $SITE->modules->Books()->listAllNewestFirst();
?>
<div class="blockcontent booklst_content"> <div class="blockcontent booklst_content">
<div class="contentheader"><h1>Books/<wbr>Webserials I self-printed</h1><hr/></div> <div class="contentheader"><h1>Books/<wbr>Webserials I self-printed</h1><hr/></div>
@ -51,14 +44,4 @@ $allbooks = Books::listAllNewestFirst();
?> ?>
</div>
</div>
<?php include (__DIR__ . '/../fragments/footer.php'); ?>
</div> </div>
<?php printAdditionalScripts(); ?>
<?php printAdditionalStylesheets(); ?>
</body>
</html>

View File

@ -1,32 +1,26 @@
<!DOCTYPE html>
<html lang="en">
<?php <?php
require_once (__DIR__ . '/../internals/base.php'); require_once (__DIR__ . '/../internals/website.php');
require_once (__DIR__ . '/../internals/books.php');
$id = $OPTIONS['id'];
$book = Books::getBook($id);
if ($book === NULL) httpError(404, 'Book not found');
/** @var PageFrameOptions $FRAME_OPTIONS */ global $FRAME_OPTIONS;
/** @var URLRoute $ROUTE */ global $ROUTE;
/** @var Website $SITE */ global $SITE;
?> ?>
<head>
<meta charset="utf-8">
<title>Mikescher.com - <?php echo $book['title']; ?></title>
<link rel="icon" type="image/png" href="/data/images/favicon.png"/>
<?php printHeaderCSS(); ?>
<?php echo '<link rel="canonical" href="' . $book['url'] . '"/>'; ?>
<?php includeAdditionalScript("/data/javascript/ms_basic.js", 'defer', true) ?>
</head>
<body>
<div id="mastercontainer">
<?php $HEADER_ACTIVE = 'book'; include (__DIR__ . '/../fragments/header.php'); ?> <?php
$id = $ROUTE->parameter['id'];
<div id="content" class="content-responsive"> $book = $SITE->modules->Books()->getBook($id);
if ($book === null) { $FRAME_OPTIONS->setForced404("Books not found"); return; }
<div class="blockcontent"> $FRAME_OPTIONS->title = $book['title'];
$FRAME_OPTIONS->canonical_url = $book['url'];
$FRAME_OPTIONS->activeHeader = 'book';
$FRAME_OPTIONS->addScript('/data/javascript/ms_basic.js', true);
?>
<div class="blockcontent">
<div class="bookv_content"> <div class="bookv_content">
@ -70,7 +64,7 @@ if ($book === NULL) httpError(404, 'Book not found');
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 24 24"> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 24 24">
<use xlink:href="/data/images/icons.svg#github"/> <use xlink:href="/data/images/icons.svg#github"/>
</svg> </svg>
<span><?php echo Books::getRepositoryHost($book); ?></span> <span><?php echo $SITE->modules->Books()->getRepositoryHost($book); ?></span>
</a> </a>
<a class="iconbutton" href="<?php echo $book['online'] ?>"> <a class="iconbutton" href="<?php echo $book['online'] ?>">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 24 24"> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 24 24">
@ -115,13 +109,4 @@ if ($book === NULL) httpError(404, 'Book not found');
</div> </div>
</div> </div>
</div>
</div> </div>
<?php include (__DIR__ . '/../fragments/footer.php'); ?>
</div>
<?php printAdditionalScripts(); ?>
<?php printAdditionalStylesheets(); ?>
</body>
</html>

View File

@ -0,0 +1,24 @@
<?php
require_once (__DIR__ . '/../internals/website.php');
/** @var PageFrameOptions $FRAME_OPTIONS */ global $FRAME_OPTIONS;
/** @var URLRoute $ROUTE */ global $ROUTE;
/** @var Website $SITE */ global $SITE;
?>
<?php
$message = isset($ROUTE->parameter['message']) ? $ROUTE->parameter['message'] : '';
$FRAME_OPTIONS->title = $message;
$FRAME_OPTIONS->canonical_url = null;
$FRAME_OPTIONS->activeHeader = null;
$FRAME_OPTIONS->contentCSSClasses []= 'content-fullheight';
?>
<div class="ev_master">
<div class="ev_code">404</div>
<?php if ($message !== ''): ?>
<div class="ev_msg"><?php echo $message; ?></div>
<?php endif; ?>
</div>

View File

@ -0,0 +1,26 @@
<?php
require_once (__DIR__ . '/../internals/website.php');
/** @var PageFrameOptions $FRAME_OPTIONS */ global $FRAME_OPTIONS;
/** @var URLRoute $ROUTE */ global $ROUTE;
/** @var Website $SITE */ global $SITE;
?>
<?php
$FRAME_OPTIONS->title = 'Error';
$FRAME_OPTIONS->canonical_url = null;
$FRAME_OPTIONS->activeHeader = null;
$FRAME_OPTIONS->contentCSSClasses []= 'content-fullheight';
$message = $ROUTE->parameter['message'];
$debuginfo = $ROUTE->parameter['debuginfo'];
?>
<div class="ev_master">
<div class="ev_code">500</div>
<div class="ev_msg"><?php echo $message; ?></div>
<?php if ($debuginfo !== null && strlen($debuginfo)>0 && ($SITE != null && !$SITE->isProd())): ?>
<p class="ev_statusmore"><?php echo nl2br($debuginfo); ?></p>
<?php endif; ?>
</div>

View File

@ -1,34 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<?php
require_once (__DIR__ . '/../internals/base.php');
global $OPTIONS;
$errorcode = $OPTIONS['code'];
$errormsg = $OPTIONS['message'];
?>
<head>
<meta charset="utf-8">
<title>Mikescher.com - <?php echo $errormsg; ?></title>
<link rel="icon" type="image/png" href="/data/images/favicon.png"/>
<?php printHeaderCSS(); ?>
</head>
<body>
<div id="mastercontainer">
<?php $HEADER_ACTIVE='none'; include (__DIR__ . '/../fragments/header.php'); ?>
<div id="content" class="content-responsive content-fullheight">
<div class="ev_master">
<div class="ev_code"><?php echo $errorcode; ?></div>
<div class="ev_msg"><?php echo $errormsg; ?></div>
</div>
</div>
</div>
<?php printAdditionalScripts(); ?>
<?php printAdditionalStylesheets(); ?>
</body>
</html>

View File

@ -1,26 +1,30 @@
<?php <?php
global $OPTIONS; require_once (__DIR__ . '/../internals/website.php');
require_once (__DIR__ . '/../internals/base.php'); /** @var PageFrameOptions $FRAME_OPTIONS */ global $FRAME_OPTIONS;
require_once (__DIR__ . '/../internals/database.php'); /** @var URLRoute $ROUTE */ global $ROUTE;
require_once (__DIR__ . '/../internals/highscores.php'); /** @var Website $SITE */ global $SITE;
Database::connect(); $FRAME_OPTIONS->title = null;
$FRAME_OPTIONS->canonical_url = null;
$FRAME_OPTIONS->activeHeader = null;
$FRAME_OPTIONS->frame = 'api_frame.php';
$gameid = $OPTIONS['gameid'];
$check = $OPTIONS['check'];
$name = $OPTIONS['name'];
$rand = $OPTIONS['rand'];
$points = $OPTIONS['points'];
if (! is_numeric($gameid)) httpError(400, 'Invalid Request'); $gameid = $ROUTE->parameter['gameid'];
if (! is_numeric($points)) httpError(400, 'Invalid Request'); $check = $ROUTE->parameter['check'];
$name = $ROUTE->parameter['name'];
$rand = $ROUTE->parameter['rand'];
$points = $ROUTE->parameter['points'];
$game = Highscores::getGameByID($gameid); if (! is_numeric($gameid)) { $FRAME_OPTIONS->forceResult(400, 'Invalid Request'); return; }
if ($game == NULL) httpError(400, 'Invalid Request'); if (! is_numeric($points)) { $FRAME_OPTIONS->forceResult(400, 'Invalid Request'); return; }
$checksum_generated = Highscores::generateChecksum($rand, $name, -1, $points, $game['SALT']); $game = $SITE->modules->Highscores()->getGameByID($gameid);
if ($checksum_generated != $check) die('Nice try !'); if ($game == NULL) { $FRAME_OPTIONS->forceResult(400, 'Invalid Request'); return; }
Highscores::insert($gameid, $points, $name, -1, $check, date("Y-m-d H:m:s", time()), $_SERVER['REMOTE_ADDR']); $checksum_generated = $SITE->modules->Highscores()->generateChecksum($rand, $name, -1, $points, $game['SALT']);
echo 'ok.'; if ($checksum_generated != $check) die('Nice try !');
$SITE->modules->Highscores()->insert($gameid, $points, $name, -1, $check, date("Y-m-d H:m:s", time()), $_SERVER['REMOTE_ADDR']);
echo 'ok.';

View File

@ -1,30 +1,35 @@
<?php <?php
global $OPTIONS; require_once (__DIR__ . '/../internals/website.php');
require_once (__DIR__ . '/../internals/base.php'); /** @var PageFrameOptions $FRAME_OPTIONS */ global $FRAME_OPTIONS;
require_once (__DIR__ . '/../internals/database.php'); /** @var URLRoute $ROUTE */ global $ROUTE;
require_once (__DIR__ . '/../internals/highscores.php'); /** @var Website $SITE */ global $SITE;
Database::connect(); $FRAME_OPTIONS->title = null;
$FRAME_OPTIONS->canonical_url = null;
$FRAME_OPTIONS->activeHeader = null;
$FRAME_OPTIONS->frame = 'api_frame.php';
$pagesize = 20;
$start = 0;
$highlight = 0;
if (isset($_GET["start"]))
{ $pagesize = 20;
$start = 0;
$highlight = 0;
if (isset($_GET["start"]))
{
$start = intval(htmlspecialchars($_GET["start"])) - 1; $start = intval(htmlspecialchars($_GET["start"])) - 1;
if ($start < 0) $start = 0; if ($start < 0) $start = 0;
} }
if (isset($_GET["highlight"])) if (isset($_GET["highlight"]))
{ {
$highlight= intval(htmlspecialchars($_GET["highlight"])); $highlight= intval(htmlspecialchars($_GET["highlight"]));
} }
$game = Highscores::getGameByID($OPTIONS['gameid']); $game = $SITE->modules->Highscores()->getGameByID($ROUTE->parameter['gameid']);
$entries = Highscores::getOrderedEntriesFromGame($OPTIONS['gameid']); $entries = $SITE->modules->Highscores()->getOrderedEntriesFromGame($ROUTE->parameter['gameid']);
?> ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

View File

@ -1,14 +1,16 @@
<?php <?php
global $OPTIONS; require_once (__DIR__ . '/../internals/website.php');
require_once (__DIR__ . '/../internals/base.php'); /** @var PageFrameOptions $FRAME_OPTIONS */ global $FRAME_OPTIONS;
require_once (__DIR__ . '/../internals/database.php'); /** @var URLRoute $ROUTE */ global $ROUTE;
require_once (__DIR__ . '/../internals/highscores.php'); /** @var Website $SITE */ global $SITE;
Database::connect(); $FRAME_OPTIONS->title = null;
$FRAME_OPTIONS->canonical_url = null;
$games = Highscores::getAllGames(); $FRAME_OPTIONS->activeHeader = null;
$FRAME_OPTIONS->frame = 'api_frame.php';
$games = $SITE->modules->Highscores()->getAllGames();
?> ?>
<html> <html>
<head> <head>

View File

@ -1,14 +1,18 @@
<?php <?php
global $OPTIONS; require_once (__DIR__ . '/../internals/website.php');
require_once (__DIR__ . '/../internals/base.php'); /** @var PageFrameOptions $FRAME_OPTIONS */ global $FRAME_OPTIONS;
require_once (__DIR__ . '/../internals/database.php'); /** @var URLRoute $ROUTE */ global $ROUTE;
require_once (__DIR__ . '/../internals/highscores.php'); /** @var Website $SITE */ global $SITE;
Database::connect(); $FRAME_OPTIONS->title = null;
$FRAME_OPTIONS->canonical_url = null;
$FRAME_OPTIONS->activeHeader = null;
$FRAME_OPTIONS->frame = 'api_frame.php';
$newid = Highscores::getNextPlayerID($OPTIONS['gameid']);
if ($newid < 1024) $newid = 1024; $newid = $SITE->modules->Highscores()->getNextPlayerID($ROUTE->parameter['gameid']);
print $newid; if ($newid < 1024) $newid = 1024;
print $newid;

View File

@ -1,13 +1,17 @@
<?php <?php
global $OPTIONS; require_once (__DIR__ . '/../internals/website.php');
require_once (__DIR__ . '/../internals/base.php'); /** @var PageFrameOptions $FRAME_OPTIONS */ global $FRAME_OPTIONS;
require_once (__DIR__ . '/../internals/database.php'); /** @var URLRoute $ROUTE */ global $ROUTE;
require_once (__DIR__ . '/../internals/highscores.php'); /** @var Website $SITE */ global $SITE;
Database::connect(); $FRAME_OPTIONS->title = null;
$FRAME_OPTIONS->canonical_url = null;
$FRAME_OPTIONS->activeHeader = null;
$FRAME_OPTIONS->frame = 'api_frame.php';
$entries = Highscores::getOrderedEntriesFromGame($OPTIONS['gameid'], 50);
$entries = $SITE->modules->Highscores()->getOrderedEntriesFromGame($ROUTE->parameter['gameid'], 50);
for ($i = 0; $i < count($entries); $i++) for ($i = 0; $i < count($entries); $i++)
{ {

View File

@ -1,38 +1,42 @@
<?php <?php
global $OPTIONS; require_once (__DIR__ . '/../internals/website.php');
require_once (__DIR__ . '/../internals/base.php'); /** @var PageFrameOptions $FRAME_OPTIONS */ global $FRAME_OPTIONS;
require_once (__DIR__ . '/../internals/database.php'); /** @var URLRoute $ROUTE */ global $ROUTE;
require_once (__DIR__ . '/../internals/highscores.php'); /** @var Website $SITE */ global $SITE;
Database::connect(); $FRAME_OPTIONS->title = null;
$FRAME_OPTIONS->canonical_url = null;
$FRAME_OPTIONS->activeHeader = null;
$FRAME_OPTIONS->frame = 'api_frame.php';
$gameid = $OPTIONS['gameid'];
$check = $OPTIONS['check'];
$name = $OPTIONS['name'];
$nameid = $OPTIONS['nameid'];
$rand = $OPTIONS['rand'];
$points = $OPTIONS['points'];
if (! is_numeric($gameid)) httpError(400, 'Invalid Request'); $gameid = $ROUTE->parameter['gameid'];
if (! is_numeric($nameid)) httpError(400, 'Invalid Request'); $check = $ROUTE->parameter['check'];
if (! is_numeric($points)) httpError(400, 'Invalid Request'); $name = $ROUTE->parameter['name'];
$nameid = $ROUTE->parameter['nameid'];
$rand = $ROUTE->parameter['rand'];
$points = $ROUTE->parameter['points'];
$game = Highscores::getGameByID($OPTIONS['gameid']); if (! is_numeric($gameid)) { $FRAME_OPTIONS->forceResult(400, 'Invalid Request'); return; }
if ($game == NULL) httpError(400, 'Invalid Request'); if (! is_numeric($nameid)) { $FRAME_OPTIONS->forceResult(400, 'Invalid Request'); return; }
if (! is_numeric($points)) { $FRAME_OPTIONS->forceResult(400, 'Invalid Request'); return; }
$checksum_generated = Highscores::generateChecksum($rand, $name, $nameid, $points, $game['SALT']); $game = $SITE->modules->Highscores()->getGameByID($ROUTE->parameter['gameid']);
if ($checksum_generated != $check) die('Nice try !'); if ($game == NULL) { $FRAME_OPTIONS->forceResult(400, 'Invalid Request'); return; }
$old = Highscores::getSpecificScore($gameid, $nameid); $checksum_generated = $SITE->modules->Highscores()->generateChecksum($rand, $name, $nameid, $points, $game['SALT']);
if ($checksum_generated != $check) die('Nice try !');
if ($old == null) $old = $SITE->modules->Highscores()->getSpecificScore($gameid, $nameid);
{
Highscores::insert($gameid, $points, $name, $nameid, $check, date("Y-m-d H:m:s", time()), $_SERVER['REMOTE_ADDR']); if ($old == null)
{
$SITE->modules->Highscores()->insert($gameid, $points, $name, $nameid, $check, date("Y-m-d H:m:s", time()), $_SERVER['REMOTE_ADDR']);
echo 'ok.'; echo 'ok.';
} }
else else
{ {
Highscores::update($gameid, $points, $name, $nameid, $check, date("Y-m-d H:m:s", time()), $_SERVER['REMOTE_ADDR']); $SITE->modules->Highscores()->update($gameid, $points, $name, $nameid, $check, date("Y-m-d H:m:s", time()), $_SERVER['REMOTE_ADDR']);
echo 'ok.'; echo 'ok.';
} }

View File

@ -1,18 +1,29 @@
<!DOCTYPE html>
<html lang="en">
<?php <?php
require_once (__DIR__ . '/../internals/base.php'); require_once (__DIR__ . '/../internals/website.php');
global $OPTIONS;
/** @var PageFrameOptions $FRAME_OPTIONS */ global $FRAME_OPTIONS;
/** @var URLRoute $ROUTE */ global $ROUTE;
/** @var Website $SITE */ global $SITE;
?>
<?php
$FRAME_OPTIONS->title = 'Login';
$FRAME_OPTIONS->canonical_url = 'https://www.mikescher.com/login';
$FRAME_OPTIONS->activeHeader = 'login';
$FRAME_OPTIONS->addScript('/data/javascript/ms_basic.js', true);
?>
<?php
$err = false; $err = false;
if (key_exists('username', $_GET) && key_exists('password', $_GET) && key_exists('redirect', $_GET)) if (key_exists('username', $_GET) && key_exists('password', $_GET) && key_exists('redirect', $_GET))
{ {
if ($_GET['username'] === $CONFIG['admin_username'] && $_GET['password'] === $CONFIG['admin_password']) if ($_GET['username'] === $SITE->config['admin_username'] && $_GET['password'] === $SITE->config['admin_password'])
{ {
setLoginCookie($_GET['username'], $_GET['password']); $SITE->setLoginCookie($_GET['username'], $_GET['password']);
header('Location: ' . $_GET['redirect']); $FRAME_OPTIONS->setForcedRedirect($_GET['redirect']);
die(); return;
} }
else else
{ {
@ -20,25 +31,12 @@ if (key_exists('username', $_GET) && key_exists('password', $_GET) && key_exists
} }
} }
$redirect = $OPTIONS['login_target']; $redirect = $ROUTE->parameter['login_target'];
if (($redirect === '/' || $redirect === '') && isset($_GET['redirect'])) $redirect = $_GET['redirect']; if (($redirect === '/' || $redirect === '') && isset($_GET['redirect'])) $redirect = $_GET['redirect'];
if (($redirect === '/' || $redirect === '')) $redirect = '/admin';
?> ?>
<head>
<meta charset="utf-8">
<title>Mikescher.com - Login</title>
<link rel="icon" type="image/png" href="/data/images/favicon.png"/>
<link rel="canonical" href="https://www.mikescher.com/login"/>
<?php printHeaderCSS(); ?>
</head>
<body>
<div id="mastercontainer">
<?php $HEADER_ACTIVE = 'login'; include (__DIR__ . '/../fragments/header.php'); ?> <div class="aboutcontent">
<div id="content" class="content-responsive">
<div class="aboutcontent">
<div class="boxedcontent"> <div class="boxedcontent">
<div class="bc_header">Mikescher.com - Login</div> <div class="bc_header">Mikescher.com - Login</div>
@ -54,7 +52,7 @@ if (($redirect === '/' || $redirect === '') && isset($_GET['redirect'])) $redire
<div> <div>
<label for="username" class="required">Username</label> <label for="username" class="required">Username</label>
<input name="username" id="username" type="text" autofocus > <input name="username" id="username" type="text" autofocus>
</div> </div>
<div> <div>
@ -74,19 +72,8 @@ if (($redirect === '/' || $redirect === '') && isset($_GET['redirect'])) $redire
</form> </form>
</div> </div>
</div> </div>
</div> </div>
</div>
</div>
<?php include (__DIR__ . '/../fragments/footer.php'); ?>
</div> </div>
<?php printAdditionalScripts(); ?>
<?php printAdditionalStylesheets(); ?>
</body>
</html>

View File

@ -1,27 +1,16 @@
<?php <?php
require_once (__DIR__ . '/../internals/base.php'); require_once (__DIR__ . '/../internals/website.php');
global $OPTIONS;
$redirect = $OPTIONS['logout_target'];
clearLoginCookie();
/** @var PageFrameOptions $FRAME_OPTIONS */ global $FRAME_OPTIONS;
/** @var URLRoute $ROUTE */ global $ROUTE;
/** @var Website $SITE */ global $SITE;
?> ?>
<!DOCTYPE html>
<html lang="en">
<head> <?php
<meta charset="utf-8"> $redirect = $ROUTE->parameter['logout_target'];
<title>Mikescher.com - Logout</title> $SITE->clearLoginCookie();
<link rel="icon" type="image/png" href="/data/images/favicon.png"/> ?>
<link rel="canonical" href="https://www.mikescher.com/logout"/>
<meta http-equiv="refresh" content="1; url=<?php echo $redirect; ?>" />
</head>
<body>
You have been logged out You have been logged out
<script> <script> setTimeout(function () { window.location.href = "<?php echo $redirect; ?>"; }, 1000); </script>
setTimeout(function () { window.location.href = "<?php echo $redirect; ?>"; }, 1000);
</script>
<?php printAdditionalScripts(); ?>
<?php printAdditionalStylesheets(); ?>
</body>
</html>

Some files were not shown because too many files have changed in this diff Show More