Merge branch 'feature-Baseclass'
This commit is contained in:
commit
9c8e61b203
4
.gitignore
vendored
4
.gitignore
vendored
@ -6,3 +6,7 @@ runtime/
|
|||||||
**/.idea/tasks.xml
|
**/.idea/tasks.xml
|
||||||
|
|
||||||
**/.idea/dataSources*
|
**/.idea/dataSources*
|
||||||
|
|
||||||
|
config.php
|
||||||
|
|
||||||
|
www/dtest.php
|
8
.idea/inspectionProfiles/Project_Default.xml
generated
8
.idea/inspectionProfiles/Project_Default.xml
generated
@ -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
6
.idea/jsLibraryMappings.xml
generated
Normal 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>
|
2
.idea/watcherTasks.xml
generated
2
.idea/watcherTasks.xml
generated
@ -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" />
|
||||||
|
1
.idea/www.mikescher.de.iml
generated
1
.idea/www.mikescher.de.iml
generated
@ -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>
|
@ -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.')
|
||||||
|
@ -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>
|
||||||
|
@ -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],
|
||||||
|
@ -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 "{}";
|
@ -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();
|
|
||||||
|
|
||||||
|
@ -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();
|
|
||||||
|
|
||||||
|
@ -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] = '';
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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']);
|
||||||
|
@ -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";
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
@ -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";
|
||||||
|
|
||||||
|
@ -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";
|
||||||
|
|
||||||
|
14
www/commands/site_selftest.php
Normal file
14
www/commands/site_selftest.php
Normal 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);
|
@ -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>
|
||||||
|
@ -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;
|
||||||
|
20
www/data/css/styles.min.css
vendored
20
www/data/css/styles.min.css
vendored
@ -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}
|
||||||
|
@ -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 ====
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------ ------------------------------------
|
// ------------------------------------ ------------------------------------
|
||||||
|
@ -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; }
|
||||||
|
@ -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);
|
||||||
|
});
|
204
www/extern/Parsedown.php
vendored
204
www/extern/Parsedown.php
vendored
@ -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('&', '<'), $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('&', '<'), $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]))
|
||||||
|
18
www/extern/ParsedownExtra.php
vendored
18
www/extern/ParsedownExtra.php
vendored
@ -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",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
8
www/extern/egg/EGGDatabase.php
vendored
8
www/extern/egg/EGGDatabase.php
vendored
@ -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)
|
||||||
|
9
www/extern/egg/RemoteSource.php
vendored
9
www/extern/egg/RemoteSource.php
vendored
@ -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);
|
||||||
|
@ -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>
|
@ -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++)
|
||||||
|
@ -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">
|
||||||
|
@ -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">
|
||||||
|
@ -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>
|
@ -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>
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
||||||
|
|
||||||
|
@ -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" ><</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" ><</a>';
|
||||||
else
|
else
|
||||||
echo '<a href="' . AdventOfCode::getURLForYear($prev_year) . '" class="aoc_calendar_header_link aoc_prev" ><</a>';
|
echo '<a href="' . $SITE->modules->AdventOfCode()->getURLForYear($prev_year) . '" class="aoc_calendar_header_link aoc_prev" ><</a>';
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
echo '<a href="#" class="aoc_calendar_header_link aoc_prev aoc_link_hidden" ><</a>';
|
echo '<a href="#" class="aoc_calendar_header_link aoc_prev aoc_link_hidden" ><</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" >></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" >></a>';
|
||||||
else
|
else
|
||||||
echo '<a href="' . AdventOfCode::getURLForYear($next_year) . '" class="aoc_calendar_header_link aoc_next" >></a>';
|
echo '<a href="' . $SITE->modules->AdventOfCode()->getURLForYear($next_year) . '" class="aoc_calendar_header_link aoc_next" >></a>';
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -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">
|
||||||
|
@ -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">
|
||||||
|
@ -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;
|
||||||
|
@ -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">
|
||||||
|
@ -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;
|
@ -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
9
www/frames/api_frame.php
Normal 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);
|
69
www/frames/default_frame.php
Normal file
69
www/frames/default_frame.php
Normal 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>
|
52
www/frames/error_frame.php
Normal file
52
www/frames/error_frame.php
Normal 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>
|
9
www/frames/nocontent_frame.php
Normal file
9
www/frames/nocontent_frame.php
Normal 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
|
262
www/index.php
262
www/index.php
@ -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
|
||||||
|
1
www/internals/.gitignore
vendored
1
www/internals/.gitignore
vendored
@ -1 +0,0 @@
|
|||||||
config.php
|
|
@ -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');
|
|
||||||
}
|
|
||||||
}
|
|
@ -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");
|
|
||||||
}
|
|
@ -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
132
www/internals/fragments.php
Normal 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,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
@ -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 ],
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
6
www/internals/iwebsitemodule.php
Normal file
6
www/internals/iwebsitemodule.php
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
interface IWebsiteModule
|
||||||
|
{
|
||||||
|
public function checkConsistency();
|
||||||
|
}
|
@ -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
99
www/internals/modules.php
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
@ -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 = [];
|
37
www/internals/modules/alephnoteStatistics.php
Normal file
37
www/internals/modules/alephnoteStatistics.php
Normal 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' => ''];
|
||||||
|
}
|
||||||
|
}
|
@ -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'];
|
@ -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://"));
|
99
www/internals/modules/database.php
Normal file
99
www/internals/modules/database.php
Normal 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' => ''];
|
||||||
|
}
|
||||||
|
}
|
@ -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'];
|
113
www/internals/modules/highscores.php
Normal file
113
www/internals/modules/highscores.php
Normal 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' => ''];
|
||||||
|
}
|
||||||
|
}
|
51
www/internals/modules/mikeschergitgraph.php
Normal file
51
www/internals/modules/mikeschergitgraph.php
Normal 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' => ''];
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
644
www/internals/modules/selftest.php
Normal file
644
www/internals/modules/selftest.php
Normal 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' => ''];
|
||||||
|
}
|
||||||
|
}
|
80
www/internals/modules/updateslog.php
Normal file
80
www/internals/modules/updateslog.php
Normal 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' => ''];
|
||||||
|
}
|
||||||
|
}
|
49
www/internals/modules/webapps.php
Normal file
49
www/internals/modules/webapps.php
Normal 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' => ''];
|
||||||
|
}
|
||||||
|
}
|
86
www/internals/pageframeoptions.php
Normal file
86
www/internals/pageframeoptions.php
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
@ -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)
|
113
www/internals/ruleengine.php
Normal file
113
www/internals/ruleengine.php
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
@ -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
112
www/internals/urlroute.php
Normal 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
287
www/internals/utils.php
Normal 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 ];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -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
216
www/internals/website.php
Normal 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);
|
||||||
|
}
|
@ -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>
|
|
@ -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']; ?>"> </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>
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
24
www/pages/error_notfound.php
Normal file
24
www/pages/error_notfound.php
Normal 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>
|
26
www/pages/error_servererror.php
Normal file
26
www/pages/error_servererror.php
Normal 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>
|
@ -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>
|
|
@ -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.';
|
@ -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">
|
||||||
|
@ -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>
|
||||||
|
@ -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;
|
@ -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++)
|
||||||
{
|
{
|
||||||
|
@ -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.';
|
||||||
|
}
|
||||||
|
@ -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>
|
|
@ -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
Loading…
Reference in New Issue
Block a user