Initial commit

This commit is contained in:
isUnknown 2026-02-12 15:22:46 +01:00
commit 65e0da7e11
1397 changed files with 596542 additions and 0 deletions

View file

@ -0,0 +1 @@
.imagekit-stats{width:100%}.imagekit-stats th{font-weight:400;text-align:left;white-space:nowrap;overflow:hidden}.imagekit-stats th::after{content:"";display:inline-block;width:100%;height:1px;background:currentColor;position:relative;bottom:.25em;margin-left:.35em;opacity:.2}.imagekit-stats td{padding-left:.35em;width:25%}.imagekit-action--disabled{opacity:.5;color:inherit!important;cursor:default!important}.imagekit-modal{background:rgba(255,255,255,.9);position:absolute;top:0;left:0;width:100%;height:100%;display:flex;flex-direction:column;justify-content:center;align-items:center;text-align:center;box-sizing:border-box;padding:1em 4em}.imagekit-modal p{margin-bottom:1em}.imagekit-modal p:last-child{margin-bottom:0}.imagekit-modal-buttons{padding-top:1em}.imagekit-error-icon{display:inline-block;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADgAAABACAQAAADl/nw5AAAAuElEQVR4Ae3St7nCUBQE4dMM7bxqpA5wFdCQ+iCjDfzc5PDtc3BNsDuZ3C9MxOWzbUhdUA80+KltScH1QYPLmxUwv4DB/uBEMy2iDeVtqDpoUEJHmihoSYWIDHYAZwLSoIgZ7AiWghQ0PmhQ9SUKyqLBduCefgueyOA44IF2JMHUigpQMtgPJPknCqJXiAUZ7AcqOAOlct5gPzBE8oTB4UD6M1Ay2AHMi1/2y9UHDZKAdL+/1GAl8Aq7a0QNCPzaUwAAAABJRU5ErkJggg==) 0 0/28px 32px no-repeat;width:28px;height:32px;margin-bottom:.75em}@keyframes imagekit-progress-indeterminate{0%{background-position:0 0}to{background-position:-40px 0}}.imagekit-progress{-webkit-appearance:none;-moz-appearance:none;appearance:none;width:100%;height:12px;background:#efefef;border:2px solid #000;animation:1s imagekit-progress-indeterminate linear infinite;background-size:40px 40px}.imagekit-progress::-webkit-progress-value{background:0 0}.imagekit-progress::-moz-progress-bar{background:0 0}.imagekit-progress[value]::-moz-progress-bar{background:#000}.imagekit-progress[value]::-webkit-progress-value{background:#000}.imagekit-progress:not([value]){background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFAAAABQAQAAAACmas8AAAAAiUlEQVR4Ae3MN2ECABQAUdLHSIgUpIE0pCCBjd7+Ow1suemmt9B9WqxnV3Yzu7Tb2T+7m/21h9kfe5n9sLfZN3sHt8E22AbbYBtsg22wDW6DbbANtsE22AbbYBvcBttgG2yDbbANtsE2uA22wTbYBttgG2yD7cDDBeOCccG4YFwwLhgHtv/wS+EH/ASOgIJwaM8AAAAASUVORK5CYII=);opacity:.5}.imagekit-progress[value]{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFAAAABQCAMAAAC5zwKfAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAAZQTFRF////5eXlCYLQawAAAJZJREFUeNrs1rENwEAMw0By/6UzwtsAixTWANeKOBzjnXjiiSeeeOKJJ5544okn/kw0FjEWMRYxFjEWMRYxFjEWMRYxFjEWMRYxFjEWMRYxFjEWMRYxFjEWMRYxFjEWMRYxFjEWMRYxFjEWXw+xFp8nthXfP7sUBymwEye1shJHQbURZ823EIdZOhen5TwWx3E/FT8BBgBWkgyBWPq8ewAAAABJRU5ErkJggg==)}.imagekit-progress.is-hidden,.imagekit-progress.is-hidden+.imagekit-progress-text{visibility:hidden}.imagekit-progress.is-disabled{animation-play-state:paused}.imagekit-progress-text{font-size:14px;font-style:italic}

Binary file not shown.

After

Width:  |  Height:  |  Size: 241 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 194 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 262 B

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,543 @@
(function(window, document, $) {
/* ===== Utility Functions ================================================ */
function i18n(key) {
var str = window.ImageKitSettings.translations[key];
if(str !== undefined) {
return str;
} else {
return '[' + key + ']';
}
}
function arrayUnique(array) {
var a = array.concat();
for(var i=0; i<a.length; ++i) {
for(var j=i+1; j<a.length; ++j) {
if(a[i] === a[j])
a.splice(j--, 1);
}
}
return a;
}
/* ===== ImageKit API ===================================================== */
function ImageKitAPI(options) {
var self = this,
settings = $.extend({
error: function(response) {
console.error(response.message);
},
}, options),
_running = false,
_cancelled = false;
var ACTION_CREATE = "create",
ACTION_CLEAR = "clear",
ACTION_INDEX = "index";
function api(command, callback, data, method) {
method = method || 'GET';
data = data || {};
callback = callback || function(){};
var url = settings.api + command;
return $.ajax({
url : url,
dataType : 'json',
method : method,
data : data,
success : function(response) {
callback(response);
},
error : function(xhr, status, error) {
settings.error(xhr.responseJSON);
}
});
}
function start(action) {
_running = action;
}
function stop() {
_running = false;
}
function running(running) {
if(running === undefined) {
return _running;
} else {
return (_running === running);
}
}
function status(callback) {
return api("status", callback);
}
function clear(callback) {
reset();
start(ACTION_CLEAR);
return api(ACTION_CLEAR, function(response) {
stop(ACTION_CLEAR);
callback(response.data);
});
}
function create(step, complete) {
reset();
start(ACTION_CREATE);
step = step || function(){};
complete = complete || function(){};
function doCreate() {
api(ACTION_CREATE, function (response) {
if (response.data.pending > 0 && !cancelled()) {
step(response.data);
doCreate();
} else {
stop(ACTION_CREATE);
complete(response.data);
}
});
}
doCreate();
}
function index(step, complete, error) {
reset();
start(ACTION_INDEX);
step = step || function(){};
complete = complete || function(){};
error = error || function(){};
api(ACTION_INDEX, function (response) {
var i = 0;
var pageUrls = response.data;
var triggerPageLoad = function() {
$.ajax({
url: pageUrls[i],
headers: {
"X-ImageKit-Indexing": 1,
},
success: function(response) {
if (response.data.links.length > 0) {
pageUrls = arrayUnique(pageUrls.concat(response.data.links));
}
if (++i >= pageUrls.length || cancelled()) {
stop(ACTION_INDEX);
complete({ total: pageUrls.length, status: response.data.status });
} else {
step({ current: i, total: pageUrls.length, url: pageUrls[i], status: response.data.status });
triggerPageLoad();
}
},
error: function(response) {
error(response.responseJSON);
}
});
};
triggerPageLoad();
});
}
function cancel() {
_cancelled = true;
}
function cancelled() {
return _cancelled;
}
function reset() {
_running = false;
_cancelled = false;
}
return {
status : status,
clear : clear,
create : create,
index : index,
cancel : cancel,
cancelled : cancelled,
running : running,
reset : reset,
};
}
/* ===== Progress Bar ===================================================== */
function ProgressBar() {
var progressElm = document.querySelector(".js-imagekit-progress"),
progressTextElm = document.querySelector(".js-imagekit-progress-text"),
_visible = false,
self = this,
_public = {};
function toggle(show) {
if (show === _visible) return self;
progressElm.classList[show ? "remove" : "add"]("is-hidden");
_visible = show;
return _public;
}
function disable() {
progressElm.classList.add("is-disabled");
return _public;
}
function enable() {
progressElm.classList.remove("is-disabled");
return _public;
}
function show() {
return toggle(true);
}
function hide() {
return toggle(false);
}
function value(value) {
if (value !== null && value !== false) {
progressElm.setAttribute("value", value);
} else {
progressElm.removeAttribute("value");
}
return _public;
}
function text(msg) {
if (msg) {
progressTextElm.innerHTML = msg;
return _public;
} else {
return progressTextElm.innerHTML;
}
}
_public = {
show : show,
hide : hide,
value : value,
text : text,
enable : enable,
disable : disable,
};
return _public;
}
/* ===== Actions ========================================================== */
function Actions() {
var _public = {},
actions = {
clear: {
element: $('[href="#imagekit-action-clear"]'),
icon: $('[href="#imagekit-action-clear"] i'),
},
create: {
element: $('[href="#imagekit-action-create"]'),
icon: $('[href="#imagekit-action-create"] i'),
}
};
function disable(action) {
if(action) {
actions[action].element.addClass("imagekit-action--disabled");
} else {
$.each(actions, function() { this.element.addClass("imagekit-action--disabled"); });
}
return _public;
}
function enable(action) {
if(action) {
actions[action].element.removeClass("imagekit-action--disabled");
} else {
$.each(actions, function() { this.element.removeClass("imagekit-action--disabled"); });
}
return _public;
}
function icon(action, oldClass, newClass) {
var elm = actions[action].icon;
elm.removeClass(oldClass);
elm.addClass(newClass);
return _public;
}
function register(action, callback) {
actions[action].element.click(function(e) {
e.preventDefault();
callback();
});
return _public;
}
_public = {
disable : disable,
enable : enable,
icon : icon,
register : register,
};
return _public;
}
/* ===== ImageKit Widget ================================================== */
function Widget(options) {
var settings = options,
api = new ImageKitAPI($.extend(ImageKitSettings, {
error: function(response) {
error(response.message);
}
})),
actions = new Actions(),
infoElm = document.querySelector(".js-imagekit-info"),
createdElm = document.querySelector(".js-imagekit-created"),
pendingElm = document.querySelector(".js-imagekit-pending"),
progress = new ProgressBar();
/* ----- Internal Interface Methods --------------------------------------- */
function updateStatus(status) {
createdElm.innerHTML = status.created;
pendingElm.innerHTML = status.pending;
}
function error(message, onClose) {
onClose = onClose || false;
actions.disable();
progress.disable();
var $overlay = $("<div/>").addClass("imagekit-modal");
$overlay.append('<i class="imagekit-error-icon">'); // fa fa-exclamation-triangle fa-2x
$overlay.append($('<p/>').html(message));
$("#imagekit-widget").append($overlay);
if(onClose) {
$overlay.append($('<a href="#" class="btn btn-rounded">OK</a>').click(function() {
$overlay.remove();
api.reset();
progress.hide();
actions.enable().icon("create", "fa-stop-circle-o", "fa-play-circle-o");
status();
onClose();
}));
}
}
function confirm(message, onClose) {
var $overlay = $("<div/>").addClass("imagekit-modal"),
esc,
close;
$overlay.append($('<p/>').html(message));
$("#imagekit-widget").append($overlay);
esc = function(e) {
if("key" in e ? (e.key == "Escape" || e.key == "Esc") : (e.keyCode == 27)) {
close(false);
} else if ("key" in e ? e.key == "Enter" : e.key == 13) {
close(true);
}
};
close = function(result) {
$overlay.remove();
onClose(result);
document.removeEventListener("keydown", esc);
};
var $buttons = $('<p class="imagekit-modal-buttons"/>');
$buttons.append($('<a href="#" class="btn btn-rounded">' + i18n('cancel') + '</a>').click(function() { close(false); } ));
$buttons.append("&nbsp;&nbsp;&nbsp;");
$buttons.append($('<a href="#" class="btn btn-rounded">' + i18n('ok') + '</a>').click(function() { close(true); } ));
$overlay.append($buttons);
document.addEventListener("keydown", esc);
}
/* ----- Widget Actions --------------------------------------------------- */
function status() {
if(api.running()) return;
api.status(function(result) {
updateStatus(result.data);
});
}
function clear() {
if(api.running()) return;
confirm(i18n('imagekit.widget.clear.confirm'), function(confirmed) {
if(confirmed) {
actions.disable();
progress
.value(false)
.text(i18n("imagekit.widget.progress.clearing"))
.show();
api.clear(function(status) {
progress.hide();
actions.enable();
updateStatus(status);
});
}
});
// if(window.confirm(i18n('imagekit.widget.clear.confirm'))) {
// actions.disable();
// progress
// .value(false)
// .text(i18n("imagekit.widget.progress.clearing"))
// .show();
// api.clear(function(status) {
// progress.hide();
// actions.enable();
// updateStatus(status);
// });
// }
}
function index(callback) {
callback = callback || function(){};
progress.text(i18n("imagekit.widget.progress.scanning"));
api.index(function (result) {
// step
progress
.value(result.current / result.total)
.text(i18n("imagekit.widget.progress.scanning") + " " + result.current + "/" + result.total);
updateStatus(result.status);
}, function (result) {
// complete
progress
.value(1)
.text(i18n("imagekit.widget.progress.scanned"));
updateStatus(result.status);
callback();
}, function (result) {
// error
error(result.message, function() {
});
});
}
function create(callback) {
callback = callback || function(){};
progress
.value(false)
.text(i18n('imagekit.widget.progress.creating'));
api.create(function (result) {
// step
var total = result.pending + result.created;
progress.value(result.created / total);
updateStatus(result);
}, function (result) {
// complete
progress.value(1);
updateStatus(result);
callback();
});
}
function run() {
actions
.disable("clear")
.icon("create", "fa-play-circle-o", "fa-stop-circle-o");
progress
.value(false)
.show();
function complete() {
progress.hide();
actions
.enable()
.icon("create", "fa-stop-circle-o", "fa-play-circle-o");
}
if (ImageKitSettings.discover) {
index(function() {
if(!api.cancelled()) {
create(complete);
} else {
complete();
}
});
} else {
create(complete);
}
}
function stop() {
if (api.running("index") || api.running("create")) {
actions.disable();
progress
.value(false)
.text(i18n('imagekit.widget.progress.cancelling'));
api.cancel();
return;
}
}
actions.register("clear", clear);
actions.register("create", function() {
if (!api.running()) {
run();
} else {
stop();
}
});
return {
status : status,
};
}
$(function() {
var widget = new Widget();
widget.status();
});
})(window, document, jQuery);

View file

@ -0,0 +1,131 @@
.imagekit-stats {
width: 100%;
th {
font-weight: normal;
text-align: left;
white-space: nowrap;
overflow: hidden;
&::after {
content: "";
display: inline-block;
width: 100%;
height: 1px;
background: currentColor;
position: relative;
bottom: .25em;
margin-left: .35em;
opacity: .2;
}
}
td {
padding-left: .35em;
width: 25%;
}
}
.imagekit-action--disabled {
opacity: .5;
color: inherit !important;
cursor: default !important;
}
.imagekit-modal {
background: rgba(#fff, .9);
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
box-sizing: border-box;
padding: 1em 4em;
p {
margin-bottom: 1em;
&:last-child {
margin-bottom: 0;
}
}
}
.imagekit-modal-buttons {
padding-top: 1em;
}
.imagekit-error-icon {
display: inline-block;
background: inline('../images/icon-error@2x.png') 0 0 / 28px 32px no-repeat;
width: 28px;
height: 32px;
margin-bottom: .75em;
}
@keyframes imagekit-progress-indeterminate {
0% { background-position: 0 0; }
100% { background-position: -40px 0; }
}
.imagekit-progress {
/* Reset the default appearance */
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
width: 100%;
height: 12px;
background: #efefef;
border: 2px solid #000;
animation: 1s imagekit-progress-indeterminate linear infinite;
background-size: 40px 40px;
&::-webkit-progress-value {
background: transparent;
}
&::-moz-progress-bar {
background: transparent;
}
&[value]::-moz-progress-bar {
background: #000;
}
&[value]::-webkit-progress-value {
background: #000;
}
&:not([value]) {
background-image: inline('../images/progress-indeterminate@2x.png');
opacity: .5;
}
&[value] {
background-image: inline('../images/progress-running@2x.png')
}
&.is-hidden {
visibility: hidden;
}
&.is-disabled {
animation-play-state: paused;
}
}
.imagekit-progress-text {
font-size: 14px;
font-style: italic;
.imagekit-progress.is-hidden + & {
visibility: hidden;
}
}

View file

@ -0,0 +1,16 @@
<?php
namespace Kirby\Plugins\ImageKit\Widget;
load([
'kirby\\plugins\\imagekit\\widget\\widget' => 'lib' . DS . 'widget.php',
'kirby\\plugins\\imagekit\\widget\\translations' => 'lib' . DS . 'translations.php',
'kirby\\plugins\\imagekit\\widget\\api' => 'lib' . DS . 'api.php',
'kirby\\plugins\\imagekit\\widget\\apicrawlerresponse' => 'lib' . DS . 'apicrawlerresponse.php',
], __DIR__);
// Initialize Widget and API
Widget::instance();
API::instance();

View file

@ -0,0 +1,48 @@
<style><?= f::read(__DIR__ . '/assets/css/widget.min.css') ?></style>
<div class="dashboard-box">
<div class="js-imagekit-info / text">
<table class="imagekit-stats">
<tr>
<th><?= $translations->get('imagekit.widget.status.pending') ?></th>
<td class="js-imagekit-pending"></td>
</tr>
<tr>
<th><?= $translations->get('imagekit.widget.status.created') ?></th>
<td class="js-imagekit-created"></td>
</tr>
</table>
</div>
</div>
<progress class="imagekit-progress is-hidden / js-imagekit-progress"></progress>
<p class="marginalia imagekit-progress-text / js-imagekit-progress-text"></span>
</p>
<?php if (imagekit()->license()->type === 'trial'): ?>
<p class="debug-warning marginalia" style="position: relative; padding-left: 30px; font-size: 14px; padding-top: 12px;">
<span class="fa fa-exclamation-triangle" style="position: absolute; top: 15px; left: 5px; font-size: 14px;"></span>
<?php printf($translations->get('imagekit.widget.license.trial'), 'http://sites.fastspring.com/fabianmichael/product/imagekit') ?>
</p>
<?php endif ?>
<script>
<?php
echo 'window.ImageKitSettings = ' . json_encode([
'api' => kirby()->urls()->index() . '/plugins/imagekit/widget/api/',
'translations' => array_merge(
$translations->get(), [
'cancel' => i18n('cancel'),
'ok' => i18n('ok'),
]),
'discover' => kirby()->option('imagekit.widget.discover'),
]) . ';';
if(kirby()->option('imagekit.debug')) {
echo f::read(__DIR__ . '/assets/js/src/widget.js');
} else {
echo f::read(__DIR__ . '/assets/js/dist/widget.min.js');
}
?>
</script>

View file

@ -0,0 +1,32 @@
<?php
namespace Kirby\Plugins\ImageKit\Widget;
use Tpl;
$translations = Translations::load();
return [
'title' => [
'text' => $translations->get('imagekit.widget.title'),
],
'options' => [
[
'text' => $translations->get('imagekit.widget.action.clear'),
'icon' => 'trash-o',
'link' => '#imagekit-action-clear',
],
[
'text' => $translations->get('imagekit.widget.action.create'),
'icon' => 'play-circle-o',
'link' => '#imagekit-action-create',
],
],
'html' => function() use ($translations) {
return tpl::load(__DIR__ . DS . 'imagekit.html.php', compact('translations'));
}
];

View file

@ -0,0 +1,122 @@
<?php
namespace Kirby\Plugins\ImageKit\Widget;
use Response;
use Exception;
use Kirby\Plugins\ImageKit\LazyThumb;
use Kirby\Plugins\ImageKit\ComplainingThumb;
use Whoops\Handler\Handler;
use Whoops\Handler\CallbackHandler;
class API {
public $kirby;
public static function instance() {
static $instance;
return $instance ?: $instance = new static();
}
protected function __construct() {
$self = $this;
$this->kirby = kirby();
$this->kirby->set('route', [
'pattern' => 'plugins/imagekit/widget/api/(:any)',
'action' => function($action) use ($self) {
if($error = $this->authorize()) {
return $error;
}
if(method_exists($self, $action)) {
return $this->$action();
} else {
throw new Exception('Invalid plugin action. The action "' . html($action) . '" is not defined.');
}
},
]);
if(isset($_SERVER['HTTP_X_IMAGEKIT_INDEXING'])) {
// Handle indexing request (discovery feature).
$this->handleCrawlerRequest();
}
}
protected function authorize() {
$user = kirby()->site()->user();
if (!$user || !$user->hasPanelAccess()) {
throw new Exception('Only logged-in users can use the ImageKit widget. Please reload this page to go to the login form.');
}
}
protected function handleCrawlerRequest() {
if($error = $this->authorize()) {
return $error;
}
if($this->kirby->option('representations.accept')) {
throw new Exception('ImageKits discover mode does currently not work, when the <code>representations.accept</code> setting is turned on. Please disable either this setting or disable <code>imagekit.widget.discover</code>.');
}
kirby()->set('component', 'response', '\\kirby\\plugins\\imagekit\\widget\\apicrawlerresponse');
}
public function status() {
return Response::success(true, lazythumb::status());
}
public function clear() {
return Response::success(lazythumb::clear(), lazythumb::status());
}
public function create() {
$pending = lazythumb::pending();
$step = kirby()->option('imagekit.widget.step');
// Always complain when trying to create thumbs from the widget
complainingthumb::enableSendError();
complainingthumb::setErrorFormat('json');
for($i = 0; $i < sizeof($pending) && $i < $step; $i++) {
lazythumb::process($pending[$i]);
}
return Response::success(true, lazythumb::status());
}
public function index() {
$index = [];
$this->kirby->cache()->flush();
$site = site();
$isMultilang = $site->multilang() && $site->languages()->count() > 1;
if($isMultilang) {
$languageCodes = [];
foreach($site->languages() as $language) {
$languageCodes[] = $language->code();
}
}
foreach($site->index() as $page) {
if($isMultilang) {
foreach($languageCodes as $code) {
$index[] = $page->url($code);
}
} else {
$index[] = $page->url();
}
}
return Response::success(true, $index);
}
}

View file

@ -0,0 +1,89 @@
<?php
namespace Kirby\Plugins\ImageKit\Widget;
use Exception;
use DOMDocument;
use Kirby;
use Response;
use Kirby\Plugins\ImageKit\LazyThumb;
use Url;
use V;
class APICrawlerResponse extends \Kirby\Component\Response {
public function __construct(Kirby $kirby) {
parent::__construct($kirby);
// Register listeners for redirects
header_register_callback([$this,'detectRedirectRequest']);
register_shutdown_function([$this,'detectRedirectRequest']);
}
public function detectRedirectRequest() {
// Redirects should be ignored by the widget, so
// override a redirect and just return a valid json
// response.
$redirect = in_array(http_response_code(), [301, 302, 303, 304, 307]);
$sent = headers_sent();
if($redirect && !$sent) {
header_remove('location');
echo Response::success(true, [
'links' => [],
'status' => LazyThumb::status(),
]);
exit;
}
}
public function make($response) {
// Try to generate response by calling Kirbys native
// respionse component.
$html = parent::make($response);
if(!class_exists('\DOMDocument')) {
throw new Exception('The discovery feature of ImageKit needs PHP with the <strong>libxml</strong> extension to run.');
}
$links = [];
try {
$doc = new DOMDocument();
libxml_use_internal_errors(true);
$doc->loadHTML($html);
libxml_clear_errors();
$elements = array_merge(
iterator_to_array($doc->getElementsByTagName('a')),
iterator_to_array($doc->getElementsByTagName('link'))
);
foreach($elements as $elm) {
$rel = $elm->getAttribute('rel');
if($rel === 'next' || $rel === 'prev') {
$href = $elm->getAttribute('href');
if(v::url($href) && url::host($href) === url::host()) {
// Only add, if href is either a URL on the same
// domain as the API call was made to, as links
// could possibly link to sth. like `#page2` or
// `javascript:;` on AJAX-powered websites.
$links[] = $href;
}
}
}
} catch(Exception $e) {
return Response::error($e->getMessage(), 500);
}
return Response::success(true, [
'links' => array_unique($links),
'status' => LazyThumb::status(),
]);
}
}

View file

@ -0,0 +1,52 @@
<?php
namespace Kirby\Plugins\ImageKit\Widget;
/**
* A very simple translations class, which can load an
* associative PHP array of language strings.
*/
class Translations {
protected static $cache;
protected $translations = [];
public function __construct($code = 'en') {
$language_directory = dirname(__DIR__) . DS . 'translations';
if ($code !== 'en') {
if (!preg_match('/^[a-z]{2}([_-][a-z0-9]{2,})?$/i', $code) ||
!file_exists($language_directory . DS . $code . '.php')) {
// Set to fallback language, if not a valid code or no translation available.
$code = 'en';
}
}
$this->translations = require($language_directory . DS . $code . '.php');
}
public function get($key = null) {
if(is_null($key)) {
return $this->translations;
} else if (isset($this->translations[$key])) {
return $this->translations[$key];
} else {
return '[missing translation: ' . $key . ']';
}
}
public static function load($code = null) {
if(is_null($code)) {
$code = panel()->translation()->code();
}
if (!isset(static::$cache[$code])) {
static::$cache[$code] = new static($code);
}
return static::$cache[$code];
}
}

View file

@ -0,0 +1,20 @@
<?php
namespace Kirby\Plugins\ImageKit\Widget;
class Widget {
public static function instance() {
static $instance;
return $instance ?: $instance = new static();
}
protected function __construct() {
$kirby = kirby();
// Register the Widget
$kirby->set('widget', 'imagekit', dirname(__DIR__));
}
}

View file

@ -0,0 +1,20 @@
<?php
return [
'imagekit.widget.title' => 'Thumbnails',
'imagekit.widget.action.create' => 'Erstellen',
'imagekit.widget.action.clear' => 'Löschen',
'imagekit.widget.clear.confirm' => 'Sollen wirklich alle Thumbnails glöscht werden? Dies löscht alle Dateien im Ordner thumbs.',
'imagekit.widget.status.pending' => 'In Warteschlange',
'imagekit.widget.status.created' => 'Erstellt',
'imagekit.widget.progress.clearing' => 'Lösche thumbnails …',
'imagekit.widget.progress.scanning' => 'Durchsuche alle Seiten …',
'imagekit.widget.progress.scanned' => 'Suche abgeschlossen',
'imagekit.widget.progress.creating' => 'Erstelle thumbnails …',
'imagekit.widget.progress.cancelling' => 'Vorgang wird abgebrochen …',
'imagekit.widget.license.trial' => 'ImageKit läuft im Testmodus. Bitte unterstützen Sie die Entwicklung des plugins und <a href="%s" target="_blank">kaufen Sie eine Lizenz</a>. Wenn Sie bereits einen Lizenzschlüssel haben, tragen Sie ihn bitte in die Datei <code title="site/config/config.php" style="border-bottom: 1px dotted; font-family: monospace;">config.php</code> ein.',
];

View file

@ -0,0 +1,20 @@
<?php
return [
'imagekit.widget.title' => 'Thumbnails',
'imagekit.widget.action.create' => 'Create',
'imagekit.widget.action.clear' => 'Clear',
'imagekit.widget.clear.confirm' => 'Do you really want to clear your thumbnails? This will delete all files in your thumbs folder.',
'imagekit.widget.status.pending' => 'Pending',
'imagekit.widget.status.created' => 'Created',
'imagekit.widget.progress.clearing' => 'Clearing thumbs folder …',
'imagekit.widget.progress.scanning' => 'Scanning pages …',
'imagekit.widget.progress.scanned' => 'Scan complete',
'imagekit.widget.progress.creating' => 'Creating thumbnails …',
'imagekit.widget.progress.cancelling' => 'Cancelling …',
'imagekit.widget.license.trial' => 'ImageKit is running in trial mode. Please support the development of this plugin and <a href="%s" target="_blank">buy a license</a>. If you already have a license key, please add it to your <code title="site/config/config.php" style="border-bottom: 1px dotted; font-family: monospace;">config.php</code> file.',
];