Compare commits
No commits in common. '2.0' and '1.0' have entirely different histories.
@ -1,12 +0,0 @@
|
|||||||
# This file is for unifying the coding style for different editors and IDEs
|
|
||||||
# editorconfig.org
|
|
||||||
|
|
||||||
root = true
|
|
||||||
|
|
||||||
[*]
|
|
||||||
charset = utf-8
|
|
||||||
end_of_line = lf
|
|
||||||
insert_final_newline = true
|
|
||||||
trim_trailing_whitespace = true
|
|
||||||
indent_style = space
|
|
||||||
indent_size = 4
|
|
@ -0,0 +1,17 @@
|
|||||||
|
# Auto detect text files and perform LF normalization
|
||||||
|
* text=auto
|
||||||
|
|
||||||
|
# Custom for Visual Studio
|
||||||
|
*.cs diff=csharp
|
||||||
|
|
||||||
|
# Standard to msysgit
|
||||||
|
*.doc diff=astextplain
|
||||||
|
*.DOC diff=astextplain
|
||||||
|
*.docx diff=astextplain
|
||||||
|
*.DOCX diff=astextplain
|
||||||
|
*.dot diff=astextplain
|
||||||
|
*.DOT diff=astextplain
|
||||||
|
*.pdf diff=astextplain
|
||||||
|
*.PDF diff=astextplain
|
||||||
|
*.rtf diff=astextplain
|
||||||
|
*.RTF diff=astextplain
|
@ -0,0 +1,39 @@
|
|||||||
|
# (c) 2015 - 2018 Wruczek <wruczekk@gmail.com> and contributors
|
||||||
|
|
||||||
|
AddDefaultCharset UTF-8
|
||||||
|
|
||||||
|
# DISABLE DIRECTORY LISTING
|
||||||
|
Options -Indexes
|
||||||
|
|
||||||
|
SetEnv HTACCESS on
|
||||||
|
|
||||||
|
ErrorDocument 403 "<!DOCTYPE html><html lang=\"en\"><head> <meta charset=\"utf-8\"> <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"> <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"> <meta name=\"author\" content=\"Wruczek\"> <title>403 - Forbidden</title> <link rel=\"shortcut icon\" href=\"img/icon/icon-64.png\" style=\"-webkit-box-sizing: border-box;-moz-box-sizing: border-box;box-sizing: border-box;\"></head><body style=\"-webkit-box-sizing: border-box;-moz-box-sizing: border-box;box-sizing: border-box;margin: 0;font-family: "Lato","Helvetica Neue",Helvetica,Arial,sans-serif;font-size: 15px;line-height: 1.42857143;color: #ebebeb;background-color: #2b3e50;\"> <div class=\"container\" style=\"-webkit-box-sizing: border-box;-moz-box-sizing: border-box;box-sizing: border-box;margin-right: auto;margin-left: auto;padding-left: 15px;padding-right: 15px;display: table;position: absolute;height: 100%;width: 100%;\"> <div class=\"text-center\" style=\"-webkit-box-sizing: border-box;-moz-box-sizing: border-box;box-sizing: border-box;text-align: center;display: table-cell;vertical-align: middle;\"> <h1 style=\"-webkit-box-sizing: border-box;-moz-box-sizing: border-box;box-sizing: border-box;font-size: 39px;margin: 0.67em 0;font-family: inherit;font-weight: 400;line-height: 1.1;color: inherit;margin-top: 21px;margin-bottom: 10.5px;\">403 <span style=\"font-size: 32px;color: #9E9E9E;-webkit-box-sizing: border-box;-moz-box-sizing: border-box;box-sizing: border-box;\">Forbidden</span></h1> <h3 style=\"-webkit-box-sizing: border-box;-moz-box-sizing: border-box;box-sizing: border-box;orphans: 3;widows: 3;page-break-after: avoid;font-family: inherit;font-weight: 400;line-height: 1.1;color: inherit;margin-top: 21px;margin-bottom: 10.5px;font-size: 26px;\">Access to this page is forbidden.</h3> <br style=\"-webkit-box-sizing: border-box;-moz-box-sizing: border-box;box-sizing: border-box;\"> <a href=\".\" class=\"btn btn-primary btn-lg\" style=\"-webkit-box-sizing: border-box;-moz-box-sizing: border-box;box-sizing: border-box;background-color: #df691a;color: #ffffff;text-decoration: none;display: inline-block;margin-bottom: 0;font-weight: normal;text-align: center;vertical-align: middle;-ms-touch-action: manipulation;touch-action: manipulation;cursor: pointer;background-image: none;border: 1px solid transparent;white-space: nowrap;padding: 12px 24px;font-size: 19px;line-height: 1.3333333;border-radius: 0;-webkit-user-select: none;-moz-user-select: none;-ms-user-select: none;user-select: none;border-color: transparent;\">← Go back</a> </div></div></body></html>"
|
||||||
|
|
||||||
|
ErrorDocument 404 "<!DOCTYPE html><html lang=\"en\"><head> <meta charset=\"utf-8\"> <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"> <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"> <meta name=\"author\" content=\"Wruczek\"> <title>404 - Not found</title> <link rel=\"shortcut icon\" href=\"img/icon/icon-64.png\"></head><body style=\"-webkit-box-sizing: border-box;-moz-box-sizing: border-box;box-sizing: border-box;margin: 0;font-family: "Lato","Helvetica Neue",Helvetica,Arial,sans-serif;font-size: 15px;line-height: 1.42857143;color: #ebebeb;background-color: #2b3e50;\"> <div class=\"container\" style=\"-webkit-box-sizing: border-box;-moz-box-sizing: border-box;box-sizing: border-box;margin-right: auto;margin-left: auto;padding-left: 15px;padding-right: 15px;display: table;position: absolute;height: 100%;width: 100%;\"> <div class=\"text-center\" style=\"-webkit-box-sizing: border-box;-moz-box-sizing: border-box;box-sizing: border-box;text-align: center;display: table-cell;vertical-align: middle;\"> <h1 style=\"-webkit-box-sizing: border-box;-moz-box-sizing: border-box;box-sizing: border-box;font-size: 39px;margin: 0.67em 0;font-family: inherit;font-weight: 400;line-height: 1.1;color: inherit;margin-top: 21px;margin-bottom: 10.5px;\">404 <span style=\"font-size: 32px;color: #9E9E9E;-webkit-box-sizing: border-box;-moz-box-sizing: border-box;box-sizing: border-box;\">page not found</span></h1> <h3 style=\"-webkit-box-sizing: border-box;-moz-box-sizing: border-box;box-sizing: border-box;orphans: 3;widows: 3;page-break-after: avoid;font-family: inherit;font-weight: 400;line-height: 1.1;color: inherit;margin-top: 21px;margin-bottom: 10.5px;font-size: 26px;\">We couldn't find what you were looking for.</h3> <br style=\"-webkit-box-sizing: border-box;-moz-box-sizing: border-box;box-sizing: border-box;\"> <a href=\".\" class=\"btn btn-primary btn-lg\" style=\"-webkit-box-sizing: border-box;-moz-box-sizing: border-box;box-sizing: border-box;background-color: #df691a;color: #ffffff;text-decoration: none;display: inline-block;margin-bottom: 0;font-weight: normal;text-align: center;vertical-align: middle;-ms-touch-action: manipulation;touch-action: manipulation;cursor: pointer;background-image: none;border: 1px solid transparent;white-space: nowrap;padding: 12px 24px;font-size: 19px;line-height: 1.3333333;border-radius: 0;-webkit-user-select: none;-moz-user-select: none;-ms-user-select: none;user-select: none;border-color: transparent;\">← Go back</a> </div></div></body></html>"
|
||||||
|
|
||||||
|
ErrorDocument 500 "<!DOCTYPE html><html lang=\"en\"><head> <meta charset=\"utf-8\"> <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"> <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"> <meta name=\"author\" content=\"Wruczek\"> <title>500 - server error</title> <link rel=\"shortcut icon\" href=\"img/icon/icon-64.png\"></head><body style=\"-webkit-box-sizing: border-box;-moz-box-sizing: border-box;box-sizing: border-box;margin: 0;font-family: "Lato","Helvetica Neue",Helvetica,Arial,sans-serif;font-size: 15px;line-height: 1.42857143;color: #ebebeb;background-color: #2b3e50;\"> <div class=\"container\" style=\"-webkit-box-sizing: border-box;-moz-box-sizing: border-box;box-sizing: border-box;margin-right: auto;margin-left: auto;padding-left: 15px;padding-right: 15px;display: table;position: absolute;height: 100%;width: 100%;\"> <div class=\"text-center\" style=\"-webkit-box-sizing: border-box;-moz-box-sizing: border-box;box-sizing: border-box;text-align: center;display: table-cell;vertical-align: middle;\"> <h1 style=\"-webkit-box-sizing: border-box;-moz-box-sizing: border-box;box-sizing: border-box;font-size: 39px;margin: 0.67em 0;font-family: inherit;font-weight: 400;line-height: 1.1;color: inherit;margin-top: 21px;margin-bottom: 10.5px;\">500 <span style=\"font-size: 32px;color: #9E9E9E;-webkit-box-sizing: border-box;-moz-box-sizing: border-box;box-sizing: border-box;\">server error</span></h1> <h3 style=\"-webkit-box-sizing: border-box;-moz-box-sizing: border-box;box-sizing: border-box;orphans: 3;widows: 3;page-break-after: avoid;font-family: inherit;font-weight: 400;line-height: 1.1;color: inherit;margin-top: 21px;margin-bottom: 10.5px;font-size: 26px;\">Something went wrong. Try again later.</h3> <br style=\"-webkit-box-sizing: border-box;-moz-box-sizing: border-box;box-sizing: border-box;\"> <a href=\".\" class=\"btn btn-primary btn-lg\" style=\"-webkit-box-sizing: border-box;-moz-box-sizing: border-box;box-sizing: border-box;background-color: #df691a;color: #ffffff;text-decoration: none;display: inline-block;margin-bottom: 0;font-weight: normal;text-align: center;vertical-align: middle;-ms-touch-action: manipulation;touch-action: manipulation;cursor: pointer;background-image: none;border: 1px solid transparent;white-space: nowrap;padding: 12px 24px;font-size: 19px;line-height: 1.3333333;border-radius: 0;-webkit-user-select: none;-moz-user-select: none;-ms-user-select: none;user-select: none;border-color: transparent;\">← Go back</a> </div></div></body></html>"
|
||||||
|
|
||||||
|
|
||||||
|
<IfModule mod_rewrite.c>
|
||||||
|
|
||||||
|
#RewriteEngine On
|
||||||
|
|
||||||
|
# PAGES WITHOUT .PHP AT THE END
|
||||||
|
RewriteCond %{REQUEST_FILENAME} !-d
|
||||||
|
RewriteCond %{REQUEST_FILENAME}\.php -f
|
||||||
|
RewriteRule ^(.*)$ $1.php
|
||||||
|
|
||||||
|
# PAGES WITHOUT .HTML AT THE END
|
||||||
|
RewriteCond %{REQUEST_FILENAME} !-d
|
||||||
|
RewriteCond %{REQUEST_FILENAME}\.html -f
|
||||||
|
RewriteRule ^(.*)$ $1.html
|
||||||
|
|
||||||
|
</IfModule>
|
||||||
|
|
||||||
|
# Enable GZIP
|
||||||
|
<ifmodule mod_deflate.c>
|
||||||
|
AddOutputFilterByType DEFLATE text/text text/html text/plain text/xml text/css application/x-javascript application/javascript
|
||||||
|
BrowserMatch ^Mozilla/4 gzip-only-text/html
|
||||||
|
BrowserMatch ^Mozilla/4\.0[678] no-gzip
|
||||||
|
BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
|
||||||
|
</ifmodule>
|
@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"strict": true,
|
|
||||||
"browser": true,
|
|
||||||
"jquery": true,
|
|
||||||
"asi": true
|
|
||||||
}
|
|
@ -0,0 +1,21 @@
|
|||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2016 - 2018 Wruczek <wruczekk@gmail.com> and contributors
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
@ -0,0 +1,5 @@
|
|||||||
|
<?php
|
||||||
|
header('Content-Type:application/javascript');
|
||||||
|
require_once __DIR__ . "/../include/language.php";
|
||||||
|
?>
|
||||||
|
var textShowMore = "<?php json_encode(tl($lang["index"]["showmore"])); ?>", textShowLess = "<?php json_encode(tl($lang["index"]["showless"])); ?>", statusOnline = "<?php json_encode(tl($lang["serverstatus"]["online"])); ?>", statusOffline = "<?php json_encode(tl($lang["serverstatus"]["offline"])); ?>", statusUptime = "<?php json_encode(tl($lang["serverstatus"]["uptime"])); ?>", statusVersion = "<?php json_encode(tl($lang["serverstatus"]["version"])); ?>", statusAvgping = "<?php json_encode(tl($lang["serverstatus"]["avgping"])); ?>", statusAvgpl = "<?php json_encode(tl($lang["serverstatus"]["avgpl"])); ?>";
|
@ -0,0 +1,76 @@
|
|||||||
|
<?php
|
||||||
|
// error_reporting(0);
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
set_error_handler("exception_error_handler", E_ALL);
|
||||||
|
|
||||||
|
require_once __DIR__ . "/../include/tsutils.php";
|
||||||
|
require_once __DIR__ . "/../include/cacheutils.class.php";
|
||||||
|
|
||||||
|
date_default_timezone_set($config["general"]["timezone"]);
|
||||||
|
|
||||||
|
$cacheutils = new CacheUtils('serverstatus');
|
||||||
|
|
||||||
|
if($cacheutils->isExpired()) {
|
||||||
|
$cacheutils->setValue(getResult(), 60);
|
||||||
|
}
|
||||||
|
|
||||||
|
die ($cacheutils->getValue());
|
||||||
|
|
||||||
|
// *********
|
||||||
|
// METHODS
|
||||||
|
// *********
|
||||||
|
|
||||||
|
function getResult() {
|
||||||
|
try {
|
||||||
|
$start = microtime(true);
|
||||||
|
|
||||||
|
$tsstatus = getTeamspeakServerStatus();
|
||||||
|
|
||||||
|
$stop = microtime(true);
|
||||||
|
|
||||||
|
return json_encode(array(
|
||||||
|
"tsstatus" => $tsstatus,
|
||||||
|
"generated" => date('d-m-Y H:i:s')
|
||||||
|
));
|
||||||
|
} catch (Exception $e) {
|
||||||
|
scriptFail($e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function scriptFail($error) {
|
||||||
|
die(json_encode(array(
|
||||||
|
"success" => false,
|
||||||
|
"id" => "script_error",
|
||||||
|
"message" => "There has been an error while retrieving the server status",
|
||||||
|
"error" => $error
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
|
||||||
|
function exception_error_handler($errno, $errstr, $errfile, $errline) {
|
||||||
|
scriptFail("[$errfile @ $errline] " . $errstr);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTeamspeakServerStatus() {
|
||||||
|
|
||||||
|
$response = pingTeamspeakServerFromConfig();
|
||||||
|
|
||||||
|
if ($response) {
|
||||||
|
return array(
|
||||||
|
"success" => $response["virtualserver_status"]->toString() == "online",
|
||||||
|
"name" => $response["virtualserver_name"]->toString(),
|
||||||
|
"clientsonline" => $response["virtualserver_clientsonline"] - $response["virtualserver_queryclientsonline"],
|
||||||
|
"maxclients" => $response["virtualserver_maxclients"],
|
||||||
|
"version" => TeamSpeak3_Helper_Convert::versionShort($response["virtualserver_version"]->toString())->toString(),
|
||||||
|
"platform" => $response["virtualserver_platform"]->toString(),
|
||||||
|
"uptime" => TeamSpeak3_Helper_Convert::seconds($response["virtualserver_uptime"], false, "%dd %02dh %02dm"),
|
||||||
|
"averagePacketloss" => $response["virtualserver_total_packetloss_total"]->toString(),
|
||||||
|
"averagePing" => $response["virtualserver_total_ping"]->toString()
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return array(
|
||||||
|
"success" => false,
|
||||||
|
"id" => "not_responding",
|
||||||
|
"message" => "Server is not responding"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,111 @@
|
|||||||
|
<?php
|
||||||
|
$bansPage = true;
|
||||||
|
require_once __DIR__ . "/include/header.php";
|
||||||
|
require_once __DIR__ . "/include/tsutils.php";
|
||||||
|
require_once __DIR__ . "/include/cacheutils.class.php";
|
||||||
|
|
||||||
|
$cacheutils = new CacheUtils('banlist');
|
||||||
|
|
||||||
|
if($cacheutils->isExpired()) {
|
||||||
|
$cacheutils->setValue([getBanlist(), date('d.m.Y H:i:s')], 300);
|
||||||
|
}
|
||||||
|
|
||||||
|
$banlist = $cacheutils->getValue();
|
||||||
|
?>
|
||||||
|
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<h3 class="panel-title"><i class="fa fa-ban" aria-hidden="true"></i> <?php tl($lang["banlist"]["title"]); ?></h3>
|
||||||
|
</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
|
||||||
|
<?php if(empty($banlist[0])) { ?>
|
||||||
|
<div class="alert alert-success">
|
||||||
|
<p class="text-center"><?php tl($lang["banlist"]["emptylist"]); ?></p>
|
||||||
|
</div>
|
||||||
|
<?php } else { ?>
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table id="banlist" class="table table-striped table-bordered" cellspacing="0" width="100%">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th><?php tl($lang["banlist"]["table"]["nickname"]); ?></th>
|
||||||
|
<th><?php tl($lang["banlist"]["table"]["reason"]); ?></th>
|
||||||
|
<th><?php tl($lang["banlist"]["table"]["bannedby"]); ?></th>
|
||||||
|
<th><?php tl($lang["banlist"]["table"]["bandate"]); ?></th>
|
||||||
|
<th><?php tl($lang["banlist"]["table"]["expires"]); ?></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<?php echo $banlist[0]; ?>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<?php } ?>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="panel-footer">
|
||||||
|
<?php tl($lang["banlist"]["lastupdate"], [$banlist[1]]); ?><!-- <span style="float: right">Data is refreshed every X seconds</span> -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
|
||||||
|
function getBanlist() {
|
||||||
|
global $lang;
|
||||||
|
|
||||||
|
try {
|
||||||
|
$tsAdmin = getTeamspeakConnection("#no_query_clients");
|
||||||
|
|
||||||
|
$bans = $tsAdmin->banList();
|
||||||
|
|
||||||
|
$output = "";
|
||||||
|
|
||||||
|
foreach ($bans as $ban) {
|
||||||
|
|
||||||
|
$user = null;
|
||||||
|
|
||||||
|
if (!empty($ban['ip']))
|
||||||
|
$user = censorIP((string)$ban['ip']);
|
||||||
|
|
||||||
|
if (!empty($ban['lastnickname']))
|
||||||
|
$user = htmlspecialchars((string)$ban['lastnickname']);
|
||||||
|
|
||||||
|
if (empty($user))
|
||||||
|
$user = "<i>Unknown</i>";
|
||||||
|
|
||||||
|
|
||||||
|
$reason = htmlspecialchars((string)$ban['reason']);
|
||||||
|
$invokername = htmlspecialchars((string)$ban['invokername']);
|
||||||
|
$duration = $ban['duration'];
|
||||||
|
$createdepoch = $ban['created'];
|
||||||
|
$expiresepoch = $ban['created'] + $duration;
|
||||||
|
$created = date('d-m-Y H:i:s', $createdepoch);
|
||||||
|
|
||||||
|
if (empty($reason))
|
||||||
|
$reason = "<b>" . translate($lang["banlist"]["table"]["emptyreason"]) . "</b>";
|
||||||
|
|
||||||
|
if ($duration == 0)
|
||||||
|
$expires = translate($lang["banlist"]["table"]["permaban"]);
|
||||||
|
else
|
||||||
|
$expires = date('d.m.Y H:i:s', $expiresepoch);
|
||||||
|
|
||||||
|
$output .= "<tr><td>$user</td><td>$reason</td><td>$invokername</td><td data-order=\"$createdepoch\">$created</td><td data-order=\"$expiresepoch\">$expires</td></tr>";
|
||||||
|
}
|
||||||
|
|
||||||
|
return $output;
|
||||||
|
} catch (TeamSpeak3_Exception $e) {
|
||||||
|
if ($e->getCode() == 1281) {
|
||||||
|
return '';
|
||||||
|
} else {
|
||||||
|
return '<div class="alert alert-danger"><p class="text-center">' . translate($lang["general"]["scripterror"], [$e->getCode(), $e->getMessage()]) . '</p></div>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function censorIP($ip) {
|
||||||
|
return preg_replace("/(\d+\.\d+\.)\d+\.\d+/", "$1***.***", $ip);
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once __DIR__ . "/include/footer.php";
|
||||||
|
?>
|
@ -0,0 +1,3 @@
|
|||||||
|
order deny,allow
|
||||||
|
deny from all
|
||||||
|
allow from 127.0.0.1
|
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"require" : {
|
||||||
|
"php" : "^5.5",
|
||||||
|
"ext-mbstring": "*"
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,77 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
Author: Wruczek
|
||||||
|
Donate: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=9PL5J7ULZQYJQ
|
||||||
|
|
||||||
|
I am happy to take any programming-related requests, add additional features or modify the code to suit your needs for a small donation :)
|
||||||
|
I am experienced at Java, PHP, HTML, CSS, Javascript, SQL, server configurations ect.
|
||||||
|
For business enquiries only: wruczekk at gmail.com, for anything else please join Telegram chat.
|
||||||
|
|
||||||
|
|
||||||
|
Need help? Join our telegram group for news, announcements, help and general chat about ts-website: https://t.me/tswebsite
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/************* General configuration *************/
|
||||||
|
|
||||||
|
$config["general"]["title"] = "BestTS.NET"; // Website title - displayed in the menu
|
||||||
|
$config["general"]["icon"] = "img/icon/icon-32.png"; // Website icon
|
||||||
|
$config["general"]["subtitle"] = " - Best TeamSpeak server!"; // Website subtitle
|
||||||
|
$config["general"]["desc"] = "Polski serwer TeamSpeak! Zapraszamy :)"; // Website description - displayed in Google search engine
|
||||||
|
$config["general"]["newsDir"] = "config/news"; // News folder (relative to project folder)
|
||||||
|
$config["general"]["timezone"] = "Europe/Warsaw"; // Your timezone - http://php.net/manual/en/timezones.php
|
||||||
|
$config["general"]["christmasmode"] = true; // Set to false to permanently disable christmas mode activated in December
|
||||||
|
|
||||||
|
$config["general"]["enablehta"] = false; // Enable / Disable additional website features (recommended, but
|
||||||
|
// you need to have up-to-date version of Apache and install mod_rewrite)
|
||||||
|
// After setting to true, go into .htaccess file and uncomment 19 line
|
||||||
|
|
||||||
|
|
||||||
|
/********* TeamSpeak configuration *********/
|
||||||
|
|
||||||
|
$config['teamspeak']['host'] = '127.0.0.1'; // TeamSpeak host address
|
||||||
|
$config['teamspeak']['login'] = 'serveradmin'; // Login
|
||||||
|
$config['teamspeak']['password'] = 'pa$$word'; // Password
|
||||||
|
$config['teamspeak']['server_port'] = 9987; // TeamSpeak server port
|
||||||
|
$config['teamspeak']['query_port'] = 10011; // Query port
|
||||||
|
$config['teamspeak']['displayip'] = 'ts.server.net'; // IP shown to users and used for connections
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/************* Additional navigation links - you can link to your stuff *************/
|
||||||
|
|
||||||
|
// TEMPLATE: (ICON is an icon name from: http://fontawesome.io/icons/)
|
||||||
|
// $config["navlinks"][] = ["icon", "displayed text", "link"];
|
||||||
|
|
||||||
|
$config["navlinks"][] = ["fa-facebook-official", "Facebook", "https://facebook.com/Facebook"];
|
||||||
|
$config["navlinks"][] = ["fa-twitter-square", "Twitter", "https://twitter.com/Twitter"];
|
||||||
|
$config["navlinks"][] = ["fa-comments", "Forum", "forum"];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/************* Adminlist configuration *************/
|
||||||
|
|
||||||
|
// ID of servergroups displayed as admins in Adminlist. Put it in the same way you want it to be displayed.
|
||||||
|
$config["adminlist"] = [6, 17, 19];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/************* Contact panel configuration *************/
|
||||||
|
|
||||||
|
$config['contact']['title'] = 'Contact the staff';
|
||||||
|
|
||||||
|
/*
|
||||||
|
TIP: You can remove all items below to hide contact panel
|
||||||
|
|
||||||
|
CONTACT PANEL SYNTAX:
|
||||||
|
$config['contact']['items'][] = ["name", "link description", "link"];
|
||||||
|
|
||||||
|
FOR EXAMPLE:
|
||||||
|
$config['contact']['items'][] = ["Telegram", "@Wruczek", "https://t.me/Wruczek"];
|
||||||
|
*/
|
||||||
|
|
||||||
|
$config['contact']['items'][] = ["TeamSpeak", "Support channel", "ts3server://teamspeakip?cid=30"];
|
||||||
|
$config['contact']['items'][] = ["Email", "contact@email.com", "mailto:contact@email.com"];
|
||||||
|
$config['contact']['items'][] = ["Telegram", "@Telegram", "https://t.me/Telegram"];
|
||||||
|
$config['contact']['items'][] = ["Twitter", "@Twitter", "https://twitter.com/Twitter"];
|
@ -0,0 +1,105 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* Tradução para PT-BR para tsweb.
|
||||||
|
* @copy Michel Lago <michel_physalis@hotmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
$lang = array();
|
||||||
|
|
||||||
|
/************* General *************/
|
||||||
|
|
||||||
|
$lang["general"]["langcode"] = "br_GB";
|
||||||
|
$lang["general"]["languageflag"] = "br";
|
||||||
|
$lang["general"]["scripterror"] = "Erro Ocorrido! {0}: {1}";
|
||||||
|
|
||||||
|
/************* Menu *************/
|
||||||
|
|
||||||
|
$lang["navbar"]["navigation"] = "Navegação";
|
||||||
|
|
||||||
|
$lang["navbar"]["viewer"] = "Ver Servidor";
|
||||||
|
$lang["navbar"]["bans"] = "Lista de Ban";
|
||||||
|
$lang["navbar"]["rules"] = "Regras do Servidor";
|
||||||
|
$lang["navbar"]["menu"] = "Menu";
|
||||||
|
|
||||||
|
$lang["navbar"]["connect"] = "Conectar ao Servidor";
|
||||||
|
$lang["navbar"]["connecttooltip"] = "Click para se conectar {0}";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Rodapé *************/
|
||||||
|
|
||||||
|
$lang["footer"]["css"] = "CSS por";
|
||||||
|
$lang["footer"]["background"] = "background";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Status do Servidor *************/
|
||||||
|
|
||||||
|
$lang["serverstatus"]["title"] = "Status do Servidor";
|
||||||
|
$lang["serverstatus"]["address"] = "Endereço";
|
||||||
|
$lang["serverstatus"]["loading"] = "Carregando...";
|
||||||
|
|
||||||
|
$lang["serverstatus"]["online"] = "Online";
|
||||||
|
$lang["serverstatus"]["offline"] = "Offline";
|
||||||
|
$lang["serverstatus"]["uptime"] = "Uptime";
|
||||||
|
$lang["serverstatus"]["version"] = "Versão";
|
||||||
|
$lang["serverstatus"]["avgping"] = "Ping";
|
||||||
|
$lang["serverstatus"]["avgpl"] = "Perda de pacotes";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Lista de Admins *************/
|
||||||
|
|
||||||
|
$lang["adminlist"]["title"] = "Lista de Admin's";
|
||||||
|
$lang["adminlist"]["emptygroup"] = "Este grupo esta vazio";
|
||||||
|
$lang["adminlist"]["status"]["online"] = "Online";
|
||||||
|
$lang["adminlist"]["status"]["away"] = "Away";
|
||||||
|
$lang["adminlist"]["status"]["offline"] = "Offline";
|
||||||
|
$lang["adminlist"]["lastupdate"] = "Ultima atualização: {0}";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Server viewer ( embaixo da lista de adm e ebaixo da aba contato) *************/
|
||||||
|
|
||||||
|
$lang["svpb"]["title"] = "Servidor Online";
|
||||||
|
$lang["svpb"]["takealook"] = "Dê uma olhada »";
|
||||||
|
|
||||||
|
|
||||||
|
/************************************/
|
||||||
|
/************* SUB-PAGINAS **********/
|
||||||
|
/************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/************* Noticias - index.php *************/
|
||||||
|
|
||||||
|
$lang["index"]["title"] = "Noticias";
|
||||||
|
$lang["index"]["showmore"] = "Ler Mais";
|
||||||
|
$lang["index"]["showless"] = "Mostrar Menos";
|
||||||
|
|
||||||
|
$lang["index"]["errortitle"] = "Error: Diretório de Noticias não encontrado!";
|
||||||
|
$lang["index"]["errorsubtitle"] = "Porfavor tenha a certeza que o arquivo no diretório <b><code>config/config.php</code></b> está valido.";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Server viewer - viewer.php *************/
|
||||||
|
|
||||||
|
$lang["viewer"]["title"] = "Servidor Online";
|
||||||
|
$lang["viewer"]["lastupdate"] = "Ultima Atualização: {0}";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Lista de Bans - bans.php *************/
|
||||||
|
|
||||||
|
$lang["banlist"]["title"] = "Lista de Ban";
|
||||||
|
$lang["banlist"]["datatablesurl"] = "//cdn.datatables.net/plug-ins/1.10.12/i18n/Portuguese.json";
|
||||||
|
$lang["banlist"]["emptylist"] = "Lista de Ban está vazia";
|
||||||
|
$lang["banlist"]["lastupdate"] = "Ultima Atualização: {0}";
|
||||||
|
|
||||||
|
$lang["banlist"]["table"]["emptyreason"] = "(sem reação)";
|
||||||
|
$lang["banlist"]["table"]["permaban"] = "Nunca";
|
||||||
|
|
||||||
|
$lang["banlist"]["table"]["nickname"] = "Nick";
|
||||||
|
$lang["banlist"]["table"]["reason"] = "Reação";
|
||||||
|
$lang["banlist"]["table"]["bannedby"] = "Banido por";
|
||||||
|
$lang["banlist"]["table"]["bandate"] = "Data do Ban";
|
||||||
|
$lang["banlist"]["table"]["expires"] = "Expira";
|
||||||
|
|
||||||
|
/************* Regras do Servidor - rules.php *************/
|
||||||
|
|
||||||
|
$lang["rules"]["title"] = "Regras do servidor";
|
||||||
|
$lang["rules"]["filenotfound"] = "Error: Arquivo <code>config/rules.md</code> não foi encontrado!";
|
||||||
|
$lang["rules"]["readerror"] = "Error: Não foi possível acessar o arquivo <code>config/rules.md</code>!";
|
@ -0,0 +1,92 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* Bosnian language for ts-website
|
||||||
|
* @copy Izet Mulalić <github.com/kallefrombosnia>
|
||||||
|
*/
|
||||||
|
|
||||||
|
$lang = array();
|
||||||
|
|
||||||
|
/************* Generalno *************/
|
||||||
|
|
||||||
|
$lang["general"]["langcode"] = "bs";
|
||||||
|
$lang["general"]["languageflag"] = "ba";
|
||||||
|
$lang["general"]["scripterror"] = "Greška se pojavila! {0}: {1}";
|
||||||
|
|
||||||
|
/************* Navigacija *************/
|
||||||
|
|
||||||
|
$lang["navbar"]["navigation"] = "Navigacija";
|
||||||
|
$lang["navbar"]["viewer"] = "Pregled Servera";
|
||||||
|
$lang["navbar"]["bans"] = "Ban Lista";
|
||||||
|
$lang["navbar"]["rules"] = "Pravila Servera";
|
||||||
|
$lang["navbar"]["connect"] = "Poveži se na server";
|
||||||
|
$lang["navbar"]["connecttooltip"] = "Klikni da se spojiš na {0}";
|
||||||
|
|
||||||
|
/************* Footer *************/
|
||||||
|
|
||||||
|
$lang["footer"]["css"] = "CSS by";
|
||||||
|
$lang["footer"]["background"] = "pozadina";
|
||||||
|
|
||||||
|
/************* Server status *************/
|
||||||
|
|
||||||
|
$lang["serverstatus"]["title"] = "Server status";
|
||||||
|
$lang["serverstatus"]["address"] = "Adresa";
|
||||||
|
$lang["serverstatus"]["loading"] = "Učitavanje...";
|
||||||
|
$lang["serverstatus"]["online"] = "Online";
|
||||||
|
$lang["serverstatus"]["offline"] = "Offline";
|
||||||
|
$lang["serverstatus"]["uptime"] = "Uptime";
|
||||||
|
$lang["serverstatus"]["version"] = "Verzija";
|
||||||
|
$lang["serverstatus"]["avgping"] = "Prosječni ping";
|
||||||
|
$lang["serverstatus"]["avgpl"] = "Prosječni packet loss";
|
||||||
|
|
||||||
|
/************* Admin lista *************/
|
||||||
|
|
||||||
|
$lang["adminlist"]["title"] = "Admin lista";
|
||||||
|
$lang["adminlist"]["emptygroup"] = "Ova grupa je prazna";
|
||||||
|
$lang["adminlist"]["status"]["online"] = "Online";
|
||||||
|
$lang["adminlist"]["status"]["away"] = "Odsutan";
|
||||||
|
$lang["adminlist"]["status"]["offline"] = "Offline";
|
||||||
|
$lang["adminlist"]["lastupdate"] = "Zadnji update: {0}";
|
||||||
|
|
||||||
|
/************* Pregled servera u promotivnom boxu (ispod admin liste i kontakata) *************/
|
||||||
|
|
||||||
|
$lang["svpb"]["title"] = "Pregled servera";
|
||||||
|
$lang["svpb"]["takealook"] = "Baci pogled »";
|
||||||
|
|
||||||
|
|
||||||
|
/************************************/
|
||||||
|
/************* SUBSTRANICE *************/
|
||||||
|
/************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/************* Vijesti - index.php *************/
|
||||||
|
|
||||||
|
$lang["index"]["title"] = "Vijesti";
|
||||||
|
$lang["index"]["showmore"] = "Pročitaj više";
|
||||||
|
$lang["index"]["showless"] = "Prikaži manje";
|
||||||
|
$lang["index"]["errortitle"] = "Pogreška: direktorij sa vijestima nije pronađen!";
|
||||||
|
$lang["index"]["errorsubtitle"] = "Molimo postavite direktorij lokaciju u <b><code>config/config.php</code></b> da bude validna.";
|
||||||
|
|
||||||
|
/************* Server pregled - viewer.php *************/
|
||||||
|
|
||||||
|
$lang["viewer"]["title"] = "Pregled Servera";
|
||||||
|
$lang["viewer"]["lastupdate"] = "Zadnji update: {0}";
|
||||||
|
|
||||||
|
/************* Ban Lista - bans.php *************/
|
||||||
|
|
||||||
|
$lang["banlist"]["title"] = "Ban Lista";
|
||||||
|
$lang["banlist"]["datatablesurl"] = "//cdn.datatables.net/plug-ins/1.10.12/i18n/English.json";
|
||||||
|
$lang["banlist"]["emptylist"] = "BAN LISTA JE PRAZNA";
|
||||||
|
$lang["banlist"]["lastupdate"] = "Zadnji update: {0}";
|
||||||
|
$lang["banlist"]["table"]["emptyreason"] = "(nema razloga)";
|
||||||
|
$lang["banlist"]["table"]["permaban"] = "Nikad";
|
||||||
|
$lang["banlist"]["table"]["nickname"] = "Nick";
|
||||||
|
$lang["banlist"]["table"]["reason"] = "Razlog";
|
||||||
|
$lang["banlist"]["table"]["bannedby"] = "Banned od strane";
|
||||||
|
$lang["banlist"]["table"]["bandate"] = "Vrijeme bana";
|
||||||
|
$lang["banlist"]["table"]["expires"] = "Ističe";
|
||||||
|
|
||||||
|
/************* Pravila - rules.php *************/
|
||||||
|
|
||||||
|
$lang["rules"]["title"] = "Pravila Servera";
|
||||||
|
$lang["rules"]["filenotfound"] = "Pogreška: fajl <code>config/rules.md</code> nije pronađen!";
|
||||||
|
$lang["rules"]["readerror"] = "Pogreška: ne možemo pristupiti fajlu <code>config/rules.md</code>!";
|
@ -0,0 +1,102 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* Czech language for ts-website
|
||||||
|
* @copy Najsr <https://github.com/Najsr>
|
||||||
|
*/
|
||||||
|
|
||||||
|
$lang = array();
|
||||||
|
|
||||||
|
/************* General *************/
|
||||||
|
|
||||||
|
$lang["general"]["langcode"] = "cs_CZ";
|
||||||
|
$lang["general"]["languageflag"] = "cz";
|
||||||
|
$lang["general"]["scripterror"] = "Nastala chyba! {0}: {1}";
|
||||||
|
|
||||||
|
/************* Navbar *************/
|
||||||
|
|
||||||
|
$lang["navbar"]["navigation"] = "Navigace";
|
||||||
|
|
||||||
|
$lang["navbar"]["viewer"] = "Prohlížeč serveru";
|
||||||
|
$lang["navbar"]["bans"] = "Banlist";
|
||||||
|
$lang["navbar"]["rules"] = "Pravidla";
|
||||||
|
|
||||||
|
$lang["navbar"]["connect"] = "Připojit";
|
||||||
|
$lang["navbar"]["connecttooltip"] = "Klikněte pro připojení na {0}";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Footer *************/
|
||||||
|
|
||||||
|
$lang["footer"]["css"] = "CSS od";
|
||||||
|
$lang["footer"]["background"] = "pozadí";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Server status *************/
|
||||||
|
|
||||||
|
$lang["serverstatus"]["title"] = "Status";
|
||||||
|
$lang["serverstatus"]["address"] = "Adresa";
|
||||||
|
$lang["serverstatus"]["loading"] = "Načítání...";
|
||||||
|
|
||||||
|
$lang["serverstatus"]["online"] = "Online";
|
||||||
|
$lang["serverstatus"]["offline"] = "Offline";
|
||||||
|
$lang["serverstatus"]["uptime"] = "Doba zapnutí";
|
||||||
|
$lang["serverstatus"]["version"] = "Verze";
|
||||||
|
$lang["serverstatus"]["avgping"] = "Průměrný ping";
|
||||||
|
$lang["serverstatus"]["avgpl"] = "Průměrná ztrátovost paketů";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Admin list *************/
|
||||||
|
|
||||||
|
$lang["adminlist"]["title"] = "Seznam adminů";
|
||||||
|
$lang["adminlist"]["emptygroup"] = "Tato skupina je prázdná";
|
||||||
|
$lang["adminlist"]["status"]["online"] = "Online";
|
||||||
|
$lang["adminlist"]["status"]["away"] = "Pryč";
|
||||||
|
$lang["adminlist"]["status"]["offline"] = "Offline";
|
||||||
|
$lang["adminlist"]["lastupdate"] = "Poslední aktualizace: {0}";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Server viewer promo box (under adminlist and contact) *************/
|
||||||
|
|
||||||
|
$lang["svpb"]["title"] = "Prohlížeč serveru";
|
||||||
|
$lang["svpb"]["takealook"] = "Otevřít »";
|
||||||
|
|
||||||
|
|
||||||
|
/************************************/
|
||||||
|
/************* SUBPAGES *************/
|
||||||
|
/************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/************* News - index.php *************/
|
||||||
|
|
||||||
|
$lang["index"]["title"] = "Novinky";
|
||||||
|
$lang["index"]["showmore"] = "Zobrazit více";
|
||||||
|
$lang["index"]["showless"] = "Zobrazit méně";
|
||||||
|
|
||||||
|
$lang["index"]["errortitle"] = "Error: stránka s novinkami nenalezena!";
|
||||||
|
$lang["index"]["errorsubtitle"] = "Ujistěte se, že cesta zadaná v <b><code>config/config.php</code></b> je správná.";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Server viewer - viewer.php *************/
|
||||||
|
|
||||||
|
$lang["viewer"]["title"] = "Prohlížeč serveru";
|
||||||
|
$lang["viewer"]["lastupdate"] = "Poslední aktualizace: {0}";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Ban List - bans.php *************/
|
||||||
|
|
||||||
|
$lang["banlist"]["title"] = "Banlist";
|
||||||
|
$lang["banlist"]["datatablesurl"] = "//cdn.datatables.net/plug-ins/1.10.12/i18n/Czech.json";
|
||||||
|
$lang["banlist"]["emptylist"] = "Banlist je prázdný";
|
||||||
|
$lang["banlist"]["lastupdate"] = "Poslední aktualizace: {0}";
|
||||||
|
$lang["banlist"]["table"]["emptyreason"] = "(bez důvodu)";
|
||||||
|
$lang["banlist"]["table"]["permaban"] = "Až naprší a uschne";
|
||||||
|
$lang["banlist"]["table"]["nickname"] = "Nick";
|
||||||
|
$lang["banlist"]["table"]["reason"] = "Důvod";
|
||||||
|
$lang["banlist"]["table"]["bannedby"] = "Zabanován od";
|
||||||
|
$lang["banlist"]["table"]["bandate"] = "Datum";
|
||||||
|
$lang["banlist"]["table"]["expires"] = "Vyprší";
|
||||||
|
|
||||||
|
/************* Rules - rules.php *************/
|
||||||
|
|
||||||
|
$lang["rules"]["title"] = "Pravidla serveru";
|
||||||
|
$lang["rules"]["filenotfound"] = "Error: soubor <code>config/rules.md</code> nebyl nalezen!";
|
||||||
|
$lang["rules"]["readerror"] = "Error: nemám přístup k <code>config/rules.md</code>!";
|
@ -0,0 +1,104 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* Danish language for ts-website
|
||||||
|
* @copy Cadmium
|
||||||
|
*/
|
||||||
|
|
||||||
|
$lang = array();
|
||||||
|
|
||||||
|
/************* General *************/
|
||||||
|
|
||||||
|
$lang["general"]["langcode"] = "da_DK";
|
||||||
|
$lang["general"]["languageflag"] = "dk";
|
||||||
|
$lang["general"]["scripterror"] = "En fejl opstod! {0}: {1}";
|
||||||
|
|
||||||
|
/************* Navbar *************/
|
||||||
|
|
||||||
|
$lang["navbar"]["navigation"] = "Navigation";
|
||||||
|
|
||||||
|
$lang["navbar"]["viewer"] = "Server Fremvisning";
|
||||||
|
$lang["navbar"]["bans"] = "Ban Liste";
|
||||||
|
$lang["navbar"]["rules"] = "Server Regler";
|
||||||
|
|
||||||
|
$lang["navbar"]["connect"] = "Forbind til server";
|
||||||
|
$lang["navbar"]["connecttooltip"] = "Klik for at fobinde til {0}";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Footer *************/
|
||||||
|
|
||||||
|
$lang["footer"]["css"] = "CSS af";
|
||||||
|
$lang["footer"]["background"] = "baggrund";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Server status *************/
|
||||||
|
|
||||||
|
$lang["serverstatus"]["title"] = "Server status";
|
||||||
|
$lang["serverstatus"]["address"] = "Adresse";
|
||||||
|
$lang["serverstatus"]["loading"] = "Indlæser...";
|
||||||
|
|
||||||
|
$lang["serverstatus"]["online"] = "Online";
|
||||||
|
$lang["serverstatus"]["offline"] = "Offline";
|
||||||
|
$lang["serverstatus"]["uptime"] = "Oppetid";
|
||||||
|
$lang["serverstatus"]["version"] = "Version";
|
||||||
|
$lang["serverstatus"]["avgping"] = "Gennemsnitlig ping";
|
||||||
|
$lang["serverstatus"]["avgpl"] = "Gennemsnitlig pakketab";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Admin list *************/
|
||||||
|
|
||||||
|
$lang["adminlist"]["title"] = "Admin Liste";
|
||||||
|
$lang["adminlist"]["emptygroup"] = "Denne gruppe er tom";
|
||||||
|
$lang["adminlist"]["status"]["online"] = "Online";
|
||||||
|
$lang["adminlist"]["status"]["away"] = "Borte";
|
||||||
|
$lang["adminlist"]["status"]["offline"] = "Offline";
|
||||||
|
$lang["adminlist"]["lastupdate"] = "Sidste opdatering: {0}";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Server viewer promo box (under adminlist and contact) *************/
|
||||||
|
|
||||||
|
$lang["svpb"]["title"] = "Server Fremvisning";
|
||||||
|
$lang["svpb"]["takealook"] = "Tag et kig »";
|
||||||
|
|
||||||
|
|
||||||
|
/************************************/
|
||||||
|
/************* SUBPAGES *************/
|
||||||
|
/************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/************* News - index.php *************/
|
||||||
|
|
||||||
|
$lang["index"]["title"] = "Nyheder";
|
||||||
|
$lang["index"]["showmore"] = "Læs mere";
|
||||||
|
$lang["index"]["showless"] = "Vis mindre";
|
||||||
|
|
||||||
|
$lang["index"]["errortitle"] = "Fejl: nyheden kunne ikke findes!";
|
||||||
|
$lang["index"]["errorsubtitle"] = "Tjek venligst, at den angivne lokation i filen <b><code>config/config.php</code></b> findes.";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Server viewer - viewer.php *************/
|
||||||
|
|
||||||
|
$lang["viewer"]["title"] = "Server Fremvisning";
|
||||||
|
$lang["viewer"]["lastupdate"] = "Sidst opdateret: {0}";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Ban List - bans.php *************/
|
||||||
|
|
||||||
|
$lang["banlist"]["title"] = "Ban Liste";
|
||||||
|
$lang["banlist"]["datatablesurl"] = "//cdn.datatables.net/plug-ins/1.10.12/i18n/Danish.json";
|
||||||
|
$lang["banlist"]["emptylist"] = "BAN LISTEN ER TOM";
|
||||||
|
$lang["banlist"]["lastupdate"] = "Sidst opdateret: {0}";
|
||||||
|
|
||||||
|
$lang["banlist"]["table"]["emptyreason"] = "(ingen grund givet)";
|
||||||
|
$lang["banlist"]["table"]["permaban"] = "Aldrig";
|
||||||
|
|
||||||
|
$lang["banlist"]["table"]["nickname"] = "Navn";
|
||||||
|
$lang["banlist"]["table"]["reason"] = "Grund";
|
||||||
|
$lang["banlist"]["table"]["bannedby"] = "Banlyst af";
|
||||||
|
$lang["banlist"]["table"]["bandate"] = "Dato for ban";
|
||||||
|
$lang["banlist"]["table"]["expires"] = "Udløber";
|
||||||
|
|
||||||
|
/************* Rules - rules.php *************/
|
||||||
|
|
||||||
|
$lang["rules"]["title"] = "Server Regler";
|
||||||
|
$lang["rules"]["filenotfound"] = "Fejl: filen <code>config/rules.md</code> kunne ikke findes!";
|
||||||
|
$lang["rules"]["readerror"] = "Fejl: adgang til filen <code>config/rules.md</code> nægtet!";
|
@ -0,0 +1,104 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* German language for ts-website
|
||||||
|
* @copy NothingTV <contact@tactical-gaming.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
$lang = array();
|
||||||
|
|
||||||
|
/************* General *************/
|
||||||
|
|
||||||
|
$lang["general"]["langcode"] = "de_DE";
|
||||||
|
$lang["general"]["languageflag"] = "de";
|
||||||
|
$lang["general"]["scripterror"] = "Es ist ein Fehler aufgetreten! {0}: {1}";
|
||||||
|
|
||||||
|
/************* Navbar *************/
|
||||||
|
|
||||||
|
$lang["navbar"]["navigation"] = "Navigation";
|
||||||
|
|
||||||
|
$lang["navbar"]["viewer"] = "Server Viewer";
|
||||||
|
$lang["navbar"]["bans"] = "Bann Liste";
|
||||||
|
$lang["navbar"]["rules"] = "Server Regeln";
|
||||||
|
|
||||||
|
$lang["navbar"]["connect"] = "Mit Server verbinden";
|
||||||
|
$lang["navbar"]["connecttooltip"] = "Klicken um mit {0} zu verbinden";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Footer *************/
|
||||||
|
|
||||||
|
$lang["footer"]["css"] = "CSS bereitgestellt von";
|
||||||
|
$lang["footer"]["background"] = "Hintergrund";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Server status *************/
|
||||||
|
|
||||||
|
$lang["serverstatus"]["title"] = "Server Status";
|
||||||
|
$lang["serverstatus"]["address"] = "Adresse";
|
||||||
|
$lang["serverstatus"]["loading"] = "Laden...";
|
||||||
|
|
||||||
|
$lang["serverstatus"]["online"] = "Online";
|
||||||
|
$lang["serverstatus"]["offline"] = "Offline";
|
||||||
|
$lang["serverstatus"]["uptime"] = "Uptime";
|
||||||
|
$lang["serverstatus"]["version"] = "Server Version";
|
||||||
|
$lang["serverstatus"]["avgping"] = "Ø Ping";
|
||||||
|
$lang["serverstatus"]["avgpl"] = "Ø Paketverlust";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Admin list *************/
|
||||||
|
|
||||||
|
$lang["adminlist"]["title"] = "Admin Liste";
|
||||||
|
$lang["adminlist"]["emptygroup"] = "Diese Gruppe ist leer";
|
||||||
|
$lang["adminlist"]["status"]["online"] = "Online";
|
||||||
|
$lang["adminlist"]["status"]["away"] = "Abwesend";
|
||||||
|
$lang["adminlist"]["status"]["offline"] = "Offline";
|
||||||
|
$lang["adminlist"]["lastupdate"] = "Letzte Aktualisierung: {0}";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Server viewer promo box (under adminlist and contact) *************/
|
||||||
|
|
||||||
|
$lang["svpb"]["title"] = "Server Viewer";
|
||||||
|
$lang["svpb"]["takealook"] = "Riskier 'n Blick »";
|
||||||
|
|
||||||
|
|
||||||
|
/************************************/
|
||||||
|
/************* SUBPAGES *************/
|
||||||
|
/************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/************* News - index.php *************/
|
||||||
|
|
||||||
|
$lang["index"]["title"] = "Neuigkeiten";
|
||||||
|
$lang["index"]["showmore"] = "Mehr anzeigen";
|
||||||
|
$lang["index"]["showless"] = "Weniger anzeigen";
|
||||||
|
|
||||||
|
$lang["index"]["errortitle"] = "Fehler: Neuigkeiten Ordner konnte nicht gefunden werden!";
|
||||||
|
$lang["index"]["errorsubtitle"] = "Bitte stelle sicher, dass der Ordner Pfad in <code>config/config.php</code> richtig angegeben wurde.";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Server viewer - viewer.php *************/
|
||||||
|
|
||||||
|
$lang["viewer"]["title"] = "Server Viewer";
|
||||||
|
$lang["viewer"]["lastupdate"] = "Letzte Aktualisierung: {0}";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Ban List - bans.php *************/
|
||||||
|
|
||||||
|
$lang["banlist"]["title"] = "Bann Liste";
|
||||||
|
$lang["banlist"]["datatablesurl"] = "//cdn.datatables.net/plug-ins/1.10.12/i18n/German.json";
|
||||||
|
$lang["banlist"]["emptylist"] = "Es gibt derzeit keine Gebannten User";
|
||||||
|
$lang["banlist"]["lastupdate"] = "Letzte Aktualisierung: {0}";
|
||||||
|
|
||||||
|
$lang["banlist"]["table"]["emptyreason"] = "(kein Grund angegeben)";
|
||||||
|
$lang["banlist"]["table"]["permaban"] = "Niemals";
|
||||||
|
|
||||||
|
$lang["banlist"]["table"]["nickname"] = "Benutzername";
|
||||||
|
$lang["banlist"]["table"]["reason"] = "Grund";
|
||||||
|
$lang["banlist"]["table"]["bannedby"] = "Gebannt von";
|
||||||
|
$lang["banlist"]["table"]["bandate"] = "Bann Zeitpunkt";
|
||||||
|
$lang["banlist"]["table"]["expires"] = "Läuft ab am";
|
||||||
|
|
||||||
|
/************* Rules - rules.php *************/
|
||||||
|
|
||||||
|
$lang["rules"]["title"] = "Server Regeln";
|
||||||
|
$lang["rules"]["filenotfound"] = "Fehler: Die Datei <code>config/rules.md</code> wurde nicht gefunden!";
|
||||||
|
$lang["rules"]["readerror"] = "Fehler: Nicht genügend Rechte um auf <code>config/rules.md</code> zuzugreifen!";
|
@ -0,0 +1,104 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* English language for ts-website
|
||||||
|
* @copy Wruczek <wruczekk@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
$lang = array();
|
||||||
|
|
||||||
|
/************* General *************/
|
||||||
|
|
||||||
|
$lang["general"]["langcode"] = "en_GB";
|
||||||
|
$lang["general"]["languageflag"] = "gb";
|
||||||
|
$lang["general"]["scripterror"] = "An error occured! {0}: {1}";
|
||||||
|
|
||||||
|
/************* Navbar *************/
|
||||||
|
|
||||||
|
$lang["navbar"]["navigation"] = "Navigation";
|
||||||
|
|
||||||
|
$lang["navbar"]["viewer"] = "Server Viewer";
|
||||||
|
$lang["navbar"]["bans"] = "Ban List";
|
||||||
|
$lang["navbar"]["rules"] = "Server Rules";
|
||||||
|
|
||||||
|
$lang["navbar"]["connect"] = "Connect to server";
|
||||||
|
$lang["navbar"]["connecttooltip"] = "Click to connect to {0}";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Footer *************/
|
||||||
|
|
||||||
|
$lang["footer"]["css"] = "CSS by";
|
||||||
|
$lang["footer"]["background"] = "background";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Server status *************/
|
||||||
|
|
||||||
|
$lang["serverstatus"]["title"] = "Server status";
|
||||||
|
$lang["serverstatus"]["address"] = "Address";
|
||||||
|
$lang["serverstatus"]["loading"] = "Loading...";
|
||||||
|
|
||||||
|
$lang["serverstatus"]["online"] = "Online";
|
||||||
|
$lang["serverstatus"]["offline"] = "Offline";
|
||||||
|
$lang["serverstatus"]["uptime"] = "Uptime";
|
||||||
|
$lang["serverstatus"]["version"] = "Version";
|
||||||
|
$lang["serverstatus"]["avgping"] = "Average ping";
|
||||||
|
$lang["serverstatus"]["avgpl"] = "Average packet loss";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Admin list *************/
|
||||||
|
|
||||||
|
$lang["adminlist"]["title"] = "Adminlist";
|
||||||
|
$lang["adminlist"]["emptygroup"] = "This group is empty";
|
||||||
|
$lang["adminlist"]["status"]["online"] = "Online";
|
||||||
|
$lang["adminlist"]["status"]["away"] = "Away";
|
||||||
|
$lang["adminlist"]["status"]["offline"] = "Offline";
|
||||||
|
$lang["adminlist"]["lastupdate"] = "Last update: {0}";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Server viewer promo box (under adminlist and contact) *************/
|
||||||
|
|
||||||
|
$lang["svpb"]["title"] = "Server Viewer";
|
||||||
|
$lang["svpb"]["takealook"] = "Take a look »";
|
||||||
|
|
||||||
|
|
||||||
|
/************************************/
|
||||||
|
/************* SUBPAGES *************/
|
||||||
|
/************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/************* News - index.php *************/
|
||||||
|
|
||||||
|
$lang["index"]["title"] = "News";
|
||||||
|
$lang["index"]["showmore"] = "Read more";
|
||||||
|
$lang["index"]["showless"] = "Show less";
|
||||||
|
|
||||||
|
$lang["index"]["errortitle"] = "Error: news directory has not been found!";
|
||||||
|
$lang["index"]["errorsubtitle"] = "Please make sure that directory location set in <b><code>config/config.php</code></b> is valid.";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Server viewer - viewer.php *************/
|
||||||
|
|
||||||
|
$lang["viewer"]["title"] = "Server Viewer";
|
||||||
|
$lang["viewer"]["lastupdate"] = "Last update: {0}";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Ban List - bans.php *************/
|
||||||
|
|
||||||
|
$lang["banlist"]["title"] = "Ban List";
|
||||||
|
$lang["banlist"]["datatablesurl"] = "//cdn.datatables.net/plug-ins/1.10.12/i18n/English.json";
|
||||||
|
$lang["banlist"]["emptylist"] = "BAN LIST IS EMPTY";
|
||||||
|
$lang["banlist"]["lastupdate"] = "Last update: {0}";
|
||||||
|
|
||||||
|
$lang["banlist"]["table"]["emptyreason"] = "(no reason set)";
|
||||||
|
$lang["banlist"]["table"]["permaban"] = "Never";
|
||||||
|
|
||||||
|
$lang["banlist"]["table"]["nickname"] = "Nick";
|
||||||
|
$lang["banlist"]["table"]["reason"] = "Reason";
|
||||||
|
$lang["banlist"]["table"]["bannedby"] = "Banned by";
|
||||||
|
$lang["banlist"]["table"]["bandate"] = "Ban date";
|
||||||
|
$lang["banlist"]["table"]["expires"] = "Expires";
|
||||||
|
|
||||||
|
/************* Rules - rules.php *************/
|
||||||
|
|
||||||
|
$lang["rules"]["title"] = "Server Rules";
|
||||||
|
$lang["rules"]["filenotfound"] = "Error: file <code>config/rules.md</code> has not been found!";
|
||||||
|
$lang["rules"]["readerror"] = "Error: cannot access the file <code>config/rules.md</code>!";
|
@ -0,0 +1,104 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* Spanish language for ts-website
|
||||||
|
* @copy Vinanrra <staff@teamworkers.es>
|
||||||
|
*/
|
||||||
|
|
||||||
|
$lang = array();
|
||||||
|
|
||||||
|
/************* General *************/
|
||||||
|
|
||||||
|
$lang["general"]["langcode"] = "es-ES";
|
||||||
|
$lang["general"]["languageflag"] = "es";
|
||||||
|
$lang["general"]["scripterror"] = "Ha ocurrido un error {0}: {1}";
|
||||||
|
|
||||||
|
/************* Navbar *************/
|
||||||
|
|
||||||
|
$lang["navbar"]["navigation"] = "Navegación";
|
||||||
|
|
||||||
|
$lang["navbar"]["viewer"] = "Server Viewer";
|
||||||
|
$lang["navbar"]["bans"] = "Lista de baneados";
|
||||||
|
$lang["navbar"]["rules"] = "Reglas del servidor";
|
||||||
|
|
||||||
|
$lang["navbar"]["connect"] = "Conectar al ts3";
|
||||||
|
$lang["navbar"]["connecttooltip"] = "Click para conectar a {0}";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Footer *************/
|
||||||
|
|
||||||
|
$lang["footer"]["css"] = "CSS por";
|
||||||
|
$lang["footer"]["background"] = "fondo";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Server status *************/
|
||||||
|
|
||||||
|
$lang["serverstatus"]["title"] = "Estado del servidor";
|
||||||
|
$lang["serverstatus"]["address"] = "Direción";
|
||||||
|
$lang["serverstatus"]["loading"] = "Cargando...";
|
||||||
|
|
||||||
|
$lang["serverstatus"]["online"] = "En linea";
|
||||||
|
$lang["serverstatus"]["offline"] = "Desconectado";
|
||||||
|
$lang["serverstatus"]["uptime"] = "Tiempo activo";
|
||||||
|
$lang["serverstatus"]["version"] = "Versión";
|
||||||
|
$lang["serverstatus"]["avgping"] = "Ping promedio";
|
||||||
|
$lang["serverstatus"]["avgpl"] = "Pérdida de paquetes";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Admin list *************/
|
||||||
|
|
||||||
|
$lang["adminlist"]["title"] = "Lista de ADM/MOD";
|
||||||
|
$lang["adminlist"]["emptygroup"] = "Grupo vacio";
|
||||||
|
$lang["adminlist"]["status"]["online"] = "En linea";
|
||||||
|
$lang["adminlist"]["status"]["away"] = "AFK";
|
||||||
|
$lang["adminlist"]["status"]["offline"] = "Desconectado";
|
||||||
|
$lang["adminlist"]["lastupdate"] = "Última actualización: {0}";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Server viewer promo box (under adminlist and contact) *************/
|
||||||
|
|
||||||
|
$lang["svpb"]["title"] = "Ver servidor";
|
||||||
|
$lang["svpb"]["takealook"] = "Echar un vistazo »";
|
||||||
|
|
||||||
|
|
||||||
|
/************************************/
|
||||||
|
/************* SUBPAGES *************/
|
||||||
|
/************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/************* News - index.php *************/
|
||||||
|
|
||||||
|
$lang["index"]["title"] = "Noticias";
|
||||||
|
$lang["index"]["showmore"] = "Leer más";
|
||||||
|
$lang["index"]["showless"] = "Mostar menos";
|
||||||
|
|
||||||
|
$lang["index"]["errortitle"] = "Error: El directorio de noticias no fue encontrado";
|
||||||
|
$lang["index"]["errorsubtitle"] = "Por favor asegurate que el directorio que está en <b><code>config/config.php</code></b> es válido.";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Server viewer - viewer.php *************/
|
||||||
|
|
||||||
|
$lang["viewer"]["title"] = "Ver servidor";
|
||||||
|
$lang["viewer"]["lastupdate"] = "Última actualización: {0}";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Ban List - bans.php *************/
|
||||||
|
|
||||||
|
$lang["banlist"]["title"] = "Lista de baneados";
|
||||||
|
$lang["banlist"]["datatablesurl"] = "//cdn.datatables.net/plug-ins/1.10.12/i18n/Spanish.json";
|
||||||
|
$lang["banlist"]["emptylist"] = "La lista de baneados está vacia";
|
||||||
|
$lang["banlist"]["lastupdate"] = "Última actualización: {0}";
|
||||||
|
|
||||||
|
$lang["banlist"]["table"]["emptyreason"] = "(sin razón)";
|
||||||
|
$lang["banlist"]["table"]["permaban"] = "Nunca";
|
||||||
|
|
||||||
|
$lang["banlist"]["table"]["nickname"] = "Usuario";
|
||||||
|
$lang["banlist"]["table"]["reason"] = "Razón";
|
||||||
|
$lang["banlist"]["table"]["bannedby"] = "Baneado por";
|
||||||
|
$lang["banlist"]["table"]["bandate"] = "Fecha de baneo";
|
||||||
|
$lang["banlist"]["table"]["expires"] = "Expiración";
|
||||||
|
|
||||||
|
/************* Rules - rules.php *************/
|
||||||
|
|
||||||
|
$lang["rules"]["title"] = "Reglas del servidor";
|
||||||
|
$lang["rules"]["filenotfound"] = "Error: archivo <code>config/rules.md</code> no ha sido encontrado";
|
||||||
|
$lang["rules"]["readerror"] = "Error: no se puede acceder al archivo <code>config/rules.md</code>";
|
@ -0,0 +1,104 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* French language for ts-website
|
||||||
|
* @copy FleuryK <contact@fleuryk.tk>
|
||||||
|
*/
|
||||||
|
|
||||||
|
$lang = array();
|
||||||
|
|
||||||
|
/************* General *************/
|
||||||
|
|
||||||
|
$lang["general"]["langcode"] = "fr_FR";
|
||||||
|
$lang["general"]["languageflag"] = "fr";
|
||||||
|
$lang["general"]["scripterror"] = "Une erreur s'est produite ! {0} : {1}";
|
||||||
|
|
||||||
|
/************* Navbar *************/
|
||||||
|
|
||||||
|
$lang["navbar"]["navigation"] = "Navigation";
|
||||||
|
|
||||||
|
$lang["navbar"]["viewer"] = "Affichage du Serveur";
|
||||||
|
$lang["navbar"]["bans"] = "Liste des Bans";
|
||||||
|
$lang["navbar"]["rules"] = "Règles du Serveur";
|
||||||
|
|
||||||
|
$lang["navbar"]["connect"] = "Se connecter au Serveur";
|
||||||
|
$lang["navbar"]["connecttooltip"] = "Cliquez pour vous connecter à {0}";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Footer *************/
|
||||||
|
|
||||||
|
$lang["footer"]["css"] = "CSS par";
|
||||||
|
$lang["footer"]["background"] = "arrière-plan";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Server status *************/
|
||||||
|
|
||||||
|
$lang["serverstatus"]["title"] = "Statut du Serveur";
|
||||||
|
$lang["serverstatus"]["address"] = "Adresse";
|
||||||
|
$lang["serverstatus"]["loading"] = "Chargement ...";
|
||||||
|
|
||||||
|
$lang["serverstatus"]["online"] = "En ligne";
|
||||||
|
$lang["serverstatus"]["offline"] = "Hors ligne";
|
||||||
|
$lang["serverstatus"]["uptime"] = "Tps de fonction.";
|
||||||
|
$lang["serverstatus"]["version"] = "Version";
|
||||||
|
$lang["serverstatus"]["avgping"] = "Moyenne du Ping";
|
||||||
|
$lang["serverstatus"]["avgpl"] = "Perte moyenne de paquets";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Admin list *************/
|
||||||
|
|
||||||
|
$lang["adminlist"]["title"] = "Liste d'Admin";
|
||||||
|
$lang["adminlist"]["emptygroup"] = "Ce groupe est vide";
|
||||||
|
$lang["adminlist"]["status"]["online"] = "En ligne";
|
||||||
|
$lang["adminlist"]["status"]["away"] = "Away";
|
||||||
|
$lang["adminlist"]["status"]["offline"] = "Hors ligne";
|
||||||
|
$lang["adminlist"]["lastupdate"] = "Dernière mise à jour : {0}";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Server viewer promo box (under adminlist and contact) *************/
|
||||||
|
|
||||||
|
$lang["svpb"]["title"] = "Affichage du Serveur";
|
||||||
|
$lang["svpb"]["takealook"] = "Regarder »";
|
||||||
|
|
||||||
|
|
||||||
|
/************************************/
|
||||||
|
/************* SUBPAGES *************/
|
||||||
|
/************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/************* News - index.php *************/
|
||||||
|
|
||||||
|
$lang["index"]["title"] = "News";
|
||||||
|
$lang["index"]["showmore"] = "Lire la suite";
|
||||||
|
$lang["index"]["showless"] = "Moins montrer";
|
||||||
|
|
||||||
|
$lang["index"]["errortitle"] = "Erreur : le dossier des news n'a pas été trouvé !";
|
||||||
|
$lang["index"]["errorsubtitle"] = "Assurez-vous que l'emplacement du répertoire défini dans <b><code>config/config.php</code></b> est valide.";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Server viewer - viewer.php *************/
|
||||||
|
|
||||||
|
$lang["viewer"]["title"] = "Affichage du Serveur";
|
||||||
|
$lang["viewer"]["lastupdate"] = "Dernière mise à jour : {0}";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Ban List - bans.php *************/
|
||||||
|
|
||||||
|
$lang["banlist"]["title"] = "Liste des Bans";
|
||||||
|
$lang["banlist"]["datatablesurl"] = "//cdn.datatables.net/plug-ins/1.10.12/i18n/French.json";
|
||||||
|
$lang["banlist"]["emptylist"] = "LA LISTE DES BANS EST VIDE";
|
||||||
|
$lang["banlist"]["lastupdate"] = "Dernière mise à jour : {0}";
|
||||||
|
|
||||||
|
$lang["banlist"]["table"]["emptyreason"] = "(pas de raison)";
|
||||||
|
$lang["banlist"]["table"]["permaban"] = "Jamais";
|
||||||
|
|
||||||
|
$lang["banlist"]["table"]["nickname"] = "Surnom";
|
||||||
|
$lang["banlist"]["table"]["reason"] = "Raison";
|
||||||
|
$lang["banlist"]["table"]["bannedby"] = "Banni par";
|
||||||
|
$lang["banlist"]["table"]["bandate"] = "Date du Ban";
|
||||||
|
$lang["banlist"]["table"]["expires"] = "Expire";
|
||||||
|
|
||||||
|
/************* Rules - rules.php *************/
|
||||||
|
|
||||||
|
$lang["rules"]["title"] = "Règles du Serveur";
|
||||||
|
$lang["rules"]["filenotfound"] = "Erreur : Le fichier <code>config/rules.md</code> n'a pas été trouvé !";
|
||||||
|
$lang["rules"]["readerror"] = "Erreur : Impossible d'accéder au fichier <code>config/rules.md</code> !";
|
@ -0,0 +1,104 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* Hungarian language for ts-website
|
||||||
|
* @copy SmaCk <steamcommunity.com/id/smackiii>
|
||||||
|
*/
|
||||||
|
|
||||||
|
$lang = array();
|
||||||
|
|
||||||
|
/************* Általános *************/
|
||||||
|
|
||||||
|
$lang["general"]["langcode"] = "hu_HU";
|
||||||
|
$lang["general"]["languageflag"] = "hu";
|
||||||
|
$lang["general"]["scripterror"] = "Hiba történt! {0}: {1}";
|
||||||
|
|
||||||
|
/************* Navbár *************/
|
||||||
|
|
||||||
|
$lang["navbar"]["navigation"] = "Navigáció";
|
||||||
|
|
||||||
|
$lang["navbar"]["viewer"] = "Szerver Státusz";
|
||||||
|
$lang["navbar"]["bans"] = "Banlista";
|
||||||
|
$lang["navbar"]["rules"] = "Szabályzat";
|
||||||
|
|
||||||
|
$lang["navbar"]["connect"] = "CSATLAKOZÁS";
|
||||||
|
$lang["navbar"]["connecttooltip"] = "Csatlakozáshoz katt.. {0}";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Lábrész *************/
|
||||||
|
|
||||||
|
$lang["footer"]["css"] = "CSS by ";
|
||||||
|
$lang["footer"]["background"] = "background";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Server Státusz *************/
|
||||||
|
|
||||||
|
$lang["serverstatus"]["title"] = "Státusz";
|
||||||
|
$lang["serverstatus"]["address"] = "IP Cím";
|
||||||
|
$lang["serverstatus"]["loading"] = "Betöltés...";
|
||||||
|
|
||||||
|
$lang["serverstatus"]["online"] = "Online";
|
||||||
|
$lang["serverstatus"]["offline"] = "Offline";
|
||||||
|
$lang["serverstatus"]["uptime"] = "Üzemidő";
|
||||||
|
$lang["serverstatus"]["version"] = "Verzió";
|
||||||
|
$lang["serverstatus"]["avgping"] = "Átlagos ping";
|
||||||
|
$lang["serverstatus"]["avgpl"] = "Csomagveszteség";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Admin lista *************/
|
||||||
|
|
||||||
|
$lang["adminlist"]["title"] = "Staff";
|
||||||
|
$lang["adminlist"]["emptygroup"] = "A csoport üres.";
|
||||||
|
$lang["adminlist"]["status"]["online"] = "Online";
|
||||||
|
$lang["adminlist"]["status"]["away"] = "Távol";
|
||||||
|
$lang["adminlist"]["status"]["offline"] = "Offline";
|
||||||
|
$lang["adminlist"]["lastupdate"] = "Utoljára frissítve: {0}";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Adminlista és Kapcsolat alatt megjelenő szövegek *************/
|
||||||
|
|
||||||
|
$lang["svpb"]["title"] = "Státusz";
|
||||||
|
$lang["svpb"]["takealook"] = "Megnéz";
|
||||||
|
|
||||||
|
|
||||||
|
/************************************/
|
||||||
|
/************* ALOLDALAK *************/
|
||||||
|
/************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/************* Hírek - index.php *************/
|
||||||
|
|
||||||
|
$lang["index"]["title"] = "Hírek";
|
||||||
|
$lang["index"]["showmore"] = "olvass tovább";
|
||||||
|
$lang["index"]["showless"] = "kevesebb";
|
||||||
|
|
||||||
|
$lang["index"]["errortitle"] = "Hiba: hírek mappa nem található!";
|
||||||
|
$lang["index"]["errorsubtitle"] = "Kérlek állítsd be a fájlt megfelelően <b><code>config/config.php</code></b>.";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Szerver Státusz - viewer.php *************/
|
||||||
|
|
||||||
|
$lang["viewer"]["title"] = "Szerver Státusz";
|
||||||
|
$lang["viewer"]["lastupdate"] = "Utoljára frissítve: {0}";
|
||||||
|
|
||||||
|
|
||||||
|
/************* BanLista - bans.php *************/
|
||||||
|
|
||||||
|
$lang["banlist"]["title"] = "Banlista";
|
||||||
|
$lang["banlist"]["datatablesurl"] = "//cdn.datatables.net/plug-ins/1.10.12/i18n/Hungarian.json";
|
||||||
|
$lang["banlist"]["emptylist"] = "A banlista üres.";
|
||||||
|
$lang["banlist"]["lastupdate"] = "Utoljára frissítve: {0}";
|
||||||
|
|
||||||
|
$lang["banlist"]["table"]["emptyreason"] = "(nincs indok)";
|
||||||
|
$lang["banlist"]["table"]["permaban"] = "Soha";
|
||||||
|
|
||||||
|
$lang["banlist"]["table"]["nickname"] = "Név";
|
||||||
|
$lang["banlist"]["table"]["reason"] = "Indok";
|
||||||
|
$lang["banlist"]["table"]["bannedby"] = "Admin";
|
||||||
|
$lang["banlist"]["table"]["bandate"] = "Dátum";
|
||||||
|
$lang["banlist"]["table"]["expires"] = "Lejár";
|
||||||
|
|
||||||
|
/************* Szabályok - rules.php *************/
|
||||||
|
|
||||||
|
$lang["rules"]["title"] = "Szabályzat";
|
||||||
|
$lang["rules"]["filenotfound"] = "Hiba: fájl <code>config/rules.md</code> nem található!";
|
||||||
|
$lang["rules"]["readerror"] = "Hiba: nincs megfelelő joga <code>config/rules.md</code>!";
|
@ -0,0 +1,104 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* Italian language for ts-website
|
||||||
|
* @copy JohnnyKing94 <https://github.com/JohnnyKing94>
|
||||||
|
*/
|
||||||
|
|
||||||
|
$lang = array();
|
||||||
|
|
||||||
|
/************* General *************/
|
||||||
|
|
||||||
|
$lang["general"]["langcode"] = "it";
|
||||||
|
$lang["general"]["languageflag"] = "it";
|
||||||
|
$lang["general"]["scripterror"] = "Un errore si è verificato! {0}: {1}";
|
||||||
|
|
||||||
|
/************* Navbar *************/
|
||||||
|
|
||||||
|
$lang["navbar"]["navigation"] = "Navigazione";
|
||||||
|
|
||||||
|
$lang["navbar"]["viewer"] = "Visualizza Server";
|
||||||
|
$lang["navbar"]["bans"] = "Lista Ban";
|
||||||
|
$lang["navbar"]["rules"] = "Regolamento";
|
||||||
|
|
||||||
|
$lang["navbar"]["connect"] = "Unisciti a noi!";
|
||||||
|
$lang["navbar"]["connecttooltip"] = "Clicca per connetterti a {0}";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Footer *************/
|
||||||
|
|
||||||
|
$lang["footer"]["css"] = "CSS di";
|
||||||
|
$lang["footer"]["background"] = "sfondo";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Server status *************/
|
||||||
|
|
||||||
|
$lang["serverstatus"]["title"] = "Stato Server";
|
||||||
|
$lang["serverstatus"]["address"] = "Indirizzo";
|
||||||
|
$lang["serverstatus"]["loading"] = "In caricamento...";
|
||||||
|
|
||||||
|
$lang["serverstatus"]["online"] = "Online";
|
||||||
|
$lang["serverstatus"]["offline"] = "Offline";
|
||||||
|
$lang["serverstatus"]["uptime"] = "Uptime";
|
||||||
|
$lang["serverstatus"]["version"] = "Versione";
|
||||||
|
$lang["serverstatus"]["avgping"] = "Ping medio";
|
||||||
|
$lang["serverstatus"]["avgpl"] = "Perdita media dei pacchetti";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Admin list *************/
|
||||||
|
|
||||||
|
$lang["adminlist"]["title"] = "Lista admin";
|
||||||
|
$lang["adminlist"]["emptygroup"] = "Questo gruppo è vuoto";
|
||||||
|
$lang["adminlist"]["status"]["online"] = "Online";
|
||||||
|
$lang["adminlist"]["status"]["away"] = "Assente";
|
||||||
|
$lang["adminlist"]["status"]["offline"] = "Offline";
|
||||||
|
$lang["adminlist"]["lastupdate"] = "Ultimo aggiornamento: {0}";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Server viewer promo box (under adminlist and contact) *************/
|
||||||
|
|
||||||
|
$lang["svpb"]["title"] = "Visualizza server";
|
||||||
|
$lang["svpb"]["takealook"] = "Guarda »";
|
||||||
|
|
||||||
|
|
||||||
|
/************************************/
|
||||||
|
/************* SUBPAGES *************/
|
||||||
|
/************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/************* News - index.php *************/
|
||||||
|
|
||||||
|
$lang["index"]["title"] = "News";
|
||||||
|
$lang["index"]["showmore"] = "Leggi di più";
|
||||||
|
$lang["index"]["showless"] = "VIsualizza meno";
|
||||||
|
|
||||||
|
$lang["index"]["errortitle"] = "Errore: la directory news non è stata trovata!";
|
||||||
|
$lang["index"]["errorsubtitle"] = "Si prega di assicurarsi che la posizione della cartella impostata in <b><code>config/config.php</code></b> sia valida.";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Server viewer - viewer.php *************/
|
||||||
|
|
||||||
|
$lang["viewer"]["title"] = "Visualizza Server";
|
||||||
|
$lang["viewer"]["lastupdate"] = "Ultimo aggiornamento: {0}";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Ban List - bans.php *************/
|
||||||
|
|
||||||
|
$lang["banlist"]["title"] = "Lista Ban";
|
||||||
|
$lang["banlist"]["datatablesurl"] = "//cdn.datatables.net/plug-ins/1.10.12/i18n/Italian.json";
|
||||||
|
$lang["banlist"]["emptylist"] = "LA LISTA BAN E' VUOTA";
|
||||||
|
$lang["banlist"]["lastupdate"] = "Ultimo aggiornamento: {0}";
|
||||||
|
|
||||||
|
$lang["banlist"]["table"]["emptyreason"] = "(nessun motivo)";
|
||||||
|
$lang["banlist"]["table"]["permaban"] = "Permanente";
|
||||||
|
|
||||||
|
$lang["banlist"]["table"]["nickname"] = "Nick";
|
||||||
|
$lang["banlist"]["table"]["reason"] = "Motivo";
|
||||||
|
$lang["banlist"]["table"]["bannedby"] = "Bananto da";
|
||||||
|
$lang["banlist"]["table"]["bandate"] = "Data del Ban";
|
||||||
|
$lang["banlist"]["table"]["expires"] = "Scade";
|
||||||
|
|
||||||
|
/************* Rules - rules.php *************/
|
||||||
|
|
||||||
|
$lang["rules"]["title"] = "Regolamento";
|
||||||
|
$lang["rules"]["filenotfound"] = "Errore: il file <code>config/rules.md</code> non è stato trovato!";
|
||||||
|
$lang["rules"]["readerror"] = "Errore: impossibile accede al file <code>config/rules.md</code>!";
|
@ -0,0 +1,104 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* Dutch language for ts-website
|
||||||
|
* @copy MojoW <mojow@solidsn4ke.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
$lang = array();
|
||||||
|
|
||||||
|
/************* General *************/
|
||||||
|
|
||||||
|
$lang["general"]["langcode"] = "nl_NL";
|
||||||
|
$lang["general"]["languageflag"] = "nl";
|
||||||
|
$lang["general"]["scripterror"] = "Er is een fout opgetreden! {0}: {1}";
|
||||||
|
|
||||||
|
/************* Navbar *************/
|
||||||
|
|
||||||
|
$lang["navbar"]["navigation"] = "Navigatie";
|
||||||
|
|
||||||
|
$lang["navbar"]["viewer"] = "Server Bekijken";
|
||||||
|
$lang["navbar"]["bans"] = "Ban Lijst";
|
||||||
|
$lang["navbar"]["rules"] = "Server Regels";
|
||||||
|
|
||||||
|
$lang["navbar"]["connect"] = "Verbinden met server";
|
||||||
|
$lang["navbar"]["connecttooltip"] = "Klik om verbinding te maken met {0}";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Footer *************/
|
||||||
|
|
||||||
|
$lang["footer"]["css"] = "CSS mogelijk gemaakt door";
|
||||||
|
$lang["footer"]["background"] = "achtergrond";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Server status *************/
|
||||||
|
|
||||||
|
$lang["serverstatus"]["title"] = "Server status";
|
||||||
|
$lang["serverstatus"]["address"] = "Adres";
|
||||||
|
$lang["serverstatus"]["loading"] = "Laden...";
|
||||||
|
|
||||||
|
$lang["serverstatus"]["online"] = "Online";
|
||||||
|
$lang["serverstatus"]["offline"] = "Offline";
|
||||||
|
$lang["serverstatus"]["uptime"] = "Uptijd";
|
||||||
|
$lang["serverstatus"]["version"] = "Versie";
|
||||||
|
$lang["serverstatus"]["avgping"] = "Gemiddelde ping";
|
||||||
|
$lang["serverstatus"]["avgpl"] = "Gemiddelde pakketverlies";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Admin list *************/
|
||||||
|
|
||||||
|
$lang["adminlist"]["title"] = "Adminlijst";
|
||||||
|
$lang["adminlist"]["emptygroup"] = "Deze groep is leeg";
|
||||||
|
$lang["adminlist"]["status"]["online"] = "Online";
|
||||||
|
$lang["adminlist"]["status"]["away"] = "Afwezig";
|
||||||
|
$lang["adminlist"]["status"]["offline"] = "Offline";
|
||||||
|
$lang["adminlist"]["lastupdate"] = "Laaste update: {0}";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Server viewer promo box (under adminlist and contact) *************/
|
||||||
|
|
||||||
|
$lang["svpb"]["title"] = "Server Bekijken";
|
||||||
|
$lang["svpb"]["takealook"] = "Neem een kijkje »";
|
||||||
|
|
||||||
|
|
||||||
|
/************************************/
|
||||||
|
/************* SUBPAGES *************/
|
||||||
|
/************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/************* News - index.php *************/
|
||||||
|
|
||||||
|
$lang["index"]["title"] = "Niews";
|
||||||
|
$lang["index"]["showmore"] = "Lees meer";
|
||||||
|
$lang["index"]["showless"] = "Minimaliseer";
|
||||||
|
|
||||||
|
$lang["index"]["errortitle"] = "Fout: niews map is niet gevonden!";
|
||||||
|
$lang["index"]["errorsubtitle"] = "Controleer A.U.B of de map locatie in <code>config/config.php</code> correct is.";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Server viewer - viewer.php *************/
|
||||||
|
|
||||||
|
$lang["viewer"]["title"] = "Server Bekijken";
|
||||||
|
$lang["viewer"]["lastupdate"] = "Laaste update: {0}";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Ban List - bans.php *************/
|
||||||
|
|
||||||
|
$lang["banlist"]["title"] = "Ban Lijst";
|
||||||
|
$lang["banlist"]["datatablesurl"] = "//cdn.datatables.net/plug-ins/1.10.12/i18n/Dutch.json";
|
||||||
|
$lang["banlist"]["emptylist"] = "BAN LIJST IS LEEG";
|
||||||
|
$lang["banlist"]["lastupdate"] = "Laaste update: {0}";
|
||||||
|
|
||||||
|
$lang["banlist"]["table"]["emptyreason"] = "(Geen reden)";
|
||||||
|
$lang["banlist"]["table"]["permaban"] = "Nooit";
|
||||||
|
|
||||||
|
$lang["banlist"]["table"]["nickname"] = "Bijnaam";
|
||||||
|
$lang["banlist"]["table"]["reason"] = "Reden";
|
||||||
|
$lang["banlist"]["table"]["bannedby"] = "Gebanned door";
|
||||||
|
$lang["banlist"]["table"]["bandate"] = "Ban datum";
|
||||||
|
$lang["banlist"]["table"]["expires"] = "Verloopt op";
|
||||||
|
|
||||||
|
/************* Rules - rules.php *************/
|
||||||
|
|
||||||
|
$lang["rules"]["title"] = "Server Regels";
|
||||||
|
$lang["rules"]["filenotfound"] = "Fout: kan het bestand <code>config/rules.md</code> niet vinden!";
|
||||||
|
$lang["rules"]["readerror"] = "Fout: Geen toegang tot het bestand <code>config/rules.md</code>!";
|
@ -0,0 +1,104 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* Polish language for ts-website
|
||||||
|
* @copy Wruczek <wruczekk@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
$lang = array();
|
||||||
|
|
||||||
|
/************* General *************/
|
||||||
|
|
||||||
|
$lang["general"]["langcode"] = "pl_PL";
|
||||||
|
$lang["general"]["languageflag"] = "pl";
|
||||||
|
$lang["general"]["scripterror"] = "Wystąpił błąd! {0}: {1}";
|
||||||
|
|
||||||
|
/************* Navbar *************/
|
||||||
|
|
||||||
|
$lang["navbar"]["navigation"] = "Nawigacja";
|
||||||
|
|
||||||
|
$lang["navbar"]["viewer"] = "Podgląd serwera";
|
||||||
|
$lang["navbar"]["bans"] = "Lista banów";
|
||||||
|
$lang["navbar"]["rules"] = "Regulamin";
|
||||||
|
|
||||||
|
$lang["navbar"]["connect"] = "Połącz z serwerem";
|
||||||
|
$lang["navbar"]["connecttooltip"] = "Kliknij, by połączyć się z serwerem {0}";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Footer *************/
|
||||||
|
|
||||||
|
$lang["footer"]["css"] = "CSS dzięki uprzejmości";
|
||||||
|
$lang["footer"]["background"] = "tło";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Server status *************/
|
||||||
|
|
||||||
|
$lang["serverstatus"]["title"] = "Status serwera";
|
||||||
|
$lang["serverstatus"]["address"] = "Adres";
|
||||||
|
$lang["serverstatus"]["loading"] = "Ładowanie...";
|
||||||
|
|
||||||
|
$lang["serverstatus"]["online"] = "Online";
|
||||||
|
$lang["serverstatus"]["offline"] = "Offline";
|
||||||
|
$lang["serverstatus"]["uptime"] = "Uptime";
|
||||||
|
$lang["serverstatus"]["version"] = "Wersja";
|
||||||
|
$lang["serverstatus"]["avgping"] = "Średni ping";
|
||||||
|
$lang["serverstatus"]["avgpl"] = "Średni packet loss";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Admin list *************/
|
||||||
|
|
||||||
|
$lang["adminlist"]["title"] = "Status administracji";
|
||||||
|
$lang["adminlist"]["emptygroup"] = "Ta grupa jest pusta";
|
||||||
|
$lang["adminlist"]["status"]["online"] = "Online";
|
||||||
|
$lang["adminlist"]["status"]["away"] = "Away";
|
||||||
|
$lang["adminlist"]["status"]["offline"] = "Offline";
|
||||||
|
$lang["adminlist"]["lastupdate"] = "Stan na {0}";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Server viewer promo box (under adminlist and contact) *************/
|
||||||
|
|
||||||
|
$lang["svpb"]["title"] = "Podgląd serwera";
|
||||||
|
$lang["svpb"]["takealook"] = "Zobacz »";
|
||||||
|
|
||||||
|
|
||||||
|
/************************************/
|
||||||
|
/************* SUBPAGES *************/
|
||||||
|
/************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/************* News - index.php *************/
|
||||||
|
|
||||||
|
$lang["index"]["title"] = "Wiadomości";
|
||||||
|
$lang["index"]["showmore"] = "Pokaż wiecej";
|
||||||
|
$lang["index"]["showless"] = "Pokaż mniej";
|
||||||
|
|
||||||
|
$lang["index"]["errortitle"] = "Wystąpił błąd: folder z newsami nie został odnaleziony.";
|
||||||
|
$lang["index"]["errorsubtitle"] = "Sprawdź, czy lokalizacja ustawiona w pliku <code>config/config.php</code> jest poprawna.";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Server viewer - viewer.php *************/
|
||||||
|
|
||||||
|
$lang["viewer"]["title"] = "Podgląd serwera";
|
||||||
|
$lang["viewer"]["lastupdate"] = "Stan na {0}";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Ban List - bans.php *************/
|
||||||
|
|
||||||
|
$lang["banlist"]["title"] = "Lista banów";
|
||||||
|
$lang["banlist"]["datatablesurl"] = "//cdn.datatables.net/plug-ins/1.10.12/i18n/Polish.json";
|
||||||
|
$lang["banlist"]["emptylist"] = "BRAK ZBANOWANYCH UŻYTKOWNIKÓW";
|
||||||
|
$lang["banlist"]["lastupdate"] = "Stan na {0}";
|
||||||
|
|
||||||
|
$lang["banlist"]["table"]["emptyreason"] = "(brak powodu)";
|
||||||
|
$lang["banlist"]["table"]["permaban"] = "Nigdy";
|
||||||
|
|
||||||
|
$lang["banlist"]["table"]["nickname"] = "Nick";
|
||||||
|
$lang["banlist"]["table"]["reason"] = "Powód";
|
||||||
|
$lang["banlist"]["table"]["bannedby"] = "Zbanowany przez";
|
||||||
|
$lang["banlist"]["table"]["bandate"] = "Data zbanowania";
|
||||||
|
$lang["banlist"]["table"]["expires"] = "Wygasa";
|
||||||
|
|
||||||
|
/************* Rules - rules.php *************/
|
||||||
|
|
||||||
|
$lang["rules"]["title"] = "Regulamin serwera";
|
||||||
|
$lang["rules"]["filenotfound"] = "Wystąpił błąd: plik <code>config/rules.md</code> nie został odnaleziony!";
|
||||||
|
$lang["rules"]["readerror"] = "Wystąpił błąd: nie można odczytać pliku <code>config/rules.md</code>!";
|
@ -0,0 +1,104 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* Swedish language for ts-website
|
||||||
|
* @copy Mattias G. <mattiasghodsian@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
$lang = array();
|
||||||
|
|
||||||
|
/************* General *************/
|
||||||
|
|
||||||
|
$lang["general"]["langcode"] = "se_SV";
|
||||||
|
$lang["general"]["languageflag"] = "se";
|
||||||
|
$lang["general"]["scripterror"] = "Ett fel inträffade! {0}: {1}";
|
||||||
|
|
||||||
|
/************* Navbar *************/
|
||||||
|
|
||||||
|
$lang["navbar"]["navigation"] = "Navigering";
|
||||||
|
|
||||||
|
$lang["navbar"]["viewer"] = "Server överblick";
|
||||||
|
$lang["navbar"]["bans"] = "Ban Lista";
|
||||||
|
$lang["navbar"]["rules"] = "Server Regler";
|
||||||
|
|
||||||
|
$lang["navbar"]["connect"] = "Anslut till servern";
|
||||||
|
$lang["navbar"]["connecttooltip"] = "Klicka för att ansluta till {0}";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Footer *************/
|
||||||
|
|
||||||
|
$lang["footer"]["css"] = "CSS av";
|
||||||
|
$lang["footer"]["background"] = "bakgrund";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Server status *************/
|
||||||
|
|
||||||
|
$lang["serverstatus"]["title"] = "Serverstatus";
|
||||||
|
$lang["serverstatus"]["address"] = "Adress";
|
||||||
|
$lang["serverstatus"]["loading"] = "Laddar...";
|
||||||
|
|
||||||
|
$lang["serverstatus"]["online"] = "Uppkopplad";
|
||||||
|
$lang["serverstatus"]["offline"] = "Nerkopplad";
|
||||||
|
$lang["serverstatus"]["uptime"] = "Upp tid";
|
||||||
|
$lang["serverstatus"]["version"] = "Version";
|
||||||
|
$lang["serverstatus"]["avgping"] = "Genomsnittlig ping";
|
||||||
|
$lang["serverstatus"]["avgpl"] = "Genomsnittlig paketförlust";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Admin list *************/
|
||||||
|
|
||||||
|
$lang["adminlist"]["title"] = "Admin lista";
|
||||||
|
$lang["adminlist"]["emptygroup"] = "Den här gruppen är tom";
|
||||||
|
$lang["adminlist"]["status"]["online"] = "Uppkopplad";
|
||||||
|
$lang["adminlist"]["status"]["away"] = "Bort";
|
||||||
|
$lang["adminlist"]["status"]["offline"] = "Nerkopplad";
|
||||||
|
$lang["adminlist"]["lastupdate"] = "Senaste uppdateringen: {0}";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Server viewer promo box (under adminlist and contact) *************/
|
||||||
|
|
||||||
|
$lang["svpb"]["title"] = "Server överblick";
|
||||||
|
$lang["svpb"]["takealook"] = "Ta en titt »";
|
||||||
|
|
||||||
|
|
||||||
|
/************************************/
|
||||||
|
/************* SUBPAGES *************/
|
||||||
|
/************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/************* News - index.php *************/
|
||||||
|
|
||||||
|
$lang["index"]["title"] = "Nyheter";
|
||||||
|
$lang["index"]["showmore"] = "Läs mer";
|
||||||
|
$lang["index"]["showless"] = "Visa mindre";
|
||||||
|
|
||||||
|
$lang["index"]["errortitle"] = "Fel: Nyhetskatalog har inte hittats!";
|
||||||
|
$lang["index"]["errorsubtitle"] = "Se till att katalogplatsen som anges i <b><code>config/config.php</code></b> är giltig. ";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Server viewer - viewer.php *************/
|
||||||
|
|
||||||
|
$lang["viewer"]["title"] = "Server överblick";
|
||||||
|
$lang["viewer"]["lastupdate"] = "Senaste uppdateringen: {0}";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Ban List - bans.php *************/
|
||||||
|
|
||||||
|
$lang["banlist"]["title"] = "Ban ListA";
|
||||||
|
$lang["banlist"]["datatablesurl"] = "/cdn.datatables.net/plug-ins/1.10.12/i18n/Swedish.json";
|
||||||
|
$lang["banlist"]["emptylist"] = "BANLISTAN ÄR TOM";
|
||||||
|
$lang["banlist"]["lastupdate"] = "Senaste uppdateringen: {0}";
|
||||||
|
|
||||||
|
$lang["banlist"]["table"]["emptyreason"] = "(Ingen anledning inställd)";
|
||||||
|
$lang["banlist"]["table"]["permaban"] = "Aldrig";
|
||||||
|
|
||||||
|
$lang["banlist"]["table"]["nickname"] = "Nick";
|
||||||
|
$lang["banlist"]["table"]["reason"] = "Anledning";
|
||||||
|
$lang["banlist"]["table"]["bannedby"] = "Banned av";
|
||||||
|
$lang["banlist"]["table"]["bandate"] = "Ban tid";
|
||||||
|
$lang["banlist"]["table"]["expires"] = "Löper ut";
|
||||||
|
|
||||||
|
/************* Rules - rules.php *************/
|
||||||
|
|
||||||
|
$lang["rules"]["title"] = "Server Regler";
|
||||||
|
$lang["rules"]["filenotfound"] = "Fel: filen <code>config/rules.md</code> har inte hittats!";
|
||||||
|
$lang["rules"]["readerror"] = "Fel: kan inte komma åt filen <code>config/rules.md</code>!";
|
@ -0,0 +1,104 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* Turkish language for ts-website
|
||||||
|
* @copy Eikichi <kontakt@eiki.moe>
|
||||||
|
*/
|
||||||
|
|
||||||
|
$lang = array();
|
||||||
|
|
||||||
|
/************* General *************/
|
||||||
|
|
||||||
|
$lang["general"]["langcode"] = "tr_TR";
|
||||||
|
$lang["general"]["languageflag"] = "tr";
|
||||||
|
$lang["general"]["scripterror"] = "Bir hata olmustur! {0}: {1}";
|
||||||
|
|
||||||
|
/************* Navbar *************/
|
||||||
|
|
||||||
|
$lang["navbar"]["navigation"] = "Navigasyon";
|
||||||
|
|
||||||
|
$lang["navbar"]["viewer"] = "Sunucu Görüntüleyici";
|
||||||
|
$lang["navbar"]["bans"] = "Ban listesi";
|
||||||
|
$lang["navbar"]["rules"] = "Sunucu kurallari";
|
||||||
|
|
||||||
|
$lang["navbar"]["connect"] = "Sunucuya Baglan";
|
||||||
|
$lang["navbar"]["connecttooltip"] = "Baglanmak için {0} tiklayin";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Footer *************/
|
||||||
|
|
||||||
|
$lang["footer"]["css"] = "CSS tarafindan saglanan";
|
||||||
|
$lang["footer"]["background"] = "Arka plân";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Server status *************/
|
||||||
|
|
||||||
|
$lang["serverstatus"]["title"] = "Sunucu durumu";
|
||||||
|
$lang["serverstatus"]["address"] = "Adres";
|
||||||
|
$lang["serverstatus"]["loading"] = "Yükleme...";
|
||||||
|
|
||||||
|
$lang["serverstatus"]["online"] = "Online";
|
||||||
|
$lang["serverstatus"]["offline"] = "Offline";
|
||||||
|
$lang["serverstatus"]["uptime"] = "Çalisma süresi";
|
||||||
|
$lang["serverstatus"]["version"] = "Sunucu sürümü";
|
||||||
|
$lang["serverstatus"]["avgping"] = "Ø Ping";
|
||||||
|
$lang["serverstatus"]["avgpl"] = "Ø Paket kaybi";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Admin list *************/
|
||||||
|
|
||||||
|
$lang["adminlist"]["title"] = "Yönetici listesi";
|
||||||
|
$lang["adminlist"]["emptygroup"] = "Bu grup bos";
|
||||||
|
$lang["adminlist"]["status"]["online"] = "Online";
|
||||||
|
$lang["adminlist"]["status"]["away"] = "Yok";
|
||||||
|
$lang["adminlist"]["status"]["offline"] = "Offline";
|
||||||
|
$lang["adminlist"]["lastupdate"] = "Son güncelleme: {0}";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Server viewer promo box (under adminlist and contact) *************/
|
||||||
|
|
||||||
|
$lang["svpb"]["title"] = "Sunucu Görüntüleyici";
|
||||||
|
$lang["svpb"]["takealook"] = "Görüntüle »";
|
||||||
|
|
||||||
|
|
||||||
|
/************************************/
|
||||||
|
/************* SUBPAGES *************/
|
||||||
|
/************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/************* News - index.php *************/
|
||||||
|
|
||||||
|
$lang["index"]["title"] = "Haber";
|
||||||
|
$lang["index"]["showmore"] = "Daha görüntüle";
|
||||||
|
$lang["index"]["showless"] = "Daha az";
|
||||||
|
|
||||||
|
$lang["index"]["errortitle"] = "Hata: Haber klasörü bulunamadi!";
|
||||||
|
$lang["index"]["errorsubtitle"] = "Klasör yolu <code>config / config.php</code> dogru belirtilen emin olun.";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Server viewer - viewer.php *************/
|
||||||
|
|
||||||
|
$lang["viewer"]["title"] = "Sunucu Görüntüleyici";
|
||||||
|
$lang["viewer"]["lastupdate"] = "Son güncelleme: {0}";
|
||||||
|
|
||||||
|
|
||||||
|
/************* Ban List - bans.php *************/
|
||||||
|
|
||||||
|
$lang["banlist"]["title"] = "Ban listesi";
|
||||||
|
$lang["banlist"]["datatablesurl"] = "//cdn.datatables.net/plug-ins/1.10.12/i18n/Turkish.json";
|
||||||
|
$lang["banlist"]["emptylist"] = "Hiçbir lanetli Kullanici su anda yok";
|
||||||
|
$lang["banlist"]["lastupdate"] = "Son güncelleme: {0}";
|
||||||
|
|
||||||
|
$lang["banlist"]["table"]["emptyreason"] = "(Verilen hiçbir neden)";
|
||||||
|
$lang["banlist"]["table"]["permaban"] = "Asla";
|
||||||
|
|
||||||
|
$lang["banlist"]["table"]["nickname"] = "Kullanici adi";
|
||||||
|
$lang["banlist"]["table"]["reason"] = "Neden";
|
||||||
|
$lang["banlist"]["table"]["bannedby"] = "Banlayan kisi";
|
||||||
|
$lang["banlist"]["table"]["bandate"] = "Ban zaman";
|
||||||
|
$lang["banlist"]["table"]["expires"] = "Sona eriyor";
|
||||||
|
|
||||||
|
/************* Rules - rules.php *************/
|
||||||
|
|
||||||
|
$lang["rules"]["title"] = "Sunucu kurallari";
|
||||||
|
$lang["rules"]["filenotfound"] = "Hata: Dosya <code>config / rules.md</code> bulunamadi!";
|
||||||
|
$lang["rules"]["readerror"] = "Hata: erisim için yeterli haklar <code>config / rules.md</code>!";
|
@ -0,0 +1 @@
|
|||||||
|
Visit your freshly installed ts-website to see instructions about news system
|
@ -0,0 +1,36 @@
|
|||||||
|
About the news system
|
||||||
|
Wruczek, 2016-10-26, 21:00
|
||||||
|
|
||||||
|
You can add, change and remove news as a separate Markdown files located in `config/news` folder with extension `.md`.
|
||||||
|
|
||||||
|
I recommend following John Gruber's excellent markdown guide, found right under this text <i class="fa fa-long-arrow-down" aria-hidden="true"></i>. It's really worth reading. To view the code that makes up the guide, go to `config/news/news2.md`.
|
||||||
|
|
||||||
|
I can also recommend GitHub's ["Mastering Markdown"](https://guides.github.com/features/mastering-markdown/) guide.
|
||||||
|
|
||||||
|
**PS**: You can mix Markdown with HTML to add cool stuff like icons <i class="fa fa-smile-o" aria-hidden="true"></i> <i class="fa fa-thumbs-o-up" aria-hidden="true"></i>, or even a full YouTube player with video!
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### Informations:
|
||||||
|
- News are read from the `config/news` folder, alphabetically sorted by file name. (news A.md will be at top of the page while Z.md at the bottom)
|
||||||
|
- Every news file need to have `.md` (Markdown) extension
|
||||||
|
- News file syntax:
|
||||||
|
- First line: News title
|
||||||
|
- Second line: author and date
|
||||||
|
- Third line: empty (seperator)
|
||||||
|
- The rest of the file is Markdown code and HTML
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### Example news file:
|
||||||
|
|
||||||
|
News system test
|
||||||
|
Wruczek, 26-10-2016
|
||||||
|
|
||||||
|
Hello **world**!
|
||||||
|
|
||||||
|
I am the *news file*, you can save me in **config/news** folder with an **.md** extension to see me on the page!
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
*Good luck and Happy writing! -Wruczek*
|
@ -0,0 +1,884 @@
|
|||||||
|
Markdown Syntax - example Markdown test file
|
||||||
|
John Gruber, daringfireball.net
|
||||||
|
|
||||||
|
Markdown: Syntax
|
||||||
|
================
|
||||||
|
|
||||||
|
* [Overview](#overview)
|
||||||
|
* [Philosophy](#philosophy)
|
||||||
|
* [Inline HTML](#html)
|
||||||
|
* [Automatic Escaping for Special Characters](#autoescape)
|
||||||
|
* [Block Elements](#block)
|
||||||
|
* [Paragraphs and Line Breaks](#p)
|
||||||
|
* [Headers](#header)
|
||||||
|
* [Blockquotes](#blockquote)
|
||||||
|
* [Lists](#list)
|
||||||
|
* [Code Blocks](#precode)
|
||||||
|
* [Horizontal Rules](#hr)
|
||||||
|
* [Span Elements](#span)
|
||||||
|
* [Links](#link)
|
||||||
|
* [Emphasis](#em)
|
||||||
|
* [Code](#code)
|
||||||
|
* [Images](#img)
|
||||||
|
* [Miscellaneous](#misc)
|
||||||
|
* [Backslash Escapes](#backslash)
|
||||||
|
* [Automatic Links](#autolink)
|
||||||
|
|
||||||
|
* * *
|
||||||
|
|
||||||
|
<h2 id="overview">Overview</h2>
|
||||||
|
|
||||||
|
<h3 id="philosophy">Philosophy</h3>
|
||||||
|
|
||||||
|
Markdown is intended to be as easy-to-read and easy-to-write as is feasible.
|
||||||
|
|
||||||
|
Readability, however, is emphasized above all else. A Markdown-formatted
|
||||||
|
document should be publishable as-is, as plain text, without looking
|
||||||
|
like it's been marked up with tags or formatting instructions. While
|
||||||
|
Markdown's syntax has been influenced by several existing text-to-HTML
|
||||||
|
filters -- including [Setext] [1], [atx] [2], [Textile] [3], [reStructuredText] [4],
|
||||||
|
[Grutatext] [5], and [EtText] [6] -- the single biggest source of
|
||||||
|
inspiration for Markdown's syntax is the format of plain text email.
|
||||||
|
|
||||||
|
[1]: http://docutils.sourceforge.net/mirror/setext.html
|
||||||
|
[2]: http://www.aaronsw.com/2002/atx/
|
||||||
|
[3]: http://textism.com/tools/textile/
|
||||||
|
[4]: http://docutils.sourceforge.net/rst.html
|
||||||
|
[5]: http://www.triptico.com/software/grutatxt.html
|
||||||
|
[6]: http://ettext.taint.org/doc/
|
||||||
|
|
||||||
|
To this end, Markdown's syntax is comprised entirely of punctuation
|
||||||
|
characters, which punctuation characters have been carefully chosen so
|
||||||
|
as to look like what they mean. E.g., asterisks around a word actually
|
||||||
|
look like \*emphasis\*. Markdown lists look like, well, lists. Even
|
||||||
|
blockquotes look like quoted passages of text, assuming you've ever
|
||||||
|
used email.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<h3 id="html">Inline HTML</h3>
|
||||||
|
|
||||||
|
Markdown's syntax is intended for one purpose: to be used as a
|
||||||
|
format for *writing* for the web.
|
||||||
|
|
||||||
|
Markdown is not a replacement for HTML, or even close to it. Its
|
||||||
|
syntax is very small, corresponding only to a very small subset of
|
||||||
|
HTML tags. The idea is *not* to create a syntax that makes it easier
|
||||||
|
to insert HTML tags. In my opinion, HTML tags are already easy to
|
||||||
|
insert. The idea for Markdown is to make it easy to read, write, and
|
||||||
|
edit prose. HTML is a *publishing* format; Markdown is a *writing*
|
||||||
|
format. Thus, Markdown's formatting syntax only addresses issues that
|
||||||
|
can be conveyed in plain text.
|
||||||
|
|
||||||
|
For any markup that is not covered by Markdown's syntax, you simply
|
||||||
|
use HTML itself. There's no need to preface it or delimit it to
|
||||||
|
indicate that you're switching from Markdown to HTML; you just use
|
||||||
|
the tags.
|
||||||
|
|
||||||
|
The only restrictions are that block-level HTML elements -- e.g. `<div>`,
|
||||||
|
`<table>`, `<pre>`, `<p>`, etc. -- must be separated from surrounding
|
||||||
|
content by blank lines, and the start and end tags of the block should
|
||||||
|
not be indented with tabs or spaces. Markdown is smart enough not
|
||||||
|
to add extra (unwanted) `<p>` tags around HTML block-level tags.
|
||||||
|
|
||||||
|
For example, to add an HTML table to a Markdown article:
|
||||||
|
|
||||||
|
This is a regular paragraph.
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td>Foo</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
This is another regular paragraph.
|
||||||
|
|
||||||
|
Note that Markdown formatting syntax is not processed within block-level
|
||||||
|
HTML tags. E.g., you can't use Markdown-style `*emphasis*` inside an
|
||||||
|
HTML block.
|
||||||
|
|
||||||
|
Span-level HTML tags -- e.g. `<span>`, `<cite>`, or `<del>` -- can be
|
||||||
|
used anywhere in a Markdown paragraph, list item, or header. If you
|
||||||
|
want, you can even use HTML tags instead of Markdown formatting; e.g. if
|
||||||
|
you'd prefer to use HTML `<a>` or `<img>` tags instead of Markdown's
|
||||||
|
link or image syntax, go right ahead.
|
||||||
|
|
||||||
|
Unlike block-level HTML tags, Markdown syntax *is* processed within
|
||||||
|
span-level tags.
|
||||||
|
|
||||||
|
|
||||||
|
<h3 id="autoescape">Automatic Escaping for Special Characters</h3>
|
||||||
|
|
||||||
|
In HTML, there are two characters that demand special treatment: `<`
|
||||||
|
and `&`. Left angle brackets are used to start tags; ampersands are
|
||||||
|
used to denote HTML entities. If you want to use them as literal
|
||||||
|
characters, you must escape them as entities, e.g. `<`, and
|
||||||
|
`&`.
|
||||||
|
|
||||||
|
Ampersands in particular are bedeviling for web writers. If you want to
|
||||||
|
write about 'AT&T', you need to write '`AT&T`'. You even need to
|
||||||
|
escape ampersands within URLs. Thus, if you want to link to:
|
||||||
|
|
||||||
|
http://images.google.com/images?num=30&q=larry+bird
|
||||||
|
|
||||||
|
you need to encode the URL as:
|
||||||
|
|
||||||
|
http://images.google.com/images?num=30&q=larry+bird
|
||||||
|
|
||||||
|
in your anchor tag `href` attribute. Needless to say, this is easy to
|
||||||
|
forget, and is probably the single most common source of HTML validation
|
||||||
|
errors in otherwise well-marked-up web sites.
|
||||||
|
|
||||||
|
Markdown allows you to use these characters naturally, taking care of
|
||||||
|
all the necessary escaping for you. If you use an ampersand as part of
|
||||||
|
an HTML entity, it remains unchanged; otherwise it will be translated
|
||||||
|
into `&`.
|
||||||
|
|
||||||
|
So, if you want to include a copyright symbol in your article, you can write:
|
||||||
|
|
||||||
|
©
|
||||||
|
|
||||||
|
and Markdown will leave it alone. But if you write:
|
||||||
|
|
||||||
|
AT&T
|
||||||
|
|
||||||
|
Markdown will translate it to:
|
||||||
|
|
||||||
|
AT&T
|
||||||
|
|
||||||
|
Similarly, because Markdown supports [inline HTML](#html), if you use
|
||||||
|
angle brackets as delimiters for HTML tags, Markdown will treat them as
|
||||||
|
such. But if you write:
|
||||||
|
|
||||||
|
4 < 5
|
||||||
|
|
||||||
|
Markdown will translate it to:
|
||||||
|
|
||||||
|
4 < 5
|
||||||
|
|
||||||
|
However, inside Markdown code spans and blocks, angle brackets and
|
||||||
|
ampersands are *always* encoded automatically. This makes it easy to use
|
||||||
|
Markdown to write about HTML code. (As opposed to raw HTML, which is a
|
||||||
|
terrible format for writing about HTML syntax, because every single `<`
|
||||||
|
and `&` in your example code needs to be escaped.)
|
||||||
|
|
||||||
|
|
||||||
|
* * *
|
||||||
|
|
||||||
|
|
||||||
|
<h2 id="block">Block Elements</h2>
|
||||||
|
|
||||||
|
|
||||||
|
<h3 id="p">Paragraphs and Line Breaks</h3>
|
||||||
|
|
||||||
|
A paragraph is simply one or more consecutive lines of text, separated
|
||||||
|
by one or more blank lines. (A blank line is any line that looks like a
|
||||||
|
blank line -- a line containing nothing but spaces or tabs is considered
|
||||||
|
blank.) Normal paragraphs should not be indented with spaces or tabs.
|
||||||
|
|
||||||
|
The implication of the "one or more consecutive lines of text" rule is
|
||||||
|
that Markdown supports "hard-wrapped" text paragraphs. This differs
|
||||||
|
significantly from most other text-to-HTML formatters (including Movable
|
||||||
|
Type's "Convert Line Breaks" option) which translate every line break
|
||||||
|
character in a paragraph into a `<br />` tag.
|
||||||
|
|
||||||
|
When you *do* want to insert a `<br />` break tag using Markdown, you
|
||||||
|
end a line with two or more spaces, then type return.
|
||||||
|
|
||||||
|
Yes, this takes a tad more effort to create a `<br />`, but a simplistic
|
||||||
|
"every line break is a `<br />`" rule wouldn't work for Markdown.
|
||||||
|
Markdown's email-style [blockquoting][bq] and multi-paragraph [list items][l]
|
||||||
|
work best -- and look better -- when you format them with hard breaks.
|
||||||
|
|
||||||
|
[bq]: #blockquote
|
||||||
|
[l]: #list
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<h3 id="header">Headers</h3>
|
||||||
|
|
||||||
|
Markdown supports two styles of headers, [Setext] [1] and [atx] [2].
|
||||||
|
|
||||||
|
Setext-style headers are "underlined" using equal signs (for first-level
|
||||||
|
headers) and dashes (for second-level headers). For example:
|
||||||
|
|
||||||
|
This is an H1
|
||||||
|
=============
|
||||||
|
|
||||||
|
This is an H2
|
||||||
|
-------------
|
||||||
|
|
||||||
|
Any number of underlining `=`'s or `-`'s will work.
|
||||||
|
|
||||||
|
Atx-style headers use 1-6 hash characters at the start of the line,
|
||||||
|
corresponding to header levels 1-6. For example:
|
||||||
|
|
||||||
|
# This is an H1
|
||||||
|
|
||||||
|
## This is an H2
|
||||||
|
|
||||||
|
###### This is an H6
|
||||||
|
|
||||||
|
Optionally, you may "close" atx-style headers. This is purely
|
||||||
|
cosmetic -- you can use this if you think it looks better. The
|
||||||
|
closing hashes don't even need to match the number of hashes
|
||||||
|
used to open the header. (The number of opening hashes
|
||||||
|
determines the header level.) :
|
||||||
|
|
||||||
|
# This is an H1 #
|
||||||
|
|
||||||
|
## This is an H2 ##
|
||||||
|
|
||||||
|
### This is an H3 ######
|
||||||
|
|
||||||
|
|
||||||
|
<h3 id="blockquote">Blockquotes</h3>
|
||||||
|
|
||||||
|
Markdown uses email-style `>` characters for blockquoting. If you're
|
||||||
|
familiar with quoting passages of text in an email message, then you
|
||||||
|
know how to create a blockquote in Markdown. It looks best if you hard
|
||||||
|
wrap the text and put a `>` before every line:
|
||||||
|
|
||||||
|
> This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
|
||||||
|
> consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.
|
||||||
|
> Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.
|
||||||
|
>
|
||||||
|
> Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
|
||||||
|
> id sem consectetuer libero luctus adipiscing.
|
||||||
|
|
||||||
|
Markdown allows you to be lazy and only put the `>` before the first
|
||||||
|
line of a hard-wrapped paragraph:
|
||||||
|
|
||||||
|
> This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
|
||||||
|
consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.
|
||||||
|
Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.
|
||||||
|
|
||||||
|
> Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
|
||||||
|
id sem consectetuer libero luctus adipiscing.
|
||||||
|
|
||||||
|
Blockquotes can be nested (i.e. a blockquote-in-a-blockquote) by
|
||||||
|
adding additional levels of `>`:
|
||||||
|
|
||||||
|
> This is the first level of quoting.
|
||||||
|
>
|
||||||
|
> > This is nested blockquote.
|
||||||
|
>
|
||||||
|
> Back to the first level.
|
||||||
|
|
||||||
|
Blockquotes can contain other Markdown elements, including headers, lists,
|
||||||
|
and code blocks:
|
||||||
|
|
||||||
|
> ## This is a header.
|
||||||
|
>
|
||||||
|
> 1. This is the first list item.
|
||||||
|
> 2. This is the second list item.
|
||||||
|
>
|
||||||
|
> Here's some example code:
|
||||||
|
>
|
||||||
|
> return shell_exec("echo $input | $markdown_script");
|
||||||
|
|
||||||
|
Any decent text editor should make email-style quoting easy. For
|
||||||
|
example, with BBEdit, you can make a selection and choose Increase
|
||||||
|
Quote Level from the Text menu.
|
||||||
|
|
||||||
|
|
||||||
|
<h3 id="list">Lists</h3>
|
||||||
|
|
||||||
|
Markdown supports ordered (numbered) and unordered (bulleted) lists.
|
||||||
|
|
||||||
|
Unordered lists use asterisks, pluses, and hyphens -- interchangably
|
||||||
|
-- as list markers:
|
||||||
|
|
||||||
|
* Red
|
||||||
|
* Green
|
||||||
|
* Blue
|
||||||
|
|
||||||
|
is equivalent to:
|
||||||
|
|
||||||
|
+ Red
|
||||||
|
+ Green
|
||||||
|
+ Blue
|
||||||
|
|
||||||
|
and:
|
||||||
|
|
||||||
|
- Red
|
||||||
|
- Green
|
||||||
|
- Blue
|
||||||
|
|
||||||
|
Ordered lists use numbers followed by periods:
|
||||||
|
|
||||||
|
1. Bird
|
||||||
|
2. McHale
|
||||||
|
3. Parish
|
||||||
|
|
||||||
|
It's important to note that the actual numbers you use to mark the
|
||||||
|
list have no effect on the HTML output Markdown produces. The HTML
|
||||||
|
Markdown produces from the above list is:
|
||||||
|
|
||||||
|
<ol>
|
||||||
|
<li>Bird</li>
|
||||||
|
<li>McHale</li>
|
||||||
|
<li>Parish</li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
If you instead wrote the list in Markdown like this:
|
||||||
|
|
||||||
|
1. Bird
|
||||||
|
1. McHale
|
||||||
|
1. Parish
|
||||||
|
|
||||||
|
or even:
|
||||||
|
|
||||||
|
3. Bird
|
||||||
|
1. McHale
|
||||||
|
8. Parish
|
||||||
|
|
||||||
|
you'd get the exact same HTML output. The point is, if you want to,
|
||||||
|
you can use ordinal numbers in your ordered Markdown lists, so that
|
||||||
|
the numbers in your source match the numbers in your published HTML.
|
||||||
|
But if you want to be lazy, you don't have to.
|
||||||
|
|
||||||
|
If you do use lazy list numbering, however, you should still start the
|
||||||
|
list with the number 1. At some point in the future, Markdown may support
|
||||||
|
starting ordered lists at an arbitrary number.
|
||||||
|
|
||||||
|
List markers typically start at the left margin, but may be indented by
|
||||||
|
up to three spaces. List markers must be followed by one or more spaces
|
||||||
|
or a tab.
|
||||||
|
|
||||||
|
To make lists look nice, you can wrap items with hanging indents:
|
||||||
|
|
||||||
|
* Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
|
||||||
|
Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi,
|
||||||
|
viverra nec, fringilla in, laoreet vitae, risus.
|
||||||
|
* Donec sit amet nisl. Aliquam semper ipsum sit amet velit.
|
||||||
|
Suspendisse id sem consectetuer libero luctus adipiscing.
|
||||||
|
|
||||||
|
But if you want to be lazy, you don't have to:
|
||||||
|
|
||||||
|
* Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
|
||||||
|
Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi,
|
||||||
|
viverra nec, fringilla in, laoreet vitae, risus.
|
||||||
|
* Donec sit amet nisl. Aliquam semper ipsum sit amet velit.
|
||||||
|
Suspendisse id sem consectetuer libero luctus adipiscing.
|
||||||
|
|
||||||
|
If list items are separated by blank lines, Markdown will wrap the
|
||||||
|
items in `<p>` tags in the HTML output. For example, this input:
|
||||||
|
|
||||||
|
* Bird
|
||||||
|
* Magic
|
||||||
|
|
||||||
|
will turn into:
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li>Bird</li>
|
||||||
|
<li>Magic</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
But this:
|
||||||
|
|
||||||
|
* Bird
|
||||||
|
|
||||||
|
* Magic
|
||||||
|
|
||||||
|
will turn into:
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li><p>Bird</p></li>
|
||||||
|
<li><p>Magic</p></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
List items may consist of multiple paragraphs. Each subsequent
|
||||||
|
paragraph in a list item must be indented by either 4 spaces
|
||||||
|
or one tab:
|
||||||
|
|
||||||
|
1. This is a list item with two paragraphs. Lorem ipsum dolor
|
||||||
|
sit amet, consectetuer adipiscing elit. Aliquam hendrerit
|
||||||
|
mi posuere lectus.
|
||||||
|
|
||||||
|
Vestibulum enim wisi, viverra nec, fringilla in, laoreet
|
||||||
|
vitae, risus. Donec sit amet nisl. Aliquam semper ipsum
|
||||||
|
sit amet velit.
|
||||||
|
|
||||||
|
2. Suspendisse id sem consectetuer libero luctus adipiscing.
|
||||||
|
|
||||||
|
It looks nice if you indent every line of the subsequent
|
||||||
|
paragraphs, but here again, Markdown will allow you to be
|
||||||
|
lazy:
|
||||||
|
|
||||||
|
* This is a list item with two paragraphs.
|
||||||
|
|
||||||
|
This is the second paragraph in the list item. You're
|
||||||
|
only required to indent the first line. Lorem ipsum dolor
|
||||||
|
sit amet, consectetuer adipiscing elit.
|
||||||
|
|
||||||
|
* Another item in the same list.
|
||||||
|
|
||||||
|
To put a blockquote within a list item, the blockquote's `>`
|
||||||
|
delimiters need to be indented:
|
||||||
|
|
||||||
|
* A list item with a blockquote:
|
||||||
|
|
||||||
|
> This is a blockquote
|
||||||
|
> inside a list item.
|
||||||
|
|
||||||
|
To put a code block within a list item, the code block needs
|
||||||
|
to be indented *twice* -- 8 spaces or two tabs:
|
||||||
|
|
||||||
|
* A list item with a code block:
|
||||||
|
|
||||||
|
<code goes here>
|
||||||
|
|
||||||
|
|
||||||
|
It's worth noting that it's possible to trigger an ordered list by
|
||||||
|
accident, by writing something like this:
|
||||||
|
|
||||||
|
1986. What a great season.
|
||||||
|
|
||||||
|
In other words, a *number-period-space* sequence at the beginning of a
|
||||||
|
line. To avoid this, you can backslash-escape the period:
|
||||||
|
|
||||||
|
1986\. What a great season.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<h3 id="precode">Code Blocks</h3>
|
||||||
|
|
||||||
|
Pre-formatted code blocks are used for writing about programming or
|
||||||
|
markup source code. Rather than forming normal paragraphs, the lines
|
||||||
|
of a code block are interpreted literally. Markdown wraps a code block
|
||||||
|
in both `<pre>` and `<code>` tags.
|
||||||
|
|
||||||
|
To produce a code block in Markdown, simply indent every line of the
|
||||||
|
block by at least 4 spaces or 1 tab. For example, given this input:
|
||||||
|
|
||||||
|
This is a normal paragraph:
|
||||||
|
|
||||||
|
This is a code block.
|
||||||
|
|
||||||
|
Markdown will generate:
|
||||||
|
|
||||||
|
<p>This is a normal paragraph:</p>
|
||||||
|
|
||||||
|
<pre><code>This is a code block.
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
One level of indentation -- 4 spaces or 1 tab -- is removed from each
|
||||||
|
line of the code block. For example, this:
|
||||||
|
|
||||||
|
Here is an example of AppleScript:
|
||||||
|
|
||||||
|
tell application "Foo"
|
||||||
|
beep
|
||||||
|
end tell
|
||||||
|
|
||||||
|
will turn into:
|
||||||
|
|
||||||
|
<p>Here is an example of AppleScript:</p>
|
||||||
|
|
||||||
|
<pre><code>tell application "Foo"
|
||||||
|
beep
|
||||||
|
end tell
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
A code block continues until it reaches a line that is not indented
|
||||||
|
(or the end of the article).
|
||||||
|
|
||||||
|
Within a code block, ampersands (`&`) and angle brackets (`<` and `>`)
|
||||||
|
are automatically converted into HTML entities. This makes it very
|
||||||
|
easy to include example HTML source code using Markdown -- just paste
|
||||||
|
it and indent it, and Markdown will handle the hassle of encoding the
|
||||||
|
ampersands and angle brackets. For example, this:
|
||||||
|
|
||||||
|
<div class="footer">
|
||||||
|
© 2004 Foo Corporation
|
||||||
|
</div>
|
||||||
|
|
||||||
|
will turn into:
|
||||||
|
|
||||||
|
<pre><code><div class="footer">
|
||||||
|
&copy; 2004 Foo Corporation
|
||||||
|
</div>
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
Regular Markdown syntax is not processed within code blocks. E.g.,
|
||||||
|
asterisks are just literal asterisks within a code block. This means
|
||||||
|
it's also easy to use Markdown to write about Markdown's own syntax.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<h3 id="hr">Horizontal Rules</h3>
|
||||||
|
|
||||||
|
You can produce a horizontal rule tag (`<hr />`) by placing three or
|
||||||
|
more hyphens, asterisks, or underscores on a line by themselves. If you
|
||||||
|
wish, you may use spaces between the hyphens or asterisks. Each of the
|
||||||
|
following lines will produce a horizontal rule:
|
||||||
|
|
||||||
|
* * *
|
||||||
|
|
||||||
|
***
|
||||||
|
|
||||||
|
*****
|
||||||
|
|
||||||
|
- - -
|
||||||
|
|
||||||
|
---------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
* * *
|
||||||
|
|
||||||
|
<h2 id="span">Span Elements</h2>
|
||||||
|
|
||||||
|
<h3 id="link">Links</h3>
|
||||||
|
|
||||||
|
Markdown supports two style of links: *inline* and *reference*.
|
||||||
|
|
||||||
|
In both styles, the link text is delimited by [square brackets].
|
||||||
|
|
||||||
|
To create an inline link, use a set of regular parentheses immediately
|
||||||
|
after the link text's closing square bracket. Inside the parentheses,
|
||||||
|
put the URL where you want the link to point, along with an *optional*
|
||||||
|
title for the link, surrounded in quotes. For example:
|
||||||
|
|
||||||
|
This is [an example](http://example.com/ "Title") inline link.
|
||||||
|
|
||||||
|
[This link](http://example.net/) has no title attribute.
|
||||||
|
|
||||||
|
Will produce:
|
||||||
|
|
||||||
|
<p>This is <a href="http://example.com/" title="Title">
|
||||||
|
an example</a> inline link.</p>
|
||||||
|
|
||||||
|
<p><a href="http://example.net/">This link</a> has no
|
||||||
|
title attribute.</p>
|
||||||
|
|
||||||
|
If you're referring to a local resource on the same server, you can
|
||||||
|
use relative paths:
|
||||||
|
|
||||||
|
See my [About](/about/) page for details.
|
||||||
|
|
||||||
|
Reference-style links use a second set of square brackets, inside
|
||||||
|
which you place a label of your choosing to identify the link:
|
||||||
|
|
||||||
|
This is [an example][id] reference-style link.
|
||||||
|
|
||||||
|
You can optionally use a space to separate the sets of brackets:
|
||||||
|
|
||||||
|
This is [an example] [id] reference-style link.
|
||||||
|
|
||||||
|
Then, anywhere in the document, you define your link label like this,
|
||||||
|
on a line by itself:
|
||||||
|
|
||||||
|
[id]: http://example.com/ "Optional Title Here"
|
||||||
|
|
||||||
|
That is:
|
||||||
|
|
||||||
|
* Square brackets containing the link identifier (optionally
|
||||||
|
indented from the left margin using up to three spaces);
|
||||||
|
* followed by a colon;
|
||||||
|
* followed by one or more spaces (or tabs);
|
||||||
|
* followed by the URL for the link;
|
||||||
|
* optionally followed by a title attribute for the link, enclosed
|
||||||
|
in double or single quotes, or enclosed in parentheses.
|
||||||
|
|
||||||
|
The following three link definitions are equivalent:
|
||||||
|
|
||||||
|
[foo]: http://example.com/ "Optional Title Here"
|
||||||
|
[foo]: http://example.com/ 'Optional Title Here'
|
||||||
|
[foo]: http://example.com/ (Optional Title Here)
|
||||||
|
|
||||||
|
**Note:** There is a known bug in Markdown.pl 1.0.1 which prevents
|
||||||
|
single quotes from being used to delimit link titles.
|
||||||
|
|
||||||
|
The link URL may, optionally, be surrounded by angle brackets:
|
||||||
|
|
||||||
|
[id]: <http://example.com/> "Optional Title Here"
|
||||||
|
|
||||||
|
You can put the title attribute on the next line and use extra spaces
|
||||||
|
or tabs for padding, which tends to look better with longer URLs:
|
||||||
|
|
||||||
|
[id]: http://example.com/longish/path/to/resource/here
|
||||||
|
"Optional Title Here"
|
||||||
|
|
||||||
|
Link definitions are only used for creating links during Markdown
|
||||||
|
processing, and are stripped from your document in the HTML output.
|
||||||
|
|
||||||
|
Link definition names may consist of letters, numbers, spaces, and
|
||||||
|
punctuation -- but they are *not* case sensitive. E.g. these two
|
||||||
|
links:
|
||||||
|
|
||||||
|
[link text][a]
|
||||||
|
[link text][A]
|
||||||
|
|
||||||
|
are equivalent.
|
||||||
|
|
||||||
|
The *implicit link name* shortcut allows you to omit the name of the
|
||||||
|
link, in which case the link text itself is used as the name.
|
||||||
|
Just use an empty set of square brackets -- e.g., to link the word
|
||||||
|
"Google" to the google.com web site, you could simply write:
|
||||||
|
|
||||||
|
[Google][]
|
||||||
|
|
||||||
|
And then define the link:
|
||||||
|
|
||||||
|
[Google]: http://google.com/
|
||||||
|
|
||||||
|
Because link names may contain spaces, this shortcut even works for
|
||||||
|
multiple words in the link text:
|
||||||
|
|
||||||
|
Visit [Daring Fireball][] for more information.
|
||||||
|
|
||||||
|
And then define the link:
|
||||||
|
|
||||||
|
[Daring Fireball]: http://daringfireball.net/
|
||||||
|
|
||||||
|
Link definitions can be placed anywhere in your Markdown document. I
|
||||||
|
tend to put them immediately after each paragraph in which they're
|
||||||
|
used, but if you want, you can put them all at the end of your
|
||||||
|
document, sort of like footnotes.
|
||||||
|
|
||||||
|
Here's an example of reference links in action:
|
||||||
|
|
||||||
|
I get 10 times more traffic from [Google] [1] than from
|
||||||
|
[Yahoo] [2] or [MSN] [3].
|
||||||
|
|
||||||
|
[1]: http://google.com/ "Google"
|
||||||
|
[2]: http://search.yahoo.com/ "Yahoo Search"
|
||||||
|
[3]: http://search.msn.com/ "MSN Search"
|
||||||
|
|
||||||
|
Using the implicit link name shortcut, you could instead write:
|
||||||
|
|
||||||
|
I get 10 times more traffic from [Google][] than from
|
||||||
|
[Yahoo][] or [MSN][].
|
||||||
|
|
||||||
|
[google]: http://google.com/ "Google"
|
||||||
|
[yahoo]: http://search.yahoo.com/ "Yahoo Search"
|
||||||
|
[msn]: http://search.msn.com/ "MSN Search"
|
||||||
|
|
||||||
|
Both of the above examples will produce the following HTML output:
|
||||||
|
|
||||||
|
<p>I get 10 times more traffic from <a href="http://google.com/"
|
||||||
|
title="Google">Google</a> than from
|
||||||
|
<a href="http://search.yahoo.com/" title="Yahoo Search">Yahoo</a>
|
||||||
|
or <a href="http://search.msn.com/" title="MSN Search">MSN</a>.</p>
|
||||||
|
|
||||||
|
For comparison, here is the same paragraph written using
|
||||||
|
Markdown's inline link style:
|
||||||
|
|
||||||
|
I get 10 times more traffic from [Google](http://google.com/ "Google")
|
||||||
|
than from [Yahoo](http://search.yahoo.com/ "Yahoo Search") or
|
||||||
|
[MSN](http://search.msn.com/ "MSN Search").
|
||||||
|
|
||||||
|
The point of reference-style links is not that they're easier to
|
||||||
|
write. The point is that with reference-style links, your document
|
||||||
|
source is vastly more readable. Compare the above examples: using
|
||||||
|
reference-style links, the paragraph itself is only 81 characters
|
||||||
|
long; with inline-style links, it's 176 characters; and as raw HTML,
|
||||||
|
it's 234 characters. In the raw HTML, there's more markup than there
|
||||||
|
is text.
|
||||||
|
|
||||||
|
With Markdown's reference-style links, a source document much more
|
||||||
|
closely resembles the final output, as rendered in a browser. By
|
||||||
|
allowing you to move the markup-related metadata out of the paragraph,
|
||||||
|
you can add links without interrupting the narrative flow of your
|
||||||
|
prose.
|
||||||
|
|
||||||
|
|
||||||
|
<h3 id="em">Emphasis</h3>
|
||||||
|
|
||||||
|
Markdown treats asterisks (`*`) and underscores (`_`) as indicators of
|
||||||
|
emphasis. Text wrapped with one `*` or `_` will be wrapped with an
|
||||||
|
HTML `<em>` tag; double `*`'s or `_`'s will be wrapped with an HTML
|
||||||
|
`<strong>` tag. E.g., this input:
|
||||||
|
|
||||||
|
*single asterisks*
|
||||||
|
|
||||||
|
_single underscores_
|
||||||
|
|
||||||
|
**double asterisks**
|
||||||
|
|
||||||
|
__double underscores__
|
||||||
|
|
||||||
|
will produce:
|
||||||
|
|
||||||
|
<em>single asterisks</em>
|
||||||
|
|
||||||
|
<em>single underscores</em>
|
||||||
|
|
||||||
|
<strong>double asterisks</strong>
|
||||||
|
|
||||||
|
<strong>double underscores</strong>
|
||||||
|
|
||||||
|
You can use whichever style you prefer; the lone restriction is that
|
||||||
|
the same character must be used to open and close an emphasis span.
|
||||||
|
|
||||||
|
Emphasis can be used in the middle of a word:
|
||||||
|
|
||||||
|
un*frigging*believable
|
||||||
|
|
||||||
|
But if you surround an `*` or `_` with spaces, it'll be treated as a
|
||||||
|
literal asterisk or underscore.
|
||||||
|
|
||||||
|
To produce a literal asterisk or underscore at a position where it
|
||||||
|
would otherwise be used as an emphasis delimiter, you can backslash
|
||||||
|
escape it:
|
||||||
|
|
||||||
|
\*this text is surrounded by literal asterisks\*
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<h3 id="code">Code</h3>
|
||||||
|
|
||||||
|
To indicate a span of code, wrap it with backtick quotes (`` ` ``).
|
||||||
|
Unlike a pre-formatted code block, a code span indicates code within a
|
||||||
|
normal paragraph. For example:
|
||||||
|
|
||||||
|
Use the `printf()` function.
|
||||||
|
|
||||||
|
will produce:
|
||||||
|
|
||||||
|
<p>Use the <code>printf()</code> function.</p>
|
||||||
|
|
||||||
|
To include a literal backtick character within a code span, you can use
|
||||||
|
multiple backticks as the opening and closing delimiters:
|
||||||
|
|
||||||
|
``There is a literal backtick (`) here.``
|
||||||
|
|
||||||
|
which will produce this:
|
||||||
|
|
||||||
|
<p><code>There is a literal backtick (`) here.</code></p>
|
||||||
|
|
||||||
|
The backtick delimiters surrounding a code span may include spaces --
|
||||||
|
one after the opening, one before the closing. This allows you to place
|
||||||
|
literal backtick characters at the beginning or end of a code span:
|
||||||
|
|
||||||
|
A single backtick in a code span: `` ` ``
|
||||||
|
|
||||||
|
A backtick-delimited string in a code span: `` `foo` ``
|
||||||
|
|
||||||
|
will produce:
|
||||||
|
|
||||||
|
<p>A single backtick in a code span: <code>`</code></p>
|
||||||
|
|
||||||
|
<p>A backtick-delimited string in a code span: <code>`foo`</code></p>
|
||||||
|
|
||||||
|
With a code span, ampersands and angle brackets are encoded as HTML
|
||||||
|
entities automatically, which makes it easy to include example HTML
|
||||||
|
tags. Markdown will turn this:
|
||||||
|
|
||||||
|
Please don't use any `<blink>` tags.
|
||||||
|
|
||||||
|
into:
|
||||||
|
|
||||||
|
<p>Please don't use any <code><blink></code> tags.</p>
|
||||||
|
|
||||||
|
You can write this:
|
||||||
|
|
||||||
|
`—` is the decimal-encoded equivalent of `—`.
|
||||||
|
|
||||||
|
to produce:
|
||||||
|
|
||||||
|
<p><code>&#8212;</code> is the decimal-encoded
|
||||||
|
equivalent of <code>&mdash;</code>.</p>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<h3 id="img">Images</h3>
|
||||||
|
|
||||||
|
Admittedly, it's fairly difficult to devise a "natural" syntax for
|
||||||
|
placing images into a plain text document format.
|
||||||
|
|
||||||
|
Markdown uses an image syntax that is intended to resemble the syntax
|
||||||
|
for links, allowing for two styles: *inline* and *reference*.
|
||||||
|
|
||||||
|
Inline image syntax looks like this:
|
||||||
|
|
||||||
|
![Alt text](/path/to/img.jpg)
|
||||||
|
|
||||||
|
![Alt text](/path/to/img.jpg "Optional title")
|
||||||
|
|
||||||
|
That is:
|
||||||
|
|
||||||
|
* An exclamation mark: `!`;
|
||||||
|
* followed by a set of square brackets, containing the `alt`
|
||||||
|
attribute text for the image;
|
||||||
|
* followed by a set of parentheses, containing the URL or path to
|
||||||
|
the image, and an optional `title` attribute enclosed in double
|
||||||
|
or single quotes.
|
||||||
|
|
||||||
|
Reference-style image syntax looks like this:
|
||||||
|
|
||||||
|
![Alt text][id]
|
||||||
|
|
||||||
|
Where "id" is the name of a defined image reference. Image references
|
||||||
|
are defined using syntax identical to link references:
|
||||||
|
|
||||||
|
[id]: url/to/image "Optional title attribute"
|
||||||
|
|
||||||
|
As of this writing, Markdown has no syntax for specifying the
|
||||||
|
dimensions of an image; if this is important to you, you can simply
|
||||||
|
use regular HTML `<img>` tags.
|
||||||
|
|
||||||
|
|
||||||
|
* * *
|
||||||
|
|
||||||
|
|
||||||
|
<h2 id="misc">Miscellaneous</h2>
|
||||||
|
|
||||||
|
<h3 id="autolink">Automatic Links</h3>
|
||||||
|
|
||||||
|
Markdown supports a shortcut style for creating "automatic" links for URLs and email addresses: simply surround the URL or email address with angle brackets. What this means is that if you want to show the actual text of a URL or email address, and also have it be a clickable link, you can do this:
|
||||||
|
|
||||||
|
<http://example.com/>
|
||||||
|
|
||||||
|
Markdown will turn this into:
|
||||||
|
|
||||||
|
<a href="http://example.com/">http://example.com/</a>
|
||||||
|
|
||||||
|
Automatic links for email addresses work similarly, except that
|
||||||
|
Markdown will also perform a bit of randomized decimal and hex
|
||||||
|
entity-encoding to help obscure your address from address-harvesting
|
||||||
|
spambots. For example, Markdown will turn this:
|
||||||
|
|
||||||
|
<address@example.com>
|
||||||
|
|
||||||
|
into something like this:
|
||||||
|
|
||||||
|
<a href="mailto:addre
|
||||||
|
ss@example.co
|
||||||
|
m">address@exa
|
||||||
|
mple.com</a>
|
||||||
|
|
||||||
|
which will render in a browser as a clickable link to "address@example.com".
|
||||||
|
|
||||||
|
(This sort of entity-encoding trick will indeed fool many, if not
|
||||||
|
most, address-harvesting bots, but it definitely won't fool all of
|
||||||
|
them. It's better than nothing, but an address published in this way
|
||||||
|
will probably eventually start receiving spam.)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<h3 id="backslash">Backslash Escapes</h3>
|
||||||
|
|
||||||
|
Markdown allows you to use backslash escapes to generate literal
|
||||||
|
characters which would otherwise have special meaning in Markdown's
|
||||||
|
formatting syntax. For example, if you wanted to surround a word
|
||||||
|
with literal asterisks (instead of an HTML `<em>` tag), you can use
|
||||||
|
backslashes before the asterisks, like this:
|
||||||
|
|
||||||
|
\*literal asterisks\*
|
||||||
|
|
||||||
|
Markdown provides backslash escapes for the following characters:
|
||||||
|
|
||||||
|
\ backslash
|
||||||
|
` backtick
|
||||||
|
* asterisk
|
||||||
|
_ underscore
|
||||||
|
{} curly braces
|
||||||
|
[] square brackets
|
||||||
|
() parentheses
|
||||||
|
# hash mark
|
||||||
|
+ plus sign
|
||||||
|
- minus sign (hyphen)
|
||||||
|
. dot
|
||||||
|
! exclamation mark
|
@ -0,0 +1,43 @@
|
|||||||
|
### Server Rules
|
||||||
|
|
||||||
|
In dieser Datei werden die Server Regeln eingetragen welche dann auf der Seite "rules.php" angezeigt werden. Zum Ändern muss einfach die Datei <code>rules.md</code> im Verzeichnis <code>config</code> verändert werden.
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
This is a dedicated file to keep your server rules. Its loaded and displayed on "rules.php" page. To change it, go to the <code>config</code> directory and edit file <code>rules.md</code>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
Oto dedykowany plik na regulamin twojego Teamspeaka wyświetlany na podstronie "regulamin". Plik z regulaminem znajdziesz w folderze <code>config</code> pod nazwą <code>rules.md</code>. Edytuje się go podobnie jak newsy.
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
### 1. Definicje
|
||||||
|
1. Teamspeak - oprogramowanie służące do komunikacji...
|
||||||
|
2. ...
|
||||||
|
|
||||||
|
|
||||||
|
### 2. Postanowienia ogólne
|
||||||
|
1. Serwer Teamspeak pod adresem "127.0.0.1" jest...
|
||||||
|
2. ...
|
||||||
|
|
||||||
|
### 3. Tytuł
|
||||||
|
1. Lista
|
||||||
|
- Sublista
|
||||||
|
- Sublista
|
||||||
|
- Sublista
|
||||||
|
2. Lista
|
||||||
|
3. Lista
|
||||||
|
|
||||||
|
### 4. Tytuł
|
||||||
|
- Lista
|
||||||
|
- Lista
|
||||||
|
- Lista
|
||||||
|
|
||||||
|
### 5. Tabela kar
|
||||||
|
Przewinienie | Kara
|
||||||
|
------------ | -------------
|
||||||
|
Wulgarny nick | Kick z serwera
|
||||||
|
Wulgarna nazwa kanału | Usunięcie z kanału
|
||||||
|
Wyzywanie użytkowników | Ban do 7 dni
|
||||||
|
Zniewaga administracji | Ban permanentny
|
@ -0,0 +1,148 @@
|
|||||||
|
/*!
|
||||||
|
* Christmas theme for ts-website
|
||||||
|
* https://github.com/Wruczek/ts-website
|
||||||
|
* (c) Wruczek 2016 - 2018
|
||||||
|
* The MIT License
|
||||||
|
*/
|
||||||
|
|
||||||
|
body {
|
||||||
|
background-image: url(../img/christmas-bg.jpg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel {
|
||||||
|
background-color: #410b13;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-hover > tbody > tr:hover {
|
||||||
|
background-color: #b41320
|
||||||
|
}
|
||||||
|
|
||||||
|
.table > thead > tr > td.active,
|
||||||
|
.table > tbody > tr > td.active,
|
||||||
|
.table > tfoot > tr > td.active,
|
||||||
|
.table > thead > tr > th.active,
|
||||||
|
.table > tbody > tr > th.active,
|
||||||
|
.table > tfoot > tr > th.active,
|
||||||
|
.table > thead > tr.active > td,
|
||||||
|
.table > tbody > tr.active > td,
|
||||||
|
.table > tfoot > tr.active > td,
|
||||||
|
.table > thead > tr.active > th,
|
||||||
|
.table > tbody > tr.active > th,
|
||||||
|
.table > tfoot > tr.active > th {
|
||||||
|
background-color: #a51321
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-menu > li > a:hover,
|
||||||
|
.dropdown-menu > li > a:focus {
|
||||||
|
background-color: #a51321
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-default .navbar-nav > .active > a,
|
||||||
|
.navbar-default .navbar-nav > .active > a:hover,
|
||||||
|
.navbar-default .navbar-nav > .active > a:focus {
|
||||||
|
background-color: #a51321
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 767px) {
|
||||||
|
.navbar-default .navbar-nav .open .dropdown-menu > li > a:hover,
|
||||||
|
.navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {
|
||||||
|
background-color: #a51321
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-default .navbar-nav .open .dropdown-menu > .active > a,
|
||||||
|
.navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover,
|
||||||
|
.navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {
|
||||||
|
background-color: #a51321
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination > li > a:hover,
|
||||||
|
.pagination > li > span:hover,
|
||||||
|
.pagination > li > a:focus,
|
||||||
|
.pagination > li > span:focus {
|
||||||
|
background-color: #a51321;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pager li > a:hover,
|
||||||
|
.pager li > a:focus {
|
||||||
|
background-color: #a51321
|
||||||
|
}
|
||||||
|
|
||||||
|
a.list-group-item:hover,
|
||||||
|
button.list-group-item:hover,
|
||||||
|
a.list-group-item:focus,
|
||||||
|
button.list-group-item:focus {
|
||||||
|
background-color: #a51321
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-footer {
|
||||||
|
background-color: #a51321;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popover-title {
|
||||||
|
background-color: #a51321;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-default:hover {
|
||||||
|
background-color: #a51321
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-default > .panel-heading {
|
||||||
|
background-color: #a51321;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-header,
|
||||||
|
.modal-footer {
|
||||||
|
background-color: #a51321
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-bordered {
|
||||||
|
border-color: #871522;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table > thead > tr > th {
|
||||||
|
background-color: #871522;
|
||||||
|
border-color: #871522;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-striped > tbody > tr:nth-of-type(odd) {
|
||||||
|
background-color: #871522;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-default {
|
||||||
|
background-color: #b91524 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-default .navbar-nav > li > a:hover,
|
||||||
|
.navbar-default .navbar-nav > li > a:focus {
|
||||||
|
background-color: #9b131f
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-default .navbar-nav > .active > a,
|
||||||
|
.navbar-default .navbar-nav > .active > a:hover,
|
||||||
|
.navbar-default .navbar-nav > .active > a:focus {
|
||||||
|
background-color: #9b131f
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-menu {
|
||||||
|
background-color: #410b13;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-default .navbar-nav > .open > a,
|
||||||
|
.navbar-default .navbar-nav > .open > a:hover,
|
||||||
|
.navbar-default .navbar-nav > .open > a:focus {
|
||||||
|
background-color: #9b131f;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 767px) {
|
||||||
|
.navbar-default .navbar-nav .open .dropdown-menu > li > a:hover,
|
||||||
|
.navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {
|
||||||
|
background-color: #9b131f
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-default .navbar-nav .open .dropdown-menu > .active > a,
|
||||||
|
.navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover,
|
||||||
|
.navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {
|
||||||
|
background-color: #9b131f
|
||||||
|
}
|
||||||
|
}
|
Before Width: | Height: | Size: 77 KiB After Width: | Height: | Size: 77 KiB |
@ -0,0 +1,66 @@
|
|||||||
|
/*!
|
||||||
|
* bootswatch v3.3.6
|
||||||
|
* Homepage: http://bootswatch.com
|
||||||
|
* Copyright 2012-2016 Thomas Park
|
||||||
|
* Licensed under MIT
|
||||||
|
* Based on Bootstrap
|
||||||
|
*/
|
||||||
|
/*!
|
||||||
|
* Bootstrap v3.3.6 (http://getbootstrap.com)
|
||||||
|
* Copyright 2011-2015 Twitter, Inc.
|
||||||
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||||
|
*/
|
||||||
|
|
||||||
|
.navbar {
|
||||||
|
min-height: 50px
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-brand {
|
||||||
|
padding: 14.5px 15px;
|
||||||
|
height: 50px
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-toggle {
|
||||||
|
margin-top: 8px;
|
||||||
|
margin-bottom: 8px
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-nav {
|
||||||
|
margin: 0px -15px 0px 0px
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.navbar-nav > li > a {
|
||||||
|
padding-top: 14.5px;
|
||||||
|
padding-bottom: 14.5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-form {
|
||||||
|
margin-top: 3.5px;
|
||||||
|
margin-bottom: 3.5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-btn {
|
||||||
|
margin-top: 3.5px;
|
||||||
|
margin-bottom: 3.5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-btn.btn-sm {
|
||||||
|
margin-top: 9.5px;
|
||||||
|
margin-bottom: 9.5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-btn.btn-xs {
|
||||||
|
margin-top: 14px;
|
||||||
|
margin-bottom: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-text {
|
||||||
|
margin-top: 14.5px;
|
||||||
|
margin-bottom: 14.5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar .dropdown-menu > li > a {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
@ -0,0 +1,138 @@
|
|||||||
|
.fa {
|
||||||
|
margin-right: 5px
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-smaller {
|
||||||
|
font-size: 0.7em
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
transition: color 500ms ease-out
|
||||||
|
}
|
||||||
|
|
||||||
|
.news-header {
|
||||||
|
font-size: 1.4em;
|
||||||
|
text-align: center
|
||||||
|
}
|
||||||
|
|
||||||
|
.news-author {
|
||||||
|
font-size: 0.7em;
|
||||||
|
text-align: right
|
||||||
|
}
|
||||||
|
|
||||||
|
.pull-right .fa {
|
||||||
|
margin-right: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
p, a {
|
||||||
|
overflow-wrap: break-word;
|
||||||
|
word-wrap: break-word
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Force 16px icon size after TeamSpeak update 3.1.5 */
|
||||||
|
.ts3_viewer img, .adminlist img {
|
||||||
|
max-height: 16px;
|
||||||
|
max-width: 16px
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ****** */
|
||||||
|
/* STATUS */
|
||||||
|
/* ****** */
|
||||||
|
|
||||||
|
.serverstatus p, .serverstatus .label .fa {
|
||||||
|
margin: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
.serverstatus a, .serverstatus span {
|
||||||
|
float: right
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ********* */
|
||||||
|
/* ADMINLIST */
|
||||||
|
/* ********* */
|
||||||
|
|
||||||
|
.adminlist > .groupname ~ .groupname {
|
||||||
|
margin-top: 15px
|
||||||
|
}
|
||||||
|
|
||||||
|
.adminlist .groupname {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 1.2em;
|
||||||
|
border-bottom: 1px solid #677481;
|
||||||
|
margin-bottom: 5px
|
||||||
|
}
|
||||||
|
|
||||||
|
.adminlist .label-primary {
|
||||||
|
background-color: #375a7f
|
||||||
|
}
|
||||||
|
|
||||||
|
.adminlist p {
|
||||||
|
margin: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
.adminlist img {
|
||||||
|
margin-right: 3px
|
||||||
|
}
|
||||||
|
|
||||||
|
.adminlist .iconspacer {
|
||||||
|
margin-left: 19px
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ****** */
|
||||||
|
/* NAVBAR */
|
||||||
|
/* ****** */
|
||||||
|
|
||||||
|
body {
|
||||||
|
padding-top: 80px
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar {
|
||||||
|
font-size: 14px
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav > li > a {
|
||||||
|
padding-left: 10px;
|
||||||
|
padding-right: 10px
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-brand {
|
||||||
|
padding: 0 10px 0 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-brand > img {
|
||||||
|
height: 100%;
|
||||||
|
padding: 5px 5px 5px 15px
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ****** */
|
||||||
|
/* FOOTER */
|
||||||
|
/* ****** */
|
||||||
|
|
||||||
|
body {
|
||||||
|
position: relative;
|
||||||
|
margin: 0;
|
||||||
|
padding-bottom: 120px;
|
||||||
|
min-height: 100vh
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 380px) {
|
||||||
|
body {
|
||||||
|
padding-bottom: 150px
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
padding: 10px
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer .pull-right p {
|
||||||
|
margin: 0 0 0 0;
|
||||||
|
font-size: 0.8em;
|
||||||
|
text-align: right
|
||||||
|
}
|
@ -0,0 +1,384 @@
|
|||||||
|
/*!
|
||||||
|
* Stylesheet kindly donated by NothingTV from https://flamespersecond.de/
|
||||||
|
* Edited by Wruczek
|
||||||
|
* The MIT License
|
||||||
|
*/
|
||||||
|
|
||||||
|
body {
|
||||||
|
background: url(../img/bg.png) no-repeat fixed center;
|
||||||
|
background-size: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-default {
|
||||||
|
background-color: #055157 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-dark {
|
||||||
|
background-color: #4e5d6c;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-muted {
|
||||||
|
color: #00343f
|
||||||
|
}
|
||||||
|
|
||||||
|
abbr[data-original-title] {
|
||||||
|
border-bottom: 1px dotted #00343f
|
||||||
|
}
|
||||||
|
|
||||||
|
blockquote {
|
||||||
|
border-left: 5px solid #00343f
|
||||||
|
}
|
||||||
|
|
||||||
|
blockquote.pull-right {
|
||||||
|
border-right: 5px solid #00343f;
|
||||||
|
}
|
||||||
|
|
||||||
|
caption {
|
||||||
|
color: #00343f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table > tfoot > tr > td {
|
||||||
|
border-top: 1px solid #00343f
|
||||||
|
}
|
||||||
|
|
||||||
|
.table > thead > tr > th {
|
||||||
|
border-bottom: 2px solid #00343f
|
||||||
|
}
|
||||||
|
|
||||||
|
.table > tbody + tbody {
|
||||||
|
border-top: 2px solid #00343f
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-bordered {
|
||||||
|
border: 1px solid #00343f
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-bordered > tfoot > tr > td {
|
||||||
|
border: 1px solid #00343f
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-striped > tbody > tr:nth-of-type(odd) {
|
||||||
|
background-color: #00343f
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-hover > tbody > tr:hover {
|
||||||
|
background-color: #004449
|
||||||
|
}
|
||||||
|
|
||||||
|
.table > thead > tr > td.active,
|
||||||
|
.table > tbody > tr > td.active,
|
||||||
|
.table > tfoot > tr > td.active,
|
||||||
|
.table > thead > tr > th.active,
|
||||||
|
.table > tbody > tr > th.active,
|
||||||
|
.table > tfoot > tr > th.active,
|
||||||
|
.table > thead > tr.active > td,
|
||||||
|
.table > tbody > tr.active > td,
|
||||||
|
.table > tfoot > tr.active > td,
|
||||||
|
.table > thead > tr.active > th,
|
||||||
|
.table > tbody > tr.active > th,
|
||||||
|
.table > tfoot > tr.active > th {
|
||||||
|
background-color: #004449
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 767px) {
|
||||||
|
.table-responsive {
|
||||||
|
border: 1px solid #00343f
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
legend {
|
||||||
|
border-bottom: 1px solid #00343f
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-default {
|
||||||
|
background-color: #00343f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-default.disabled:hover,
|
||||||
|
.btn-default[disabled]:hover,
|
||||||
|
fieldset[disabled] .btn-default:hover,
|
||||||
|
.btn-default.disabled:focus,
|
||||||
|
.btn-default[disabled]:focus,
|
||||||
|
fieldset[disabled] .btn-default:focus,
|
||||||
|
.btn-default.disabled.focus,
|
||||||
|
.btn-default[disabled].focus,
|
||||||
|
fieldset[disabled] .btn-default.focus {
|
||||||
|
background-color: #00343f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-default .badge {
|
||||||
|
color: #00343f;
|
||||||
|
}
|
||||||
|
|
||||||
|
fieldset[disabled] .btn-link:focus {
|
||||||
|
color: #00343f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-menu {
|
||||||
|
background-color: #00343f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-menu > li > a:hover,
|
||||||
|
.dropdown-menu > li > a:focus {
|
||||||
|
background-color: #004449
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group-addon {
|
||||||
|
background-color: #00343f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav > li > a:focus {
|
||||||
|
background-color: #00343f
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav > li.disabled > a {
|
||||||
|
color: #00343f
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav > li.disabled > a:hover,
|
||||||
|
.nav > li.disabled > a:focus {
|
||||||
|
color: #00343f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav .open > a,
|
||||||
|
.nav .open > a:hover,
|
||||||
|
.nav .open > a:focus {
|
||||||
|
background-color: #00343f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-tabs > li > a:hover {
|
||||||
|
border-color: #00343f #00343f transparent
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-tabs > li.active > a:focus {
|
||||||
|
border: 1px solid #00343f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-tabs > li.active > a,
|
||||||
|
.nav-tabs > li.active > a:hover,
|
||||||
|
.nav-tabs > li.active > a:focus {
|
||||||
|
border: 1px solid #00343f;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.nav-tabs.nav-justified > li > a {
|
||||||
|
border-bottom: 1px solid #00343f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-tabs.nav-justified > .active > a,
|
||||||
|
.nav-tabs.nav-justified > .active > a:hover,
|
||||||
|
.nav-tabs.nav-justified > .active > a:focus {
|
||||||
|
border-bottom-color: #00343f
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-tabs-justified > .active > a,
|
||||||
|
.nav-tabs-justified > .active > a:hover,
|
||||||
|
.nav-tabs-justified > .active > a:focus {
|
||||||
|
border: 1px solid #00343f
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.nav-tabs-justified > li > a {
|
||||||
|
border-bottom: 1px solid #00343f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-tabs-justified > .active > a,
|
||||||
|
.nav-tabs-justified > .active > a:hover,
|
||||||
|
.nav-tabs-justified > .active > a:focus {
|
||||||
|
border-bottom-color: #00343f
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-default {
|
||||||
|
background-color: #00343f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-default .navbar-nav > li > a:hover,
|
||||||
|
.navbar-default .navbar-nav > li > a:focus {
|
||||||
|
background-color: #083d48
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-default .navbar-nav > .active > a,
|
||||||
|
.navbar-default .navbar-nav > .active > a:hover,
|
||||||
|
.navbar-default .navbar-nav > .active > a:focus {
|
||||||
|
background-color: #004449
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 767px) {
|
||||||
|
.navbar-default .navbar-nav .open .dropdown-menu > li > a:hover,
|
||||||
|
.navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {
|
||||||
|
background-color: #004449
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-default .navbar-nav .open .dropdown-menu > .active > a,
|
||||||
|
.navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover,
|
||||||
|
.navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {
|
||||||
|
background-color: #004449
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.breadcrumb {
|
||||||
|
background-color: #00343f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination > li > a,
|
||||||
|
.pagination > li > span {
|
||||||
|
background-color: #00343f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination > li > a:hover,
|
||||||
|
.pagination > li > span:hover,
|
||||||
|
.pagination > li > a:focus,
|
||||||
|
.pagination > li > span:focus {
|
||||||
|
background-color: #004449;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination > .disabled > a:focus {
|
||||||
|
background-color: #00343f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pager li > a,
|
||||||
|
.pager li > span {
|
||||||
|
background-color: #00343f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pager li > a:hover,
|
||||||
|
.pager li > a:focus {
|
||||||
|
background-color: #004449
|
||||||
|
}
|
||||||
|
|
||||||
|
.pager .disabled > a,
|
||||||
|
.pager .disabled > a:hover,
|
||||||
|
.pager .disabled > a:focus,
|
||||||
|
.pager .disabled > span {
|
||||||
|
background-color: #00343f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label-default {
|
||||||
|
background-color: #00343f
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge {
|
||||||
|
background-color: #00343f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.jumbotron {
|
||||||
|
background-color: #00343f
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress {
|
||||||
|
background-color: #00343f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-group-item {
|
||||||
|
background-color: #00343f;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.list-group-item:hover,
|
||||||
|
button.list-group-item:hover,
|
||||||
|
a.list-group-item:focus,
|
||||||
|
button.list-group-item:focus {
|
||||||
|
background-color: #004449
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-group-item.disabled,
|
||||||
|
.list-group-item.disabled:hover,
|
||||||
|
.list-group-item.disabled:focus {
|
||||||
|
color: #00343f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-group-item.disabled .list-group-item-text,
|
||||||
|
.list-group-item.disabled:hover .list-group-item-text,
|
||||||
|
.list-group-item.disabled:focus .list-group-item-text {
|
||||||
|
color: #00343f
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel {
|
||||||
|
background-color: #00343f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-footer {
|
||||||
|
background-color: #004449;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel > .panel-body + .table,
|
||||||
|
.panel > .panel-body + .table-responsive,
|
||||||
|
.panel > .table + .panel-body,
|
||||||
|
.panel > .table-responsive + .panel-body {
|
||||||
|
border-top: 1px solid #00343f
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-success > .panel-heading {
|
||||||
|
color: #13ddcd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-info > .panel-heading {
|
||||||
|
color: #13ddcd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-warning > .panel-heading {
|
||||||
|
color: #13ddcd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.well {
|
||||||
|
background-color: #00343f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-content {
|
||||||
|
background-color: #00343f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popover {
|
||||||
|
background-color: #00343f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popover-title {
|
||||||
|
background-color: #004449;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popover.top > .arrow:after {
|
||||||
|
border-top-color: #00343f
|
||||||
|
}
|
||||||
|
|
||||||
|
.popover.right > .arrow:after {
|
||||||
|
border-right-color: #00343f
|
||||||
|
}
|
||||||
|
|
||||||
|
.popover.bottom > .arrow:after {
|
||||||
|
border-bottom-color: #00343f
|
||||||
|
}
|
||||||
|
|
||||||
|
.popover.left > .arrow:after {
|
||||||
|
border-left-color: #00343f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-default .badge {
|
||||||
|
color: #00343f
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-default:hover {
|
||||||
|
background-color: #004449
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-header {
|
||||||
|
border-bottom-color: #00343f
|
||||||
|
}
|
||||||
|
|
||||||
|
table .text-muted,
|
||||||
|
.table .text-muted {
|
||||||
|
color: #00343f
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-default > .panel-heading {
|
||||||
|
background-color: #004449;
|
||||||
|
}
|
||||||
|
|
||||||
|
.thumbnail {
|
||||||
|
background-color: #00343f
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-header,
|
||||||
|
.modal-footer {
|
||||||
|
background-color: #004449
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="pl">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
|
||||||
|
<meta name="author" content="Wruczek">
|
||||||
|
|
||||||
|
<title>403 - Forbidden</title>
|
||||||
|
|
||||||
|
<!-- Icon -->
|
||||||
|
<link rel="shortcut icon" href="../img/icon/icon-64.png">
|
||||||
|
|
||||||
|
<!-- Bootswatch -->
|
||||||
|
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootswatch/3.3.7/superhero/bootstrap.min.css" rel="stylesheet">
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.container {
|
||||||
|
display: table;
|
||||||
|
position: absolute;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-center {
|
||||||
|
display: table-cell;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<div class="text-center">
|
||||||
|
<h1>403 <span style="font-size: 32px;color: #9E9E9E">forbidden</span></h1>
|
||||||
|
<h3>Access to this page is forbidden.</h3>
|
||||||
|
<br>
|
||||||
|
<a href="." class="btn btn-primary btn-lg">← Go back</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
@ -0,0 +1,47 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="pl">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
|
||||||
|
<meta name="author" content="Wruczek">
|
||||||
|
|
||||||
|
<title>404 - Not found</title>
|
||||||
|
|
||||||
|
<!-- Icon -->
|
||||||
|
<link rel="shortcut icon" href="../img/icon/icon-64.png">
|
||||||
|
|
||||||
|
<!-- Bootswatch -->
|
||||||
|
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootswatch/3.3.7/superhero/bootstrap.min.css" rel="stylesheet">
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.container {
|
||||||
|
display: table;
|
||||||
|
position: absolute;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-center {
|
||||||
|
display: table-cell;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<div class="text-center">
|
||||||
|
<h1>404 <span style="font-size: 32px;color: #9E9E9E">page not found</span></h1>
|
||||||
|
<h3>We couldn't find what you were looking for.</h3>
|
||||||
|
<br>
|
||||||
|
<a href="." class="btn btn-primary btn-lg">← Go back</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
@ -0,0 +1,47 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="pl">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
|
||||||
|
<meta name="author" content="Wruczek">
|
||||||
|
|
||||||
|
<title>500 - Server Error</title>
|
||||||
|
|
||||||
|
<!-- Icon -->
|
||||||
|
<link rel="shortcut icon" href="../img/icon/icon-64.png">
|
||||||
|
|
||||||
|
<!-- Bootswatch -->
|
||||||
|
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootswatch/3.3.7/superhero/bootstrap.min.css" rel="stylesheet">
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.container {
|
||||||
|
display: table;
|
||||||
|
position: absolute;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-center {
|
||||||
|
display: table-cell;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<div class="text-center">
|
||||||
|
<h1>500 <span style="font-size: 32px;color: #9E9E9E">server error</span></h1>
|
||||||
|
<h3>Something went wrong. Try again later.</h3>
|
||||||
|
<br>
|
||||||
|
<a href="." class="btn btn-primary btn-lg">← Go back</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
After Width: | Height: | Size: 779 KiB |
After Width: | Height: | Size: 142 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 55 KiB |
After Width: | Height: | Size: 4.6 KiB |
@ -0,0 +1,112 @@
|
|||||||
|
<?php
|
||||||
|
require_once __DIR__ . "/tsutils.php";
|
||||||
|
require_once __DIR__ . "/cacheutils.class.php";
|
||||||
|
|
||||||
|
$cacheutils = new CacheUtils('adminlist');
|
||||||
|
|
||||||
|
if($cacheutils->isExpired()) {
|
||||||
|
$cacheutils->setValue([getAdminList(), date('d.m.Y H:i:s')], 120);
|
||||||
|
}
|
||||||
|
|
||||||
|
$adminlist = $cacheutils->getValue();
|
||||||
|
|
||||||
|
// FUNCTIONS
|
||||||
|
|
||||||
|
function getAdminList() {
|
||||||
|
global $config;
|
||||||
|
global $lang;
|
||||||
|
|
||||||
|
$admingroups = $config["adminlist"];
|
||||||
|
$localIcons = array(100, 200, 300, 400, 500, 600);
|
||||||
|
|
||||||
|
try {
|
||||||
|
$tsAdmin = getTeamspeakConnection();
|
||||||
|
|
||||||
|
$output = "";
|
||||||
|
|
||||||
|
foreach ($admingroups as $group) {
|
||||||
|
|
||||||
|
if (!array_key_exists((string)$group, $tsAdmin->serverGroupList()))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
$group = $tsAdmin->serverGroupGetById($group);
|
||||||
|
|
||||||
|
$icon = '';
|
||||||
|
|
||||||
|
if ($group["iconid"]) {
|
||||||
|
if (!$group->iconIsLocal("iconid")) {
|
||||||
|
$groupicon = getGroupIcon($tsAdmin, $group);
|
||||||
|
|
||||||
|
if ($groupicon) {
|
||||||
|
$icon = '<img src="data:' . TeamSpeak3_Helper_Convert::imageMimeType($groupicon) . ';base64,' . base64_encode($groupicon) . '" alt="Group icon" /> ';
|
||||||
|
}
|
||||||
|
} elseif (in_array($group["iconid"], $localIcons)) {
|
||||||
|
$icon = '<img src="lib/ts3phpframework/images/viewer/group_icon_' . $group["iconid"] . '.png" alt="Group icon" /> ';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$output .= "<p class=\"groupname\">$icon$group</p>";
|
||||||
|
|
||||||
|
$clients = $group->clientList();
|
||||||
|
|
||||||
|
if (empty($clients)) {
|
||||||
|
$output .= '<p class="text-center"><i>' . translate($lang["adminlist"]["emptygroup"]) . '</i></p>';
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$onlineClients = [];
|
||||||
|
$offlineClients = [];
|
||||||
|
|
||||||
|
foreach ($clients as $userInfo) {
|
||||||
|
$user = getClientByDbid($tsAdmin, $userInfo['cldbid']);
|
||||||
|
|
||||||
|
if($user["client_type"]) continue;
|
||||||
|
|
||||||
|
if (!$user) {
|
||||||
|
$offlineClients[] = '<p><span class="label label-primary iconspacer">' . htmlspecialchars($userInfo['client_nickname']) . '</span><span class="label label-danger pull-right">' . translate($lang["adminlist"]["status"]["offline"]) . '</span></p>';
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$userAwayTitle = '';
|
||||||
|
|
||||||
|
if(!$user["client_away_message"]) {
|
||||||
|
$userAway = translate($lang["adminlist"]["status"]["away"]);
|
||||||
|
} else {
|
||||||
|
$userAway = htmlspecialchars($user["client_away_message"]);
|
||||||
|
if (mb_strlen($userAway) > 23) {
|
||||||
|
$userAwayTitle = 'title="' . $userAway . '"';
|
||||||
|
$userAway = mb_substr($userAway, 0, 23) . "...";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$onlineClients[] = '<p><img src="lib/ts3phpframework/images/viewer/' . $user->getIcon() . '.png" alt="User status">' . '<span class="label label-primary">' . htmlspecialchars($user) . '</span>' . ($user['client_away'] ? '<span class="label label-warning pull-right" ' . $userAwayTitle . '>' . $userAway . '</span>' : '<span class="label label-success pull-right">' . translate($lang["adminlist"]["status"]["online"]) . '</span>') . '</p>';
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (array_merge($onlineClients, $offlineClients) as $str)
|
||||||
|
$output .= $str;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $output;
|
||||||
|
} catch (TeamSpeak3_Exception $e) {
|
||||||
|
return '<div class="alert alert-danger"><p class="text-center">' . translate($lang["general"]["scripterror"], [$e->getCode(), $e->getMessage()]) . '</p></div>';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function getClientByDbid($tsAdmin, $cldbid) {
|
||||||
|
try {
|
||||||
|
return $tsAdmin->clientGetByDbid($cldbid);
|
||||||
|
} catch (TeamSpeak3_Exception $e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getGroupIcon($tsAdmin, $group) {
|
||||||
|
try {
|
||||||
|
return $group->iconDownload();
|
||||||
|
} catch (TeamSpeak3_Exception $e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// echo getAdminList();
|
@ -0,0 +1,61 @@
|
|||||||
|
<?php
|
||||||
|
require_once __DIR__ . "/../lib/phpfastcache/src/autoload.php";
|
||||||
|
require_once __DIR__ . "/../config/config.php";
|
||||||
|
|
||||||
|
use phpFastCache\CacheManager;
|
||||||
|
use phpFastCache\Util\Languages;
|
||||||
|
|
||||||
|
class CacheUtils {
|
||||||
|
|
||||||
|
private $devMode;
|
||||||
|
private $cacheInstance;
|
||||||
|
private $cacheItem;
|
||||||
|
private $key;
|
||||||
|
|
||||||
|
public function __construct($key) {
|
||||||
|
// If devMode is set, the cache will be invalidated immediately
|
||||||
|
$this->devMode = defined("DEV_MODE") || getenv("DEV_MODE") || file_exists(__DIR__ . "/dev_mode");
|
||||||
|
|
||||||
|
if(!is_string($key))
|
||||||
|
throw new InvalidArgumentException("Key must be a string");
|
||||||
|
|
||||||
|
global $config;
|
||||||
|
if(isset($config["general"]["timezone"])) {
|
||||||
|
date_default_timezone_set($config["general"]["timezone"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->cacheInstance = CacheManager::getInstance('Files', ["path" => __DIR__ . '/../cache']);
|
||||||
|
Languages::setEncoding();
|
||||||
|
$this->cacheItem = $this->cacheInstance->getItem($key);
|
||||||
|
$this->key = $key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCacheInstance() {
|
||||||
|
return $this->cacheInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCacheItem() {
|
||||||
|
return $this->cacheItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getValue() {
|
||||||
|
return $this->cacheItem->get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setValue($value, $expireTime) {
|
||||||
|
if($this->devMode)
|
||||||
|
$expireTime = 1;
|
||||||
|
|
||||||
|
$this->cacheItem = $this->cacheItem->set($value)->expiresAfter($expireTime);
|
||||||
|
$this->cacheInstance->save($this->cacheItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isExpired() {
|
||||||
|
return $this->devMode || !$this->cacheItem->isHit();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function remove() {
|
||||||
|
$this->cacheInstance->deleteItem($this->key);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,73 @@
|
|||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- /container -->
|
||||||
|
|
||||||
|
<!-- Footer -->
|
||||||
|
<div class="footer">
|
||||||
|
<div class="container">
|
||||||
|
<hr>
|
||||||
|
<p class="pull-left" id="website-copyright">© <?php tl($config["general"]["title"]); ?></p>
|
||||||
|
<div class="pull-right">
|
||||||
|
<ul class="list-inline">
|
||||||
|
<li>
|
||||||
|
<p>
|
||||||
|
<label class="label label-danger">
|
||||||
|
<a href="https://github.com/Wruczek/ts-website" style="color: inherit">
|
||||||
|
This is the last release of ts-website 1.0. Please upgrade to 2.0 to stay up-to-date
|
||||||
|
</a>
|
||||||
|
</label>
|
||||||
|
</p>
|
||||||
|
<!-- Please respect the amount of work we've put for free into this project and leave the authors in the footer. Thank you. -->
|
||||||
|
<p>
|
||||||
|
<a href="https://github.com/Wruczek/ts-website">ts-website</a> v 1.4.7 — © <a href="https://wruczek.tech">Wruczek</a> and contributors 2016 - 2018
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<?php tl($lang["footer"]["css"]); ?> <a href="https://nothingtv.de/">NothingTV</a>, <?php tl($lang["footer"]["background"]); ?> ©
|
||||||
|
<span id="background-artist"><a href="https://twitter.com/MrSanman98">NabulsiGraphix</a></span>
|
||||||
|
</p>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- ################ -->
|
||||||
|
<!-- # JAVASCRIPT # -->
|
||||||
|
<!-- ################ -->
|
||||||
|
|
||||||
|
<!-- jQuery -->
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
|
||||||
|
|
||||||
|
<!-- Twitter Bootstrap -->
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
|
||||||
|
|
||||||
|
<!-- Readmore.js -->
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/Readmore.js/2.2.0/readmore.min.js"></script>
|
||||||
|
|
||||||
|
<?php if (isset($bansPage)) { ?>
|
||||||
|
<script>var datatablesUrl = "<?php tl($lang["banlist"]["datatablesurl"]); ?>";</script>
|
||||||
|
|
||||||
|
<!-- DataTables for Bootstrap -->
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/datatables/1.10.12/js/jquery.dataTables.min.js"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/datatables/1.10.12/js/dataTables.bootstrap.min.js"></script>
|
||||||
|
<script src="js/bans.js"></script>
|
||||||
|
<?php } ?>
|
||||||
|
|
||||||
|
<!-- Custom JS -->
|
||||||
|
<script>
|
||||||
|
var apiurl = "api/status<?php echo $htalink; ?>";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script src="js/script.js"></script>
|
||||||
|
<script src="js/status.js"></script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
|
<?php
|
||||||
|
$end = microtime(true);
|
||||||
|
$creationtime = ($end - $start);
|
||||||
|
printf("<!-- Page generated " . date('d-m-Y H:i:s') . " in %.6f seconds. -->", $creationtime);
|
||||||
|
?>
|
@ -0,0 +1,185 @@
|
|||||||
|
<?php
|
||||||
|
$start = microtime(true);
|
||||||
|
require_once __DIR__ . "/../include/modulecheck.php";
|
||||||
|
require_once __DIR__ . "/../config/config.php";
|
||||||
|
require_once __DIR__ . "/../include/language.php";
|
||||||
|
require_once __DIR__ . "/../include/adminlist.php";
|
||||||
|
|
||||||
|
$htalink = $config["general"]["enablehta"] ? "" : ".php";
|
||||||
|
?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
|
||||||
|
<meta name="description" content="<?php echo $config["general"]["desc"]; ?>">
|
||||||
|
<meta name="author" content="Wruczek and contributors">
|
||||||
|
|
||||||
|
<title><?php echo $config["general"]["title"] . $config["general"]["subtitle"]; ?></title>
|
||||||
|
|
||||||
|
<!-- Icon -->
|
||||||
|
<link rel="shortcut icon" href="img/icon/icon-64.png">
|
||||||
|
|
||||||
|
<!-- Bootswatch -->
|
||||||
|
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootswatch/3.3.7/superhero/bootstrap.min.css" rel="stylesheet">
|
||||||
|
<link href="css/theme.css" rel="stylesheet">
|
||||||
|
|
||||||
|
<!-- Font Awesome -->
|
||||||
|
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
|
||||||
|
|
||||||
|
<?php if(isset($bansPage)) { ?>
|
||||||
|
<!-- DataTables for Bootstrap -->
|
||||||
|
<link href="https://cdnjs.cloudflare.com/ajax/libs/datatables/1.10.12/css/dataTables.bootstrap.min.css" rel="stylesheet">
|
||||||
|
<?php } ?>
|
||||||
|
|
||||||
|
<link href="css/flags/famfamfam-flags.min.css" rel="stylesheet">
|
||||||
|
|
||||||
|
<!-- Custom CSS -->
|
||||||
|
<link href="css/navbar.css" rel="stylesheet">
|
||||||
|
<link href="css/style.css" rel="stylesheet">
|
||||||
|
|
||||||
|
<?php if(!empty($config["general"]["christmasmode"])) { ?>
|
||||||
|
<script src="js/christmas.js"></script>
|
||||||
|
<?php } ?>
|
||||||
|
|
||||||
|
<script src="api/i18n.php"></script>
|
||||||
|
|
||||||
|
<!--[if IE]>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.min.js"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/respond.js/1.4.2/respond.min.js"></script>
|
||||||
|
<![endif]-->
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<nav class="navbar navbar-default navbar-fixed-top">
|
||||||
|
<div class="container">
|
||||||
|
<!-- Brand and toggle get grouped for better mobile display -->
|
||||||
|
<div class="navbar-header">
|
||||||
|
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
|
||||||
|
<span class="sr-only"><?php tl($lang["navbar"]["navigation"]); ?></span>
|
||||||
|
<span class="icon-bar"></span>
|
||||||
|
<span class="icon-bar"></span>
|
||||||
|
<span class="icon-bar"></span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<a class="navbar-brand" href="."><img style="width: 64px;" src="img/icon/icon-64.png" alt="Site logo"><?php echo $config["general"]["title"]; ?></a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Collect the nav links, forms, and other content for toggling -->
|
||||||
|
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
|
||||||
|
<ul class="nav navbar-nav">
|
||||||
|
<li><a href="viewer<?php echo $htalink ?>"><i class="fa fa-eye" aria-hidden="true"></i> <?php tl($lang["navbar"]["viewer"]); ?></a></li>
|
||||||
|
<li><a href="bans<?php echo $htalink ?>"><i class="fa fa-ban" aria-hidden="true"></i> <?php tl($lang["navbar"]["bans"]); ?></a></li>
|
||||||
|
<li><a href="rules<?php echo $htalink ?>"><i class="fa fa-book" aria-hidden="true"></i> <?php tl($lang["navbar"]["rules"]); ?></a></li>
|
||||||
|
<!-- I don't have time for this.
|
||||||
|
<li class="dropdown">
|
||||||
|
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><i class="fa fa-television" aria-hidden="true"></i></i>Ranking <span class="caret"></span></a>
|
||||||
|
<ul class="dropdown-menu">
|
||||||
|
<li><a href="#"><i class="fa fa-clock-o" aria-hidden="true"></i>Ranking Aktywności</a></li>
|
||||||
|
<li><a href="#"><i class="fa fa-sign-in" aria-hidden="true"></i>Ranking Połaczeń</a></li>
|
||||||
|
<li><a href="#"><i class="fa fa-sign-out" aria-hidden="true"></i>Ranking Połączenia</a></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
-->
|
||||||
|
</ul>
|
||||||
|
<ul class="nav navbar-nav navbar-right">
|
||||||
|
<?php foreach ($config["navlinks"] as $navlink) {
|
||||||
|
$icon = $navlink[0];
|
||||||
|
$text = $navlink[1];
|
||||||
|
$link = $navlink[2]; ?>
|
||||||
|
<li><a href="<?php echo $link; ?>"><i class="fa <?php echo $icon; ?>" aria-hidden="true"></i> <?php echo $text; ?></a></li>
|
||||||
|
<?php } ?>
|
||||||
|
|
||||||
|
<li data-toggle="tooltip" data-placement="bottom" title="<?php tl($lang["navbar"]["connecttooltip"], [$config['teamspeak']['displayip']]); ?>"><a href="ts3server://<?php echo $config['teamspeak']['displayip']; ?>"><i class="fa fa-sign-in" aria-hidden="true"></i><?php tl($lang["navbar"]["connect"]); ?></a></li>
|
||||||
|
|
||||||
|
<li class="dropdown">
|
||||||
|
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><i class="famfamfam-flags <?php tl($lang["general"]["languageflag"]) ?>" aria-hidden="true"></i> Language <span class="caret"></span></a>
|
||||||
|
<ul class="dropdown-menu">
|
||||||
|
|
||||||
|
<!-- Languages are sorted by number of total speakers in millions in all countries, based on ethnologue.com and Wikipedia -->
|
||||||
|
|
||||||
|
<li><a href="?lang=en"><i class="famfamfam-flags gb" aria-hidden="true"></i> English</a></li> <!-- English : 1010 -->
|
||||||
|
<li><a href="?lang=es"><i class="famfamfam-flags es" aria-hidden="true"></i> Español</a></li> <!-- Spanish : 528 -->
|
||||||
|
<li><a href="?lang=ru"><i class="famfamfam-flags ru" aria-hidden="true"></i> Русский</a></li> <!-- Russian : 268 -->
|
||||||
|
<li><a href="?lang=br"><i class="famfamfam-flags br" aria-hidden="true"></i> Português</a></li> <!-- Portuguese : 229,945 -->
|
||||||
|
<li><a href="?lang=fr"><i class="famfamfam-flags fr" aria-hidden="true"></i> Français</a></li> <!-- French : 229,582 -->
|
||||||
|
<li><a href="?lang=de"><i class="famfamfam-flags de" aria-hidden="true"></i> Deutsch</a></li> <!-- German : 130 -->
|
||||||
|
<li><a href="?lang=tr"><i class="famfamfam-flags tr" aria-hidden="true"></i> Türkçe</a></li> <!-- Turkish : 71 -->
|
||||||
|
<li><a href="?lang=it"><i class="famfamfam-flags it" aria-hidden="true"></i> Italiano</a></li> <!-- Italian : 66 -->
|
||||||
|
<li><a href="?lang=pl"><i class="famfamfam-flags pl" aria-hidden="true"></i> Polski</a></li> <!-- Polish : 41 -->
|
||||||
|
<li><a href="?lang=ua"><i class="famfamfam-flags ua" aria-hidden="true"></i> Українська</a></li> <!-- Ukrainian : 35 -->
|
||||||
|
<li><a href="?lang=nl"><i class="famfamfam-flags nl" aria-hidden="true"></i> Nederlands</a></li> <!-- Dutch : 22 -->
|
||||||
|
<li><a href="?lang=cz"><i class="famfamfam-flags cz" aria-hidden="true"></i> Česky</a></li> <!-- Czech : 13,217 -->
|
||||||
|
<li><a href="?lang=gr"><i class="famfamfam-flags gr" aria-hidden="true"></i> Ελληνικά</a></li> <!-- Greek : 13,134 -->
|
||||||
|
<li><a href="?lang=hu"><i class="famfamfam-flags hu" aria-hidden="true"></i> Magyar</a></li> <!-- Hungarian : 13 -->
|
||||||
|
<li><a href="?lang=se"><i class="famfamfam-flags se" aria-hidden="true"></i> Svenska</a></li> <!-- Swedish : 12 -->
|
||||||
|
<li><a href="?lang=bg"><i class="famfamfam-flags bg" aria-hidden="true"></i> български</a></li> <!-- Bulgarian : 8 -->
|
||||||
|
<li><a href="?lang=da"><i class="famfamfam-flags dk" aria-hidden="true"></i> Dansk</a></li> <!-- Danish : 6 -->
|
||||||
|
<li><a href="?lang=by"><i class="famfamfam-flags by" aria-hidden="true"></i> Беларуская мова</a></li> <!-- Belarusian : 3 -->
|
||||||
|
<li><a href="?lang=bs"><i class="famfamfam-flags ba" aria-hidden="true"></i> Босански</a></li> <!-- Bosnian : 2,59 -->
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<!-- /.navbar-collapse -->
|
||||||
|
</div>
|
||||||
|
<!-- /.container-fluid -->
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
|
||||||
|
<div class="col-md-3 col-md-push-9">
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading"><i class="fa fa-bar-chart" aria-hidden="true"></i> <?php tl($lang["serverstatus"]["title"]); ?></div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<div class="serverstatus">
|
||||||
|
<p><i class="fa fa-globe fa-fw" aria-hidden="true"></i> <?php tl($lang["serverstatus"]["address"]); ?>: <a href="ts3server://<?php echo $config['teamspeak']['displayip']; ?>"><?php echo $config['teamspeak']['displayip']; ?></a></p>
|
||||||
|
<div id="serverstatus">
|
||||||
|
<div class="text-center">
|
||||||
|
<i class="fa fa-refresh fa-spin fa-3x fa-fw"></i>
|
||||||
|
<span class="sr-only"><?php tl($lang["serverstatus"]["loading"]); ?></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading"><i class="fa fa-shield" aria-hidden="true"></i> <?php tl($lang["adminlist"]["title"]); ?> <span class="pull-right"><i class="fa fa-question-circle" aria-hidden="true" data-toggle="tooltip" data-placement="bottom" title="<?php tl($lang["adminlist"]["lastupdate"], [$adminlist[1]]); ?>"></i></span></div>
|
||||||
|
<div class="panel-body adminlist">
|
||||||
|
<?php echo $adminlist[0]; ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php if(!empty($config['contact']['items'])) { ?>
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading"><i class="fa fa-envelope" aria-hidden="true"></i> <?php echo $config['contact']['title']; ?></div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<ul class="list-unstyled">
|
||||||
|
<?php foreach ($config['contact']['items'] as $item) {
|
||||||
|
$name = $item[0];
|
||||||
|
$linkdesc = $item[1];
|
||||||
|
$link = $item[2];
|
||||||
|
echo '<li>' . $name . ' <span class="pull-right"><a href="' . $link . '">' . $linkdesc . '</a></span></li>';
|
||||||
|
} ?>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php } ?>
|
||||||
|
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading"><i class="fa fa-eye" aria-hidden="true"></i> <?php tl($lang["svpb"]["title"]); ?></div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<a href="viewer<?php echo $htalink ?>" class="btn btn-primary btn-lg btn-block"><i class="fa fa-eye" aria-hidden="true"></i> <?php tl($lang["svpb"]["takealook"]); ?></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-9 col-md-pull-3">
|
@ -0,0 +1,49 @@
|
|||||||
|
<?php
|
||||||
|
session_start();
|
||||||
|
header('Cache-control: private');
|
||||||
|
|
||||||
|
if (isset($_GET['lang'])) {
|
||||||
|
$langcode = $_GET['lang'];
|
||||||
|
|
||||||
|
$_SESSION['lang'] = $langcode;
|
||||||
|
|
||||||
|
setcookie('lang', $langcode, time() + (3600 * 24 * 60));
|
||||||
|
|
||||||
|
header("Location: {$_SERVER['PHP_SELF']}");
|
||||||
|
} else if (isset($_SESSION['lang'])) {
|
||||||
|
$langcode = $_SESSION['lang'];
|
||||||
|
} else if (isset($_COOKIE['lang'])) {
|
||||||
|
$langcode = $_COOKIE['lang'];
|
||||||
|
} else if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
|
||||||
|
$langcode = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2);
|
||||||
|
} else {
|
||||||
|
$langcode = "en";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!file_exists(getLanguagePath($langcode)))
|
||||||
|
$langcode = "en";
|
||||||
|
|
||||||
|
require_once getLanguagePath($langcode);
|
||||||
|
|
||||||
|
function getLanguagePath($langcode) {
|
||||||
|
return __DIR__ . '/../config/languages/lang.' . $langcode . '.php';
|
||||||
|
}
|
||||||
|
|
||||||
|
function tl($pattern, $args = null) {
|
||||||
|
echo translate($pattern, $args);
|
||||||
|
}
|
||||||
|
|
||||||
|
function translate($pattern, $args = null) {
|
||||||
|
|
||||||
|
if (!$args) {
|
||||||
|
return $pattern;
|
||||||
|
}
|
||||||
|
|
||||||
|
$size = count($args);
|
||||||
|
|
||||||
|
for ($i = 0; $i < $size; $i++) {
|
||||||
|
$pattern = str_ireplace('{' . $i . '}', $args[$i], $pattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $pattern;
|
||||||
|
}
|
@ -0,0 +1,117 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
if (!defined("PHP_VERSION_ID") || PHP_VERSION_ID < 50500) {
|
||||||
|
$title = 'Unsupported PHP version';
|
||||||
|
|
||||||
|
$text =
|
||||||
|
'<p>You are using old, unsupported PHP version.</p>' .
|
||||||
|
'<p>Your PHP version: <b>' . PHP_VERSION . '</b>, required PHP version: <b>5.5.0</b>.</p>' .
|
||||||
|
'<p>Please update your PHP installation and try again.</p>';
|
||||||
|
|
||||||
|
showError($title, $text);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!function_exists("utf8_encode")) {
|
||||||
|
showExtensionMissingError("xml");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!extension_loaded("json")) {
|
||||||
|
showExtensionMissingError("json");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!extension_loaded("mbstring")) {
|
||||||
|
showExtensionMissingError("mbstring");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((fileperms(__DIR__ . '/../cache') & 0777) !== 0777) {
|
||||||
|
$title = 'Cache directory is not writable';
|
||||||
|
|
||||||
|
$text =
|
||||||
|
'<p>Please make sure that the <code>cache</code> directory is fully readable, writable and executable.</p>' .
|
||||||
|
'<p>Running: <code>sudo chmod 777 -R ' . realpath(__DIR__ . '/../cache') . '</code> should fix the problem.</p>';
|
||||||
|
|
||||||
|
showError($title, $text);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!file_exists(__DIR__ . "/../config/config.php")) {
|
||||||
|
$title = 'config.php does not exists';
|
||||||
|
|
||||||
|
$text =
|
||||||
|
'<p>Please go into the directory <code>config</code> and rename <code>config.template.php</code> to <code>config.php</code>.</p>' .
|
||||||
|
'<p>Edit the new file and tweak it to suite your needs.</p>';
|
||||||
|
|
||||||
|
showError($title, $text);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// FUNCTION
|
||||||
|
|
||||||
|
function showExtensionMissingError($extension_name) {
|
||||||
|
$title = 'Required extension "' . $extension_name . '" is missing';
|
||||||
|
|
||||||
|
$text =
|
||||||
|
'<p>Required PHP extension <code>' . $extension_name . '</code> is missing or is not loaded.</p>' .
|
||||||
|
'<p>Install it and restart your server. Usually running <code>sudo apt-get install php-' . $extension_name . '</code> should be enough.</p>' .
|
||||||
|
'<p>If you still get this error, try restarting your web server and <code>php-fpm</code> service or just reboot your machine</p>' .
|
||||||
|
'<p>If you are using Web Hosting service, please contact their support for instructions on enabling <code>' . $extension_name . '</code> extension</p>';
|
||||||
|
|
||||||
|
showError($title, $text);
|
||||||
|
}
|
||||||
|
|
||||||
|
function showError($title, $text) { ?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
|
||||||
|
<meta name="author" content="Wruczek">
|
||||||
|
|
||||||
|
<title><?php echo $title ?></title>
|
||||||
|
|
||||||
|
<!-- Icon -->
|
||||||
|
<link rel="shortcut icon" href="https://assets-cdn.github.com/images/icons/emoji/unicode/26a0.png">
|
||||||
|
|
||||||
|
<!-- Twitter Bootstrap -->
|
||||||
|
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootswatch/3.3.7/superhero/bootstrap.min.css" rel="stylesheet">
|
||||||
|
|
||||||
|
<!--[if IE]>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.min.js"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/respond.js/1.4.2/respond.min.js"></script>
|
||||||
|
<![endif]-->
|
||||||
|
|
||||||
|
<style>
|
||||||
|
body { margin-top: 70px }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<h3 class="panel-title"><img src="https://assets-cdn.github.com/images/icons/emoji/unicode/26a0.png" width="20px" alt="Error"> <?php echo $title ?></h3>
|
||||||
|
</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<?php echo $text ?>
|
||||||
|
</div>
|
||||||
|
<div class="panel-footer">
|
||||||
|
© <a href="https://wruczek.tech">Wruczek</a> 2016 - 2018 | <a href="https://github.com/Wruczek/ts-website">ts-website</a> v 1.4.7 | MIT License
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- /container -->
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
|
<?php }
|
@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
require_once __DIR__ . '/../config/config.php';
|
||||||
|
require_once __DIR__ . "/../lib/ts3phpframework/libraries/TeamSpeak3/TeamSpeak3.php";
|
||||||
|
|
||||||
|
function pingTeamspeakServerFromConfig() {
|
||||||
|
return pingTeamspeakServer(getTeamspeakConnection("?use_offline_as_virtual=1&no_query_clients=1"));
|
||||||
|
}
|
||||||
|
|
||||||
|
function pingTeamspeakServer() {
|
||||||
|
try {
|
||||||
|
$tsAdmin = getTeamspeakConnection();
|
||||||
|
|
||||||
|
if ($tsAdmin->isOffline())
|
||||||
|
throw new Exception("Server is offline");
|
||||||
|
|
||||||
|
return $tsAdmin->getInfo();
|
||||||
|
} catch (TeamSpeak3_Exception $e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTeamspeakConnection($arguments = '') {
|
||||||
|
try {
|
||||||
|
global $config;
|
||||||
|
$host = $config['teamspeak']['host'];
|
||||||
|
$login = $config['teamspeak']['login'];
|
||||||
|
$passwd = $config['teamspeak']['password'];
|
||||||
|
$sport = $config['teamspeak']['server_port'];
|
||||||
|
$qport = $config['teamspeak']['query_port'];
|
||||||
|
|
||||||
|
$tsNodeHost = TeamSpeak3::factory("serverquery://$host:$qport/$arguments");
|
||||||
|
$tsNodeHost->login($login, $passwd);
|
||||||
|
return $tsNodeHost->serverGetByPort($sport);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,75 @@
|
|||||||
|
<?php
|
||||||
|
require_once dirname(__FILE__) . "/include/modulecheck.php";
|
||||||
|
require_once __DIR__ . "/include/header.php";
|
||||||
|
require_once __DIR__ . "/lib/parsedown/parsedown.php";
|
||||||
|
?>
|
||||||
|
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<h3 class="panel-title news-header"><i class="fa fa-newspaper-o" aria-hidden="true"></i> <?php tl($lang["index"]["title"]); ?></h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- NEWSY -->
|
||||||
|
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$parsedown = new Parsedown();
|
||||||
|
|
||||||
|
$path = __DIR__ . "/" . $config["general"]["newsDir"];
|
||||||
|
|
||||||
|
if (file_exists($path))
|
||||||
|
showNews($path);
|
||||||
|
else
|
||||||
|
echo '<div class="alert alert-danger"><p class="text-center">' . translate($lang["index"]["errortitle"]) . '</p><p class="text-center">' . translate($lang["index"]["errorsubtitle"]) . '</p></div>';
|
||||||
|
|
||||||
|
// *******
|
||||||
|
// METHODS
|
||||||
|
// *******
|
||||||
|
|
||||||
|
function showNews($path) {
|
||||||
|
global $parsedown;
|
||||||
|
|
||||||
|
$files = array_diff(scandir($path), array('..', '.'));
|
||||||
|
foreach ($files as $newsFile) {
|
||||||
|
|
||||||
|
if (!endsWith($newsFile, ".md"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
$file = readFileContent($path . "/" . $newsFile);
|
||||||
|
$lines = explode("\n", $file);
|
||||||
|
|
||||||
|
$title = $lines[0];
|
||||||
|
$author = $lines[1];
|
||||||
|
$text = implode("\n", array_slice($lines, 3));
|
||||||
|
|
||||||
|
generateNewsBox($title, $author, $parsedown->text($text));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function generateNewsBox($title, $author, $text) { ?>
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<h3 class="panel-title"><div class="row"><div class="col-md-8"><i class="fa fa-info-circle" aria-hidden="true"></i> <?php echo $title; ?></div><div class="col-md-4 news-author"><i class="fa fa-user" aria-hidden="true"></i> <?php echo $author; ?></div></div></h3>
|
||||||
|
</div>
|
||||||
|
<div class="panel-body news-body">
|
||||||
|
<?php echo $text; ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php }
|
||||||
|
|
||||||
|
function readFileContent($file) {
|
||||||
|
$fopen = @fopen($file, "r");
|
||||||
|
if (!$fopen) return false;
|
||||||
|
$text = fread($fopen, filesize($file));
|
||||||
|
fclose($fopen);
|
||||||
|
return $text;
|
||||||
|
}
|
||||||
|
|
||||||
|
function endsWith($haystack, $needle) {
|
||||||
|
return $needle === "" || (($temp = strlen($haystack) - strlen($needle)) >= 0 && strpos($haystack, $needle, $temp) !== false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
require_once __DIR__ . "/include/footer.php";
|
||||||
|
?>
|
@ -0,0 +1,8 @@
|
|||||||
|
$(document).ready(function () {
|
||||||
|
$('#banlist').dataTable({
|
||||||
|
"order": [[3, "desc"]],
|
||||||
|
"language": {
|
||||||
|
"url": datatablesUrl
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,74 @@
|
|||||||
|
// Remember: This file is loaded before jQuery!
|
||||||
|
|
||||||
|
// Check if the current month on user device is December...
|
||||||
|
if (new Date().getMonth() === 11) {
|
||||||
|
// Enable the christmas functions! Happy holidays from Wruczek! :D
|
||||||
|
|
||||||
|
// Load and enable the christmas theme
|
||||||
|
var stylesheet = document.createElement('link');
|
||||||
|
stylesheet.href = 'css/christmas-theme.css';
|
||||||
|
stylesheet.rel = 'stylesheet';
|
||||||
|
document.head.appendChild(stylesheet);
|
||||||
|
|
||||||
|
// Load and enable the snow
|
||||||
|
var script = document.createElement('script');
|
||||||
|
script.src = 'https://cdnjs.cloudflare.com/ajax/libs/JQuery-Snowfall/1.7.4/snowfall.min.js';
|
||||||
|
document.head.appendChild(script);
|
||||||
|
|
||||||
|
window.addEventListener('load', function () {
|
||||||
|
// Change background artist in the footer
|
||||||
|
document.getElementById('background-artist').innerHTML = '<a href="http://www.publicdomainpictures.net/view-image.php?image=28562&picture=christmas-bulbs-red-background">Debi Geroux - Public Domain</a>';
|
||||||
|
|
||||||
|
if(getCookie('snoweffect') === 'false') {
|
||||||
|
document.getElementById('website-copyright').innerHTML += ' — <a class="disableSnowLink" href="#" onclick="enableSnowEffect()">Enable snow effect</a>';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add a link to disable the effect
|
||||||
|
document.getElementById('website-copyright').innerHTML += ' — <a class="disableSnowLink" href="#" onclick="disableSnowEffect()">Disable snow effect</a>';
|
||||||
|
|
||||||
|
// Add the snow effect
|
||||||
|
snowFall.snow(document.body, {
|
||||||
|
flakeCount: (document.body.clientWidth > 992 ? 500 : 100),
|
||||||
|
flakeIndex: -1,
|
||||||
|
minSize: 4,
|
||||||
|
maxSize: 5,
|
||||||
|
minSpeed: 1,
|
||||||
|
maxSpeed: 2,
|
||||||
|
round: true,
|
||||||
|
shadow: true
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function disableSnowEffect() {
|
||||||
|
setCookie('snoweffect', 'false', 30);
|
||||||
|
location.reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
function enableSnowEffect() {
|
||||||
|
setCookie('snoweffect', 'true', 30);
|
||||||
|
location.reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
function setCookie(cname,cvalue,exdays) {
|
||||||
|
var d = new Date();
|
||||||
|
d.setTime(d.getTime() + (exdays*24*60*60*1000));
|
||||||
|
var expires = "expires=" + d.toGMTString();
|
||||||
|
document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCookie(cname) {
|
||||||
|
var name = cname + "=";
|
||||||
|
var ca = document.cookie.split(';');
|
||||||
|
for(var i = 0; i < ca.length; i++) {
|
||||||
|
var c = ca[i];
|
||||||
|
while (c.charAt(0) == ' ') {
|
||||||
|
c = c.substring(1);
|
||||||
|
}
|
||||||
|
if (c.indexOf(name) == 0) {
|
||||||
|
return c.substring(name.length, c.length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
$(document).ready(function () {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
// Bootstrap tooltips initialization
|
||||||
|
$('[data-toggle="tooltip"]').tooltip({
|
||||||
|
"html": true
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add "Show more" button to news panels
|
||||||
|
$('.news-body').readmore({
|
||||||
|
speed: 500,
|
||||||
|
collapsedHeight: 300,
|
||||||
|
moreLink: '<button type="button" class="btn btn-dark"><i class="fa fa-plus-circle" aria-hidden="true"></i> ' + textShowMore + '</button>',
|
||||||
|
lessLink: '<button type="button" class="btn btn-dark"><i class="fa fa-minus-circle" aria-hidden="true"></i> ' + textShowLess + '</button>'
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
@ -0,0 +1,62 @@
|
|||||||
|
$(document).ready(function () {
|
||||||
|
checkStatus();
|
||||||
|
|
||||||
|
var intervalid = setInterval(function () {
|
||||||
|
checkStatus();
|
||||||
|
}, 10 * 1000);
|
||||||
|
});
|
||||||
|
|
||||||
|
function checkStatus() {
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: apiurl,
|
||||||
|
success: function (json) {
|
||||||
|
|
||||||
|
json = json.tsstatus;
|
||||||
|
|
||||||
|
var result = "";
|
||||||
|
|
||||||
|
if (json.success) {
|
||||||
|
var clientsonline = json.clientsonline;
|
||||||
|
var maxclients = json.maxclients;
|
||||||
|
var clientsprecent = Math.round(json.clientsonline * 100 / json.maxclients);
|
||||||
|
var version = json.version;
|
||||||
|
var platform = json.platform;
|
||||||
|
var uptime = json.uptime;
|
||||||
|
var averagePacketloss = Math.round(json.averagePacketloss * 10000) / 100;
|
||||||
|
var averagePing = Math.round(json.averagePing * 100) / 100;
|
||||||
|
|
||||||
|
var platformIcon = '<i class="fa %s fa-fw" title="' + platform + '" aria-hidden="true"></i>';
|
||||||
|
|
||||||
|
switch (platform.toLowerCase()) {
|
||||||
|
case "windows":
|
||||||
|
platformIcon = platformIcon.replace(/%s/, 'fa-windows');
|
||||||
|
break;
|
||||||
|
case "linux":
|
||||||
|
platformIcon = platformIcon.replace(/%s/, 'fa-linux');
|
||||||
|
break;
|
||||||
|
case "os x":
|
||||||
|
case "macos":
|
||||||
|
platformIcon = platformIcon.replace(/%s/, 'fa-apple');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
platformIcon = platform;
|
||||||
|
}
|
||||||
|
|
||||||
|
result =
|
||||||
|
'<p><i class="fa fa-power-off fa-fw" aria-hidden="true"></i> ' + statusOnline + ': <span class="label label-success">' + clientsonline + ' / ' + maxclients + ' (' + clientsprecent + '%)</span></p>' +
|
||||||
|
'<p><i class="fa fa-clock-o fa-fw" aria-hidden="true"></i> ' + statusUptime + ': <span class="label label-success">' + uptime + '</span></p>' +
|
||||||
|
'<p><i class="fa fa-info-circle fa-fw" aria-hidden="true"></i> ' + statusVersion + ': <span class="label label-success">' + version + ' on ' + platformIcon + '</span></p>' +
|
||||||
|
'<p><i class="fa fa-signal fa-fw" aria-hidden="true"></i> ' + statusAvgping + ': <span class="label label-success">' + averagePing + ' ms</span></p>' +
|
||||||
|
'<p><i class="fa fa-bolt fa-fw" aria-hidden="true"></i> ' + statusAvgpl + ': <span class="label label-success">' + averagePacketloss + '%</span></p>';
|
||||||
|
} else {
|
||||||
|
result = '<p><i class="fa fa-power-off fa-fw" aria-hidden="true"></i> Online: <span class="label label-danger">' + statusOffline + '</span></p>';
|
||||||
|
}
|
||||||
|
|
||||||
|
$("#serverstatus").html(result);
|
||||||
|
},
|
||||||
|
error: function (result) {
|
||||||
|
$("#serverstatus").html('<p><i class="fa fa-power-off fa-fw" aria-hidden="true"></i> ' + statusOnline + ': <span class="label label-danger">ERROR</span></p>');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
Copyright (c) 2016 phpFastCache
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
Software), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
@ -0,0 +1,19 @@
|
|||||||
|
Copyright (c) 2015 PHP Framework Interoperability Group
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
@ -0,0 +1,9 @@
|
|||||||
|
PSR Cache
|
||||||
|
=========
|
||||||
|
|
||||||
|
This repository holds all interfaces defined by
|
||||||
|
[PSR-6](http://www.php-fig.org/psr/psr-6/).
|
||||||
|
|
||||||
|
Note that this is not a Cache implementation of its own. It is merely an
|
||||||
|
interface that describes a Cache implementation. See the specification for more
|
||||||
|
details.
|
@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"name": "psr/cache",
|
||||||
|
"description": "Common interface for caching libraries",
|
||||||
|
"keywords": ["psr", "psr-6", "cache"],
|
||||||
|
"license": "MIT",
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "PHP-FIG",
|
||||||
|
"homepage": "http://www.php-fig.org/"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"require": {
|
||||||
|
"php": ">=5.3.0"
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Psr\\Cache\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "1.0.x-dev"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Psr\Cache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exception interface for all exceptions thrown by an Implementing Library.
|
||||||
|
*/
|
||||||
|
interface CacheException
|
||||||
|
{
|
||||||
|
}
|
@ -0,0 +1,106 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Psr\Cache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CacheItemInterface defines an interface for interacting with objects inside a cache.
|
||||||
|
*
|
||||||
|
* Each Item object MUST be associated with a specific key, which can be set
|
||||||
|
* according to the implementing system and is typically passed by the
|
||||||
|
* Cache\CacheItemPoolInterface object.
|
||||||
|
*
|
||||||
|
* The Cache\CacheItemInterface object encapsulates the storage and retrieval of
|
||||||
|
* cache items. Each Cache\CacheItemInterface is generated by a
|
||||||
|
* Cache\CacheItemPoolInterface object, which is responsible for any required
|
||||||
|
* setup as well as associating the object with a unique Key.
|
||||||
|
* Cache\CacheItemInterface objects MUST be able to store and retrieve any type
|
||||||
|
* of PHP value defined in the Data section of the specification.
|
||||||
|
*
|
||||||
|
* Calling Libraries MUST NOT instantiate Item objects themselves. They may only
|
||||||
|
* be requested from a Pool object via the getItem() method. Calling Libraries
|
||||||
|
* SHOULD NOT assume that an Item created by one Implementing Library is
|
||||||
|
* compatible with a Pool from another Implementing Library.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
interface CacheItemInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Returns the key for the current cache item.
|
||||||
|
*
|
||||||
|
* The key is loaded by the Implementing Library, but should be available to
|
||||||
|
* the higher level callers when needed.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* The key string for this cache item.
|
||||||
|
*/
|
||||||
|
public function getKey();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the value of the item from the cache associated with this object's key.
|
||||||
|
*
|
||||||
|
* The value returned must be identical to the value originally stored by set().
|
||||||
|
*
|
||||||
|
* If isHit() returns false, this method MUST return null. Note that null
|
||||||
|
* is a legitimate cached value, so the isHit() method SHOULD be used to
|
||||||
|
* differentiate between "null value was found" and "no value was found."
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
* The value corresponding to this cache item's key, or null if not found.
|
||||||
|
*/
|
||||||
|
public function get();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Confirms if the cache item lookup resulted in a cache hit.
|
||||||
|
*
|
||||||
|
* Note: This method MUST NOT have a race condition between calling isHit()
|
||||||
|
* and calling get().
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* True if the request resulted in a cache hit. False otherwise.
|
||||||
|
*/
|
||||||
|
public function isHit();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the value represented by this cache item.
|
||||||
|
*
|
||||||
|
* The $value argument may be any item that can be serialized by PHP,
|
||||||
|
* although the method of serialization is left up to the Implementing
|
||||||
|
* Library.
|
||||||
|
*
|
||||||
|
* @param mixed $value
|
||||||
|
* The serializable value to be stored.
|
||||||
|
*
|
||||||
|
* @return static
|
||||||
|
* The invoked object.
|
||||||
|
*/
|
||||||
|
public function set($value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the expiration time for this cache item.
|
||||||
|
*
|
||||||
|
* @param \DateTimeInterface $expiration
|
||||||
|
* The point in time after which the item MUST be considered expired.
|
||||||
|
* If null is passed explicitly, a default value MAY be used. If none is set,
|
||||||
|
* the value should be stored permanently or for as long as the
|
||||||
|
* implementation allows.
|
||||||
|
*
|
||||||
|
* @return static
|
||||||
|
* The called object.
|
||||||
|
*/
|
||||||
|
public function expiresAt($expiration);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the expiration time for this cache item.
|
||||||
|
*
|
||||||
|
* @param int|\DateInterval $time
|
||||||
|
* The period of time from the present after which the item MUST be considered
|
||||||
|
* expired. An integer parameter is understood to be the time in seconds until
|
||||||
|
* expiration. If null is passed explicitly, a default value MAY be used.
|
||||||
|
* If none is set, the value should be stored permanently or for as long as the
|
||||||
|
* implementation allows.
|
||||||
|
*
|
||||||
|
* @return static
|
||||||
|
* The called object.
|
||||||
|
*/
|
||||||
|
public function expiresAfter($time);
|
||||||
|
}
|
@ -0,0 +1,139 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Psr\Cache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CacheItemPoolInterface generates CacheItemInterface objects.
|
||||||
|
*
|
||||||
|
* The primary purpose of Cache\CacheItemPoolInterface is to accept a key from
|
||||||
|
* the Calling Library and return the associated Cache\CacheItemInterface object.
|
||||||
|
* It is also the primary point of interaction with the entire cache collection.
|
||||||
|
* All configuration and initialization of the Pool is left up to an
|
||||||
|
* Implementing Library.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
interface CacheItemPoolInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Returns a Cache Item representing the specified key.
|
||||||
|
*
|
||||||
|
* This method must always return a CacheItemInterface object, even in case of
|
||||||
|
* a cache miss. It MUST NOT return null.
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* The key for which to return the corresponding Cache Item.
|
||||||
|
*
|
||||||
|
* @throws InvalidArgumentException
|
||||||
|
* If the $key string is not a legal value a \Psr\Cache\InvalidArgumentException
|
||||||
|
* MUST be thrown.
|
||||||
|
*
|
||||||
|
* @return CacheItemInterface
|
||||||
|
* The corresponding Cache Item.
|
||||||
|
*/
|
||||||
|
public function getItem($key);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a traversable set of cache items.
|
||||||
|
*
|
||||||
|
* @param array $keys
|
||||||
|
* An indexed array of keys of items to retrieve.
|
||||||
|
*
|
||||||
|
* @throws InvalidArgumentException
|
||||||
|
* If any of the keys in $keys are not a legal value a \Psr\Cache\InvalidArgumentException
|
||||||
|
* MUST be thrown.
|
||||||
|
*
|
||||||
|
* @return array|\Traversable
|
||||||
|
* A traversable collection of Cache Items keyed by the cache keys of
|
||||||
|
* each item. A Cache item will be returned for each key, even if that
|
||||||
|
* key is not found. However, if no keys are specified then an empty
|
||||||
|
* traversable MUST be returned instead.
|
||||||
|
*/
|
||||||
|
public function getItems(array $keys = array());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Confirms if the cache contains specified cache item.
|
||||||
|
*
|
||||||
|
* Note: This method MAY avoid retrieving the cached value for performance reasons.
|
||||||
|
* This could result in a race condition with CacheItemInterface::get(). To avoid
|
||||||
|
* such situation use CacheItemInterface::isHit() instead.
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* The key for which to check existence.
|
||||||
|
*
|
||||||
|
* @throws InvalidArgumentException
|
||||||
|
* If the $key string is not a legal value a \Psr\Cache\InvalidArgumentException
|
||||||
|
* MUST be thrown.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* True if item exists in the cache, false otherwise.
|
||||||
|
*/
|
||||||
|
public function hasItem($key);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes all items in the pool.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* True if the pool was successfully cleared. False if there was an error.
|
||||||
|
*/
|
||||||
|
public function clear();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the item from the pool.
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* The key for which to delete
|
||||||
|
*
|
||||||
|
* @throws InvalidArgumentException
|
||||||
|
* If the $key string is not a legal value a \Psr\Cache\InvalidArgumentException
|
||||||
|
* MUST be thrown.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* True if the item was successfully removed. False if there was an error.
|
||||||
|
*/
|
||||||
|
public function deleteItem($key);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes multiple items from the pool.
|
||||||
|
*
|
||||||
|
* @param array $keys
|
||||||
|
* An array of keys that should be removed from the pool.
|
||||||
|
|
||||||
|
* @throws InvalidArgumentException
|
||||||
|
* If any of the keys in $keys are not a legal value a \Psr\Cache\InvalidArgumentException
|
||||||
|
* MUST be thrown.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* True if the items were successfully removed. False if there was an error.
|
||||||
|
*/
|
||||||
|
public function deleteItems(array $keys);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Persists a cache item immediately.
|
||||||
|
*
|
||||||
|
* @param CacheItemInterface $item
|
||||||
|
* The cache item to save.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* True if the item was successfully persisted. False if there was an error.
|
||||||
|
*/
|
||||||
|
public function save(CacheItemInterface $item);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a cache item to be persisted later.
|
||||||
|
*
|
||||||
|
* @param CacheItemInterface $item
|
||||||
|
* The cache item to save.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* False if the item could not be queued or if a commit was attempted and failed. True otherwise.
|
||||||
|
*/
|
||||||
|
public function saveDeferred(CacheItemInterface $item);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Persists any deferred cache items.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* True if all not-yet-saved items were successfully saved or there were none. False otherwise.
|
||||||
|
*/
|
||||||
|
public function commit();
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Psr\Cache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exception interface for invalid cache arguments.
|
||||||
|
*
|
||||||
|
* Any time an invalid argument is passed into a method it must throw an
|
||||||
|
* exception class which implements Psr\Cache\InvalidArgumentException.
|
||||||
|
*/
|
||||||
|
interface InvalidArgumentException extends CacheException
|
||||||
|
{
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* This file is part of phpFastCache.
|
||||||
|
*
|
||||||
|
* @license MIT License (MIT)
|
||||||
|
*
|
||||||
|
* For full copyright and license information, please see the docs/CREDITS.txt file.
|
||||||
|
*
|
||||||
|
* @author Khoa Bui (khoaofgod) <khoaofgod@gmail.com> http://www.phpfastcache.com
|
||||||
|
* @author Georges.L (Geolim4) <contact@geolim4.com>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
define('PFC_PHP_EXT', 'php');
|
||||||
|
define('PFC_BIN_DIR', __DIR__ . '/../bin/');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register Autoload
|
||||||
|
*/
|
||||||
|
spl_autoload_register(function ($entity) {
|
||||||
|
$module = explode('\\', $entity, 2);
|
||||||
|
if (!in_array($module[ 0 ], ['phpFastCache', 'Psr'])) {
|
||||||
|
/**
|
||||||
|
* Not a part of phpFastCache file
|
||||||
|
* then we return here.
|
||||||
|
*/
|
||||||
|
return;
|
||||||
|
} else if (strpos($entity, 'Psr\Cache') === 0) {
|
||||||
|
$path = PFC_BIN_DIR . 'legacy/Psr/Cache/src/' . substr(strrchr($entity, '\\'), 1) . '.' . PFC_PHP_EXT;
|
||||||
|
|
||||||
|
if (is_readable($path)) {
|
||||||
|
require_once $path;
|
||||||
|
}else{
|
||||||
|
trigger_error('Cannot locate the Psr/Cache files', E_USER_ERROR);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$entity = str_replace('\\', '/', $entity);
|
||||||
|
$path = __DIR__ . '/' . $entity . '.' . PFC_PHP_EXT;
|
||||||
|
|
||||||
|
if (is_readable($path)) {
|
||||||
|
require_once $path;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if ((!defined('PFC_IGNORE_COMPOSER_WARNING') || !PFC_IGNORE_COMPOSER_WARNING) && class_exists('Composer\Autoload\ClassLoader')) {
|
||||||
|
trigger_error('Your project already makes use of Composer. You SHOULD use the composer dependency "phpfastcache/phpfastcache" instead of hard-autoloading.',
|
||||||
|
E_USER_WARNING);
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
order deny,allow
|
||||||
|
deny from all
|
||||||
|
allow from 127.0.0.1
|
@ -0,0 +1,72 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* This file is part of phpFastCache.
|
||||||
|
*
|
||||||
|
* @license MIT License (MIT)
|
||||||
|
*
|
||||||
|
* For full copyright and license information, please see the docs/CREDITS.txt file.
|
||||||
|
*
|
||||||
|
* @author Khoa Bui (khoaofgod) <khoaofgod@gmail.com> http://www.phpfastcache.com
|
||||||
|
* @author Georges.L (Geolim4) <contact@geolim4.com>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace phpFastCache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Api
|
||||||
|
* @package phpFastCache
|
||||||
|
*/
|
||||||
|
class Api
|
||||||
|
{
|
||||||
|
protected static $version = '1.1.3';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method will returns the current
|
||||||
|
* API version, the API version will be
|
||||||
|
* updated by following the semantic versioning
|
||||||
|
* based on changes of:
|
||||||
|
* - ExtendedCacheItemPoolInterface
|
||||||
|
* - ExtendedCacheItemInterface
|
||||||
|
*
|
||||||
|
* @see http://semver.org/
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function getVersion()
|
||||||
|
{
|
||||||
|
return self::$version;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the API changelog, as a string.
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function getChangelog()
|
||||||
|
{
|
||||||
|
return <<<CHANGELOG
|
||||||
|
- 1.1.3
|
||||||
|
-- Added an additional CacheItemInterface method:
|
||||||
|
ExtendedCacheItemInterface::getEncodedKey()
|
||||||
|
|
||||||
|
- 1.1.2
|
||||||
|
-- Implemented [de|a]ttaching methods to improve memory management
|
||||||
|
ExtendedCacheItemPoolInterface::detachItem()
|
||||||
|
ExtendedCacheItemPoolInterface::detachAllItems()
|
||||||
|
ExtendedCacheItemPoolInterface::attachItem()
|
||||||
|
ExtendedCacheItemPoolInterface::isAttached()
|
||||||
|
|
||||||
|
- 1.1.1
|
||||||
|
-- Implemented JsonSerializable interface to ExtendedCacheItemInterface
|
||||||
|
|
||||||
|
- 1.1.0
|
||||||
|
-- Implemented JSON methods such as:
|
||||||
|
ExtendedCacheItemPoolInterface::getItemsAsJsonString()
|
||||||
|
ExtendedCacheItemPoolInterface::getItemsByTagsAsJsonString()
|
||||||
|
ExtendedCacheItemInterface::getDataAsJsonString()
|
||||||
|
|
||||||
|
- 1.0.0
|
||||||
|
-- First initial version
|
||||||
|
CHANGELOG;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,334 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* This file is part of phpFastCache.
|
||||||
|
*
|
||||||
|
* @license MIT License (MIT)
|
||||||
|
*
|
||||||
|
* For full copyright and license information, please see the docs/CREDITS.txt file.
|
||||||
|
*
|
||||||
|
* @author Khoa Bui (khoaofgod) <khoaofgod@gmail.com> http://www.phpfastcache.com
|
||||||
|
* @author Georges.L (Geolim4) <contact@geolim4.com>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
namespace phpFastCache\Cache;
|
||||||
|
|
||||||
|
use phpFastCache\Core\ExtendedCacheItemPoolTrait;
|
||||||
|
use phpFastCache\Exceptions\phpFastCacheDriverException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class DriverBaseTrait
|
||||||
|
* @package phpFastCache\Cache
|
||||||
|
*/
|
||||||
|
trait DriverBaseTrait
|
||||||
|
{
|
||||||
|
use ExtendedCacheItemPoolTrait;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array default options, this will be merge to Driver's Options
|
||||||
|
*/
|
||||||
|
protected $config = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
protected $fallback = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var mixed Instance of driver service
|
||||||
|
*/
|
||||||
|
protected $instance;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $config_name
|
||||||
|
* @param string $value
|
||||||
|
*/
|
||||||
|
public function setup($config_name, $value = '')
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Config for class
|
||||||
|
*/
|
||||||
|
if (is_array($config_name)) {
|
||||||
|
$this->config = array_merge($this->config, $config_name);
|
||||||
|
} else {
|
||||||
|
$this->config[ $config_name ] = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getConfig()
|
||||||
|
{
|
||||||
|
return $this->config;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $file
|
||||||
|
* @return string
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
protected function readfile($file)
|
||||||
|
{
|
||||||
|
if (function_exists('file_get_contents')) {
|
||||||
|
return file_get_contents($file);
|
||||||
|
} else {
|
||||||
|
$string = '';
|
||||||
|
|
||||||
|
$file_handle = @fopen($file, 'r');
|
||||||
|
if (!$file_handle) {
|
||||||
|
throw new phpFastCacheDriverException("Can't Read File", 96);
|
||||||
|
|
||||||
|
}
|
||||||
|
while (!feof($file_handle)) {
|
||||||
|
$line = fgets($file_handle);
|
||||||
|
$string .= $line;
|
||||||
|
}
|
||||||
|
fclose($file_handle);
|
||||||
|
|
||||||
|
return $string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encode data types such as object/array
|
||||||
|
* for driver that does not support
|
||||||
|
* non-scalar value
|
||||||
|
* @param $data
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function encode($data)
|
||||||
|
{
|
||||||
|
return serialize($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decode data types such as object/array
|
||||||
|
* for driver that does not support
|
||||||
|
* non-scalar value
|
||||||
|
* @param $value
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
protected function decode($value)
|
||||||
|
{
|
||||||
|
return @unserialize($value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check phpModules or CGI
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
protected function isPHPModule()
|
||||||
|
{
|
||||||
|
if (PHP_SAPI === 'apache2handler') {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
if (strpos(PHP_SAPI, 'handler') !== false) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $class
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
protected function isExistingDriver($class)
|
||||||
|
{
|
||||||
|
return class_exists("\\phpFastCache\\Drivers\\{$class}");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $tag
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function _getTagName($tag)
|
||||||
|
{
|
||||||
|
return "__tag__" . $tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \phpFastCache\Cache\ExtendedCacheItemInterface $item
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function driverPreWrap(ExtendedCacheItemInterface $item)
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
self::DRIVER_DATA_WRAPPER_INDEX => $item->get(),
|
||||||
|
self::DRIVER_TIME_WRAPPER_INDEX => $item->getExpirationDate(),
|
||||||
|
self::DRIVER_TAGS_WRAPPER_INDEX => $item->getTags(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $wrapper
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function driverUnwrapData(array $wrapper)
|
||||||
|
{
|
||||||
|
return $wrapper[ self::DRIVER_DATA_WRAPPER_INDEX ];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $wrapper
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function driverUnwrapTags(array $wrapper)
|
||||||
|
{
|
||||||
|
return $wrapper[ self::DRIVER_TAGS_WRAPPER_INDEX ];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $wrapper
|
||||||
|
* @return \DateTime
|
||||||
|
*/
|
||||||
|
public function driverUnwrapTime(array $wrapper)
|
||||||
|
{
|
||||||
|
return $wrapper[ self::DRIVER_TIME_WRAPPER_INDEX ];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getDriverName()
|
||||||
|
{
|
||||||
|
static $driverName;
|
||||||
|
|
||||||
|
return ($driverName ?: $driverName = ucfirst(substr(strrchr((new \ReflectionObject($this))->getNamespaceName(), '\\'), 1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \phpFastCache\Cache\ExtendedCacheItemInterface $item
|
||||||
|
* @return bool
|
||||||
|
* @throws \LogicException
|
||||||
|
*/
|
||||||
|
public function driverWriteTags(ExtendedCacheItemInterface $item)
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Do not attempt to write tags
|
||||||
|
* on tags item, it can leads
|
||||||
|
* to an infinite recursive calls
|
||||||
|
*/
|
||||||
|
if(strpos($item->getKey(), self::DRIVER_TAGS_KEY_PREFIX ) === 0){
|
||||||
|
throw new \LogicException('Trying to set tag(s) to an Tag item index: ' . $item->getKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var $tagsItems ExtendedCacheItemInterface[]
|
||||||
|
*/
|
||||||
|
$tagsItems = $this->getItems($this->getTagKeys($item->getTags()));
|
||||||
|
|
||||||
|
foreach ($tagsItems as $tagsItem) {
|
||||||
|
$data = $tagsItem->get();
|
||||||
|
$expTimestamp = $item->getExpirationDate()->getTimestamp();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Using the key will
|
||||||
|
* avoid to use array_unique
|
||||||
|
* that has slow performances
|
||||||
|
*/
|
||||||
|
|
||||||
|
$tagsItem->set(array_merge((array) $data, [$item->getKey() => $expTimestamp]));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the expiration date
|
||||||
|
* of the $tagsItem based
|
||||||
|
* on the older $item
|
||||||
|
* expiration date
|
||||||
|
*/
|
||||||
|
if ($expTimestamp > $tagsItem->getExpirationDate()->getTimestamp()) {
|
||||||
|
$tagsItem->expiresAt($item->getExpirationDate());
|
||||||
|
}
|
||||||
|
$this->driverWrite($tagsItem);
|
||||||
|
$tagsItem->setHit(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Also update removed tags to
|
||||||
|
* keep the index up to date
|
||||||
|
*/
|
||||||
|
$tagsItems = $this->getItems($this->getTagKeys($item->getRemovedTags()));
|
||||||
|
|
||||||
|
foreach ($tagsItems as $tagsItem) {
|
||||||
|
$data = (array) $tagsItem->get();
|
||||||
|
|
||||||
|
unset($data[ $item->getKey() ]);
|
||||||
|
$tagsItem->set($data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recalculate the expiration date
|
||||||
|
*
|
||||||
|
* If the $tagsItem does not have
|
||||||
|
* any cache item references left
|
||||||
|
* then remove it from tagsItems index
|
||||||
|
*/
|
||||||
|
if (count($data)) {
|
||||||
|
$tagsItem->expiresAt(max($data));
|
||||||
|
$this->driverWrite($tagsItem);
|
||||||
|
$tagsItem->setHit(true);
|
||||||
|
} else {
|
||||||
|
$this->deleteItem($tagsItem->getKey());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $key
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getTagKey($key)
|
||||||
|
{
|
||||||
|
return self::DRIVER_TAGS_KEY_PREFIX . $key;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $key
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getTagKeys(array $keys)
|
||||||
|
{
|
||||||
|
foreach ($keys as &$key) {
|
||||||
|
$key = $this->getTagKey($key);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $keys;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $optionName
|
||||||
|
* @param mixed $optionValue
|
||||||
|
* @return bool
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public static function isValidOption($optionName, $optionValue)
|
||||||
|
{
|
||||||
|
if (!is_string($optionName)) {
|
||||||
|
throw new \InvalidArgumentException('$optionName must be a string');
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function getRequiredOptions()
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function getValidOptions()
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,170 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* This file is part of phpFastCache.
|
||||||
|
*
|
||||||
|
* @license MIT License (MIT)
|
||||||
|
*
|
||||||
|
* For full copyright and license information, please see the docs/CREDITS.txt file.
|
||||||
|
*
|
||||||
|
* @author Khoa Bui (khoaofgod) <khoaofgod@gmail.com> http://www.phpfastcache.com
|
||||||
|
* @author Georges.L (Geolim4) <contact@geolim4.com>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace phpFastCache\Cache;
|
||||||
|
|
||||||
|
use Psr\Cache\CacheItemInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface ExtendedCacheItemInterface
|
||||||
|
* @package phpFastCache\Cache
|
||||||
|
*/
|
||||||
|
interface ExtendedCacheItemInterface extends CacheItemInterface, \JsonSerializable
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Returns the encoded key for the current cache item.
|
||||||
|
* Usually as a MD5 hash
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* The encoded key string for this cache item.
|
||||||
|
*/
|
||||||
|
public function getEncodedKey();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function getUncommittedData();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return \DateTimeInterface
|
||||||
|
*/
|
||||||
|
public function getExpirationDate();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getTtl();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isExpired();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \phpFastCache\Cache\ExtendedCacheItemPoolInterface $driver
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function setDriver(ExtendedCacheItemPoolInterface $driver);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param bool $isHit
|
||||||
|
* @return $this
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function setHit($isHit);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $step
|
||||||
|
* @return $this
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function increment($step = 1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $step
|
||||||
|
* @return $this
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function decrement($step = 1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array|string $data
|
||||||
|
* @return $this
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function append($data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array|string $data
|
||||||
|
* @return $this
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function prepend($data);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the expiration time for this cache item.
|
||||||
|
*
|
||||||
|
* @param int|\DateInterval $time
|
||||||
|
* The period of time from the present after which the item MUST be considered
|
||||||
|
* expired. An integer parameter is understood to be the time in seconds until
|
||||||
|
* expiration. If null is passed explicitly, a default value MAY be used.
|
||||||
|
* If none is set, the value should be stored permanently or for as long as the
|
||||||
|
* implementation allows.
|
||||||
|
*
|
||||||
|
* @return static
|
||||||
|
* The called object.
|
||||||
|
*
|
||||||
|
* @deprecated Use CacheItemInterface::expiresAfter() instead
|
||||||
|
*/
|
||||||
|
public function touch($time);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $tagName
|
||||||
|
* @return $this
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function addTag($tagName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $tagNames
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function addTags(array $tagNames);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $tags
|
||||||
|
* @return $this
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function setTags(array $tags);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getTags();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $separator
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function getTagsAsString($separator = ', ');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $tagName
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function removeTag($tagName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $tagNames
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function removeTags(array $tagNames);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getRemovedTags();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the data as a well-formatted string.
|
||||||
|
* Any scalar value will be casted to an array
|
||||||
|
* @param int $option json_encode() options
|
||||||
|
* @param int $depth json_encode() depth
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getDataAsJsonString($option = 0, $depth = 512);
|
||||||
|
}
|
@ -0,0 +1,357 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* This file is part of phpFastCache.
|
||||||
|
*
|
||||||
|
* @license MIT License (MIT)
|
||||||
|
*
|
||||||
|
* For full copyright and license information, please see the docs/CREDITS.txt file.
|
||||||
|
*
|
||||||
|
* @author Khoa Bui (khoaofgod) <khoaofgod@gmail.com> http://www.phpfastcache.com
|
||||||
|
* @author Georges.L (Geolim4) <contact@geolim4.com>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace phpFastCache\Cache;
|
||||||
|
|
||||||
|
use InvalidArgumentException;
|
||||||
|
use phpFastCache\Entities\driverStatistic;
|
||||||
|
use Psr\Cache\CacheItemInterface;
|
||||||
|
use Psr\Cache\CacheItemPoolInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface ExtendedCacheItemPoolInterface
|
||||||
|
* @package phpFastCache\Cache
|
||||||
|
*/
|
||||||
|
interface ExtendedCacheItemPoolInterface extends CacheItemPoolInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getConfig();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getDriverName();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [phpFastCache phpDoc Override]
|
||||||
|
* Returns a Cache Item representing the specified key.
|
||||||
|
*
|
||||||
|
* This method must always return a CacheItemInterface object, even in case of
|
||||||
|
* a cache miss. It MUST NOT return null.
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* The key for which to return the corresponding Cache Item.
|
||||||
|
*
|
||||||
|
* @throws InvalidArgumentException
|
||||||
|
* If the $key string is not a legal value a \Psr\Cache\InvalidArgumentException
|
||||||
|
* MUST be thrown.
|
||||||
|
*
|
||||||
|
* @return ExtendedCacheItemInterface
|
||||||
|
* The corresponding Cache Item.
|
||||||
|
*/
|
||||||
|
public function getItem($key);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [phpFastCache phpDoc Override]
|
||||||
|
* Returns a traversable set of cache items.
|
||||||
|
*
|
||||||
|
* @param array $keys
|
||||||
|
* An indexed array of keys of items to retrieve.
|
||||||
|
*
|
||||||
|
* @throws InvalidArgumentException
|
||||||
|
* If any of the keys in $keys are not a legal value a \Psr\Cache\InvalidArgumentException
|
||||||
|
* MUST be thrown.
|
||||||
|
*
|
||||||
|
* @return ExtendedCacheItemInterface[]
|
||||||
|
* A traversable collection of Cache Items keyed by the cache keys of
|
||||||
|
* each item. A Cache item will be returned for each key, even if that
|
||||||
|
* key is not found. However, if no keys are specified then an empty
|
||||||
|
* traversable MUST be returned instead.
|
||||||
|
*/
|
||||||
|
public function getItems(array $keys = []);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns A json string that represents an array of items.
|
||||||
|
*
|
||||||
|
* @param array $keys
|
||||||
|
* An indexed array of keys of items to retrieve.
|
||||||
|
* @param int $option json_encode() options
|
||||||
|
* @param int $depth json_encode() depth
|
||||||
|
*
|
||||||
|
* @throws InvalidArgumentException
|
||||||
|
* If any of the keys in $keys are not a legal value a \Psr\Cache\InvalidArgumentException
|
||||||
|
* MUST be thrown.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getItemsAsJsonString(array $keys = [], $option = 0, $depth = 512);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \Psr\Cache\CacheItemInterface $item
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function setItem(CacheItemInterface $item);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes all items in the pool.
|
||||||
|
* @deprecated Use clear() instead
|
||||||
|
* Will be removed in 5.1
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* True if the pool was successfully cleared. False if there was an error.
|
||||||
|
*/
|
||||||
|
public function clean();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return driverStatistic
|
||||||
|
*/
|
||||||
|
public function getStats();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a traversable set of cache items by a tag name.
|
||||||
|
*
|
||||||
|
* @param string $tagName
|
||||||
|
* An indexed array of keys of items to retrieve.
|
||||||
|
*
|
||||||
|
* @throws InvalidArgumentException
|
||||||
|
* If any of the keys in $keys are not a legal value a \Psr\Cache\InvalidArgumentException
|
||||||
|
* MUST be thrown.
|
||||||
|
*
|
||||||
|
* @return ExtendedCacheItemInterface[]
|
||||||
|
* A traversable collection of Cache Items keyed by the cache keys of
|
||||||
|
* each item. A Cache item will be returned for each key, even if that
|
||||||
|
* key is not found. However, if no keys are specified then an empty
|
||||||
|
* traversable MUST be returned instead.
|
||||||
|
*/
|
||||||
|
public function getItemsByTag($tagName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a traversable set of cache items by a tag name.
|
||||||
|
*
|
||||||
|
* @param array $tagNames
|
||||||
|
* An indexed array of keys of items to retrieve.
|
||||||
|
*
|
||||||
|
* @throws InvalidArgumentException
|
||||||
|
* If any of the keys in $keys are not a legal value a \Psr\Cache\InvalidArgumentException
|
||||||
|
* MUST be thrown.
|
||||||
|
*
|
||||||
|
* @return ExtendedCacheItemInterface[]
|
||||||
|
* A traversable collection of Cache Items keyed by the cache keys of
|
||||||
|
* each item. A Cache item will be returned for each key, even if that
|
||||||
|
* key is not found. However, if no keys are specified then an empty
|
||||||
|
* traversable MUST be returned instead.
|
||||||
|
*/
|
||||||
|
public function getItemsByTags(array $tagNames);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns A json string that represents an array of items by tags-based.
|
||||||
|
*
|
||||||
|
* @param array $tagNames
|
||||||
|
* An indexed array of keys of items to retrieve.
|
||||||
|
* @param int $option json_encode() options
|
||||||
|
* @param int $depth json_encode() depth
|
||||||
|
*
|
||||||
|
* @throws InvalidArgumentException
|
||||||
|
* If any of the keys in $keys are not a legal value a \Psr\Cache\InvalidArgumentException
|
||||||
|
* MUST be thrown.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getItemsByTagsAsJsonString(array $tagNames, $option = 0, $depth = 512);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the item from the pool by tag.
|
||||||
|
*
|
||||||
|
* @param string $tagName
|
||||||
|
* The tag for which to delete
|
||||||
|
*
|
||||||
|
* @throws InvalidArgumentException
|
||||||
|
* If the $key string is not a legal value a \Psr\Cache\InvalidArgumentException
|
||||||
|
* MUST be thrown.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* True if the item was successfully removed. False if there was an error.
|
||||||
|
*/
|
||||||
|
public function deleteItemsByTag($tagName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the item from the pool by tag.
|
||||||
|
*
|
||||||
|
* @param array $tagNames
|
||||||
|
* The tag for which to delete
|
||||||
|
*
|
||||||
|
* @throws InvalidArgumentException
|
||||||
|
* If the $key string is not a legal value a \Psr\Cache\InvalidArgumentException
|
||||||
|
* MUST be thrown.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* True if the item was successfully removed. False if there was an error.
|
||||||
|
*/
|
||||||
|
public function deleteItemsByTags(array $tagNames);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increment the items from the pool by tag.
|
||||||
|
*
|
||||||
|
* @param string $tagName
|
||||||
|
* The tag for which to increment
|
||||||
|
* @param int $step
|
||||||
|
*
|
||||||
|
* @throws InvalidArgumentException
|
||||||
|
* If the $key string is not a legal value a \Psr\Cache\InvalidArgumentException
|
||||||
|
* MUST be thrown.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* True if the item was successfully incremented. False if there was an error.
|
||||||
|
*/
|
||||||
|
public function incrementItemsByTag($tagName, $step = 1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increment the items from the pool by tag.
|
||||||
|
*
|
||||||
|
* @param array $tagNames
|
||||||
|
* The tag for which to increment
|
||||||
|
* @param int $step
|
||||||
|
*
|
||||||
|
* @throws InvalidArgumentException
|
||||||
|
* If the $key string is not a legal value a \Psr\Cache\InvalidArgumentException
|
||||||
|
* MUST be thrown.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* True if the item was successfully incremented. False if there was an error.
|
||||||
|
*/
|
||||||
|
public function incrementItemsByTags(array $tagNames, $step = 1);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decrement the items from the pool by tag.
|
||||||
|
*
|
||||||
|
* @param string $tagName
|
||||||
|
* The tag for which to decrement
|
||||||
|
* @param int $step
|
||||||
|
*
|
||||||
|
* @throws InvalidArgumentException
|
||||||
|
* If the $key string is not a legal value a \Psr\Cache\InvalidArgumentException
|
||||||
|
* MUST be thrown.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* True if the item was successfully decremented. False if there was an error.
|
||||||
|
*/
|
||||||
|
public function decrementItemsByTag($tagName, $step = 1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decrement the items from the pool by tag.
|
||||||
|
*
|
||||||
|
* @param array $tagNames
|
||||||
|
* The tag for which to decrement
|
||||||
|
* @param int $step
|
||||||
|
*
|
||||||
|
* @throws InvalidArgumentException
|
||||||
|
* If the $key string is not a legal value a \Psr\Cache\InvalidArgumentException
|
||||||
|
* MUST be thrown.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* True if the item was successfully decremented. False if there was an error.
|
||||||
|
*/
|
||||||
|
public function decrementItemsByTags(array $tagNames, $step = 1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decrement the items from the pool by tag.
|
||||||
|
*
|
||||||
|
* @param string $tagName
|
||||||
|
* The tag for which to append
|
||||||
|
*
|
||||||
|
* @param array|string $data
|
||||||
|
*
|
||||||
|
* @throws InvalidArgumentException
|
||||||
|
* If the $key string is not a legal value a \Psr\Cache\InvalidArgumentException
|
||||||
|
* MUST be thrown.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* True if the item was successfully appended. False if there was an error.
|
||||||
|
*/
|
||||||
|
public function appendItemsByTag($tagName, $data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decrement the items from the pool by tag.
|
||||||
|
*
|
||||||
|
* @param array $tagNames
|
||||||
|
* The tag for which to append
|
||||||
|
*
|
||||||
|
* @param array|string $data
|
||||||
|
*
|
||||||
|
* @throws InvalidArgumentException
|
||||||
|
* If the $key string is not a legal value a \Psr\Cache\InvalidArgumentException
|
||||||
|
* MUST be thrown.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* True if the item was successfully appended. False if there was an error.
|
||||||
|
*/
|
||||||
|
public function appendItemsByTags(array $tagNames, $data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepend the items from the pool by tag.
|
||||||
|
*
|
||||||
|
* @param string $tagName
|
||||||
|
* The tag for which to prepend
|
||||||
|
*
|
||||||
|
* @param array|string $data
|
||||||
|
*
|
||||||
|
* @throws InvalidArgumentException
|
||||||
|
* If the $key string is not a legal value a \Psr\Cache\InvalidArgumentException
|
||||||
|
* MUST be thrown.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* True if the item was successfully prepended. False if there was an error.
|
||||||
|
*/
|
||||||
|
public function prependItemsByTag($tagName, $data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepend the items from the pool by tag.
|
||||||
|
*
|
||||||
|
* @param array $tagNames
|
||||||
|
* The tag for which to prepend
|
||||||
|
*
|
||||||
|
* @param array|string $data
|
||||||
|
*
|
||||||
|
* @throws InvalidArgumentException
|
||||||
|
* If the $key string is not a legal value a \Psr\Cache\InvalidArgumentException
|
||||||
|
* MUST be thrown.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* True if the item was successfully prepended. False if there was an error.
|
||||||
|
*/
|
||||||
|
public function prependItemsByTags(array $tagNames, $data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \Psr\Cache\CacheItemInterface $item
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function detachItem(CacheItemInterface $item);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function detachAllItems();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \Psr\Cache\CacheItemInterface $item
|
||||||
|
* @return void
|
||||||
|
* @throws \LogicException
|
||||||
|
*/
|
||||||
|
public function attachItem(CacheItemInterface $item);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the item exists, is attached and the Spl Hash matches
|
||||||
|
* Returns false if the item exists, is attached and the Spl Hash mismatches
|
||||||
|
* Returns null if the item does not exists
|
||||||
|
*
|
||||||
|
* @param \Psr\Cache\CacheItemInterface $item
|
||||||
|
* @return bool|null
|
||||||
|
* @throws \LogicException
|
||||||
|
*/
|
||||||
|
public function isAttached(CacheItemInterface $item);
|
||||||
|
}
|
@ -0,0 +1,447 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* This file is part of phpFastCache.
|
||||||
|
*
|
||||||
|
* @license MIT License (MIT)
|
||||||
|
*
|
||||||
|
* For full copyright and license information, please see the docs/CREDITS.txt file.
|
||||||
|
*
|
||||||
|
* @author Khoa Bui (khoaofgod) <khoaofgod@gmail.com> http://www.phpfastcache.com
|
||||||
|
* @author Georges.L (Geolim4) <contact@geolim4.com>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace phpFastCache\Cache;
|
||||||
|
|
||||||
|
use phpFastCache\Core\DriverAbstract;
|
||||||
|
|
||||||
|
trait ItemBaseTrait
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
protected $fetched = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var DriverAbstract
|
||||||
|
*/
|
||||||
|
protected $driver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $key;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var mixed
|
||||||
|
*/
|
||||||
|
protected $data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \DateTime
|
||||||
|
*/
|
||||||
|
protected $expirationDate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $tags = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $removedTags = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
protected $isHit = false;
|
||||||
|
|
||||||
|
/********************
|
||||||
|
*
|
||||||
|
* PSR-6 Methods
|
||||||
|
*
|
||||||
|
*******************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getKey()
|
||||||
|
{
|
||||||
|
return $this->key;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function get()
|
||||||
|
{
|
||||||
|
return $this->data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param mixed $value
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function set($value)
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The user set a value,
|
||||||
|
* therefore there is no need to
|
||||||
|
* fetch from source anymore
|
||||||
|
*/
|
||||||
|
$this->fetched = true;
|
||||||
|
$this->data = $value;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function isHit()
|
||||||
|
{
|
||||||
|
return $this->isHit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param bool $isHit
|
||||||
|
* @return $this
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function setHit($isHit)
|
||||||
|
{
|
||||||
|
if (is_bool($isHit)) {
|
||||||
|
$this->isHit = $isHit;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
} else {
|
||||||
|
throw new \InvalidArgumentException('$isHit must be a boolean');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \DateTimeInterface $expiration
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function expiresAt($expiration)
|
||||||
|
{
|
||||||
|
if ($expiration instanceof \DateTimeInterface) {
|
||||||
|
$this->expirationDate = $expiration;
|
||||||
|
} else {
|
||||||
|
throw new \InvalidArgumentException('$expiration must be an object implementing the DateTimeInterface');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the expiration time for this cache item.
|
||||||
|
*
|
||||||
|
* @param int|\DateInterval $time
|
||||||
|
* The period of time from the present after which the item MUST be considered
|
||||||
|
* expired. An integer parameter is understood to be the time in seconds until
|
||||||
|
* expiration. If null is passed explicitly, a default value MAY be used.
|
||||||
|
* If none is set, the value should be stored permanently or for as long as the
|
||||||
|
* implementation allows.
|
||||||
|
*
|
||||||
|
* @return static
|
||||||
|
* The called object.
|
||||||
|
*
|
||||||
|
* @deprecated Use CacheItemInterface::expiresAfter() instead
|
||||||
|
*/
|
||||||
|
public function touch($time)
|
||||||
|
{
|
||||||
|
trigger_error('touch() is deprecated and will be removed in the next major release, use CacheItemInterface::expiresAfter() instead');
|
||||||
|
|
||||||
|
return $this->expiresAfter($time);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \DateInterval|int $time
|
||||||
|
* @return $this
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function expiresAfter($time)
|
||||||
|
{
|
||||||
|
if (is_numeric($time)) {
|
||||||
|
if ($time <= 0) {
|
||||||
|
/**
|
||||||
|
* 5 years, however memcached or memory cached will gone when u restart it
|
||||||
|
* just recommended for sqlite. files
|
||||||
|
*/
|
||||||
|
$time = 30 * 24 * 3600 * 5;
|
||||||
|
}
|
||||||
|
$this->expirationDate = (new \DateTime())->add(new \DateInterval(sprintf('PT%dS', $time)));
|
||||||
|
} else if ($time instanceof \DateInterval) {
|
||||||
|
$this->expirationDate = (new \DateTime())->add($time);
|
||||||
|
} else {
|
||||||
|
throw new \InvalidArgumentException('Invalid date format');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************
|
||||||
|
*
|
||||||
|
* PSR-6 Extended Methods
|
||||||
|
*
|
||||||
|
*******************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getEncodedKey()
|
||||||
|
{
|
||||||
|
return md5($this->getKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function getUncommittedData()
|
||||||
|
{
|
||||||
|
return $this->data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return \DateTimeInterface
|
||||||
|
*/
|
||||||
|
public function getExpirationDate()
|
||||||
|
{
|
||||||
|
return $this->expirationDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getTtl()
|
||||||
|
{
|
||||||
|
$ttl = $this->expirationDate->getTimestamp() - time();
|
||||||
|
if ($ttl > 2592000) {
|
||||||
|
$ttl = time() + $ttl;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $ttl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isExpired()
|
||||||
|
{
|
||||||
|
return $this->expirationDate->getTimestamp() < (new \DateTime())->getTimestamp();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $step
|
||||||
|
* @return $this
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function increment($step = 1)
|
||||||
|
{
|
||||||
|
if (is_int($step)) {
|
||||||
|
$this->fetched = true;
|
||||||
|
$this->data += $step;
|
||||||
|
} else {
|
||||||
|
throw new \InvalidArgumentException('$step must be numeric.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $step
|
||||||
|
* @return $this
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function decrement($step = 1)
|
||||||
|
{
|
||||||
|
if (is_int($step)) {
|
||||||
|
$this->fetched = true;
|
||||||
|
$this->data -= $step;
|
||||||
|
} else {
|
||||||
|
throw new \InvalidArgumentException('$step must be numeric.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array|string $data
|
||||||
|
* @return $this
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function append($data)
|
||||||
|
{
|
||||||
|
if (is_array($this->data)) {
|
||||||
|
array_push($this->data, $data);
|
||||||
|
} else if (is_string($data)) {
|
||||||
|
$this->data .= (string) $data;
|
||||||
|
} else {
|
||||||
|
throw new \InvalidArgumentException('$data must be either array nor string.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array|string $data
|
||||||
|
* @return $this
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function prepend($data)
|
||||||
|
{
|
||||||
|
if (is_array($this->data)) {
|
||||||
|
array_unshift($this->data, $data);
|
||||||
|
} else if (is_string($data)) {
|
||||||
|
$this->data = (string) $data . $this->data;
|
||||||
|
} else {
|
||||||
|
throw new \InvalidArgumentException('$data must be either array nor string.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $tagName
|
||||||
|
* @return $this
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function addTag($tagName)
|
||||||
|
{
|
||||||
|
if (is_string($tagName)) {
|
||||||
|
$this->tags = array_unique(array_merge($this->tags, [$tagName]));
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
} else {
|
||||||
|
throw new \InvalidArgumentException('$tagName must be a string');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $tagNames
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function addTags(array $tagNames)
|
||||||
|
{
|
||||||
|
foreach ($tagNames as $tagName) {
|
||||||
|
$this->addTag($tagName);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $tags
|
||||||
|
* @return $this
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function setTags(array $tags)
|
||||||
|
{
|
||||||
|
if (count($tags)) {
|
||||||
|
if (array_filter($tags, 'is_string')) {
|
||||||
|
$this->tags = $tags;
|
||||||
|
} else {
|
||||||
|
throw new \InvalidArgumentException('$tagName must be an array of string');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getTags()
|
||||||
|
{
|
||||||
|
return $this->tags;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getTagsAsString($separator = ', ')
|
||||||
|
{
|
||||||
|
return implode($separator, $this->tags);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $tagName
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function removeTag($tagName)
|
||||||
|
{
|
||||||
|
if (($key = array_search($tagName, $this->tags)) !== false) {
|
||||||
|
unset($this->tags[ $key ]);
|
||||||
|
$this->removedTags[] = $tagName;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $tagNames
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function removeTags(array $tagNames)
|
||||||
|
{
|
||||||
|
foreach ($tagNames as $tagName) {
|
||||||
|
$this->removeTag($tagName);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getRemovedTags()
|
||||||
|
{
|
||||||
|
return array_diff($this->removedTags, $this->tags);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the data as a well-formatted string.
|
||||||
|
* Any scalar value will be casted to an array
|
||||||
|
* @param int $option json_encode() options
|
||||||
|
* @param int $depth json_encode() depth
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getDataAsJsonString($option = 0, $depth = 512)
|
||||||
|
{
|
||||||
|
$data = $this->get();
|
||||||
|
|
||||||
|
if (is_object($data) || is_array($data)) {
|
||||||
|
$data = json_encode($data, $option, $depth);
|
||||||
|
} else {
|
||||||
|
$data = json_encode([$data], $option, $depth);
|
||||||
|
}
|
||||||
|
|
||||||
|
return json_encode($data, $option, $depth);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements \JsonSerializable interface
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function jsonSerialize()
|
||||||
|
{
|
||||||
|
return $this->get();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prevent recursions for Debug (php 5.6+)
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
final public function __debugInfo()
|
||||||
|
{
|
||||||
|
$info = get_object_vars($this);
|
||||||
|
$info[ 'driver' ] = 'object(' . get_class($info[ 'driver' ]) . ')';
|
||||||
|
|
||||||
|
return (array) $info;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,270 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* This file is part of phpFastCache.
|
||||||
|
*
|
||||||
|
* @license MIT License (MIT)
|
||||||
|
*
|
||||||
|
* For full copyright and license information, please see the docs/CREDITS.txt file.
|
||||||
|
*
|
||||||
|
* @author Khoa Bui (khoaofgod) <khoaofgod@gmail.com> http://www.phpfastcache.com
|
||||||
|
* @author Georges.L (Geolim4) <contact@geolim4.com>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace phpFastCache;
|
||||||
|
|
||||||
|
use phpFastCache\Cache\ExtendedCacheItemPoolInterface;
|
||||||
|
use phpFastCache\Core\DriverAbstract;
|
||||||
|
use phpFastCache\Exceptions\phpFastCacheDriverCheckException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class CacheManager
|
||||||
|
* @package phpFastCache
|
||||||
|
*
|
||||||
|
* @method static ExtendedCacheItemPoolInterface Apc() Apc($config = []) Return a driver "apc" instance
|
||||||
|
* @method static ExtendedCacheItemPoolInterface Apcu() Apcu($config = []) Return a driver "apcu" instance
|
||||||
|
* @method static ExtendedCacheItemPoolInterface Cookie() Cookie($config = []) Return a driver "cookie" instance
|
||||||
|
* @method static ExtendedCacheItemPoolInterface Couchbase() Couchbase($config = []) Return a driver "couchbase" instance
|
||||||
|
* @method static ExtendedCacheItemPoolInterface Files() Files($config = []) Return a driver "files" instance
|
||||||
|
* @method static ExtendedCacheItemPoolInterface Leveldb() Leveldb($config = []) Return a driver "leveldb" instance
|
||||||
|
* @method static ExtendedCacheItemPoolInterface Memcache() Memcache($config = []) Return a driver "memcache" instance
|
||||||
|
* @method static ExtendedCacheItemPoolInterface Memcached() Memcached($config = []) Return a driver "memcached" instance
|
||||||
|
* @method static ExtendedCacheItemPoolInterface Mongodb() Mongodb($config = []) Return a driver "mongodb" instance
|
||||||
|
* @method static ExtendedCacheItemPoolInterface Predis() Predis($config = []) Return a driver "predis" instance
|
||||||
|
* @method static ExtendedCacheItemPoolInterface Redis() Redis($config = []) Return a driver "redis" instance
|
||||||
|
* @method static ExtendedCacheItemPoolInterface Sqlite() Sqlite($config = []) Return a driver "sqlite" instance
|
||||||
|
* @method static ExtendedCacheItemPoolInterface Ssdb() Ssdb($config = []) Return a driver "ssdb" instance
|
||||||
|
* @method static ExtendedCacheItemPoolInterface Wincache() Wincache($config = []) Return a driver "wincache" instance
|
||||||
|
* @method static ExtendedCacheItemPoolInterface Xcache() Xcache($config = []) Return a driver "xcache" instance
|
||||||
|
* @method static ExtendedCacheItemPoolInterface Zenddisk() Zenddisk($config = []) Return a driver "zend disk cache" instance
|
||||||
|
* @method static ExtendedCacheItemPoolInterface Zendshm() Zendshm($config = []) Return a driver "zend memory cache" instance
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class CacheManager
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
public static $ReadHits = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
public static $WriteHits = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected static $config = [
|
||||||
|
'securityKey' => 'auto', // The securityKey that will be used to create the sub-directory
|
||||||
|
'ignoreSymfonyNotice' => false, // Ignore Symfony notices for Symfony projects that do not makes use of PhpFastCache's Symfony Bundle
|
||||||
|
'defaultTtl' => 900, // Default time-to-live in seconds
|
||||||
|
'htaccess' => true, // Auto-generate .htaccess if it is missing
|
||||||
|
'default_chmod' => 0777, // 0777 is recommended
|
||||||
|
'path' => '', // If not set will be the value of sys_get_temp_dir()
|
||||||
|
'fallback' => false, // Fall back when old driver is not supported
|
||||||
|
'limited_memory_each_object' => 4096, // Maximum size (bytes) of object store in memory
|
||||||
|
'compress_data' => false, // Compress stored data if the backend supports it
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected static $namespacePath;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected static $instances = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $driver
|
||||||
|
* @param array $config
|
||||||
|
* @return ExtendedCacheItemPoolInterface
|
||||||
|
*/
|
||||||
|
public static function getInstance($driver = 'auto', $config = [])
|
||||||
|
{
|
||||||
|
static $badPracticeOmeter = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @todo: Standardize a method for driver name
|
||||||
|
*/
|
||||||
|
$driver = self::standardizeDriverName($driver);
|
||||||
|
$config = array_merge(self::$config, $config);
|
||||||
|
if (!$driver || $driver === 'Auto') {
|
||||||
|
$driver = self::getAutoClass($config);
|
||||||
|
}
|
||||||
|
|
||||||
|
$instance = crc32($driver . serialize($config));
|
||||||
|
if (!isset(self::$instances[ $instance ])) {
|
||||||
|
$badPracticeOmeter[$driver] = 1;
|
||||||
|
if(!$config['ignoreSymfonyNotice'] && interface_exists('Symfony\Component\HttpKernel\KernelInterface') && !class_exists('phpFastCache\Bundle\phpFastCacheBundle')){
|
||||||
|
trigger_error('A Symfony Bundle to make the PhpFastCache integration more easier is now available here: https://github.com/PHPSocialNetwork/phpfastcache-bundle', E_USER_NOTICE);
|
||||||
|
}
|
||||||
|
$class = self::getNamespacePath() . $driver . '\Driver';
|
||||||
|
try{
|
||||||
|
self::$instances[ $instance ] = new $class($config);
|
||||||
|
}catch(phpFastCacheDriverCheckException $e){
|
||||||
|
$fallback = self::standardizeDriverName($config['fallback']);
|
||||||
|
if($fallback && $fallback !== $driver){
|
||||||
|
$class = self::getNamespacePath() . $fallback . '\Driver';
|
||||||
|
self::$instances[ $instance ] = new $class($config);
|
||||||
|
trigger_error(sprintf('The "%s" driver is unavailable at the moment, the fallback driver "%s" has been used instead.', $driver, $fallback), E_USER_WARNING);
|
||||||
|
}else{
|
||||||
|
throw new phpFastCacheDriverCheckException($e->getMessage(), $e->getCode(), $e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if(++$badPracticeOmeter[$driver] >= 5){
|
||||||
|
trigger_error('[' . $driver . '] Calling many times CacheManager::getInstance() for already instanced drivers is a bad practice and have a significant impact on performances.
|
||||||
|
See https://github.com/PHPSocialNetwork/phpfastcache/wiki/[V5]-Why-calling-getInstance%28%29-each-time-is-a-bad-practice-%3F');
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::$instances[ $instance ];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $config
|
||||||
|
* @return string
|
||||||
|
* @throws phpFastCacheDriverCheckException
|
||||||
|
*/
|
||||||
|
public static function getAutoClass($config = [])
|
||||||
|
{
|
||||||
|
static $autoDriver;
|
||||||
|
|
||||||
|
if ($autoDriver === null) {
|
||||||
|
foreach (self::getStaticSystemDrivers() as $driver) {
|
||||||
|
try {
|
||||||
|
self::getInstance($driver, $config);
|
||||||
|
$autoDriver = $driver;
|
||||||
|
} catch (phpFastCacheDriverCheckException $e) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $autoDriver;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $name
|
||||||
|
* @param array $arguments
|
||||||
|
* @return \Psr\Cache\CacheItemPoolInterface
|
||||||
|
*/
|
||||||
|
public static function __callStatic($name, $arguments)
|
||||||
|
{
|
||||||
|
$options = (array_key_exists(0, $arguments) && is_array($arguments) ? $arguments[ 0 ] : []);
|
||||||
|
|
||||||
|
return self::getInstance($name, $options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public static function clearInstances()
|
||||||
|
{
|
||||||
|
self::$instances = [];
|
||||||
|
|
||||||
|
gc_collect_cycles();
|
||||||
|
return !count(self::$instances);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function getNamespacePath()
|
||||||
|
{
|
||||||
|
return self::$namespacePath ?: __NAMESPACE__ . '\Drivers\\';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $path
|
||||||
|
*/
|
||||||
|
public static function setNamespacePath($path)
|
||||||
|
{
|
||||||
|
self::$namespacePath = $path;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $name
|
||||||
|
* @param string $value
|
||||||
|
* @deprecated Method "setup" is deprecated and will be removed in V6. Use method "setDefaultConfig" instead.
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public static function setup($name, $value = '')
|
||||||
|
{
|
||||||
|
trigger_error('Method "setup" is deprecated and will be removed in V6 Use method "setDefaultConfig" instead.', E_USER_DEPRECATED);
|
||||||
|
self::setDefaultConfig($name, $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $name string|array
|
||||||
|
* @param mixed $value
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public static function setDefaultConfig($name, $value = null)
|
||||||
|
{
|
||||||
|
if (is_array($name)) {
|
||||||
|
self::$config = array_merge(self::$config, $name);
|
||||||
|
} else if (is_string($name)){
|
||||||
|
self::$config[ $name ] = $value;
|
||||||
|
}else{
|
||||||
|
throw new \InvalidArgumentException('Invalid variable type: $name');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function getDefaultConfig()
|
||||||
|
{
|
||||||
|
return self::$config;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function getStaticSystemDrivers()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'Sqlite',
|
||||||
|
'Files',
|
||||||
|
'Apc',
|
||||||
|
'Apcu',
|
||||||
|
'Memcache',
|
||||||
|
'Memcached',
|
||||||
|
'Couchbase',
|
||||||
|
'Mongodb',
|
||||||
|
'Predis',
|
||||||
|
'Redis',
|
||||||
|
'Ssdb',
|
||||||
|
'Leveldb',
|
||||||
|
'Wincache',
|
||||||
|
'Xcache',
|
||||||
|
'Zenddisk',
|
||||||
|
'Zendshm',
|
||||||
|
'Devnull',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function getStaticAllDrivers()
|
||||||
|
{
|
||||||
|
return array_merge(self::getStaticSystemDrivers(), [
|
||||||
|
'Devtrue',
|
||||||
|
'Devfalse',
|
||||||
|
'Cookie',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $driverName
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function standardizeDriverName($driverName)
|
||||||
|
{
|
||||||
|
return ucfirst(strtolower(trim($driverName)));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* This file is part of phpFastCache.
|
||||||
|
*
|
||||||
|
* @license MIT License (MIT)
|
||||||
|
*
|
||||||
|
* For full copyright and license information, please see the docs/CREDITS.txt file.
|
||||||
|
*
|
||||||
|
* @author Khoa Bui (khoaofgod) <khoaofgod@gmail.com> http://www.phpfastcache.com
|
||||||
|
* @author Georges.L (Geolim4) <contact@geolim4.com>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace phpFastCache\Core;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Trait ClassNamespaceResolverTrait
|
||||||
|
* @package phpFastCache\Core
|
||||||
|
*/
|
||||||
|
trait ClassNamespaceResolverTrait
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function getClassNamespace()
|
||||||
|
{
|
||||||
|
static $namespace;
|
||||||
|
|
||||||
|
if (!$namespace) {
|
||||||
|
$namespace = (new \ReflectionObject($this))->getNamespaceName();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $namespace;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,67 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* This file is part of phpFastCache.
|
||||||
|
*
|
||||||
|
* @license MIT License (MIT)
|
||||||
|
*
|
||||||
|
* For full copyright and license information, please see the docs/CREDITS.txt file.
|
||||||
|
*
|
||||||
|
* @author Khoa Bui (khoaofgod) <khoaofgod@gmail.com> http://www.phpfastcache.com
|
||||||
|
* @author Georges.L (Geolim4) <contact@geolim4.com>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace phpFastCache\Core;
|
||||||
|
|
||||||
|
use phpFastCache\Cache\DriverBaseTrait;
|
||||||
|
use phpFastCache\Cache\ExtendedCacheItemPoolInterface;
|
||||||
|
use Psr\Cache\CacheItemInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class DriverAbstract
|
||||||
|
* @package phpFastCache\Core
|
||||||
|
*/
|
||||||
|
abstract class DriverAbstract implements ExtendedCacheItemPoolInterface
|
||||||
|
{
|
||||||
|
use DriverBaseTrait;
|
||||||
|
|
||||||
|
const DRIVER_CHECK_FAILURE = '%s is not installed or is misconfigured, cannot continue.';
|
||||||
|
const DRIVER_TAGS_KEY_PREFIX = '_TAG_';
|
||||||
|
const DRIVER_DATA_WRAPPER_INDEX = 'd';
|
||||||
|
const DRIVER_TIME_WRAPPER_INDEX = 't';
|
||||||
|
const DRIVER_TAGS_WRAPPER_INDEX = 'g';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \Psr\Cache\CacheItemInterface $item
|
||||||
|
* @return array [
|
||||||
|
* 'd' => 'THE ITEM DATA'
|
||||||
|
* 't' => 'THE ITEM DATE EXPIRATION'
|
||||||
|
* 'g' => 'THE ITEM TAGS'
|
||||||
|
* ]
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
abstract protected function driverRead(CacheItemInterface $item);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \Psr\Cache\CacheItemInterface $item
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
abstract protected function driverWrite(CacheItemInterface $item);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
abstract protected function driverClear();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
abstract protected function driverConnect();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \Psr\Cache\CacheItemInterface $item
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
abstract protected function driverDelete(CacheItemInterface $item);
|
||||||
|
}
|
@ -0,0 +1,370 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* This file is part of phpFastCache.
|
||||||
|
*
|
||||||
|
* @license MIT License (MIT)
|
||||||
|
*
|
||||||
|
* For full copyright and license information, please see the docs/CREDITS.txt file.
|
||||||
|
*
|
||||||
|
* @author Khoa Bui (khoaofgod) <khoaofgod@gmail.com> http://www.phpfastcache.com
|
||||||
|
* @author Georges.L (Geolim4) <contact@geolim4.com>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace phpFastCache\Core;
|
||||||
|
|
||||||
|
use InvalidArgumentException;
|
||||||
|
use phpFastCache\Cache\ExtendedCacheItemInterface;
|
||||||
|
use Psr\Cache\CacheItemInterface;
|
||||||
|
|
||||||
|
trait ExtendedCacheItemPoolTrait
|
||||||
|
{
|
||||||
|
use StandardPsr6StructureTrait;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes all items in the pool.
|
||||||
|
* @deprecated Use clear() instead
|
||||||
|
* Will be removed in 5.1
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* True if the pool was successfully cleared. False if there was an error.
|
||||||
|
*/
|
||||||
|
public function clean()
|
||||||
|
{
|
||||||
|
trigger_error('Cache clean() method is deprecated, use clear() method instead', E_USER_DEPRECATED);
|
||||||
|
return $this->clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $keys
|
||||||
|
* An indexed array of keys of items to retrieve.
|
||||||
|
* @param int $option json_encode() options
|
||||||
|
* @param int $depth json_encode() depth
|
||||||
|
* @return string
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function getItemsAsJsonString(array $keys = [], $option = 0, $depth = 512)
|
||||||
|
{
|
||||||
|
$callback = function(CacheItemInterface $item){
|
||||||
|
return $item->get();
|
||||||
|
};
|
||||||
|
return json_encode(array_map($callback, array_values($this->getItems($keys))), $option, $depth);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $tagName
|
||||||
|
* @return \phpFastCache\Cache\ExtendedCacheItemInterface[]
|
||||||
|
* @throws InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function getItemsByTag($tagName)
|
||||||
|
{
|
||||||
|
if (is_string($tagName)) {
|
||||||
|
$driverResponse = $this->getItem($this->getTagKey($tagName));
|
||||||
|
if ($driverResponse->isHit()) {
|
||||||
|
$items = (array) $driverResponse->get();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getItems() may provides expired item(s)
|
||||||
|
* themselves provided by a cache of item
|
||||||
|
* keys based stored the tag item.
|
||||||
|
* Therefore we pass a filter callback
|
||||||
|
* to remove the expired Item(s) provided by
|
||||||
|
* the item keys passed through getItems()
|
||||||
|
*
|
||||||
|
* #headache
|
||||||
|
*/
|
||||||
|
return array_filter($this->getItems(array_unique(array_keys($items))), function(ExtendedCacheItemInterface $item){
|
||||||
|
return $item->isHit();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new InvalidArgumentException('$tagName must be a string');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $tagNames
|
||||||
|
* @return \phpFastCache\Cache\ExtendedCacheItemInterface[]
|
||||||
|
* @throws InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function getItemsByTags(array $tagNames)
|
||||||
|
{
|
||||||
|
$items = [];
|
||||||
|
foreach (array_unique($tagNames) as $tagName) {
|
||||||
|
$items = array_merge($items, $this->getItemsByTag($tagName));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $items;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns A json string that represents an array of items by tags-based.
|
||||||
|
*
|
||||||
|
* @param array $tagNames
|
||||||
|
* An indexed array of keys of items to retrieve.
|
||||||
|
* @param int $option json_encode() options
|
||||||
|
* @param int $depth json_encode() depth
|
||||||
|
*
|
||||||
|
* @throws InvalidArgumentException
|
||||||
|
* If any of the keys in $keys are not a legal value a \Psr\Cache\InvalidArgumentException
|
||||||
|
* MUST be thrown.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getItemsByTagsAsJsonString(array $tagNames, $option = 0, $depth = 512)
|
||||||
|
{
|
||||||
|
$callback = function(CacheItemInterface $item){
|
||||||
|
return $item->get();
|
||||||
|
};
|
||||||
|
|
||||||
|
return json_encode(array_map($callback, array_values($this->getItemsByTags($tagNames))), $option, $depth);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $tagName
|
||||||
|
* @return bool|null
|
||||||
|
* @throws InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function deleteItemsByTag($tagName)
|
||||||
|
{
|
||||||
|
if (is_string($tagName)) {
|
||||||
|
$return = null;
|
||||||
|
foreach ($this->getItemsByTag($tagName) as $item) {
|
||||||
|
$result = $this->deleteItem($item->getKey());
|
||||||
|
if ($return !== false) {
|
||||||
|
$return = $result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $return;
|
||||||
|
} else {
|
||||||
|
throw new InvalidArgumentException('$tagName must be a string');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $tagNames
|
||||||
|
* @return bool|null
|
||||||
|
* @throws InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function deleteItemsByTags(array $tagNames)
|
||||||
|
{
|
||||||
|
$return = null;
|
||||||
|
foreach ($tagNames as $tagName) {
|
||||||
|
$result = $this->deleteItemsByTag($tagName);
|
||||||
|
if ($return !== false) {
|
||||||
|
$return = $result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function incrementItemsByTag($tagName, $step = 1)
|
||||||
|
{
|
||||||
|
if (is_string($tagName) && is_int($step)) {
|
||||||
|
foreach ($this->getItemsByTag($tagName) as $item) {
|
||||||
|
$item->increment($step);
|
||||||
|
$this->saveDeferred($item);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->commit();
|
||||||
|
} else {
|
||||||
|
throw new InvalidArgumentException('$tagName must be a string and $step an integer');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function incrementItemsByTags(array $tagNames, $step = 1)
|
||||||
|
{
|
||||||
|
$return = null;
|
||||||
|
foreach ($tagNames as $tagName) {
|
||||||
|
$result = $this->incrementItemsByTag($tagName, $step);
|
||||||
|
if ($return !== false) {
|
||||||
|
$return = $result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function decrementItemsByTag($tagName, $step = 1)
|
||||||
|
{
|
||||||
|
if (is_string($tagName) && is_int($step)) {
|
||||||
|
foreach ($this->getItemsByTag($tagName) as $item) {
|
||||||
|
$item->decrement($step);
|
||||||
|
$this->saveDeferred($item);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->commit();
|
||||||
|
} else {
|
||||||
|
throw new InvalidArgumentException('$tagName must be a string and $step an integer');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function decrementItemsByTags(array $tagNames, $step = 1)
|
||||||
|
{
|
||||||
|
$return = null;
|
||||||
|
foreach ($tagNames as $tagName) {
|
||||||
|
$result = $this->decrementItemsByTag($tagName, $step);
|
||||||
|
if ($return !== false) {
|
||||||
|
$return = $result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function appendItemsByTag($tagName, $data)
|
||||||
|
{
|
||||||
|
if (is_string($tagName)) {
|
||||||
|
foreach ($this->getItemsByTag($tagName) as $item) {
|
||||||
|
$item->append($data);
|
||||||
|
$this->saveDeferred($item);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->commit();
|
||||||
|
} else {
|
||||||
|
throw new InvalidArgumentException('$tagName must be a string');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function appendItemsByTags(array $tagNames, $data)
|
||||||
|
{
|
||||||
|
$return = null;
|
||||||
|
foreach ($tagNames as $tagName) {
|
||||||
|
$result = $this->appendItemsByTag($tagName, $data);
|
||||||
|
if ($return !== false) {
|
||||||
|
$return = $result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function prependItemsByTag($tagName, $data)
|
||||||
|
{
|
||||||
|
if (is_string($tagName)) {
|
||||||
|
foreach ($this->getItemsByTag($tagName) as $item) {
|
||||||
|
$item->prepend($data);
|
||||||
|
$this->saveDeferred($item);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->commit();
|
||||||
|
} else {
|
||||||
|
throw new InvalidArgumentException('$tagName must be a string');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function prependItemsByTags(array $tagNames, $data)
|
||||||
|
{
|
||||||
|
$return = null;
|
||||||
|
foreach ($tagNames as $tagName) {
|
||||||
|
$result = $this->prependItemsByTag($tagName, $data);
|
||||||
|
if ($return !== false) {
|
||||||
|
$return = $result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \Psr\Cache\CacheItemInterface $item
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function detachItem(CacheItemInterface $item)
|
||||||
|
{
|
||||||
|
if(isset($this->itemInstances[$item->getKey()])){
|
||||||
|
$this->deregisterItem($item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function detachAllItems()
|
||||||
|
{
|
||||||
|
foreach ($this->itemInstances as $item) {
|
||||||
|
$this->detachItem($item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \Psr\Cache\CacheItemInterface $item
|
||||||
|
* @return void
|
||||||
|
* @throws \LogicException
|
||||||
|
*/
|
||||||
|
public function attachItem(CacheItemInterface $item)
|
||||||
|
{
|
||||||
|
if(isset($this->itemInstances[$item->getKey()]) && spl_object_hash($item) !== spl_object_hash($this->itemInstances[ $item->getKey() ])){
|
||||||
|
throw new \LogicException('The item already exists and cannot be overwritten because the Spl object hash mismatches ! You probably tried to re-attach a detached item which has been already retrieved from cache.');
|
||||||
|
}else{
|
||||||
|
$this->itemInstances[$item->getKey()] = $item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal This method de-register an item from $this->itemInstances
|
||||||
|
* @param CacheItemInterface|string $item
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
protected function deregisterItem($item)
|
||||||
|
{
|
||||||
|
if($item instanceof CacheItemInterface){
|
||||||
|
unset($this->itemInstances[ $item->getKey() ]);
|
||||||
|
|
||||||
|
}else if(is_string($item)){
|
||||||
|
unset($this->itemInstances[ $item ]);
|
||||||
|
}else{
|
||||||
|
throw new \InvalidArgumentException('Invalid type for $item variable');
|
||||||
|
}
|
||||||
|
if(gc_enabled()){
|
||||||
|
gc_collect_cycles();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the item exists, is attached and the Spl Hash matches
|
||||||
|
* Returns false if the item exists, is attached and the Spl Hash mismatches
|
||||||
|
* Returns null if the item does not exists
|
||||||
|
*
|
||||||
|
* @param \Psr\Cache\CacheItemInterface $item
|
||||||
|
* @return bool|null
|
||||||
|
* @throws \LogicException
|
||||||
|
*/
|
||||||
|
public function isAttached(CacheItemInterface $item)
|
||||||
|
{
|
||||||
|
if(isset($this->itemInstances[$item->getKey()])){
|
||||||
|
return spl_object_hash($item) === spl_object_hash($this->itemInstances[ $item->getKey() ]);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
<?php
|
||||||
|
namespace phpFastCache\Core;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Trait MemcacheDriverCollisionDetectorTrait
|
||||||
|
* @package phpFastCache\Core
|
||||||
|
*/
|
||||||
|
trait MemcacheDriverCollisionDetectorTrait
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected static $driverUsed;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $driverName
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public static function checkCollision($driverName)
|
||||||
|
{
|
||||||
|
$CONSTANT_NAME = __NAMESPACE__ . '\MEMCACHE_DRIVER_USED';
|
||||||
|
|
||||||
|
if ($driverName && is_string($driverName)) {
|
||||||
|
if (!defined($CONSTANT_NAME)) {
|
||||||
|
define($CONSTANT_NAME, $driverName);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} else if (constant($CONSTANT_NAME) !== $driverName) {
|
||||||
|
trigger_error('Memcache collision detected, you used both Memcache and Memcached driver in your script, this may leads to unexpected behaviours',
|
||||||
|
E_USER_WARNING);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,242 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* This file is part of phpFastCache.
|
||||||
|
*
|
||||||
|
* @license MIT License (MIT)
|
||||||
|
*
|
||||||
|
* For full copyright and license information, please see the docs/CREDITS.txt file.
|
||||||
|
*
|
||||||
|
* @author Khoa Bui (khoaofgod) <khoaofgod@gmail.com> http://www.phpfastcache.com
|
||||||
|
* @author Georges.L (Geolim4) <contact@geolim4.com>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace phpFastCache\Core;
|
||||||
|
|
||||||
|
use phpFastCache\Exceptions\phpFastCacheCoreException;
|
||||||
|
use phpFastCache\Exceptions\phpFastCacheDriverException;
|
||||||
|
use phpFastCache\Util\Directory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Trait PathSeekerTrait
|
||||||
|
* @package phpFastCache\Core\Pool\IO
|
||||||
|
* @property array $config The configuration array passed via DriverBaseTrait
|
||||||
|
*/
|
||||||
|
trait PathSeekerTrait
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
public $tmp = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param bool $readonly
|
||||||
|
* @return string
|
||||||
|
* @throws phpFastCacheDriverException
|
||||||
|
*/
|
||||||
|
public function getPath($readonly = false)
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Get the base system temporary directory
|
||||||
|
*/
|
||||||
|
$tmp_dir = rtrim(ini_get('upload_tmp_dir') ?: sys_get_temp_dir(), '\\/') . DIRECTORY_SEPARATOR . 'phpfastcache';
|
||||||
|
/**
|
||||||
|
* Calculate the security key
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
$securityKey = array_key_exists('securityKey', $this->config) ? $this->config[ 'securityKey' ] : '';
|
||||||
|
if (!$securityKey || $securityKey === 'auto') {
|
||||||
|
if (isset($_SERVER[ 'HTTP_HOST' ])) {
|
||||||
|
$securityKey = preg_replace('/^www./', '', strtolower(str_replace(':', '_', $_SERVER[ 'HTTP_HOST' ])));
|
||||||
|
} else {
|
||||||
|
$securityKey = ($this->isPHPModule() ? 'web' : 'cli');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($securityKey !== '') {
|
||||||
|
$securityKey .= '/';
|
||||||
|
}
|
||||||
|
$securityKey = static::cleanFileName($securityKey);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Extends the temporary directory
|
||||||
|
* with the security key and the driver name
|
||||||
|
*/
|
||||||
|
$tmp_dir = rtrim($tmp_dir, '/') . DIRECTORY_SEPARATOR;
|
||||||
|
if (empty($this->config[ 'path' ]) || !is_string($this->config[ 'path' ])) {
|
||||||
|
$path = $tmp_dir;
|
||||||
|
} else {
|
||||||
|
$path = rtrim($this->config[ 'path' ], '/') . DIRECTORY_SEPARATOR;
|
||||||
|
}
|
||||||
|
$path_suffix = $securityKey . DIRECTORY_SEPARATOR . $this->getDriverName();
|
||||||
|
$full_path = Directory::getAbsolutePath($path . $path_suffix);
|
||||||
|
$full_path_tmp = Directory::getAbsolutePath($tmp_dir . $path_suffix);
|
||||||
|
$full_path_hash = md5($full_path);
|
||||||
|
/**
|
||||||
|
* In readonly mode we only attempt
|
||||||
|
* to verify if the directory exists
|
||||||
|
* or not, if it does not then we
|
||||||
|
* return the temp dir
|
||||||
|
*/
|
||||||
|
if ($readonly === true) {
|
||||||
|
if(!@file_exists($full_path) || !@is_writable($full_path)){
|
||||||
|
return $full_path_tmp;
|
||||||
|
}
|
||||||
|
return $full_path;
|
||||||
|
}else{
|
||||||
|
if (!isset($this->tmp[ $full_path_hash ]) || (!@file_exists($full_path) || !@is_writable($full_path))) {
|
||||||
|
if (!@file_exists($full_path)) {
|
||||||
|
@mkdir($full_path, $this->setChmodAuto(), true);
|
||||||
|
}elseif (!@is_writable($full_path)) {
|
||||||
|
if (!@chmod($full_path, $this->setChmodAuto()))
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Switch back to tmp dir
|
||||||
|
* again if the path is not writable
|
||||||
|
*/
|
||||||
|
$full_path = $full_path_tmp;
|
||||||
|
if (!@file_exists($full_path)) {
|
||||||
|
@mkdir($full_path, $this->setChmodAuto(), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In case there is no directory
|
||||||
|
* writable including tye temporary
|
||||||
|
* one, we must throw an exception
|
||||||
|
*/
|
||||||
|
if (!@file_exists($full_path) || !@is_writable($full_path)) {
|
||||||
|
throw new phpFastCacheDriverException('PLEASE CREATE OR CHMOD ' . $full_path . ' - 0777 OR ANY WRITABLE PERMISSION!');
|
||||||
|
}
|
||||||
|
$this->tmp[ $full_path_hash ] = $full_path;
|
||||||
|
$this->htaccessGen($full_path, array_key_exists('htaccess', $this->config) ? $this->config[ 'htaccess' ] : false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return realpath($full_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $keyword
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function encodeFilename($keyword)
|
||||||
|
{
|
||||||
|
return md5($keyword);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isExpired()
|
||||||
|
{
|
||||||
|
trigger_error(__FUNCTION__ . '() is deprecated, use ExtendedCacheItemInterface::isExpired() instead.', E_USER_DEPRECATED);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
* @throws \phpFastCache\Exceptions\phpFastCacheCoreException
|
||||||
|
*/
|
||||||
|
public function getFileDir()
|
||||||
|
{
|
||||||
|
return $this->getPath() . DIRECTORY_SEPARATOR . self::FILE_DIR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $keyword
|
||||||
|
* @param bool $skip
|
||||||
|
* @return string
|
||||||
|
* @throws phpFastCacheDriverException
|
||||||
|
*/
|
||||||
|
private function getFilePath($keyword, $skip = false)
|
||||||
|
{
|
||||||
|
$path = $this->getFileDir();
|
||||||
|
|
||||||
|
if ($keyword === false) {
|
||||||
|
return $path;
|
||||||
|
}
|
||||||
|
|
||||||
|
$filename = $this->encodeFilename($keyword);
|
||||||
|
$folder = substr($filename, 0, 2);
|
||||||
|
$path = rtrim($path, '/') . '/' . $folder;
|
||||||
|
/**
|
||||||
|
* Skip Create Sub Folders;
|
||||||
|
*/
|
||||||
|
if ($skip == false) {
|
||||||
|
if (!file_exists($path)) {
|
||||||
|
if (@!mkdir($path, $this->setChmodAuto(), true)) {
|
||||||
|
throw new phpFastCacheDriverException('PLEASE CHMOD ' . $this->getPath() . ' - ' . $this->setChmodAuto() . ' OR ANY WRITABLE PERMISSION!');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $path . '/' . $filename . '.txt';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $this ->config
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function setChmodAuto()
|
||||||
|
{
|
||||||
|
if (!isset($this->config[ 'default_chmod' ]) || $this->config[ 'default_chmod' ] == '' || is_null($this->config[ 'default_chmod' ])) {
|
||||||
|
return 0777;
|
||||||
|
} else {
|
||||||
|
return $this->config[ 'default_chmod' ];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $filename
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
protected static function cleanFileName($filename)
|
||||||
|
{
|
||||||
|
$regex = [
|
||||||
|
'/[\?\[\]\/\\\=\<\>\:\;\,\'\"\&\$\#\*\(\)\|\~\`\!\{\}]/',
|
||||||
|
'/\.$/',
|
||||||
|
'/^\./',
|
||||||
|
];
|
||||||
|
$replace = ['-', '', ''];
|
||||||
|
|
||||||
|
return trim(preg_replace($regex, $replace, trim($filename)), '-');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $path
|
||||||
|
* @param bool $create
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
protected function htaccessGen($path, $create = true)
|
||||||
|
{
|
||||||
|
if ($create === true) {
|
||||||
|
if (!is_writable($path)) {
|
||||||
|
try {
|
||||||
|
if(!chmod($path, 0777)){
|
||||||
|
throw new phpFastCacheDriverException('Chmod failed on : ' . $path);
|
||||||
|
}
|
||||||
|
} catch (phpFastCacheDriverException $e) {
|
||||||
|
throw new phpFastCacheDriverException('PLEASE CHMOD ' . $path . ' - 0777 OR ANY WRITABLE PERMISSION!', 0, $e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!file_exists($path . "/.htaccess")) {
|
||||||
|
$html = "order deny, allow \r\n
|
||||||
|
deny from all \r\n
|
||||||
|
allow from 127.0.0.1";
|
||||||
|
|
||||||
|
$file = @fopen($path . '/.htaccess', 'w+');
|
||||||
|
if (!$file) {
|
||||||
|
throw new phpFastCacheDriverException('PLEASE CHMOD ' . $path . ' - 0777 OR ANY WRITABLE PERMISSION!');
|
||||||
|
}
|
||||||
|
fwrite($file, $html);
|
||||||
|
fclose($file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,247 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* This file is part of phpFastCache.
|
||||||
|
*
|
||||||
|
* @license MIT License (MIT)
|
||||||
|
*
|
||||||
|
* For full copyright and license information, please see the docs/CREDITS.txt file.
|
||||||
|
*
|
||||||
|
* @author Khoa Bui (khoaofgod) <khoaofgod@gmail.com> http://www.phpfastcache.com
|
||||||
|
* @author Georges.L (Geolim4) <contact@geolim4.com>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace phpFastCache\Core;
|
||||||
|
|
||||||
|
use phpFastCache\Cache\ExtendedCacheItemInterface;
|
||||||
|
use phpFastCache\CacheManager;
|
||||||
|
use phpFastCache\Exceptions\phpFastCacheCoreException;
|
||||||
|
use Psr\Cache\CacheItemInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Trait StandardPsr6StructureTrait
|
||||||
|
* @package phpFastCache\Core
|
||||||
|
*/
|
||||||
|
trait StandardPsr6StructureTrait
|
||||||
|
{
|
||||||
|
use ClassNamespaceResolverTrait;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $deferredList = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var ExtendedCacheItemInterface[]
|
||||||
|
*/
|
||||||
|
protected $itemInstances = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $key
|
||||||
|
* @return \phpFastCache\Cache\ExtendedCacheItemInterface
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
* @throws phpFastCacheCoreException
|
||||||
|
*/
|
||||||
|
public function getItem($key)
|
||||||
|
{
|
||||||
|
if (is_string($key)) {
|
||||||
|
if (!array_key_exists($key, $this->itemInstances)) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var $item ExtendedCacheItemInterface
|
||||||
|
*/
|
||||||
|
CacheManager::$ReadHits++;
|
||||||
|
$class = new \ReflectionClass((new \ReflectionObject($this))->getNamespaceName() . '\Item');
|
||||||
|
$item = $class->newInstanceArgs([$this, $key]);
|
||||||
|
$driverArray = $this->driverRead($item);
|
||||||
|
|
||||||
|
if ($driverArray) {
|
||||||
|
if(!is_array($driverArray)){
|
||||||
|
throw new phpFastCacheCoreException(sprintf('The driverRead method returned an unexpected variable type: %s', gettype($driverArray)));
|
||||||
|
}
|
||||||
|
$item->set($this->driverUnwrapData($driverArray));
|
||||||
|
$item->expiresAt($this->driverUnwrapTime($driverArray));
|
||||||
|
$item->setTags($this->driverUnwrapTags($driverArray));
|
||||||
|
if ($item->isExpired()) {
|
||||||
|
/**
|
||||||
|
* Using driverDelete() instead of delete()
|
||||||
|
* to avoid infinite loop caused by
|
||||||
|
* getItem() call in delete() method
|
||||||
|
* As we MUST return an item in any
|
||||||
|
* way, we do not de-register here
|
||||||
|
*/
|
||||||
|
$this->driverDelete($item);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
$item->setHit(true);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$item->expiresAfter(abs((int) $this->getConfig()[ 'defaultTtl' ]));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new \InvalidArgumentException(sprintf('$key must be a string, got type "%s" instead.', gettype($key)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->itemInstances[ $key ];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \Psr\Cache\CacheItemInterface $item
|
||||||
|
* @return $this
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function setItem(CacheItemInterface $item)
|
||||||
|
{
|
||||||
|
if ($this->getClassNamespace() . '\\Item' === get_class($item)) {
|
||||||
|
$this->itemInstances[ $item->getKey() ] = $item;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
} else {
|
||||||
|
throw new \InvalidArgumentException(sprintf('Invalid Item Class "%s" for this driver.', get_class($item)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $keys
|
||||||
|
* @return CacheItemInterface[]
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function getItems(array $keys = [])
|
||||||
|
{
|
||||||
|
$collection = [];
|
||||||
|
foreach ($keys as $key) {
|
||||||
|
$collection[ $key ] = $this->getItem($key);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $collection;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $key
|
||||||
|
* @return bool
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function hasItem($key)
|
||||||
|
{
|
||||||
|
CacheManager::$ReadHits++;
|
||||||
|
|
||||||
|
return $this->getItem($key)->isHit();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function clear()
|
||||||
|
{
|
||||||
|
CacheManager::$WriteHits++;
|
||||||
|
$this->itemInstances = [];
|
||||||
|
|
||||||
|
return $this->driverClear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $key
|
||||||
|
* @return bool
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function deleteItem($key)
|
||||||
|
{
|
||||||
|
$item = $this->getItem($key);
|
||||||
|
if ($this->hasItem($key) && $this->driverDelete($item)) {
|
||||||
|
$item->setHit(false);
|
||||||
|
CacheManager::$WriteHits++;
|
||||||
|
/**
|
||||||
|
* De-register the item instance
|
||||||
|
* then collect gc cycles
|
||||||
|
*/
|
||||||
|
$this->deregisterItem($key);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $keys
|
||||||
|
* @return bool
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function deleteItems(array $keys)
|
||||||
|
{
|
||||||
|
$return = null;
|
||||||
|
foreach ($keys as $key) {
|
||||||
|
$result = $this->deleteItem($key);
|
||||||
|
if ($result !== false) {
|
||||||
|
$return = $result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (bool) $return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \Psr\Cache\CacheItemInterface $item
|
||||||
|
* @return mixed
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
* @throws \RuntimeException
|
||||||
|
*/
|
||||||
|
public function save(CacheItemInterface $item)
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var ExtendedCacheItemInterface $item
|
||||||
|
*/
|
||||||
|
if (!array_key_exists($item->getKey(), $this->itemInstances)) {
|
||||||
|
$this->itemInstances[ $item->getKey() ] = $item;
|
||||||
|
} else if(spl_object_hash($item) !== spl_object_hash($this->itemInstances[ $item->getKey() ])){
|
||||||
|
throw new \RuntimeException('Spl object hash mismatches ! You probably tried to save a detached item which has been already retrieved from cache.');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if ($this->driverWrite($item) && $this->driverWriteTags($item)) {
|
||||||
|
$item->setHit(true);
|
||||||
|
CacheManager::$WriteHits++;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \Psr\Cache\CacheItemInterface $item
|
||||||
|
* @return \Psr\Cache\CacheItemInterface
|
||||||
|
* @throws \RuntimeException
|
||||||
|
*/
|
||||||
|
public function saveDeferred(CacheItemInterface $item)
|
||||||
|
{
|
||||||
|
if (!array_key_exists($item->getKey(), $this->itemInstances)) {
|
||||||
|
$this->itemInstances[ $item->getKey() ] = $item;
|
||||||
|
}else if(spl_object_hash($item) !== spl_object_hash($this->itemInstances[ $item->getKey() ])){
|
||||||
|
throw new \RuntimeException('Spl object hash mismatches ! You probably tried to save a detached item which has been already retrieved from cache.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->deferredList[ $item->getKey() ] = $item;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return mixed|null
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function commit()
|
||||||
|
{
|
||||||
|
$return = null;
|
||||||
|
foreach ($this->deferredList as $key => $item) {
|
||||||
|
$result = $this->save($item);
|
||||||
|
if ($return !== false) {
|
||||||
|
unset($this->deferredList[ $key ]);
|
||||||
|
$return = $result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (bool) $return;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,143 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* This file is part of phpFastCache.
|
||||||
|
*
|
||||||
|
* @license MIT License (MIT)
|
||||||
|
*
|
||||||
|
* For full copyright and license information, please see the docs/CREDITS.txt file.
|
||||||
|
*
|
||||||
|
* @author Khoa Bui (khoaofgod) <khoaofgod@gmail.com> http://www.phpfastcache.com
|
||||||
|
* @author Georges.L (Geolim4) <contact@geolim4.com>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace phpFastCache\Drivers\Apc;
|
||||||
|
|
||||||
|
use phpFastCache\Core\DriverAbstract;
|
||||||
|
use phpFastCache\Core\StandardPsr6StructureTrait;
|
||||||
|
use phpFastCache\Entities\driverStatistic;
|
||||||
|
use phpFastCache\Exceptions\phpFastCacheDriverCheckException;
|
||||||
|
use phpFastCache\Exceptions\phpFastCacheDriverException;
|
||||||
|
use Psr\Cache\CacheItemInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Driver
|
||||||
|
* @package phpFastCache\Drivers
|
||||||
|
*/
|
||||||
|
class Driver extends DriverAbstract
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Driver constructor.
|
||||||
|
* @param array $config
|
||||||
|
* @throws phpFastCacheDriverException
|
||||||
|
*/
|
||||||
|
public function __construct(array $config = [])
|
||||||
|
{
|
||||||
|
$this->setup($config);
|
||||||
|
|
||||||
|
if (!$this->driverCheck()) {
|
||||||
|
throw new phpFastCacheDriverCheckException(sprintf(self::DRIVER_CHECK_FAILURE, $this->getDriverName()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function driverCheck()
|
||||||
|
{
|
||||||
|
if (extension_loaded('apc') && ini_get('apc.enabled')) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \Psr\Cache\CacheItemInterface $item
|
||||||
|
* @return mixed
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
protected function driverWrite(CacheItemInterface $item)
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Check for Cross-Driver type confusion
|
||||||
|
*/
|
||||||
|
if ($item instanceof Item) {
|
||||||
|
$ttl = $item->getExpirationDate()->getTimestamp() - time();
|
||||||
|
|
||||||
|
return apc_store($item->getKey(), $this->driverPreWrap($item), ($ttl > 0 ? $ttl : 0));
|
||||||
|
} else {
|
||||||
|
throw new \InvalidArgumentException('Cross-Driver type confusion detected');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \Psr\Cache\CacheItemInterface $item
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
protected function driverRead(CacheItemInterface $item)
|
||||||
|
{
|
||||||
|
$data = apc_fetch($item->getKey(), $success);
|
||||||
|
if ($success === false) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \Psr\Cache\CacheItemInterface $item
|
||||||
|
* @return bool
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
protected function driverDelete(CacheItemInterface $item)
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Check for Cross-Driver type confusion
|
||||||
|
*/
|
||||||
|
if ($item instanceof Item) {
|
||||||
|
return apc_delete($item->getKey());
|
||||||
|
} else {
|
||||||
|
throw new \InvalidArgumentException('Cross-Driver type confusion detected');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
protected function driverClear()
|
||||||
|
{
|
||||||
|
return @apc_clear_cache() && @apc_clear_cache('user');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
protected function driverConnect()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************
|
||||||
|
*
|
||||||
|
* PSR-6 Extended Methods
|
||||||
|
*
|
||||||
|
*******************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return driverStatistic
|
||||||
|
*/
|
||||||
|
public function getStats()
|
||||||
|
{
|
||||||
|
$stats = (array) apc_cache_info('user');
|
||||||
|
$date = (new \DateTime())->setTimestamp($stats[ 'start_time' ]);
|
||||||
|
|
||||||
|
return (new driverStatistic())
|
||||||
|
->setData(implode(', ', array_keys($this->itemInstances)))
|
||||||
|
->setInfo(sprintf("The APC cache is up since %s, and have %d item(s) in cache.\n For more information see RawData.", $date->format(DATE_RFC2822),
|
||||||
|
$stats[ 'num_entries' ]))
|
||||||
|
->setRawData($stats)
|
||||||
|
->setSize($stats[ 'mem_size' ]);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,63 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* This file is part of phpFastCache.
|
||||||
|
*
|
||||||
|
* @license MIT License (MIT)
|
||||||
|
*
|
||||||
|
* For full copyright and license information, please see the docs/CREDITS.txt file.
|
||||||
|
*
|
||||||
|
* @author Khoa Bui (khoaofgod) <khoaofgod@gmail.com> http://www.phpfastcache.com
|
||||||
|
* @author Georges.L (Geolim4) <contact@geolim4.com>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace phpFastCache\Drivers\Apc;
|
||||||
|
|
||||||
|
use phpFastCache\Cache\ExtendedCacheItemInterface;
|
||||||
|
use phpFastCache\Cache\ExtendedCacheItemPoolInterface;
|
||||||
|
use phpFastCache\Cache\ItemBaseTrait;
|
||||||
|
use phpFastCache\Drivers\Apc\Driver as ApcDriver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Item
|
||||||
|
* @package phpFastCache\Drivers\Apc
|
||||||
|
*/
|
||||||
|
class Item implements ExtendedCacheItemInterface
|
||||||
|
{
|
||||||
|
use ItemBaseTrait;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Item constructor.
|
||||||
|
* @param \phpFastCache\Drivers\Apc\Driver $driver
|
||||||
|
* @param $key
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function __construct(ApcDriver $driver, $key)
|
||||||
|
{
|
||||||
|
if (is_string($key)) {
|
||||||
|
$this->key = $key;
|
||||||
|
$this->driver = $driver;
|
||||||
|
$this->driver->setItem($this);
|
||||||
|
$this->expirationDate = new \DateTime();
|
||||||
|
} else {
|
||||||
|
throw new \InvalidArgumentException(sprintf('$key must be a string, got type "%s" instead.', gettype($key)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param ExtendedCacheItemPoolInterface $driver
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
* @return static
|
||||||
|
*/
|
||||||
|
public function setDriver(ExtendedCacheItemPoolInterface $driver)
|
||||||
|
{
|
||||||
|
if ($driver instanceof ApcDriver) {
|
||||||
|
$this->driver = $driver;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
} else {
|
||||||
|
throw new \InvalidArgumentException('Invalid driver instance');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,142 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* This file is part of phpFastCache.
|
||||||
|
*
|
||||||
|
* @license MIT License (MIT)
|
||||||
|
*
|
||||||
|
* For full copyright and license information, please see the docs/CREDITS.txt file.
|
||||||
|
*
|
||||||
|
* @author Khoa Bui (khoaofgod) <khoaofgod@gmail.com> http://www.phpfastcache.com
|
||||||
|
* @author Georges.L (Geolim4) <contact@geolim4.com>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace phpFastCache\Drivers\Apcu;
|
||||||
|
|
||||||
|
use phpFastCache\Core\DriverAbstract;
|
||||||
|
use phpFastCache\Core\StandardPsr6StructureTrait;
|
||||||
|
use phpFastCache\Entities\driverStatistic;
|
||||||
|
use phpFastCache\Exceptions\phpFastCacheDriverCheckException;
|
||||||
|
use phpFastCache\Exceptions\phpFastCacheDriverException;
|
||||||
|
use Psr\Cache\CacheItemInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Driver
|
||||||
|
* @package phpFastCache\Drivers
|
||||||
|
*/
|
||||||
|
class Driver extends DriverAbstract
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Driver constructor.
|
||||||
|
* @param array $config
|
||||||
|
* @throws phpFastCacheDriverException
|
||||||
|
*/
|
||||||
|
public function __construct(array $config = [])
|
||||||
|
{
|
||||||
|
$this->setup($config);
|
||||||
|
|
||||||
|
if (!$this->driverCheck()) {
|
||||||
|
throw new phpFastCacheDriverCheckException(sprintf(self::DRIVER_CHECK_FAILURE, $this->getDriverName()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function driverCheck()
|
||||||
|
{
|
||||||
|
if (extension_loaded('apcu') && ini_get('apc.enabled')) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \Psr\Cache\CacheItemInterface $item
|
||||||
|
* @return mixed
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
protected function driverWrite(CacheItemInterface $item)
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Check for Cross-Driver type confusion
|
||||||
|
*/
|
||||||
|
if ($item instanceof Item) {
|
||||||
|
$ttl = $item->getExpirationDate()->getTimestamp() - time();
|
||||||
|
|
||||||
|
return apcu_store($item->getKey(), $this->driverPreWrap($item), ($ttl > 0 ? $ttl : 0));
|
||||||
|
} else {
|
||||||
|
throw new \InvalidArgumentException('Cross-Driver type confusion detected');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \Psr\Cache\CacheItemInterface $item
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
protected function driverRead(CacheItemInterface $item)
|
||||||
|
{
|
||||||
|
$data = apcu_fetch($item->getKey(), $success);
|
||||||
|
if ($success === false) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \Psr\Cache\CacheItemInterface $item
|
||||||
|
* @return bool
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
protected function driverDelete(CacheItemInterface $item)
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Check for Cross-Driver type confusion
|
||||||
|
*/
|
||||||
|
if ($item instanceof Item) {
|
||||||
|
return apcu_delete($item->getKey());
|
||||||
|
} else {
|
||||||
|
throw new \InvalidArgumentException('Cross-Driver type confusion detected');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
protected function driverClear()
|
||||||
|
{
|
||||||
|
return @apcu_clear_cache() && @apcu_clear_cache('user');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
protected function driverConnect()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************
|
||||||
|
*
|
||||||
|
* PSR-6 Extended Methods
|
||||||
|
*
|
||||||
|
*******************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return driverStatistic
|
||||||
|
*/
|
||||||
|
public function getStats()
|
||||||
|
{
|
||||||
|
$stats = (array) apcu_cache_info('user');
|
||||||
|
$date = (new \DateTime())->setTimestamp($stats[ 'start_time' ]);
|
||||||
|
|
||||||
|
return (new driverStatistic())
|
||||||
|
->setData(implode(', ', array_keys($this->itemInstances)))
|
||||||
|
->setInfo(sprintf("The APCU cache is up since %s, and have %d item(s) in cache.\n For more information see RawData.", $date->format(DATE_RFC2822), $stats[ 'num_entries' ]))
|
||||||
|
->setRawData($stats)
|
||||||
|
->setSize($stats[ 'mem_size' ]);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,63 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* This file is part of phpFastCache.
|
||||||
|
*
|
||||||
|
* @license MIT License (MIT)
|
||||||
|
*
|
||||||
|
* For full copyright and license information, please see the docs/CREDITS.txt file.
|
||||||
|
*
|
||||||
|
* @author Khoa Bui (khoaofgod) <khoaofgod@gmail.com> http://www.phpfastcache.com
|
||||||
|
* @author Georges.L (Geolim4) <contact@geolim4.com>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace phpFastCache\Drivers\Apcu;
|
||||||
|
|
||||||
|
use phpFastCache\Cache\ExtendedCacheItemInterface;
|
||||||
|
use phpFastCache\Cache\ExtendedCacheItemPoolInterface;
|
||||||
|
use phpFastCache\Cache\ItemBaseTrait;
|
||||||
|
use phpFastCache\Drivers\Apcu\Driver as ApcuDriver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Item
|
||||||
|
* @package phpFastCache\Drivers\Apcu
|
||||||
|
*/
|
||||||
|
class Item implements ExtendedCacheItemInterface
|
||||||
|
{
|
||||||
|
use ItemBaseTrait;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Item constructor.
|
||||||
|
* @param \phpFastCache\Drivers\Apcu\Driver $driver
|
||||||
|
* @param $key
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function __construct(ApcuDriver $driver, $key)
|
||||||
|
{
|
||||||
|
if (is_string($key)) {
|
||||||
|
$this->key = $key;
|
||||||
|
$this->driver = $driver;
|
||||||
|
$this->driver->setItem($this);
|
||||||
|
$this->expirationDate = new \DateTime();
|
||||||
|
} else {
|
||||||
|
throw new \InvalidArgumentException(sprintf('$key must be a string, got type "%s" instead.', gettype($key)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param ExtendedCacheItemPoolInterface $driver
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
* @return static
|
||||||
|
*/
|
||||||
|
public function setDriver(ExtendedCacheItemPoolInterface $driver)
|
||||||
|
{
|
||||||
|
if ($driver instanceof ApcuDriver) {
|
||||||
|
$this->driver = $driver;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
} else {
|
||||||
|
throw new \InvalidArgumentException('Invalid driver instance');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,197 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* This file is part of phpFastCache.
|
||||||
|
*
|
||||||
|
* @license MIT License (MIT)
|
||||||
|
*
|
||||||
|
* For full copyright and license information, please see the docs/CREDITS.txt file.
|
||||||
|
*
|
||||||
|
* @author Khoa Bui (khoaofgod) <khoaofgod@gmail.com> http://www.phpfastcache.com
|
||||||
|
* @author Georges.L (Geolim4) <contact@geolim4.com>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace phpFastCache\Drivers\Cookie;
|
||||||
|
|
||||||
|
use phpFastCache\Core\DriverAbstract;
|
||||||
|
use phpFastCache\Core\StandardPsr6StructureTrait;
|
||||||
|
use phpFastCache\Entities\driverStatistic;
|
||||||
|
use phpFastCache\Exceptions\phpFastCacheDriverCheckException;
|
||||||
|
use phpFastCache\Exceptions\phpFastCacheDriverException;
|
||||||
|
use Psr\Cache\CacheItemInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Driver
|
||||||
|
* @package phpFastCache\Drivers
|
||||||
|
*/
|
||||||
|
class Driver extends DriverAbstract
|
||||||
|
{
|
||||||
|
const PREFIX = 'PFC_';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Driver constructor.
|
||||||
|
* @param array $config
|
||||||
|
* @throws phpFastCacheDriverException
|
||||||
|
*/
|
||||||
|
public function __construct(array $config = [])
|
||||||
|
{
|
||||||
|
$this->setup($config);
|
||||||
|
|
||||||
|
if (!$this->driverCheck()) {
|
||||||
|
throw new phpFastCacheDriverCheckException(sprintf(self::DRIVER_CHECK_FAILURE, $this->getDriverName()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function driverCheck()
|
||||||
|
{
|
||||||
|
if (function_exists('setcookie')) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
protected function driverConnect()
|
||||||
|
{
|
||||||
|
return !(!array_key_exists('phpFastCache', $_COOKIE) && !@setcookie('phpFastCache', 1, 10));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \Psr\Cache\CacheItemInterface $item
|
||||||
|
* @return mixed
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
protected function driverWrite(CacheItemInterface $item)
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Check for Cross-Driver type confusion
|
||||||
|
*/
|
||||||
|
if ($item instanceof Item) {
|
||||||
|
$this->driverConnect();
|
||||||
|
$keyword = self::PREFIX . $item->getKey();
|
||||||
|
$v = json_encode($this->driverPreWrap($item));
|
||||||
|
|
||||||
|
if (isset($this->config[ 'limited_memory_each_object' ]) && strlen($v) > $this->config[ 'limited_memory_each_object' ]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return setcookie($keyword, $v, $item->getExpirationDate()->getTimestamp(), '/');
|
||||||
|
} else {
|
||||||
|
throw new \InvalidArgumentException('Cross-Driver type confusion detected');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \Psr\Cache\CacheItemInterface $item
|
||||||
|
* @return mixed
|
||||||
|
* @throws \phpFastCache\Exceptions\phpFastCacheDriverException
|
||||||
|
*/
|
||||||
|
protected function driverRead(CacheItemInterface $item)
|
||||||
|
{
|
||||||
|
$this->driverConnect();
|
||||||
|
// return null if no caching
|
||||||
|
// return value if in caching
|
||||||
|
$keyword = self::PREFIX . $item->getKey();
|
||||||
|
$x = isset($_COOKIE[ $keyword ]) ? json_decode($_COOKIE[ $keyword ], true) : false;
|
||||||
|
|
||||||
|
if ($x == false) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
if (!is_scalar($this->driverUnwrapData($x)) && !is_null($this->driverUnwrapData($x))) {
|
||||||
|
throw new phpFastCacheDriverException('Hacking attempt: The decoding returned a non-scalar value, Cookie driver does not allow this.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $key
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
protected function driverReadExpirationDate($key)
|
||||||
|
{
|
||||||
|
$this->driverConnect();
|
||||||
|
$keyword = self::PREFIX . $key;
|
||||||
|
$x = isset($_COOKIE[ $keyword ]) ? $this->decode(json_decode($_COOKIE[ $keyword ])->t) : false;
|
||||||
|
|
||||||
|
return $x ? $x - time() : $x;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \Psr\Cache\CacheItemInterface $item
|
||||||
|
* @return bool
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
protected function driverDelete(CacheItemInterface $item)
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Check for Cross-Driver type confusion
|
||||||
|
*/
|
||||||
|
if ($item instanceof Item) {
|
||||||
|
$this->driverConnect();
|
||||||
|
$keyword = self::PREFIX . $item->getKey();
|
||||||
|
$_COOKIE[ $keyword ] = null;
|
||||||
|
|
||||||
|
return @setcookie($keyword, null, -10);
|
||||||
|
} else {
|
||||||
|
throw new \InvalidArgumentException('Cross-Driver type confusion detected');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
protected function driverClear()
|
||||||
|
{
|
||||||
|
$return = null;
|
||||||
|
$this->driverConnect();
|
||||||
|
foreach ($_COOKIE as $keyword => $value) {
|
||||||
|
if (strpos($keyword, self::PREFIX) !== false) {
|
||||||
|
$_COOKIE[ $keyword ] = null;
|
||||||
|
$result = @setcookie($keyword, null, -10);
|
||||||
|
if ($return !== false) {
|
||||||
|
$return = $result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************
|
||||||
|
*
|
||||||
|
* PSR-6 Extended Methods
|
||||||
|
*
|
||||||
|
*******************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return driverStatistic
|
||||||
|
*/
|
||||||
|
public function getStats()
|
||||||
|
{
|
||||||
|
$size = 0;
|
||||||
|
$stat = new driverStatistic();
|
||||||
|
$stat->setData($_COOKIE);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Only count PFC Cookie
|
||||||
|
*/
|
||||||
|
foreach ($_COOKIE as $key => $value) {
|
||||||
|
if (strpos($key, self::PREFIX) === 0) {
|
||||||
|
$size += strlen($value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$stat->setSize($size);
|
||||||
|
|
||||||
|
return $stat;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,65 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* This file is part of phpFastCache.
|
||||||
|
*
|
||||||
|
* @license MIT License (MIT)
|
||||||
|
*
|
||||||
|
* For full copyright and license information, please see the docs/CREDITS.txt file.
|
||||||
|
*
|
||||||
|
* @author Khoa Bui (khoaofgod) <khoaofgod@gmail.com> http://www.phpfastcache.com
|
||||||
|
* @author Georges.L (Geolim4) <contact@geolim4.com>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace phpFastCache\Drivers\Cookie;
|
||||||
|
|
||||||
|
use phpFastCache\Cache\ExtendedCacheItemInterface;
|
||||||
|
use phpFastCache\Cache\ExtendedCacheItemPoolInterface;
|
||||||
|
use phpFastCache\Cache\ItemBaseTrait;
|
||||||
|
use phpFastCache\Drivers\Cookie\Driver as CookieDriver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Item
|
||||||
|
* @package phpFastCache\Drivers\Apc
|
||||||
|
*/
|
||||||
|
class Item implements ExtendedCacheItemInterface
|
||||||
|
{
|
||||||
|
use ItemBaseTrait;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Item constructor.
|
||||||
|
* @param \phpFastCache\Drivers\Cookie\Driver $driver
|
||||||
|
* @param $key
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function __construct(CookieDriver $driver, $key)
|
||||||
|
{
|
||||||
|
if (is_string($key)) {
|
||||||
|
$this->expirationDate = new \DateTime();
|
||||||
|
$this->key = $key;
|
||||||
|
$this->driver = $driver;
|
||||||
|
$this->driver->setItem($this);
|
||||||
|
} else {
|
||||||
|
throw new \InvalidArgumentException(sprintf('$key must be a string, got type "%s" instead.',
|
||||||
|
gettype($key)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param ExtendedCacheItemPoolInterface $driver
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
* @return static
|
||||||
|
*/
|
||||||
|
public function setDriver(ExtendedCacheItemPoolInterface $driver)
|
||||||
|
{
|
||||||
|
if ($driver instanceof CookieDriver) {
|
||||||
|
$this->driver = $driver;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
} else {
|
||||||
|
throw new \InvalidArgumentException('Invalid driver instance');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,199 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* This file is part of phpFastCache.
|
||||||
|
*
|
||||||
|
* @license MIT License (MIT)
|
||||||
|
*
|
||||||
|
* For full copyright and license information, please see the docs/CREDITS.txt file.
|
||||||
|
*
|
||||||
|
* @author Khoa Bui (khoaofgod) <khoaofgod@gmail.com> http://www.phpfastcache.com
|
||||||
|
* @author Georges.L (Geolim4) <contact@geolim4.com>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace phpFastCache\Drivers\Couchbase;
|
||||||
|
|
||||||
|
use CouchbaseCluster as CouchbaseClient;
|
||||||
|
use phpFastCache\Core\DriverAbstract;
|
||||||
|
use phpFastCache\Core\StandardPsr6StructureTrait;
|
||||||
|
use phpFastCache\Entities\driverStatistic;
|
||||||
|
use phpFastCache\Exceptions\phpFastCacheDriverCheckException;
|
||||||
|
use phpFastCache\Exceptions\phpFastCacheDriverException;
|
||||||
|
use Psr\Cache\CacheItemInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Driver
|
||||||
|
* @package phpFastCache\Drivers
|
||||||
|
*/
|
||||||
|
class Driver extends DriverAbstract
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var CouchbaseClient
|
||||||
|
*/
|
||||||
|
public $instance;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \CouchbaseBucket[]
|
||||||
|
*/
|
||||||
|
protected $bucketInstances = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $bucketCurrent = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Driver constructor.
|
||||||
|
* @param array $config
|
||||||
|
* @throws phpFastCacheDriverException
|
||||||
|
*/
|
||||||
|
public function __construct(array $config = [])
|
||||||
|
{
|
||||||
|
$this->setup($config);
|
||||||
|
|
||||||
|
if (!$this->driverCheck()) {
|
||||||
|
throw new phpFastCacheDriverCheckException(sprintf(self::DRIVER_CHECK_FAILURE, $this->getDriverName()));
|
||||||
|
} else {
|
||||||
|
$this->driverConnect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function driverCheck()
|
||||||
|
{
|
||||||
|
return extension_loaded('Couchbase');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \Psr\Cache\CacheItemInterface $item
|
||||||
|
* @return mixed
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
protected function driverWrite(CacheItemInterface $item)
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Check for Cross-Driver type confusion
|
||||||
|
*/
|
||||||
|
if ($item instanceof Item) {
|
||||||
|
return $this->getBucket()->upsert($item->getKey(), $this->encode($this->driverPreWrap($item)), ['expiry' => $item->getTtl()]);
|
||||||
|
} else {
|
||||||
|
throw new \InvalidArgumentException('Cross-Driver type confusion detected');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \Psr\Cache\CacheItemInterface $item
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
protected function driverRead(CacheItemInterface $item)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
/**
|
||||||
|
* CouchbaseBucket::get() returns a CouchbaseMetaDoc object
|
||||||
|
*/
|
||||||
|
return $this->decode($this->getBucket()->get($item->getKey())->value);
|
||||||
|
} catch (\CouchbaseException $e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \Psr\Cache\CacheItemInterface $item
|
||||||
|
* @return bool
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
protected function driverDelete(CacheItemInterface $item)
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Check for Cross-Driver type confusion
|
||||||
|
*/
|
||||||
|
if ($item instanceof Item) {
|
||||||
|
return $this->getBucket()->remove($item->getKey());
|
||||||
|
} else {
|
||||||
|
throw new \InvalidArgumentException('Cross-Driver type confusion detected');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
protected function driverClear()
|
||||||
|
{
|
||||||
|
return $this->getBucket()->manager()->flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
protected function driverConnect()
|
||||||
|
{
|
||||||
|
if ($this->instance instanceof CouchbaseClient) {
|
||||||
|
throw new \LogicException('Already connected to Couchbase server');
|
||||||
|
} else {
|
||||||
|
|
||||||
|
|
||||||
|
$host = isset($this->config[ 'host' ]) ? $this->config[ 'host' ] : '127.0.0.1';
|
||||||
|
//$port = isset($server[ 'port' ]) ? $server[ 'port' ] : '11211';
|
||||||
|
$password = isset($this->config[ 'password' ]) ? $this->config[ 'password' ] : '';
|
||||||
|
$username = isset($this->config[ 'username' ]) ? $this->config[ 'username' ] : '';
|
||||||
|
$buckets = isset($this->config[ 'buckets' ]) ? $this->config[ 'buckets' ] : [
|
||||||
|
[
|
||||||
|
'bucket' => 'default',
|
||||||
|
'password' => '',
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
$this->instance = $this->instance ?: new CouchbaseClient("couchbase://{$host}", $username, $password);
|
||||||
|
|
||||||
|
foreach ($buckets as $bucket) {
|
||||||
|
$this->bucketCurrent = $this->bucketCurrent ?: $bucket[ 'bucket' ];
|
||||||
|
$this->setBucket($bucket[ 'bucket' ], $this->instance->openBucket($bucket[ 'bucket' ], $bucket[ 'password' ]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return \CouchbaseBucket
|
||||||
|
*/
|
||||||
|
protected function getBucket()
|
||||||
|
{
|
||||||
|
return $this->bucketInstances[ $this->bucketCurrent ];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $bucketName
|
||||||
|
* @param \CouchbaseBucket $CouchbaseBucket
|
||||||
|
* @throws \LogicException
|
||||||
|
*/
|
||||||
|
protected function setBucket($bucketName, \CouchbaseBucket $CouchbaseBucket)
|
||||||
|
{
|
||||||
|
if (!array_key_exists($bucketName, $this->bucketInstances)) {
|
||||||
|
$this->bucketInstances[ $bucketName ] = $CouchbaseBucket;
|
||||||
|
} else {
|
||||||
|
throw new \LogicException('A bucket instance with this name already exists.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************
|
||||||
|
*
|
||||||
|
* PSR-6 Extended Methods
|
||||||
|
*
|
||||||
|
*******************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return driverStatistic
|
||||||
|
*/
|
||||||
|
public function getStats()
|
||||||
|
{
|
||||||
|
$info = $this->getBucket()->manager()->info();
|
||||||
|
|
||||||
|
return (new driverStatistic())
|
||||||
|
->setSize($info[ 'basicStats' ][ 'diskUsed' ])
|
||||||
|
->setRawData($info)
|
||||||
|
->setData(implode(', ', array_keys($this->itemInstances)))
|
||||||
|
->setInfo('CouchBase version ' . $info[ 'nodes' ][ 0 ][ 'version' ] . ', Uptime (in days): ' . round($info[ 'nodes' ][ 0 ][ 'uptime' ] / 86400, 1) . "\n For more information see RawData.");
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,63 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* This file is part of phpFastCache.
|
||||||
|
*
|
||||||
|
* @license MIT License (MIT)
|
||||||
|
*
|
||||||
|
* For full copyright and license information, please see the docs/CREDITS.txt file.
|
||||||
|
*
|
||||||
|
* @author Khoa Bui (khoaofgod) <khoaofgod@gmail.com> http://www.phpfastcache.com
|
||||||
|
* @author Georges.L (Geolim4) <contact@geolim4.com>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace phpFastCache\Drivers\Couchbase;
|
||||||
|
|
||||||
|
use phpFastCache\Cache\ExtendedCacheItemInterface;
|
||||||
|
use phpFastCache\Cache\ExtendedCacheItemPoolInterface;
|
||||||
|
use phpFastCache\Cache\ItemBaseTrait;
|
||||||
|
use phpFastCache\Drivers\Couchbase\Driver as CouchbaseDriver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Item
|
||||||
|
* @package phpFastCache\Drivers\Apc
|
||||||
|
*/
|
||||||
|
class Item implements ExtendedCacheItemInterface
|
||||||
|
{
|
||||||
|
use ItemBaseTrait;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Item constructor.
|
||||||
|
* @param \phpFastCache\Drivers\Couchbase\Driver $driver
|
||||||
|
* @param $key
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function __construct(CouchbaseDriver $driver, $key)
|
||||||
|
{
|
||||||
|
if (is_string($key)) {
|
||||||
|
$this->key = $key;
|
||||||
|
$this->driver = $driver;
|
||||||
|
$this->driver->setItem($this);
|
||||||
|
$this->expirationDate = new \DateTime();
|
||||||
|
} else {
|
||||||
|
throw new \InvalidArgumentException(sprintf('$key must be a string, got type "%s" instead.', gettype($key)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param ExtendedCacheItemPoolInterface $driver
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
* @return static
|
||||||
|
*/
|
||||||
|
public function setDriver(ExtendedCacheItemPoolInterface $driver)
|
||||||
|
{
|
||||||
|
if ($driver instanceof CouchbaseDriver) {
|
||||||
|
$this->driver = $driver;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
} else {
|
||||||
|
throw new \InvalidArgumentException('Invalid driver instance');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,136 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* This file is part of phpFastCache.
|
||||||
|
*
|
||||||
|
* @license MIT License (MIT)
|
||||||
|
*
|
||||||
|
* For full copyright and license information, please see the docs/CREDITS.txt file.
|
||||||
|
*
|
||||||
|
* @author Khoa Bui (khoaofgod) <khoaofgod@gmail.com> http://www.phpfastcache.com
|
||||||
|
* @author Georges.L (Geolim4) <contact@geolim4.com>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace phpFastCache\Drivers\Devfalse;
|
||||||
|
|
||||||
|
use phpFastCache\Core\DriverAbstract;
|
||||||
|
use phpFastCache\Entities\driverStatistic;
|
||||||
|
use phpFastCache\Exceptions\phpFastCacheDriverCheckException;
|
||||||
|
use phpFastCache\Exceptions\phpFastCacheDriverException;
|
||||||
|
use Psr\Cache\CacheItemInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Driver
|
||||||
|
* @package phpFastCache\Drivers
|
||||||
|
*/
|
||||||
|
class Driver extends DriverAbstract
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Driver constructor.
|
||||||
|
* @param array $config
|
||||||
|
* @throws phpFastCacheDriverException
|
||||||
|
*/
|
||||||
|
public function __construct(array $config = [])
|
||||||
|
{
|
||||||
|
$this->setup($config);
|
||||||
|
|
||||||
|
if (!$this->driverCheck()) {
|
||||||
|
throw new phpFastCacheDriverCheckException(sprintf(self::DRIVER_CHECK_FAILURE, $this->getDriverName()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function driverCheck()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \Psr\Cache\CacheItemInterface $item
|
||||||
|
* @return mixed
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
protected function driverWrite(CacheItemInterface $item)
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Check for Cross-Driver type confusion
|
||||||
|
*/
|
||||||
|
if ($item instanceof Item) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
throw new \InvalidArgumentException('Cross-Driver type confusion detected');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \Psr\Cache\CacheItemInterface $item
|
||||||
|
* @return array [
|
||||||
|
* 'd' => 'THE ITEM DATA'
|
||||||
|
* 't' => 'THE ITEM DATE EXPIRATION'
|
||||||
|
* 'g' => 'THE ITEM TAGS'
|
||||||
|
* ]
|
||||||
|
*/
|
||||||
|
protected function driverRead(CacheItemInterface $item)
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
self::DRIVER_DATA_WRAPPER_INDEX => false,
|
||||||
|
self::DRIVER_TAGS_WRAPPER_INDEX => [],
|
||||||
|
self::DRIVER_TIME_WRAPPER_INDEX => new \DateTime(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param \Psr\Cache\CacheItemInterface $item
|
||||||
|
* @return bool
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
protected function driverDelete(CacheItemInterface $item)
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Check for Cross-Driver type confusion
|
||||||
|
*/
|
||||||
|
if ($item instanceof Item) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
throw new \InvalidArgumentException('Cross-Driver type confusion detected');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
protected function driverClear()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
protected function driverConnect()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************
|
||||||
|
*
|
||||||
|
* PSR-6 Extended Methods
|
||||||
|
*
|
||||||
|
*******************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return driverStatistic
|
||||||
|
*/
|
||||||
|
public function getStats()
|
||||||
|
{
|
||||||
|
$stat = new driverStatistic();
|
||||||
|
$stat->setInfo('[Devfalse] A void info string')
|
||||||
|
->setSize(0)
|
||||||
|
->setData(implode(', ', array_keys($this->itemInstances)))
|
||||||
|
->setRawData(false);
|
||||||
|
|
||||||
|
return $stat;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,63 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* This file is part of phpFastCache.
|
||||||
|
*
|
||||||
|
* @license MIT License (MIT)
|
||||||
|
*
|
||||||
|
* For full copyright and license information, please see the docs/CREDITS.txt file.
|
||||||
|
*
|
||||||
|
* @author Khoa Bui (khoaofgod) <khoaofgod@gmail.com> http://www.phpfastcache.com
|
||||||
|
* @author Georges.L (Geolim4) <contact@geolim4.com>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace phpFastCache\Drivers\Devfalse;
|
||||||
|
|
||||||
|
use phpFastCache\Cache\ExtendedCacheItemInterface;
|
||||||
|
use phpFastCache\Cache\ExtendedCacheItemPoolInterface;
|
||||||
|
use phpFastCache\Cache\ItemBaseTrait;
|
||||||
|
use phpFastCache\Drivers\Devnull\Driver as DevnullDriver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Item
|
||||||
|
* @package phpFastCache\Drivers\Devnull
|
||||||
|
*/
|
||||||
|
class Item implements ExtendedCacheItemInterface
|
||||||
|
{
|
||||||
|
use ItemBaseTrait;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Item constructor.
|
||||||
|
* @param \phpFastCache\Drivers\Devnull\Driver $driver
|
||||||
|
* @param $key
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function __construct(DevnullDriver $driver, $key)
|
||||||
|
{
|
||||||
|
if (is_string($key)) {
|
||||||
|
$this->key = $key;
|
||||||
|
$this->driver = $driver;
|
||||||
|
$this->driver->setItem($this);
|
||||||
|
$this->expirationDate = new \DateTime();
|
||||||
|
} else {
|
||||||
|
throw new \InvalidArgumentException(sprintf('$key must be a string, got type "%s" instead.', gettype($key)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param ExtendedCacheItemPoolInterface $driver
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
* @return static
|
||||||
|
*/
|
||||||
|
public function setDriver(ExtendedCacheItemPoolInterface $driver)
|
||||||
|
{
|
||||||
|
if ($driver instanceof DevnullDriver) {
|
||||||
|
$this->driver = $driver;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
} else {
|
||||||
|
throw new \InvalidArgumentException('Invalid driver instance');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,138 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* This file is part of phpFastCache.
|
||||||
|
*
|
||||||
|
* @license MIT License (MIT)
|
||||||
|
*
|
||||||
|
* For full copyright and license information, please see the docs/CREDITS.txt file.
|
||||||
|
*
|
||||||
|
* @author Khoa Bui (khoaofgod) <khoaofgod@gmail.com> http://www.phpfastcache.com
|
||||||
|
* @author Georges.L (Geolim4) <contact@geolim4.com>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace phpFastCache\Drivers\Devnull;
|
||||||
|
|
||||||
|
use phpFastCache\Core\DriverAbstract;
|
||||||
|
use phpFastCache\Core\StandardPsr6StructureTrait;
|
||||||
|
use phpFastCache\Entities\driverStatistic;
|
||||||
|
use phpFastCache\Exceptions\phpFastCacheDriverCheckException;
|
||||||
|
use phpFastCache\Exceptions\phpFastCacheDriverException;
|
||||||
|
use Psr\Cache\CacheItemInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Driver
|
||||||
|
* @package phpFastCache\Drivers
|
||||||
|
*/
|
||||||
|
class Driver extends DriverAbstract
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Driver constructor.
|
||||||
|
* @param array $config
|
||||||
|
* @throws phpFastCacheDriverException
|
||||||
|
*/
|
||||||
|
public function __construct(array $config = [])
|
||||||
|
{
|
||||||
|
$this->setup($config);
|
||||||
|
|
||||||
|
if (!$this->driverCheck()) {
|
||||||
|
throw new phpFastCacheDriverCheckException(sprintf(self::DRIVER_CHECK_FAILURE, $this->getDriverName()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function driverCheck()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \Psr\Cache\CacheItemInterface $item
|
||||||
|
* @return mixed
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
protected function driverWrite(CacheItemInterface $item)
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Check for Cross-Driver type confusion
|
||||||
|
*/
|
||||||
|
if ($item instanceof Item) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
throw new \InvalidArgumentException('Cross-Driver type confusion detected');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \Psr\Cache\CacheItemInterface $item
|
||||||
|
* @return array [
|
||||||
|
* 'd' => 'THE ITEM DATA'
|
||||||
|
* 't' => 'THE ITEM DATE EXPIRATION'
|
||||||
|
* 'g' => 'THE ITEM TAGS'
|
||||||
|
* ]
|
||||||
|
*/
|
||||||
|
protected function driverRead(CacheItemInterface $item)
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
self::DRIVER_DATA_WRAPPER_INDEX => null,
|
||||||
|
self::DRIVER_TAGS_WRAPPER_INDEX => [],
|
||||||
|
self::DRIVER_TIME_WRAPPER_INDEX => new \DateTime(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \Psr\Cache\CacheItemInterface $item
|
||||||
|
* @return bool
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
protected function driverDelete(CacheItemInterface $item)
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Check for Cross-Driver type confusion
|
||||||
|
*/
|
||||||
|
if ($item instanceof Item) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
throw new \InvalidArgumentException('Cross-Driver type confusion detected');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
protected function driverClear()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
protected function driverConnect()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************
|
||||||
|
*
|
||||||
|
* PSR-6 Extended Methods
|
||||||
|
*
|
||||||
|
*******************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return driverStatistic
|
||||||
|
*/
|
||||||
|
public function getStats()
|
||||||
|
{
|
||||||
|
$stat = new driverStatistic();
|
||||||
|
$stat->setInfo('[Devnull] A void info string')
|
||||||
|
->setSize(0)
|
||||||
|
->setData(implode(', ', array_keys($this->itemInstances)))
|
||||||
|
->setRawData(null);
|
||||||
|
|
||||||
|
return $stat;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,63 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* This file is part of phpFastCache.
|
||||||
|
*
|
||||||
|
* @license MIT License (MIT)
|
||||||
|
*
|
||||||
|
* For full copyright and license information, please see the docs/CREDITS.txt file.
|
||||||
|
*
|
||||||
|
* @author Khoa Bui (khoaofgod) <khoaofgod@gmail.com> http://www.phpfastcache.com
|
||||||
|
* @author Georges.L (Geolim4) <contact@geolim4.com>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace phpFastCache\Drivers\Devnull;
|
||||||
|
|
||||||
|
use phpFastCache\Cache\ExtendedCacheItemInterface;
|
||||||
|
use phpFastCache\Cache\ExtendedCacheItemPoolInterface;
|
||||||
|
use phpFastCache\Cache\ItemBaseTrait;
|
||||||
|
use phpFastCache\Drivers\Devnull\Driver as DevnullDriver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Item
|
||||||
|
* @package phpFastCache\Drivers\Devnull
|
||||||
|
*/
|
||||||
|
class Item implements ExtendedCacheItemInterface
|
||||||
|
{
|
||||||
|
use ItemBaseTrait;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Item constructor.
|
||||||
|
* @param \phpFastCache\Drivers\Devnull\Driver $driver
|
||||||
|
* @param $key
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function __construct(DevnullDriver $driver, $key)
|
||||||
|
{
|
||||||
|
if (is_string($key)) {
|
||||||
|
$this->key = $key;
|
||||||
|
$this->driver = $driver;
|
||||||
|
$this->driver->setItem($this);
|
||||||
|
$this->expirationDate = new \DateTime();
|
||||||
|
} else {
|
||||||
|
throw new \InvalidArgumentException(sprintf('$key must be a string, got type "%s" instead.', gettype($key)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param ExtendedCacheItemPoolInterface $driver
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
* @return static
|
||||||
|
*/
|
||||||
|
public function setDriver(ExtendedCacheItemPoolInterface $driver)
|
||||||
|
{
|
||||||
|
if ($driver instanceof DevnullDriver) {
|
||||||
|
$this->driver = $driver;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
} else {
|
||||||
|
throw new \InvalidArgumentException('Invalid driver instance');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,138 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* This file is part of phpFastCache.
|
||||||
|
*
|
||||||
|
* @license MIT License (MIT)
|
||||||
|
*
|
||||||
|
* For full copyright and license information, please see the docs/CREDITS.txt file.
|
||||||
|
*
|
||||||
|
* @author Khoa Bui (khoaofgod) <khoaofgod@gmail.com> http://www.phpfastcache.com
|
||||||
|
* @author Georges.L (Geolim4) <contact@geolim4.com>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace phpFastCache\Drivers\Devtrue;
|
||||||
|
|
||||||
|
use phpFastCache\Core\DriverAbstract;
|
||||||
|
use phpFastCache\Core\StandardPsr6StructureTrait;
|
||||||
|
use phpFastCache\Entities\driverStatistic;
|
||||||
|
use phpFastCache\Exceptions\phpFastCacheDriverCheckException;
|
||||||
|
use phpFastCache\Exceptions\phpFastCacheDriverException;
|
||||||
|
use Psr\Cache\CacheItemInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Driver
|
||||||
|
* @package phpFastCache\Drivers
|
||||||
|
*/
|
||||||
|
class Driver extends DriverAbstract
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Driver constructor.
|
||||||
|
* @param array $config
|
||||||
|
* @throws phpFastCacheDriverException
|
||||||
|
*/
|
||||||
|
public function __construct(array $config = [])
|
||||||
|
{
|
||||||
|
$this->setup($config);
|
||||||
|
|
||||||
|
if (!$this->driverCheck()) {
|
||||||
|
throw new phpFastCacheDriverCheckException(sprintf(self::DRIVER_CHECK_FAILURE, $this->getDriverName()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function driverCheck()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \Psr\Cache\CacheItemInterface $item
|
||||||
|
* @return mixed
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
protected function driverWrite(CacheItemInterface $item)
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Check for Cross-Driver type confusion
|
||||||
|
*/
|
||||||
|
if ($item instanceof Item) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
throw new \InvalidArgumentException('Cross-Driver type confusion detected');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \Psr\Cache\CacheItemInterface $item
|
||||||
|
* @return array [
|
||||||
|
* 'd' => 'THE ITEM DATA'
|
||||||
|
* 't' => 'THE ITEM DATE EXPIRATION'
|
||||||
|
* 'g' => 'THE ITEM TAGS'
|
||||||
|
* ]
|
||||||
|
*/
|
||||||
|
protected function driverRead(CacheItemInterface $item)
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
self::DRIVER_DATA_WRAPPER_INDEX => true,
|
||||||
|
self::DRIVER_TAGS_WRAPPER_INDEX => [],
|
||||||
|
self::DRIVER_TIME_WRAPPER_INDEX => new \DateTime(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \Psr\Cache\CacheItemInterface $item
|
||||||
|
* @return bool
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
protected function driverDelete(CacheItemInterface $item)
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Check for Cross-Driver type confusion
|
||||||
|
*/
|
||||||
|
if ($item instanceof Item) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
throw new \InvalidArgumentException('Cross-Driver type confusion detected');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
protected function driverClear()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
protected function driverConnect()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************
|
||||||
|
*
|
||||||
|
* PSR-6 Extended Methods
|
||||||
|
*
|
||||||
|
*******************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return driverStatistic
|
||||||
|
*/
|
||||||
|
public function getStats()
|
||||||
|
{
|
||||||
|
$stat = new driverStatistic();
|
||||||
|
$stat->setInfo('[Devtrue] A void info string')
|
||||||
|
->setSize(0)
|
||||||
|
->setData(implode(', ', array_keys($this->itemInstances)))
|
||||||
|
->setRawData(true);
|
||||||
|
|
||||||
|
return $stat;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,63 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* This file is part of phpFastCache.
|
||||||
|
*
|
||||||
|
* @license MIT License (MIT)
|
||||||
|
*
|
||||||
|
* For full copyright and license information, please see the docs/CREDITS.txt file.
|
||||||
|
*
|
||||||
|
* @author Khoa Bui (khoaofgod) <khoaofgod@gmail.com> http://www.phpfastcache.com
|
||||||
|
* @author Georges.L (Geolim4) <contact@geolim4.com>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace phpFastCache\Drivers\Devtrue;
|
||||||
|
|
||||||
|
use phpFastCache\Cache\ExtendedCacheItemInterface;
|
||||||
|
use phpFastCache\Cache\ExtendedCacheItemPoolInterface;
|
||||||
|
use phpFastCache\Cache\ItemBaseTrait;
|
||||||
|
use phpFastCache\Drivers\Devtrue\Driver as DevtrueDriver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Item
|
||||||
|
* @package phpFastCache\Drivers\Devtrue
|
||||||
|
*/
|
||||||
|
class Item implements ExtendedCacheItemInterface
|
||||||
|
{
|
||||||
|
use ItemBaseTrait;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Item constructor.
|
||||||
|
* @param \phpFastCache\Drivers\Devtrue\Driver $driver
|
||||||
|
* @param $key
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function __construct(DevtrueDriver $driver, $key)
|
||||||
|
{
|
||||||
|
if (is_string($key)) {
|
||||||
|
$this->key = $key;
|
||||||
|
$this->driver = $driver;
|
||||||
|
$this->driver->setItem($this);
|
||||||
|
$this->expirationDate = new \DateTime();
|
||||||
|
} else {
|
||||||
|
throw new \InvalidArgumentException(sprintf('$key must be a string, got type "%s" instead.', gettype($key)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param ExtendedCacheItemPoolInterface $driver
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
* @return static
|
||||||
|
*/
|
||||||
|
public function setDriver(ExtendedCacheItemPoolInterface $driver)
|
||||||
|
{
|
||||||
|
if ($driver instanceof DevtrueDriver) {
|
||||||
|
$this->driver = $driver;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
} else {
|
||||||
|
throw new \InvalidArgumentException('Invalid driver instance');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|