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,78 +2,83 @@
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):
s = match.group(0) s = match.group(0)
if s.startswith('/'): if s.startswith('/'):
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])
else: 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,18 +175,17 @@ 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')
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_ok { background: $COL_ADMIN_OK; } .consistency_result:after { content: '\00a0' }
.consistency_result_warn { background: $COL_ADMIN_WARN; }
.consistency_result_err { background: $COL_ADMIN_ERROR; } .consistency_result_ok { background: $COL_ADMIN_OK; }
.consistency_result_warn { background: $COL_ADMIN_WARN; }
.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

@ -115,9 +115,21 @@ $COL_FOOTER_FG: #CCCCCC;
// ------------------------------------ // ------------------------------------
$COL_TOAST_ERROR_FG: #222222; $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;
// ------------------------------------ // ------------------------------------
@ -149,12 +161,17 @@ $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';
@ -22,8 +39,8 @@ 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'];
@ -54,50 +67,42 @@ 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,114 +1,98 @@
<!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> <!-- - - - - - - - - - - - - - - - - - - - - -->
<!-- - - - - - - - - - - - - - - - - - - - - --> <div class="boxedcontent">
<div class="bc_header">About me</div>
<div class="boxedcontent"> <div class="bc_data">
<div class="bc_header">About me</div>
<div class="bc_data"> <p>Welcome to my Mikescher.com</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>Welcome to my Mikescher.com</p> </div>
<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>
</div>
</div> <!-- - - - - - - - - - - - - - - - - - - - - -->
</div> <div class="boxedcontent">
<div class="bc_header">My git timeline</div>
<!-- - - - - - - - - - - - - - - - - - - - - --> <div class="bc_data about_egg_container">
<div class="boxedcontent"> <?php
<div class="bc_header">My git timeline</div> $FRAME_OPTIONS->addScript('/data/javascript/extendedgitgraph.js', true);
echo $SITE->modules->ExtendedGitGraph()->get();
?>
<div class="bc_data about_egg_container"> </div>
<?php print(MikescherGitGraph::get()); ?> </div>
</div> <!-- - - - - - - - - - - - - - - - - - - - - -->
</div> <div class="boxedcontent">
<div class="bc_header">Other addresses</div>
<!-- - - - - - - - - - - - - - - - - - - - - --> <div class="bc_data about_circles">
<div class="boxedcontent"> <a class="iconbutton_light" href="https://github.com/Mikescher">
<div class="bc_header">Other addresses</div> <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>
</svg>
<span>Github</span>
</a>
<a class="iconbutton_light" href="https://www.goodreads.com/C4terpillar">
<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#goodreads"></use>
</svg>
<span>Goodreads</span>
</a>
<a class="iconbutton_light" href="https://stackoverflow.com/users/1761622/mikescher">
<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#stackoverflow"></use>
</svg>
<span>Stackoverflow</span>
</a>
<a class="iconbutton_light" href="https://www.reddit.com/user/M1kescher/">
<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#reddit"></use>
</svg>
<span>Reddit</span>
</a>
<a class="iconbutton_light" href="http://www.delphipraxis.net/members/46235-mikescher.html">
<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#delphipraxis"></use>
</svg>
<span>Delphi-Praxis</span>
</a>
<a class="iconbutton_light" href="mailto:website_mailto@mikescher.com">
<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#email"></use>
</svg>
<span>E-Mail</span>
</a>
<div class="bc_data about_circles"> </div>
<a class="iconbutton_light" href="https://github.com/Mikescher"> </div>
<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>
</svg>
<span>Github</span>
</a>
<a class="iconbutton_light" href="https://www.goodreads.com/C4terpillar">
<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#goodreads"></use>
</svg>
<span>Goodreads</span>
</a>
<a class="iconbutton_light" href="https://stackoverflow.com/users/1761622/mikescher">
<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#stackoverflow"></use>
</svg>
<span>Stackoverflow</span>
</a>
<a class="iconbutton_light" href="https://www.reddit.com/user/M1kescher/">
<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#reddit"></use>
</svg>
<span>Reddit</span>
</a>
<a class="iconbutton_light" href="http://www.delphipraxis.net/members/46235-mikescher.html">
<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#delphipraxis"></use>
</svg>
<span>Delphi-Praxis</span>
</a>
<a class="iconbutton_light" href="mailto:website_mailto@mikescher.com">
<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#email"></use>
</svg>
<span>E-Mail</span>
</a>
</div>
</div>
</div>
</div>
<?php include (__DIR__ . '/../fragments/footer.php'); ?>
</div> </div>
<?php printAdditionalScripts(); ?>
<?php printAdditionalStylesheets(); ?>
</body>
</html>

View File

@ -1,261 +1,220 @@
<!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>";
}
?> <div class="contentheader"><h1>Admin</h1><hr/></div>
<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'); ?> <?php if (!$connected): ?>
<div class="boxedcontent alertbox">
<div class="bc_data">Could not connect to database</div>
</div>
<?php endif; ?>
<div id="content" class="content-responsive"> <?php if (!$SITE->isProd()): ?>
<div class="boxedcontent warnbox">
<div class="bc_data">Website runs in /dev/ mode</div>
</div>
<?php endif; ?>
<div class="admincontent"> <!-- - - - - - - - - - - - - - - - - - - - - -->
<div class="contentheader"><h1>Admin</h1><hr/></div> <div class="boxedcontent">
<div class="bc_header">Version</div>
<?php if (!$connected): ?> <div class="bc_data keyvaluelist kvl_100">
<div class="boxedcontent alertbox"> <div><span>Branch:</span> <span><?php echo exec('git rev-parse --abbrev-ref HEAD'); ?></span></div>
<div class="bc_data">Could not connect to database</div> <div><span>Commit:</span> <span><?php echo exec('git rev-parse HEAD'); ?></span></div>
</div> <div><span>Date:</span> <span><?php echo exec('git log -1 --format=%cd'); ?></span></div>
<?php endif; ?> <div><span>Message:</span><span><?php echo nl2br(trim(exec('git log -1'))); ?></span></div>
</div>
<!-- - - - - - - - - - - - - - - - - - - - - --> </div>
<div class="boxedcontent"> <!-- - - - - - - - - - - - - - - - - - - - - -->
<div class="bc_header">Version</div>
<div class="boxedcontent">
<div class="bc_data keyvaluelist kvl_100"> <div class="bc_header">Self test</div>
<div><span>Branch:</span> <span><?php echo exec('git rev-parse --abbrev-ref HEAD'); ?></span></div>
<div><span>Commit:</span> <span><?php echo exec('git rev-parse HEAD'); ?></span></div> <div class="bc_data">
<div><span>Date:</span> <span><?php echo exec('git log -1 --format=%cd'); ?></span></div> <div class="keyvaluelist kvl_200">
<div><span>Message:</span><span><?php echo nl2br(trim(exec('git log -1'))); ?></span></div> <?php foreach ($SITE->modules->SelfTest()->listMethodGroups() as $group): ?>
<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>
<?php endforeach; ?>
</div>
<br/>
<a class="button" href="/api/site::createProgramThumbnails">Update Program Thumbnails</a>
<a class="button" href="/api/site::createBookThumbnails">Update Book Thumbnails</a>
</div>
</div>
<!-- - - - - - - - - - - - - - - - - - - - - -->
<div class="boxedcontent">
<div class="bc_header">Self IP Addr</div>
<?php
$ippath = __DIR__ . '/../dynamic/self_ip_address.auto.cfg';
$self_ip = file_exists($ippath) ? file_get_contents($ippath) : 'N/A';
$real_ip = get_client_ip();
$me = $real_ip == $self_ip
?>
<div class="bc_data keyvaluelist kvl_200">
<div><span>Registered IP:</span> <span><?php echo $self_ip; ?></span></div>
<div><span>Current IP:</span> <span><?php echo $real_ip; ?></span></div>
</div>
</div>
<!-- - - - - - - - - - - - - - - - - - - - - -->
<div class="boxedcontent">
<div class="bc_header">ExtendedGitGraph</div>
<div class="bc_data">
<textarea class="egg_ajaxOutput" id="egg_ajaxOutput" readonly="readonly"></textarea>
<a class="button" href="javascript:startAjaxRefresh('<?php echo $SITE->config['ajax_secret'] ?>')">Update</a>
<a class="button" href="javascript:startAjaxRedraw('<?php echo $SITE->config['ajax_secret'] ?>')">Redraw</a>
</div>
</div>
<!-- - - - - - - - - - - - - - - - - - - - - -->
<div class="boxedcontent">
<div class="bc_header">AlephNote</div>
<?php if ($connected): ?>
<div class="bc_data">
<div class="keyvaluelist kvl_200">
<div><span>Total users:</span> <span><?php echo $SITE->modules->AlephNoteStatistics()->getTotalUserCount(); ?></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 $SITE->modules->AlephNoteStatistics()->getActiveUserCount(32); ?></span></div>
</div> </div>
<br/>
<div id="an_ajax_target"></div>
<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: ?>
<div class="bc_data keyvaluelist admindberr">Database not connected.</div>
<?php endif; ?>
<!-- - - - - - - - - - - - - - - - - - - - - --> </div>
<div class="boxedcontent"> <!-- - - - - - - - - - - - - - - - - - - - - -->
<div class="bc_header">Self test</div>
<div class="bc_data"> <div class="boxedcontent">
<div class="keyvaluelist kvl_200"> <div class="bc_header">Statics</div>
<div><span>Program thumbnails:</span> <?php dumpConsistency($consistency_progimg); ?></div>
<div><span>ExtendedGitGraph:</span> <?php dumpConsistency($consistency_egg); ?></div>
<div><span>Book thumbnails:</span> <?php dumpConsistency($consistency_bookimg); ?></div>
<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>
<br/>
<a class="button" href="/api/site::createProgramThumbnails">Update Program Thumbnails</a>
<a class="button" href="/api/site::createBookThumbnails">Update Book Thumbnails</a>
</div> <div class="bc_data keyvaluelist kvl_200">
<div><span>Blog entries:</span> <span><?php echo count($SITE->modules->Blog()->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($SITE->modules->Euler()->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($SITE->modules->UpdatesLog()->listUpdateData()); ?></span></div>
</div>
</div>
<!-- - - - - - - - - - - - - - - - - - - - - -->
<div class="boxedcontent">
<div class="bc_header">UpdatesLog</div>
<?php if ($connected): ?>
<div class="bc_data keyvaluelist kvl_300">
<?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 $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'] . '] Count (1 week):' ?></span> <span><?php echo $info['count_week']; ?></span></div>
<hr />
<?php endforeach; ?>
<br/>
<div id="ul_ajax_target"></div>
</div> </div>
<?php else: ?>
<div class="bc_data keyvaluelist admindberr">Database not connected.</div>
<?php endif; ?>
</div>
<!-- - - - - - - - - - - - - - - - - - - - - --> <!-- - - - - - - - - - - - - - - - - - - - - -->
<div class="boxedcontent"> <div class="boxedcontent">
<div class="bc_header">Self IP Addr</div> <div class="bc_header">Highscores</div>
<?php <?php if ($connected): ?>
$ippath = __DIR__ . '/../dynamic/self_ip_address.auto.cfg'; <div class="bc_data keyvaluelist kvl_300">
$self_ip = file_exists($ippath) ? file_get_contents($ippath) : 'N/A';
$real_ip = get_client_ip();
$me = $real_ip == $self_ip
?>
<div class="bc_data keyvaluelist kvl_200"> <?php foreach ($SITE->modules->Highscores()->getAllGames() as $game): ?>
<div><span>Registered IP:</span> <span><?php echo $self_ip; ?></span></div>
<div><span>Current IP:</span> <span><?php echo $real_ip; ?></span></div>
</div>
</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
$hs = $SITE->modules->Highscores()->getOrderedEntriesFromGame($game['ID'], 1)[0];
echo $hs['POINTS'] . ' (' . $hs['PLAYER'] . ') @ ' . $hs['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>
<div class="boxedcontent"> <hr />
<div class="bc_header">ExtendedGitGraph</div>
<div class="bc_data"> <?php endforeach; ?>
<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:startAjaxRedraw('<?php echo $CONFIG['ajax_secret'] ?>')">Redraw</a>
</div>
</div> </div>
<?php else: ?>
<div class="bc_data keyvaluelist admindberr">Database not connected.</div>
<?php endif; ?>
<!-- - - - - - - - - - - - - - - - - - - - - --> </div>
<div class="boxedcontent"> <!-- - - - - - - - - - - - - - - - - - - - - -->
<div class="bc_header">AlephNote</div>
<?php if ($connected): ?> <div class="boxedcontent">
<div class="bc_data"> <div class="bc_header">Configuration</div>
<div class="keyvaluelist kvl_200"> <div class="bc_data keyvaluelist kvl_200">
<div><span>Total users:</span> <span><?php echo AlephNoteStatistics::getTotalUserCount(); ?></span></div> <?php
<div><span>Users on latest version:</span> <span><?php echo AlephNoteStatistics::getUserCountFromLastVersion(); ?></span></div> foreach ($SITE->config as $key => $value)
<div><span>Active users:</span> <span><?php echo AlephNoteStatistics::getActiveUserCount(32); ?></span></div> {
</div> if ($key === 'extendedgitgraph') continue;
<br/>
<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>
</div>
<?php else: ?>
<div class="bc_data keyvaluelist">Database not connected.</div>
<?php endif; ?>
</div> 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";
else
echo '<div><span>' . $key . '</span> <span>' . nl2br(var_export($value, true)) . '</span></div>' . "\n";
}
?>
</div>
</div>
<!-- - - - - - - - - - - - - - - - - - - - - --> <div class="boxedcontent">
<div class="bc_header">Configuration['extendedgitgraph']</div>
<div class="boxedcontent"> <div class="bc_data keyvaluelist kvl_200">
<div class="bc_header">Statics</div> <?php
foreach ($SITE->config['extendedgitgraph'] as $key => $value)
<div class="bc_data keyvaluelist kvl_200"> {
<div><span>Blog entries:</span> <span><?php echo count(Blog::listAll()); ?></span></div> if (is_array($value))
<div><span>Book entries:</span> <span><?php echo count(Books::listAll()); ?></span></div> 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";
<div><span>Euler entries:</span> <span><?php echo count(Euler::listAll()); ?></span></div> else
<div><span>Program entries:</span> <span><?php echo count(Programs::listAll()); ?></span></div> echo '<div><span>' . $key . '</span> <span>' . nl2br(var_export($value, true)) . '</span></div>' . "\n";
<div><span>Update entries:</span> <span><?php echo count(Programs::listUpdateData()); ?></span></div> }
</div> ?>
</div> </div>
</div>
<!-- - - - - - - - - - - - - - - - - - - - - -->
<div class="boxedcontent">
<div class="bc_header">UpdatesLog</div>
<?php if ($connected): ?>
<div class="bc_data keyvaluelist kvl_300">
<?php foreach (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'] . '] 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>
<hr />
<?php endforeach; ?>
<br/>
<div id="ul_ajax_target"></div>
</div>
<?php else: ?>
<div class="bc_data keyvaluelist">Database not connected.</div>
<?php endif; ?>
</div>
<!-- - - - - - - - - - - - - - - - - - - - - -->
<div class="boxedcontent">
<div class="bc_header">Highscores</div>
<?php if ($connected): ?>
<div class="bc_data keyvaluelist kvl_300">
<?php foreach (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'] . '] Highscore:' ?></span> <span><?php
$hs = Highscores::getOrderedEntriesFromGame($game['ID'], 1)[0];
echo $hs['POINTS'] . ' (' . $hs['PLAYER'] . ') @ ' . $hs['TIMESTAMP'];
?></span></div>
<div><span><?php echo '[' . $game['NAME'] . '] Last Update:' ?></span> <span><?php echo Highscores::getNewestEntriesFromGame($game['ID'], 1)[0]['TIMESTAMP']; ?></span></div>
<hr />
<?php endforeach; ?>
</div>
<?php else: ?>
<div class="bc_data keyvaluelist">Database not connected.</div>
<?php endif; ?>
</div>
<!-- - - - - - - - - - - - - - - - - - - - - -->
<div class="boxedcontent">
<div class="bc_header">Configuration</div>
<div class="bc_data keyvaluelist kvl_200">
<?php
foreach ($CONFIG as $key => $value)
{
if ($key === 'extendedgitgraph') continue;
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";
else
echo '<div><span>' . $key . '</span> <span>' . nl2br(var_export($value, true)) . '</span></div>' . "\n";
}
?>
</div>
</div>
<div class="boxedcontent">
<div class="bc_header">Configuration['extendedgitgraph']</div>
<div class="bc_data keyvaluelist kvl_200">
<?php
foreach ($CONFIG['extendedgitgraph'] as $key => $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";
else
echo '<div><span>' . $key . '</span> <span>' . nl2br(var_export($value, true)) . '</span></div>' . "\n";
}
?>
</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,55 +1,38 @@
<!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>
<div class='bloglistelem_container'> <div class='bloglistelem_container'>
<?php <?php
foreach ($allposts as $post) foreach ($allposts as $post)
{ {
if (!$post['visible']) continue; if (!$post['visible']) continue;
if ($post['cat']=='blog') echo "<a class='bloglistelem ble_blog' href='" . $post['url'] . "'>\n"; if ($post['cat']=='blog') echo "<a class='bloglistelem ble_blog' href='" . $post['url'] . "'>\n";
else if ($post['cat']=='log') echo "<a class='bloglistelem ble_log' href='" . $post['url'] . "'>\n"; else if ($post['cat']=='log') echo "<a class='bloglistelem ble_log' href='" . $post['url'] . "'>\n";
echo "<div class='ble_date'>" . $post['date'] . "</div>\n"; echo "<div class='ble_date'>" . $post['date'] . "</div>\n";
echo "<div class='ble_title'>" . $post['title'] . "</div>\n"; echo "<div class='ble_title'>" . $post['title'] . "</div>\n";
echo "</a>\n"; echo "</a>\n";
} }
?> ?>
</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; }
<div class="contentheader"><h1><?php echo htmlspecialchars($post['title']); ?></h1><hr/></div> $FRAME_OPTIONS->title = $post['title'];
$FRAME_OPTIONS->canonical_url = $post['canonical'];
<?php if ($post['type'] == 'euler')
$FRAME_OPTIONS->activeHeader = 'euler';
else if ($post['type'] == 'euler' && $post['issubview'])
$FRAME_OPTIONS->activeHeader = 'aoc';
else
$FRAME_OPTIONS->activeHeader = 'blog';
?>
if ($post['type'] === 'plain') {
include (__DIR__ . '/../fragments/blogview_plain.php'); <div class="blockcontent">
} elseif ($post['type'] === 'markdown') { <div class="contentheader"><h1><?php echo htmlspecialchars($post['title']); ?></h1><hr/></div>
include (__DIR__ . '/../fragments/blogview_markdown.php'); <?php
} elseif ($post['type'] === 'euler') { if ($post['type'] === 'plain')
{
if ($subview === '') include (__DIR__ . '/../fragments/blogview_euler_list.php'); echo $SITE->fragments->BlogviewPlain($post);
else include (__DIR__ . '/../fragments/blogview_euler_single.php'); }
elseif ($post['type'] === 'markdown')
} elseif ($post['type'] === 'aoc') { {
echo $SITE->fragments->BlogviewMarkdown($post);
if ($subview === '') include (__DIR__ . '/../fragments/blogview_aoc_list.php'); }
else include (__DIR__ . '/../fragments/blogview_aoc_single.php'); elseif ($post['type'] === 'euler')
{
} if ($subview === '') echo $SITE->fragments->BlogviewEulerList($post);
?> else echo $SITE->fragments->BlogviewEulerSingle($post, $subview);
}
</div> elseif ($post['type'] === 'aoc')
{
if ($subview === '') echo $SITE->fragments->BlogviewAdventOfCodeList($post);
else echo $SITE->fragments->BlogviewAdventOfCodeSingle($post, $subview);
}
?>
</div> </div>
<?php include (__DIR__ . '/../fragments/footer.php'); ?>
</div>
<?php printAdditionalScripts(); ?>
<?php printAdditionalStylesheets(); ?>
</body>
</html>

View File

@ -1,64 +1,47 @@
<!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>
<p> <p>
These are some books I read but that do not have an official print version.<br /> These are some books I read but that do not have an official print version.<br />
So I type-setted them myself (mostly in <a href="https://www.lyx.org/">LyX</a>) and printed them <a href="https://www.epubli.de/">online</a>.<br /> So I type-setted them myself (mostly in <a href="https://www.lyx.org/">LyX</a>) and printed them <a href="https://www.epubli.de/">online</a>.<br />
I do <b>not</b> own the rights of any of these books.<br /> I do <b>not</b> own the rights of any of these books.<br />
The LyX files and generated PDF's are public and everyone who wants can print them on his own. The LyX files and generated PDF's are public and everyone who wants can print them on his own.
</p> </p>
<?php <?php
echo '<div class="booklst_parent">' . "\n"; echo '<div class="booklst_parent">' . "\n";
foreach ($allbooks as $book) foreach ($allbooks as $book)
{ {
echo '<a class="booklst_entry" href="'.$book['url'].'">'; echo '<a class="booklst_entry" href="'.$book['url'].'">';
echo ' <div class="booklst_left">'; echo ' <div class="booklst_left">';
echo ' <img src="' . $book['preview_url'] . '" alt="Thumbnail ' . $book['title'] . '" />'; echo ' <img src="' . $book['preview_url'] . '" alt="Thumbnail ' . $book['title'] . '" />';
echo ' </div>'; echo ' </div>';
echo ' <div class="booklst_right">'; echo ' <div class="booklst_right">';
echo ' <div class="booklst_date"><span>' . $book['date'] . '</span></div>'; echo ' <div class="booklst_date"><span>' . $book['date'] . '</span></div>';
echo ' <div class="booklst_title">' . htmlspecialchars($book['title']) . '</div>'; echo ' <div class="booklst_title">' . htmlspecialchars($book['title']) . '</div>';
echo ' </div>'; echo ' </div>';
echo '</a>' . "\n"; echo '</a>' . "\n";
} }
echo '</div>' . "\n"; echo '</div>' . "\n";
?> ?>
</div>
</div>
<?php include (__DIR__ . '/../fragments/footer.php'); ?>
</div> </div>
<?php printAdditionalScripts(); ?>
<?php printAdditionalStylesheets(); ?>
</body>
</html>

View File

@ -1,127 +1,112 @@
<!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';
<div class="bookv_content"> $FRAME_OPTIONS->addScript('/data/javascript/ms_basic.js', true);
?>
<div class="contentheader" id="bookv_header"><h1><?php echo htmlspecialchars($book['title']); ?></h1><hr/></div>
<div class="bookv_top"> <div class="blockcontent">
<div class="bookv_left"><img src="<?php echo $book['imgfull_url']; ?>" alt="<?php echo $book['title'] ?>" /></div>
<div class="bookv_right">
<div class="bookv_right_key" style="grid-row:1">Name:</div>
<div class="bookv_right_value" style="grid-row:1"><?php echo htmlspecialchars($book['title_short']) ?></div>
<div class="bookv_right_key" style="grid-row:2">Pages:</div> <div class="bookv_content">
<div class="bookv_right_value" style="grid-row:2"><?php
if (is_string($book['pages']))
{
echo $book['pages'];
}
else
{
$pagi = 1;
foreach ($book['pages'] as $page)
{
echo 'Buch ' . $pagi . ': ' . $page . '<br/>';
$pagi++;
}
}
?></div>
<div class="bookv_right_key" style="grid-row:3">Author:</div> <div class="contentheader" id="bookv_header"><h1><?php echo htmlspecialchars($book['title']); ?></h1><hr/></div>
<div class="bookv_right_value" style="grid-row:3"><?php echo htmlspecialchars($book['author']) ?></div>
<div class="bookv_right_key" style="grid-row:4">Size:</div> <div class="bookv_top">
<div class="bookv_right_value" style="grid-row:4"><?php echo $book['size'][0] . 'cm x ' . $book['size'][1] . 'cm'; ?></div> <div class="bookv_left"><img src="<?php echo $book['imgfull_url']; ?>" alt="<?php echo $book['title'] ?>" /></div>
<div class="bookv_right">
<div class="bookv_right_key" style="grid-row:1">Name:</div>
<div class="bookv_right_value" style="grid-row:1"><?php echo htmlspecialchars($book['title_short']) ?></div>
<div class="bookv_right_key" style="grid-row:5">Date:</div> <div class="bookv_right_key" style="grid-row:2">Pages:</div>
<div class="bookv_right_value" style="grid-row:5"><?php echo $book['date'] ?></div> <div class="bookv_right_value" style="grid-row:2"><?php
if (is_string($book['pages']))
{
echo $book['pages'];
}
else
{
$pagi = 1;
foreach ($book['pages'] as $page)
{
echo 'Buch ' . $pagi . ': ' . $page . '<br/>';
$pagi++;
}
}
?></div>
<div class="bookv_right_comb" style="grid-row:6"> <div class="bookv_right_key" style="grid-row:3">Author:</div>
<div class="bookv_right_value" style="grid-row:3"><?php echo htmlspecialchars($book['author']) ?></div>
<a class="iconbutton" href="<?php echo $book['repository'] ?>"> <div class="bookv_right_key" style="grid-row:4">Size:</div>
<div class="bookv_right_value" style="grid-row:4"><?php echo $book['size'][0] . 'cm x ' . $book['size'][1] . 'cm'; ?></div>
<div class="bookv_right_key" style="grid-row:5">Date:</div>
<div class="bookv_right_value" style="grid-row:5"><?php echo $book['date'] ?></div>
<div class="bookv_right_comb" style="grid-row:6">
<a class="iconbutton" href="<?php echo $book['repository'] ?>">
<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"/>
</svg>
<span><?php echo $SITE->modules->Books()->getRepositoryHost($book); ?></span>
</a>
<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">
<use xlink:href="/data/images/icons.svg#home"/>
</svg>
<span>Homepage</span>
</a>
<?php if (is_string($book['pdf'])): ?>
<a class="iconbutton" href="<?php echo $book['pdf'] ?>">
<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#pdf"/>
</svg> </svg>
<span><?php echo Books::getRepositoryHost($book); ?></span> <span>PDF</span>
</a> </a>
<a class="iconbutton" href="<?php echo $book['online'] ?>"> <?php else: ?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 24 24"> <?php $pdfi = 1; foreach ($book['pdf'] as $pdf): ?>
<use xlink:href="/data/images/icons.svg#home"/> <a class="iconbutton" href="<?php echo $pdf ?>">
</svg>
<span>Homepage</span>
</a>
<?php if (is_string($book['pdf'])): ?>
<a class="iconbutton" href="<?php echo $book['pdf'] ?>">
<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#pdf"/> <use xlink:href="/data/images/icons.svg#pdf"/>
</svg> </svg>
<span>PDF</span> <span>PDF (Buch <?php echo $pdfi; $pdfi++; ?>)</span>
</a> </a>
<?php else: ?> <?php endforeach; ?>
<?php $pdfi = 1; foreach ($book['pdf'] as $pdf): ?> <?php endif; ?>
<a class="iconbutton" href="<?php echo $pdf ?>">
<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#pdf"/>
</svg>
<span>PDF (Buch <?php echo $pdfi; $pdfi++; ?>)</span>
</a>
<?php endforeach; ?>
<?php endif; ?>
</div>
</div> </div>
</div> </div>
<div class="bookv_extra imgcarousel_parent" data-imgcarousel-index="0" data-imgcarousel-images="<?php echo htmlspecialchars(json_encode($book['extraimages_urls'])); ?>" >
<a class="imgcarousel_prev">
<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#arrow_left"/>
</svg>
</a>
<div class="imgcarousel_content" style="background-image: url(<?php echo $book['extraimages_urls'][0]; ?>);"></div>
<a class="imgcarousel_next">
<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#arrow_right"/>
</svg>
</a>
</div>
</div> </div>
</div>
</div>
<?php include (__DIR__ . '/../fragments/footer.php'); ?> <div class="bookv_extra imgcarousel_parent" data-imgcarousel-index="0" data-imgcarousel-images="<?php echo htmlspecialchars(json_encode($book['extraimages_urls'])); ?>" >
<a class="imgcarousel_prev">
<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#arrow_left"/>
</svg>
</a>
<div class="imgcarousel_content" style="background-image: url(<?php echo $book['extraimages_urls'][0]; ?>);"></div>
<a class="imgcarousel_next">
<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#arrow_right"/>
</svg>
</a>
</div>
</div>
</div> </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"]))
{
$start = intval(htmlspecialchars($_GET["start"])) - 1;
if ($start < 0) $start = 0;
}
if (isset($_GET["highlight"])) $pagesize = 20;
{ $start = 0;
$highlight= intval(htmlspecialchars($_GET["highlight"])); $highlight = 0;
}
$game = Highscores::getGameByID($OPTIONS['gameid']); if (isset($_GET["start"]))
{
$start = intval(htmlspecialchars($_GET["start"])) - 1;
if ($start < 0) $start = 0;
}
$entries = Highscores::getOrderedEntriesFromGame($OPTIONS['gameid']); if (isset($_GET["highlight"]))
{
$highlight= intval(htmlspecialchars($_GET["highlight"]));
}
$game = $SITE->modules->Highscores()->getGameByID($ROUTE->parameter['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)
echo 'ok.'; {
} $SITE->modules->Highscores()->insert($gameid, $points, $name, $nameid, $check, date("Y-m-d H:m:s", time()), $_SERVER['REMOTE_ADDR']);
else echo 'ok.';
{ }
Highscores::update($gameid, $points, $name, $nameid, $check, date("Y-m-d H:m:s", time()), $_SERVER['REMOTE_ADDR']); else
echo 'ok.'; {
} $SITE->modules->Highscores()->update($gameid, $points, $name, $nameid, $check, date("Y-m-d H:m:s", time()), $_SERVER['REMOTE_ADDR']);
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,73 +31,49 @@ 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="boxedcontent">
<div class="bc_header">Mikescher.com - Login</div>
<div class="aboutcontent"> <div class="bc_data">
<div class="boxedcontent"> <div class="form">
<div class="bc_header">Mikescher.com - Login</div> <form id="loginform" action="/login" method="GET">
<div class="bc_data"> <?php if ($err): ?>
<span class="loginerror">Wrong username or password</span>
<?php endif; ?>
<div class="form"> <div>
<form id="loginform" action="/login" method="GET"> <label for="username" class="required">Username</label>
<input name="username" id="username" type="text" autofocus>
</div>
<?php if ($err): ?> <div>
<span class="loginerror">Wrong username or password</span> <label for="password">Password</label>
<?php endif; ?> <input name="password" id="password" type="password">
</div>
<div> <div style="display: none; visibility: hidden">
<label for="username" class="required">Username</label> <label for="redirect">Redirect</label>
<input name="username" id="username" type="text" autofocus > <input name="redirect" id="redirect" type="text" value="<?php echo $redirect ?>">
</div> </div>
<div> <div>
<label for="password">Password</label> <button class="button" type="submit" name="yt0">Login</button>
<input name="password" id="password" type="password"> </div>
</div>
<div style="display: none; visibility: hidden"> </form>
<label for="redirect">Redirect</label> </div>
<input name="redirect" id="redirect" type="text" value="<?php echo $redirect ?>">
</div>
<div> </div>
<button class="button" type="submit" name="yt0">Login</button>
</div>
</form> </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