diff --git a/README.md b/README.md
index 5907010..a8cb1bd 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,102 @@
-# Leilukin's Tumbleblog
+[English](README.md), [Deutsch](README_de_DE.md), [Italiano](README_it_IT.md), [한국인](README_ko_KR.md), [Nederlands](README_nl_NL.md), [简体中文](README_zh_CN.md).
-Leilukin's tumbleblog. Built with [Chyrp Lite](https://chyrplite.net/).
+## What can Chyrp Lite do for me?
-I have made changes to the code to suit my purposes:
-- Added my own favicon
-- Added the Lexend and Intel One Mono typefaces
-- Created my custom blog theme based on the Umbra theme
\ No newline at end of file
+Chyrp Lite makes it possible to host a blog on your own web server with minimal fuss. You can have
+a traditional blog, a tumbleblog, or you can add oodles of customisation and build a general-purpose
+web publishing platform with blogging features on the side. You get five beautiful blog themes and
+a friendly administration console, all fully navigable on a broad range of devices, thanks to the
+power of responsive HTML5. Semantic markup and comprehensive ARIA labelling ensure your blog will be
+accessible to visitors who use assistive technologies.
+
+With a flexible system of Feathers and Pages, you can make your website whatever you want it to be.
+Feathers enable different types of blog content – you can restrict yourself to absolute textual purity,
+or you can create a multimedia rainbow. Pages let you publish articles separate from your blog content
+– be it a simple colophon or a hierarchy of multiple pages, optionally including a homepage that your
+visitors will see when they first arrive at your website.
+
+## What are the key features?
+
+#### Core:
+* Easy to install, simple to maintain, extensible by design.
+* Built with responsive and accessible W3C-validated HTML5.
+* Universal support for plain text, Markdown, or raw markup.
+* Personalise your blog using powerful extensions.
+* Theme development is easy with the Twig template engine.
+* Manage users and visitors with a comprehensive rights model.
+
+#### Feathers:
+* Text: write textual blog entries.
+* Photo: upload an image.
+* Quote: make a quotation.
+* Link: link to another website.
+* Video: upload a video file.
+* Audio: upload an audio file.
+* Uploader: upload multiple files.
+
+#### Modules:
+* Cacher: cache your blog pages for reduced server load.
+* Categorize: give each of your blog entries a category.
+* Tags: apply multiple searchable tags to your blog entries.
+* Mentionable: register webmentions from blogs that link to yours.
+* Comments: a comprehensive comments system for your blog.
+* Likes: allow your visitors to show their appreciation.
+* Read More: excerpt long blog entries on the blog index.
+* Rights: set attribution and copyright/left for your entries.
+* Cascade: ajax-powered infinite scrolling for your blog.
+* Lightbox: on-page image viewer with image protection.
+* Sitemap: index your blog for search engines.
+* MAPTCHA: use simple mathematics problems to prevent spam.
+* Highlighter: syntax highlighting for your code snippets.
+* Easy Embed: the easiest way to embed videos in your blog.
+* Post Views: maintain a view count for your blog entries.
+* MathJax: a JavaScript display engine for mathematics.
+
+## Requirements
+
+* [PHP 8.0+](https://www.php.net/supported-versions.php) with default extensions (Session, JSON, Ctype, Filter, libxml, SimpleXML)
+* [Multibyte String](https://www.php.net/manual/en/book.mbstring.php)
+* [PDO](https://www.php.net/manual/en/book.pdo.php)
+* [cURL](https://www.php.net/manual/en/book.curl.php)
+* MySQL 5.7+
+* SQLite 3+
+* PostgreSQL 10+
+
+## Installation
+
+You can install Chyrp Lite in three steps:
+
+1. If using MySQL, create a MySQL database with a username and password.
+2. Download the [latest release](https://github.com/xenocrat/chyrp-lite/releases), unzip, and upload to your web server.
+3. Run the installation process by visiting [install.php](install.php) in your web browser.
+
+## Upgrading
+
+You can upgrade Chyrp Lite in six steps:
+
+1. __Backup your database before proceeding!__
+2. Download the latest version of Chyrp Lite.
+3. Move your _uploads_ folder and _includes/config.json.php_ somewhere safe.
+4. Overwrite your current version with the new one.
+5. Restore your _uploads_ folder and _includes/config.json.php_.
+6. Run the upgrade process by visiting [upgrade.php](upgrade.php) in your web browser.
+
+## Documentation
+
+The Chyrp Lite [wiki](https://chyrplite.net/wiki/) has comprehensive documentation
+for users and developers.
+
+## Authors
+
+Chyrp Lite was created by the following people:
+
+* Lite Developer: Daniel Pimley
+* Chyrp Developer: Arian Xhezairi
+* Project Founder: Alex Suraci
+* Module authors and other contributors.
+
+## Licenses
+
+Chyrp Lite is Copyright 2008-2024 Alex Suraci, Arian Xhezairi, Daniel Pimley, and other contributors,
+distributed under the [BSD license](https://raw.githubusercontent.com/xenocrat/chyrp-lite/master/LICENSE.md).
+Please see the [licenses](licenses) directory for the full license text of all software packages distributed with Chyrp Lite.
\ No newline at end of file
diff --git a/admin/javascripts/admin.js.php b/admin/javascripts/admin.js.php
index 1c3b05c..8472b01 100644
--- a/admin/javascripts/admin.js.php
+++ b/admin/javascripts/admin.js.php
@@ -70,11 +70,11 @@ function toggle_all() {
}
// Validates slug fields.
function validate_slug() {
- $("input[name='slug']").keyup(
+ $("input[pattern='^[a-z0-9\\\\-]*$']").keyup(
function(e) {
var slug = $(this).val();
- if (/^([a-z0-9\-]*)$/.test(slug))
+ if (/^[a-z0-9\-]*$/.test(slug))
$(this).removeClass("error");
else
$(this).addClass("error");
@@ -213,7 +213,7 @@ function test_uploads() {
if (file.size > Uploads.limit) {
e.target.value = null;
- alert(Uploads.message);
+ alert(Uploads.messages.size_err);
break;
}
}
@@ -240,7 +240,12 @@ var Oops = {
}
var Uploads = {
limit: uploads_limit * 1000000)); ?>,
- message: 'uploads_limit)); ?>',
+ messages: {
+ send_msg: '',
+ send_err: '',
+ type_err: '',
+ size_err: 'uploads_limit, "admin")); ?>'
+ },
active: 0,
send: function(file, doneCallback, failCallback, alwaysCallback) {
Uploads.active++;
@@ -672,14 +677,20 @@ var Write = {
if (!!e.target.files && e.target.files.length > 0) {
var file = e.target.files[0];
- // Reject files too large to upload.
- if (file.size > Uploads.limit) {
- e.target.value = null;
- tray.html(Uploads.message);
+ // Reject files that are not images.
+ if (file.type.indexOf("image/") != 0) {
+ tray.html(Uploads.messages.type_err);
return;
}
- tray.loader().html('');
+ // Reject files too large to upload.
+ if (file.size > Uploads.limit) {
+ e.target.value = null;
+ tray.html(Uploads.messages.size_err);
+ return;
+ }
+
+ tray.loader().html(Uploads.messages.send_msg);
// Upload the file and insert the tag if successful.
Uploads.send(
@@ -688,7 +699,7 @@ var Write = {
Write.formatting(target, "img", response.data.url);
},
function(response) {
- tray.html(Oops.message);
+ tray.html(Uploads.messages.send_err);
},
function(response) {
tray.loader(true);
@@ -918,30 +929,34 @@ var Write = {
var form = new FormData();
var tray = $("#" + $(e.target).attr("id") + "_tray");
- if (file.type.indexOf("image/") == 0) {
- // Reject files too large to upload.
- if (file.size > Uploads.limit) {
- tray.html(Uploads.message);
- return;
- }
-
- tray.loader().html('');
-
- // Upload the file and insert the tag if successful.
- Uploads.send(
- file,
- function(response) {
- Write.formatting($(e.target), "img", response.data.url);
- },
- function(response) {
- tray.html(Oops.message);
- },
- function(response) {
- tray.loader(true);
- $(e.target).removeClass("drag_highlight");
- }
- );
+ // Reject files that are not images.
+ if (file.type.indexOf("image/") != 0) {
+ tray.html(Uploads.messages.type_err);
+ return;
}
+
+ // Reject files too large to upload.
+ if (file.size > Uploads.limit) {
+ tray.html(Uploads.messages.size_err);
+ return;
+ }
+
+ tray.loader().html(Uploads.messages.send_msg);
+
+ // Upload the file and insert the tag if successful.
+ Uploads.send(
+ file,
+ function(response) {
+ Write.formatting($(e.target), "img", response.data.url);
+ },
+ function(response) {
+ tray.html(Uploads.messages.send_err);
+ },
+ function(response) {
+ tray.loader(true);
+ $(e.target).removeClass("drag_highlight");
+ }
+ );
}
},
formatting: function(target, effect, fragment = "") {
diff --git a/admin/layouts/default.twig b/admin/layouts/default.twig
index 6151ab2..6d34746 100644
--- a/admin/layouts/default.twig
+++ b/admin/layouts/default.twig
@@ -14,10 +14,9 @@
{{- " | " -}}
{{- site.name | fix -}}
-
-
-
-
+
+
+
{% if site.monospace_font %}
diff --git a/admin/locale/de_DE/LC_MESSAGES/admin.mo b/admin/locale/de_DE/LC_MESSAGES/admin.mo
index 700c97a..99befe0 100644
Binary files a/admin/locale/de_DE/LC_MESSAGES/admin.mo and b/admin/locale/de_DE/LC_MESSAGES/admin.mo differ
diff --git a/admin/locale/de_DE/LC_MESSAGES/admin.po b/admin/locale/de_DE/LC_MESSAGES/admin.po
index 93a2636..77611ab 100644
--- a/admin/locale/de_DE/LC_MESSAGES/admin.po
+++ b/admin/locale/de_DE/LC_MESSAGES/admin.po
@@ -116,7 +116,7 @@ msgid "## Heading"
msgstr "## Kopf"
#: admin/help/markdown.twig:20 admin/help/markdown.twig:24
-#: admin/javascripts/admin.js.php:450 admin/javascripts/admin.js.php:451
+#: admin/javascripts/admin.js.php:455 admin/javascripts/admin.js.php:456
msgid "Heading"
msgstr "Kopf"
@@ -128,8 +128,8 @@ msgstr "### Kopf"
msgid "**Strong**"
msgstr "**Stark**"
-#: admin/help/markdown.twig:28 admin/javascripts/admin.js.php:475
-#: admin/javascripts/admin.js.php:476
+#: admin/help/markdown.twig:28 admin/javascripts/admin.js.php:480
+#: admin/javascripts/admin.js.php:481
msgid "Strong"
msgstr "Stark"
@@ -137,8 +137,8 @@ msgstr "Stark"
msgid "*Emphasis*"
msgstr "*Schwerpunkt*"
-#: admin/help/markdown.twig:32 admin/javascripts/admin.js.php:500
-#: admin/javascripts/admin.js.php:501
+#: admin/help/markdown.twig:32 admin/javascripts/admin.js.php:505
+#: admin/javascripts/admin.js.php:506
msgid "Emphasis"
msgstr "Schwerpunkt"
@@ -154,8 +154,8 @@ msgstr "Zitat"
msgid "~~Strikethrough~~"
msgstr "~~Durchgestrichen~~"
-#: admin/help/markdown.twig:40 admin/javascripts/admin.js.php:525
-#: admin/javascripts/admin.js.php:526
+#: admin/help/markdown.twig:40 admin/javascripts/admin.js.php:530
+#: admin/javascripts/admin.js.php:531
msgid "Strikethrough"
msgstr "Durchgestrichen"
@@ -163,8 +163,8 @@ msgstr "Durchgestrichen"
msgid "`Code`"
msgstr "`Code`"
-#: admin/help/markdown.twig:44 admin/javascripts/admin.js.php:575
-#: admin/javascripts/admin.js.php:576
+#: admin/help/markdown.twig:44 admin/javascripts/admin.js.php:580
+#: admin/javascripts/admin.js.php:581
msgid "Code"
msgstr "Code"
@@ -172,8 +172,8 @@ msgstr "Code"
msgid "==Highlight=="
msgstr "==Markieren=="
-#: admin/help/markdown.twig:48 admin/javascripts/admin.js.php:550
-#: admin/javascripts/admin.js.php:551
+#: admin/help/markdown.twig:48 admin/javascripts/admin.js.php:555
+#: admin/javascripts/admin.js.php:556
msgid "Highlight"
msgstr "Markieren"
@@ -205,8 +205,8 @@ msgstr "Neuer Absatz"
msgid "[title](URL)"
msgstr "[title](URL)"
-#: admin/help/markdown.twig:65 admin/javascripts/admin.js.php:600
-#: admin/javascripts/admin.js.php:601
+#: admin/help/markdown.twig:65 admin/javascripts/admin.js.php:605
+#: admin/javascripts/admin.js.php:606
msgid "Hyperlink"
msgstr "Hyperlink"
@@ -214,8 +214,8 @@ msgstr "Hyperlink"
msgid "![description](URL)"
msgstr "![description](URL)"
-#: admin/help/markdown.twig:69 admin/javascripts/admin.js.php:625
-#: admin/javascripts/admin.js.php:626
+#: admin/help/markdown.twig:69 admin/javascripts/admin.js.php:630
+#: admin/javascripts/admin.js.php:631
msgid "Image"
msgstr "Bild"
@@ -332,91 +332,104 @@ msgstr "Alle umschalten"
msgid "Are you sure you want to proceed?"
msgstr "Sind Sie sicher, dass Sie fortfahren möchten?"
-#: admin/javascripts/admin.js.php:295 admin/javascripts/admin.js.php:383
-#: admin/javascripts/admin.js.php:1171
-msgid "Modal window"
-msgstr "Modales Fenster"
-
-#: admin/javascripts/admin.js.php:304 admin/pages/manage_uploads.twig:18
-msgid "Uploads"
-msgstr "Hochladungen"
-
-#: admin/javascripts/admin.js.php:330 admin/javascripts/admin.js.php:409
-#: admin/javascripts/admin.js.php:1199
-msgid "Close"
-msgstr "Schliessen"
-
-#: admin/javascripts/admin.js.php:344 admin/javascripts/admin.js.php:423
-#: admin/javascripts/admin.js.php:1213
-msgid "close"
-msgstr "schliessen"
-
-#: admin/javascripts/admin.js.php:392
-msgid "Help content"
-msgstr "Hilfe inhalte"
-
-#: admin/javascripts/admin.js.php:464
-msgid "heading"
-msgstr "kopf"
-
-#: admin/javascripts/admin.js.php:489
-msgid "strong"
-msgstr "stark"
-
-#: admin/javascripts/admin.js.php:514
-msgid "emphasis"
-msgstr "schwerpunkt"
-
-#: admin/javascripts/admin.js.php:539
-msgid "strikethrough"
-msgstr "durchgestrichen"
-
-#: admin/javascripts/admin.js.php:564
-msgid "highlight"
-msgstr "markieren"
-
-#: admin/javascripts/admin.js.php:589
-msgid "code"
-msgstr "code"
-
-#: admin/javascripts/admin.js.php:614
-msgid "hyperlink"
-msgstr "hyperlink"
-
-#: admin/javascripts/admin.js.php:639 admin/javascripts/admin.js.php:705
-msgid "image"
-msgstr "bild"
-
-#: admin/javascripts/admin.js.php:654 admin/javascripts/admin.js.php:655
-msgid "Upload"
-msgstr "Hochladen"
-
-#: admin/javascripts/admin.js.php:682 admin/javascripts/admin.js.php:928
+#: admin/javascripts/admin.js.php:244
msgid "Uploading..."
msgstr "Hochladen..."
-#: admin/javascripts/admin.js.php:718 admin/javascripts/admin.js.php:719
+#: admin/javascripts/admin.js.php:245
+msgid "File upload failed!"
+msgstr "Datei-Upload fehlgeschlagen!"
+
+#: admin/javascripts/admin.js.php:246
+msgid "File type not supported!"
+msgstr "Dateityp wird nicht unterstützt!"
+
+#: admin/javascripts/admin.js.php:247
+#, php-format
+msgid "Maximum file size: %d Megabytes!"
+msgstr "Maximale Dateigröße: %d Megabyte!"
+
+#: admin/javascripts/admin.js.php:300 admin/javascripts/admin.js.php:388
+#: admin/javascripts/admin.js.php:1186
+msgid "Modal window"
+msgstr "Modales Fenster"
+
+#: admin/javascripts/admin.js.php:309 admin/pages/manage_uploads.twig:18
+msgid "Uploads"
+msgstr "Hochladungen"
+
+#: admin/javascripts/admin.js.php:335 admin/javascripts/admin.js.php:414
+#: admin/javascripts/admin.js.php:1214
+msgid "Close"
+msgstr "Schliessen"
+
+#: admin/javascripts/admin.js.php:349 admin/javascripts/admin.js.php:428
+#: admin/javascripts/admin.js.php:1228
+msgid "close"
+msgstr "schliessen"
+
+#: admin/javascripts/admin.js.php:397
+msgid "Help content"
+msgstr "Hilfe inhalte"
+
+#: admin/javascripts/admin.js.php:469
+msgid "heading"
+msgstr "kopf"
+
+#: admin/javascripts/admin.js.php:494
+msgid "strong"
+msgstr "stark"
+
+#: admin/javascripts/admin.js.php:519
+msgid "emphasis"
+msgstr "schwerpunkt"
+
+#: admin/javascripts/admin.js.php:544
+msgid "strikethrough"
+msgstr "durchgestrichen"
+
+#: admin/javascripts/admin.js.php:569
+msgid "highlight"
+msgstr "markieren"
+
+#: admin/javascripts/admin.js.php:594
+msgid "code"
+msgstr "code"
+
+#: admin/javascripts/admin.js.php:619
+msgid "hyperlink"
+msgstr "hyperlink"
+
+#: admin/javascripts/admin.js.php:644 admin/javascripts/admin.js.php:716
+msgid "image"
+msgstr "bild"
+
+#: admin/javascripts/admin.js.php:659 admin/javascripts/admin.js.php:660
+msgid "Upload"
+msgstr "Hochladen"
+
+#: admin/javascripts/admin.js.php:729 admin/javascripts/admin.js.php:730
msgid "Insert"
msgstr "Einfügen"
-#: admin/javascripts/admin.js.php:747
+#: admin/javascripts/admin.js.php:758
msgid "insert"
msgstr "einfügen"
-#: admin/javascripts/admin.js.php:766 admin/javascripts/admin.js.php:767
+#: admin/javascripts/admin.js.php:777 admin/javascripts/admin.js.php:778
#: admin/pages/themes.twig:24
msgid "Preview"
msgstr "Vorschau"
-#: admin/javascripts/admin.js.php:792
+#: admin/javascripts/admin.js.php:803
msgid "preview"
msgstr "vorschau"
-#: admin/javascripts/admin.js.php:824
+#: admin/javascripts/admin.js.php:835
msgid "Words:"
msgstr "Wörter:"
-#: admin/javascripts/admin.js.php:1181
+#: admin/javascripts/admin.js.php:1196
msgid "Preview content"
msgstr "Vorschau inhalt"
diff --git a/admin/locale/en_US/LC_MESSAGES/admin.pot b/admin/locale/en_US/LC_MESSAGES/admin.pot
index cb79240..7c57a51 100644
--- a/admin/locale/en_US/LC_MESSAGES/admin.pot
+++ b/admin/locale/en_US/LC_MESSAGES/admin.pot
@@ -62,8 +62,8 @@ msgstr ""
#: admin/help/markdown.twig:20
#: admin/help/markdown.twig:24
-#: admin/javascripts/admin.js.php:450
-#: admin/javascripts/admin.js.php:451
+#: admin/javascripts/admin.js.php:455
+#: admin/javascripts/admin.js.php:456
msgid "Heading"
msgstr ""
@@ -76,8 +76,8 @@ msgid "**Strong**"
msgstr ""
#: admin/help/markdown.twig:28
-#: admin/javascripts/admin.js.php:475
-#: admin/javascripts/admin.js.php:476
+#: admin/javascripts/admin.js.php:480
+#: admin/javascripts/admin.js.php:481
msgid "Strong"
msgstr ""
@@ -86,8 +86,8 @@ msgid "*Emphasis*"
msgstr ""
#: admin/help/markdown.twig:32
-#: admin/javascripts/admin.js.php:500
-#: admin/javascripts/admin.js.php:501
+#: admin/javascripts/admin.js.php:505
+#: admin/javascripts/admin.js.php:506
msgid "Emphasis"
msgstr ""
@@ -104,8 +104,8 @@ msgid "~~Strikethrough~~"
msgstr ""
#: admin/help/markdown.twig:40
-#: admin/javascripts/admin.js.php:525
-#: admin/javascripts/admin.js.php:526
+#: admin/javascripts/admin.js.php:530
+#: admin/javascripts/admin.js.php:531
msgid "Strikethrough"
msgstr ""
@@ -114,8 +114,8 @@ msgid "`Code`"
msgstr ""
#: admin/help/markdown.twig:44
-#: admin/javascripts/admin.js.php:575
-#: admin/javascripts/admin.js.php:576
+#: admin/javascripts/admin.js.php:580
+#: admin/javascripts/admin.js.php:581
msgid "Code"
msgstr ""
@@ -124,8 +124,8 @@ msgid "==Highlight=="
msgstr ""
#: admin/help/markdown.twig:48
-#: admin/javascripts/admin.js.php:550
-#: admin/javascripts/admin.js.php:551
+#: admin/javascripts/admin.js.php:555
+#: admin/javascripts/admin.js.php:556
msgid "Highlight"
msgstr ""
@@ -158,8 +158,8 @@ msgid "[title](URL)"
msgstr ""
#: admin/help/markdown.twig:65
-#: admin/javascripts/admin.js.php:600
-#: admin/javascripts/admin.js.php:601
+#: admin/javascripts/admin.js.php:605
+#: admin/javascripts/admin.js.php:606
msgid "Hyperlink"
msgstr ""
@@ -168,8 +168,8 @@ msgid "![description](URL)"
msgstr ""
#: admin/help/markdown.twig:69
-#: admin/javascripts/admin.js.php:625
-#: admin/javascripts/admin.js.php:626
+#: admin/javascripts/admin.js.php:630
+#: admin/javascripts/admin.js.php:631
msgid "Image"
msgstr ""
@@ -275,100 +275,112 @@ msgstr ""
msgid "Are you sure you want to proceed?"
msgstr ""
-#: admin/javascripts/admin.js.php:295
-#: admin/javascripts/admin.js.php:383
-#: admin/javascripts/admin.js.php:1171
+#: admin/javascripts/admin.js.php:244
+msgid "Uploading..."
+msgstr ""
+
+#: admin/javascripts/admin.js.php:245
+msgid "File upload failed!"
+msgstr ""
+
+#: admin/javascripts/admin.js.php:246
+msgid "File type not supported!"
+msgstr ""
+
+#: admin/javascripts/admin.js.php:247
+#, php-format
+msgid "Maximum file size: %d Megabytes!"
+msgstr ""
+
+#: admin/javascripts/admin.js.php:300
+#: admin/javascripts/admin.js.php:388
+#: admin/javascripts/admin.js.php:1186
msgid "Modal window"
msgstr ""
-#: admin/javascripts/admin.js.php:304
+#: admin/javascripts/admin.js.php:309
#: admin/pages/manage_uploads.twig:18
msgid "Uploads"
msgstr ""
-#: admin/javascripts/admin.js.php:330
-#: admin/javascripts/admin.js.php:409
-#: admin/javascripts/admin.js.php:1199
+#: admin/javascripts/admin.js.php:335
+#: admin/javascripts/admin.js.php:414
+#: admin/javascripts/admin.js.php:1214
msgid "Close"
msgstr ""
-#: admin/javascripts/admin.js.php:344
-#: admin/javascripts/admin.js.php:423
-#: admin/javascripts/admin.js.php:1213
+#: admin/javascripts/admin.js.php:349
+#: admin/javascripts/admin.js.php:428
+#: admin/javascripts/admin.js.php:1228
msgid "close"
msgstr ""
-#: admin/javascripts/admin.js.php:392
+#: admin/javascripts/admin.js.php:397
msgid "Help content"
msgstr ""
-#: admin/javascripts/admin.js.php:464
+#: admin/javascripts/admin.js.php:469
msgid "heading"
msgstr ""
-#: admin/javascripts/admin.js.php:489
+#: admin/javascripts/admin.js.php:494
msgid "strong"
msgstr ""
-#: admin/javascripts/admin.js.php:514
+#: admin/javascripts/admin.js.php:519
msgid "emphasis"
msgstr ""
-#: admin/javascripts/admin.js.php:539
+#: admin/javascripts/admin.js.php:544
msgid "strikethrough"
msgstr ""
-#: admin/javascripts/admin.js.php:564
+#: admin/javascripts/admin.js.php:569
msgid "highlight"
msgstr ""
-#: admin/javascripts/admin.js.php:589
+#: admin/javascripts/admin.js.php:594
msgid "code"
msgstr ""
-#: admin/javascripts/admin.js.php:614
+#: admin/javascripts/admin.js.php:619
msgid "hyperlink"
msgstr ""
-#: admin/javascripts/admin.js.php:639
-#: admin/javascripts/admin.js.php:705
+#: admin/javascripts/admin.js.php:644
+#: admin/javascripts/admin.js.php:716
msgid "image"
msgstr ""
-#: admin/javascripts/admin.js.php:654
-#: admin/javascripts/admin.js.php:655
+#: admin/javascripts/admin.js.php:659
+#: admin/javascripts/admin.js.php:660
msgid "Upload"
msgstr ""
-#: admin/javascripts/admin.js.php:682
-#: admin/javascripts/admin.js.php:928
-msgid "Uploading..."
-msgstr ""
-
-#: admin/javascripts/admin.js.php:718
-#: admin/javascripts/admin.js.php:719
+#: admin/javascripts/admin.js.php:729
+#: admin/javascripts/admin.js.php:730
msgid "Insert"
msgstr ""
-#: admin/javascripts/admin.js.php:747
+#: admin/javascripts/admin.js.php:758
msgid "insert"
msgstr ""
-#: admin/javascripts/admin.js.php:766
-#: admin/javascripts/admin.js.php:767
+#: admin/javascripts/admin.js.php:777
+#: admin/javascripts/admin.js.php:778
#: admin/pages/themes.twig:24
msgid "Preview"
msgstr ""
-#: admin/javascripts/admin.js.php:792
+#: admin/javascripts/admin.js.php:803
msgid "preview"
msgstr ""
-#: admin/javascripts/admin.js.php:824
+#: admin/javascripts/admin.js.php:835
msgid "Words:"
msgstr ""
-#: admin/javascripts/admin.js.php:1181
+#: admin/javascripts/admin.js.php:1196
msgid "Preview content"
msgstr ""
diff --git a/admin/locale/fr_FR/LC_MESSAGES/admin.mo b/admin/locale/fr_FR/LC_MESSAGES/admin.mo
index a07d1bf..527c42d 100644
Binary files a/admin/locale/fr_FR/LC_MESSAGES/admin.mo and b/admin/locale/fr_FR/LC_MESSAGES/admin.mo differ
diff --git a/admin/locale/fr_FR/LC_MESSAGES/admin.po b/admin/locale/fr_FR/LC_MESSAGES/admin.po
index 094f1b3..0c801da 100644
--- a/admin/locale/fr_FR/LC_MESSAGES/admin.po
+++ b/admin/locale/fr_FR/LC_MESSAGES/admin.po
@@ -114,7 +114,7 @@ msgid "## Heading"
msgstr "## Titre"
#: admin/help/markdown.twig:20 admin/help/markdown.twig:24
-#: admin/javascripts/admin.js.php:450 admin/javascripts/admin.js.php:451
+#: admin/javascripts/admin.js.php:455 admin/javascripts/admin.js.php:456
msgid "Heading"
msgstr "Titre"
@@ -126,8 +126,8 @@ msgstr "### Titre"
msgid "**Strong**"
msgstr "**Gras**"
-#: admin/help/markdown.twig:28 admin/javascripts/admin.js.php:475
-#: admin/javascripts/admin.js.php:476
+#: admin/help/markdown.twig:28 admin/javascripts/admin.js.php:480
+#: admin/javascripts/admin.js.php:481
msgid "Strong"
msgstr "Gras"
@@ -135,8 +135,8 @@ msgstr "Gras"
msgid "*Emphasis*"
msgstr "*Emphase*"
-#: admin/help/markdown.twig:32 admin/javascripts/admin.js.php:500
-#: admin/javascripts/admin.js.php:501
+#: admin/help/markdown.twig:32 admin/javascripts/admin.js.php:505
+#: admin/javascripts/admin.js.php:506
msgid "Emphasis"
msgstr "Emphase"
@@ -152,8 +152,8 @@ msgstr "Citation"
msgid "~~Strikethrough~~"
msgstr "~~Barré~~"
-#: admin/help/markdown.twig:40 admin/javascripts/admin.js.php:525
-#: admin/javascripts/admin.js.php:526
+#: admin/help/markdown.twig:40 admin/javascripts/admin.js.php:530
+#: admin/javascripts/admin.js.php:531
msgid "Strikethrough"
msgstr "Barré"
@@ -161,8 +161,8 @@ msgstr "Barré"
msgid "`Code`"
msgstr "`Code`"
-#: admin/help/markdown.twig:44 admin/javascripts/admin.js.php:575
-#: admin/javascripts/admin.js.php:576
+#: admin/help/markdown.twig:44 admin/javascripts/admin.js.php:580
+#: admin/javascripts/admin.js.php:581
msgid "Code"
msgstr "Code"
@@ -170,8 +170,8 @@ msgstr "Code"
msgid "==Highlight=="
msgstr "==Surligné=="
-#: admin/help/markdown.twig:48 admin/javascripts/admin.js.php:550
-#: admin/javascripts/admin.js.php:551
+#: admin/help/markdown.twig:48 admin/javascripts/admin.js.php:555
+#: admin/javascripts/admin.js.php:556
msgid "Highlight"
msgstr "Surligné"
@@ -203,8 +203,8 @@ msgstr "Nouveau paragraphe"
msgid "[title](URL)"
msgstr "[titre](URL)"
-#: admin/help/markdown.twig:65 admin/javascripts/admin.js.php:600
-#: admin/javascripts/admin.js.php:601
+#: admin/help/markdown.twig:65 admin/javascripts/admin.js.php:605
+#: admin/javascripts/admin.js.php:606
msgid "Hyperlink"
msgstr "Lien hypertexte"
@@ -212,8 +212,8 @@ msgstr "Lien hypertexte"
msgid "![description](URL)"
msgstr "![description](URL)"
-#: admin/help/markdown.twig:69 admin/javascripts/admin.js.php:625
-#: admin/javascripts/admin.js.php:626
+#: admin/help/markdown.twig:69 admin/javascripts/admin.js.php:630
+#: admin/javascripts/admin.js.php:631
msgid "Image"
msgstr "Image"
@@ -326,91 +326,104 @@ msgstr "Tout basculer"
msgid "Are you sure you want to proceed?"
msgstr "Êtes-vous sûr de vouloir continuer ?"
-#: admin/javascripts/admin.js.php:295 admin/javascripts/admin.js.php:383
-#: admin/javascripts/admin.js.php:1171
-msgid "Modal window"
-msgstr "Fenêtre modale"
-
-#: admin/javascripts/admin.js.php:304 admin/pages/manage_uploads.twig:18
-msgid "Uploads"
-msgstr "Téléchargements"
-
-#: admin/javascripts/admin.js.php:330 admin/javascripts/admin.js.php:409
-#: admin/javascripts/admin.js.php:1199
-msgid "Close"
-msgstr "Fermer"
-
-#: admin/javascripts/admin.js.php:344 admin/javascripts/admin.js.php:423
-#: admin/javascripts/admin.js.php:1213
-msgid "close"
-msgstr "fermer"
-
-#: admin/javascripts/admin.js.php:392
-msgid "Help content"
-msgstr "Contenu de l’aide"
-
-#: admin/javascripts/admin.js.php:464
-msgid "heading"
-msgstr "titre"
-
-#: admin/javascripts/admin.js.php:489
-msgid "strong"
-msgstr "gras"
-
-#: admin/javascripts/admin.js.php:514
-msgid "emphasis"
-msgstr "italique"
-
-#: admin/javascripts/admin.js.php:539
-msgid "strikethrough"
-msgstr "barré"
-
-#: admin/javascripts/admin.js.php:564
-msgid "highlight"
-msgstr "surligné"
-
-#: admin/javascripts/admin.js.php:589
-msgid "code"
-msgstr "code"
-
-#: admin/javascripts/admin.js.php:614
-msgid "hyperlink"
-msgstr "lien hypertexte"
-
-#: admin/javascripts/admin.js.php:639 admin/javascripts/admin.js.php:705
-msgid "image"
-msgstr "image"
-
-#: admin/javascripts/admin.js.php:654 admin/javascripts/admin.js.php:655
-msgid "Upload"
-msgstr "Téléchargement"
-
-#: admin/javascripts/admin.js.php:682 admin/javascripts/admin.js.php:928
+#: admin/javascripts/admin.js.php:244
msgid "Uploading..."
msgstr "Téléchargement..."
-#: admin/javascripts/admin.js.php:718 admin/javascripts/admin.js.php:719
+#: admin/javascripts/admin.js.php:245
+msgid "File upload failed!"
+msgstr "Le téléchargement du fichier a échoué !"
+
+#: admin/javascripts/admin.js.php:246
+msgid "File type not supported!"
+msgstr "Le type de fichier n’est pas pris en charge !"
+
+#: admin/javascripts/admin.js.php:247
+#, php-format
+msgid "Maximum file size: %d Megabytes!"
+msgstr "Taille maximale du fichier : %d mégaoctets !"
+
+#: admin/javascripts/admin.js.php:300 admin/javascripts/admin.js.php:388
+#: admin/javascripts/admin.js.php:1186
+msgid "Modal window"
+msgstr "Fenêtre modale"
+
+#: admin/javascripts/admin.js.php:309 admin/pages/manage_uploads.twig:18
+msgid "Uploads"
+msgstr "Téléchargements"
+
+#: admin/javascripts/admin.js.php:335 admin/javascripts/admin.js.php:414
+#: admin/javascripts/admin.js.php:1214
+msgid "Close"
+msgstr "Fermer"
+
+#: admin/javascripts/admin.js.php:349 admin/javascripts/admin.js.php:428
+#: admin/javascripts/admin.js.php:1228
+msgid "close"
+msgstr "fermer"
+
+#: admin/javascripts/admin.js.php:397
+msgid "Help content"
+msgstr "Contenu de l’aide"
+
+#: admin/javascripts/admin.js.php:469
+msgid "heading"
+msgstr "titre"
+
+#: admin/javascripts/admin.js.php:494
+msgid "strong"
+msgstr "gras"
+
+#: admin/javascripts/admin.js.php:519
+msgid "emphasis"
+msgstr "italique"
+
+#: admin/javascripts/admin.js.php:544
+msgid "strikethrough"
+msgstr "barré"
+
+#: admin/javascripts/admin.js.php:569
+msgid "highlight"
+msgstr "surligné"
+
+#: admin/javascripts/admin.js.php:594
+msgid "code"
+msgstr "code"
+
+#: admin/javascripts/admin.js.php:619
+msgid "hyperlink"
+msgstr "lien hypertexte"
+
+#: admin/javascripts/admin.js.php:644 admin/javascripts/admin.js.php:716
+msgid "image"
+msgstr "image"
+
+#: admin/javascripts/admin.js.php:659 admin/javascripts/admin.js.php:660
+msgid "Upload"
+msgstr "Téléchargement"
+
+#: admin/javascripts/admin.js.php:729 admin/javascripts/admin.js.php:730
msgid "Insert"
msgstr "Insérer"
-#: admin/javascripts/admin.js.php:747
+#: admin/javascripts/admin.js.php:758
msgid "insert"
msgstr "insérer"
-#: admin/javascripts/admin.js.php:766 admin/javascripts/admin.js.php:767
+#: admin/javascripts/admin.js.php:777 admin/javascripts/admin.js.php:778
#: admin/pages/themes.twig:24
msgid "Preview"
msgstr "Prévisualisation"
-#: admin/javascripts/admin.js.php:792
+#: admin/javascripts/admin.js.php:803
msgid "preview"
msgstr "prévisualisation"
-#: admin/javascripts/admin.js.php:824
+#: admin/javascripts/admin.js.php:835
msgid "Words:"
msgstr "Mots :"
-#: admin/javascripts/admin.js.php:1181
+#: admin/javascripts/admin.js.php:1196
msgid "Preview content"
msgstr "Contenu du prévisualisation"
diff --git a/admin/locale/it_IT/LC_MESSAGES/admin.mo b/admin/locale/it_IT/LC_MESSAGES/admin.mo
index 8cd13dd..4c4da3c 100644
Binary files a/admin/locale/it_IT/LC_MESSAGES/admin.mo and b/admin/locale/it_IT/LC_MESSAGES/admin.mo differ
diff --git a/admin/locale/it_IT/LC_MESSAGES/admin.po b/admin/locale/it_IT/LC_MESSAGES/admin.po
index 41630af..bd92290 100644
--- a/admin/locale/it_IT/LC_MESSAGES/admin.po
+++ b/admin/locale/it_IT/LC_MESSAGES/admin.po
@@ -114,7 +114,7 @@ msgid "## Heading"
msgstr "## Intestazione"
#: admin/help/markdown.twig:20 admin/help/markdown.twig:24
-#: admin/javascripts/admin.js.php:450 admin/javascripts/admin.js.php:451
+#: admin/javascripts/admin.js.php:455 admin/javascripts/admin.js.php:456
msgid "Heading"
msgstr "Intestazione"
@@ -126,8 +126,8 @@ msgstr "### Intestazione"
msgid "**Strong**"
msgstr "**Forte**"
-#: admin/help/markdown.twig:28 admin/javascripts/admin.js.php:475
-#: admin/javascripts/admin.js.php:476
+#: admin/help/markdown.twig:28 admin/javascripts/admin.js.php:480
+#: admin/javascripts/admin.js.php:481
msgid "Strong"
msgstr "Forte"
@@ -135,8 +135,8 @@ msgstr "Forte"
msgid "*Emphasis*"
msgstr "*Enfasi*"
-#: admin/help/markdown.twig:32 admin/javascripts/admin.js.php:500
-#: admin/javascripts/admin.js.php:501
+#: admin/help/markdown.twig:32 admin/javascripts/admin.js.php:505
+#: admin/javascripts/admin.js.php:506
msgid "Emphasis"
msgstr "Enfasi"
@@ -152,8 +152,8 @@ msgstr "Citazione"
msgid "~~Strikethrough~~"
msgstr "~~Barrato~~"
-#: admin/help/markdown.twig:40 admin/javascripts/admin.js.php:525
-#: admin/javascripts/admin.js.php:526
+#: admin/help/markdown.twig:40 admin/javascripts/admin.js.php:530
+#: admin/javascripts/admin.js.php:531
msgid "Strikethrough"
msgstr "Barrato"
@@ -161,8 +161,8 @@ msgstr "Barrato"
msgid "`Code`"
msgstr "`Codice`"
-#: admin/help/markdown.twig:44 admin/javascripts/admin.js.php:575
-#: admin/javascripts/admin.js.php:576
+#: admin/help/markdown.twig:44 admin/javascripts/admin.js.php:580
+#: admin/javascripts/admin.js.php:581
msgid "Code"
msgstr "Codice"
@@ -170,8 +170,8 @@ msgstr "Codice"
msgid "==Highlight=="
msgstr "==Evidenziare=="
-#: admin/help/markdown.twig:48 admin/javascripts/admin.js.php:550
-#: admin/javascripts/admin.js.php:551
+#: admin/help/markdown.twig:48 admin/javascripts/admin.js.php:555
+#: admin/javascripts/admin.js.php:556
msgid "Highlight"
msgstr "Evidenziare"
@@ -203,8 +203,8 @@ msgstr "Nuovo paragrafo"
msgid "[title](URL)"
msgstr "[titolo](URL)"
-#: admin/help/markdown.twig:65 admin/javascripts/admin.js.php:600
-#: admin/javascripts/admin.js.php:601
+#: admin/help/markdown.twig:65 admin/javascripts/admin.js.php:605
+#: admin/javascripts/admin.js.php:606
msgid "Hyperlink"
msgstr "Collegamento ipertestuale"
@@ -212,8 +212,8 @@ msgstr "Collegamento ipertestuale"
msgid "![description](URL)"
msgstr "![descrizione](URL)"
-#: admin/help/markdown.twig:69 admin/javascripts/admin.js.php:625
-#: admin/javascripts/admin.js.php:626
+#: admin/help/markdown.twig:69 admin/javascripts/admin.js.php:630
+#: admin/javascripts/admin.js.php:631
msgid "Image"
msgstr "Immagine"
@@ -329,91 +329,104 @@ msgstr "Spunta tutto"
msgid "Are you sure you want to proceed?"
msgstr "Sei sicuro di volere procedere?"
-#: admin/javascripts/admin.js.php:295 admin/javascripts/admin.js.php:383
-#: admin/javascripts/admin.js.php:1171
-msgid "Modal window"
-msgstr "Finestra modale"
-
-#: admin/javascripts/admin.js.php:304 admin/pages/manage_uploads.twig:18
-msgid "Uploads"
-msgstr "Caricamenti"
-
-#: admin/javascripts/admin.js.php:330 admin/javascripts/admin.js.php:409
-#: admin/javascripts/admin.js.php:1199
-msgid "Close"
-msgstr "Chiudi"
-
-#: admin/javascripts/admin.js.php:344 admin/javascripts/admin.js.php:423
-#: admin/javascripts/admin.js.php:1213
-msgid "close"
-msgstr "chiudi"
-
-#: admin/javascripts/admin.js.php:392
-msgid "Help content"
-msgstr "Contenuto di aiuto"
-
-#: admin/javascripts/admin.js.php:464
-msgid "heading"
-msgstr "intestazione"
-
-#: admin/javascripts/admin.js.php:489
-msgid "strong"
-msgstr "forte"
-
-#: admin/javascripts/admin.js.php:514
-msgid "emphasis"
-msgstr "enfasi"
-
-#: admin/javascripts/admin.js.php:539
-msgid "strikethrough"
-msgstr "barrato"
-
-#: admin/javascripts/admin.js.php:564
-msgid "highlight"
-msgstr "evidenza"
-
-#: admin/javascripts/admin.js.php:589
-msgid "code"
-msgstr "codice"
-
-#: admin/javascripts/admin.js.php:614
-msgid "hyperlink"
-msgstr "collegamento ipertestuale"
-
-#: admin/javascripts/admin.js.php:639 admin/javascripts/admin.js.php:705
-msgid "image"
-msgstr "immagine"
-
-#: admin/javascripts/admin.js.php:654 admin/javascripts/admin.js.php:655
-msgid "Upload"
-msgstr "Carica"
-
-#: admin/javascripts/admin.js.php:682 admin/javascripts/admin.js.php:928
+#: admin/javascripts/admin.js.php:244
msgid "Uploading..."
msgstr "Caricamento in corso…."
-#: admin/javascripts/admin.js.php:718 admin/javascripts/admin.js.php:719
+#: admin/javascripts/admin.js.php:245
+msgid "File upload failed!"
+msgstr "Caricamento file fallito!"
+
+#: admin/javascripts/admin.js.php:246
+msgid "File type not supported!"
+msgstr "Tipo di file non supportato!"
+
+#: admin/javascripts/admin.js.php:247
+#, php-format
+msgid "Maximum file size: %d Megabytes!"
+msgstr "Dimensione massima del file: %d Megabyte!"
+
+#: admin/javascripts/admin.js.php:300 admin/javascripts/admin.js.php:388
+#: admin/javascripts/admin.js.php:1186
+msgid "Modal window"
+msgstr "Finestra modale"
+
+#: admin/javascripts/admin.js.php:309 admin/pages/manage_uploads.twig:18
+msgid "Uploads"
+msgstr "Caricamenti"
+
+#: admin/javascripts/admin.js.php:335 admin/javascripts/admin.js.php:414
+#: admin/javascripts/admin.js.php:1214
+msgid "Close"
+msgstr "Chiudi"
+
+#: admin/javascripts/admin.js.php:349 admin/javascripts/admin.js.php:428
+#: admin/javascripts/admin.js.php:1228
+msgid "close"
+msgstr "chiudi"
+
+#: admin/javascripts/admin.js.php:397
+msgid "Help content"
+msgstr "Contenuto di aiuto"
+
+#: admin/javascripts/admin.js.php:469
+msgid "heading"
+msgstr "intestazione"
+
+#: admin/javascripts/admin.js.php:494
+msgid "strong"
+msgstr "forte"
+
+#: admin/javascripts/admin.js.php:519
+msgid "emphasis"
+msgstr "enfasi"
+
+#: admin/javascripts/admin.js.php:544
+msgid "strikethrough"
+msgstr "barrato"
+
+#: admin/javascripts/admin.js.php:569
+msgid "highlight"
+msgstr "evidenza"
+
+#: admin/javascripts/admin.js.php:594
+msgid "code"
+msgstr "codice"
+
+#: admin/javascripts/admin.js.php:619
+msgid "hyperlink"
+msgstr "collegamento ipertestuale"
+
+#: admin/javascripts/admin.js.php:644 admin/javascripts/admin.js.php:716
+msgid "image"
+msgstr "immagine"
+
+#: admin/javascripts/admin.js.php:659 admin/javascripts/admin.js.php:660
+msgid "Upload"
+msgstr "Carica"
+
+#: admin/javascripts/admin.js.php:729 admin/javascripts/admin.js.php:730
msgid "Insert"
msgstr "Inserisci"
-#: admin/javascripts/admin.js.php:747
+#: admin/javascripts/admin.js.php:758
msgid "insert"
msgstr "inserisci"
-#: admin/javascripts/admin.js.php:766 admin/javascripts/admin.js.php:767
+#: admin/javascripts/admin.js.php:777 admin/javascripts/admin.js.php:778
#: admin/pages/themes.twig:24
msgid "Preview"
msgstr "Anteprima"
-#: admin/javascripts/admin.js.php:792
+#: admin/javascripts/admin.js.php:803
msgid "preview"
msgstr "anteprima"
-#: admin/javascripts/admin.js.php:824
+#: admin/javascripts/admin.js.php:835
msgid "Words:"
msgstr "Parole:"
-#: admin/javascripts/admin.js.php:1181
+#: admin/javascripts/admin.js.php:1196
msgid "Preview content"
msgstr "Contenuto di anteprima"
diff --git a/admin/locale/nl_NL/LC_MESSAGES/admin.mo b/admin/locale/nl_NL/LC_MESSAGES/admin.mo
index 394878f..96c7753 100644
Binary files a/admin/locale/nl_NL/LC_MESSAGES/admin.mo and b/admin/locale/nl_NL/LC_MESSAGES/admin.mo differ
diff --git a/admin/locale/nl_NL/LC_MESSAGES/admin.po b/admin/locale/nl_NL/LC_MESSAGES/admin.po
index ab9d5bb..edd876b 100644
--- a/admin/locale/nl_NL/LC_MESSAGES/admin.po
+++ b/admin/locale/nl_NL/LC_MESSAGES/admin.po
@@ -112,7 +112,7 @@ msgid "## Heading"
msgstr "## Kop"
#: admin/help/markdown.twig:20 admin/help/markdown.twig:24
-#: admin/javascripts/admin.js.php:450 admin/javascripts/admin.js.php:451
+#: admin/javascripts/admin.js.php:455 admin/javascripts/admin.js.php:456
msgid "Heading"
msgstr "Kop"
@@ -124,8 +124,8 @@ msgstr "### Kop"
msgid "**Strong**"
msgstr "**Sterk**"
-#: admin/help/markdown.twig:28 admin/javascripts/admin.js.php:475
-#: admin/javascripts/admin.js.php:476
+#: admin/help/markdown.twig:28 admin/javascripts/admin.js.php:480
+#: admin/javascripts/admin.js.php:481
msgid "Strong"
msgstr "Sterk"
@@ -133,8 +133,8 @@ msgstr "Sterk"
msgid "*Emphasis*"
msgstr "*Vet*"
-#: admin/help/markdown.twig:32 admin/javascripts/admin.js.php:500
-#: admin/javascripts/admin.js.php:501
+#: admin/help/markdown.twig:32 admin/javascripts/admin.js.php:505
+#: admin/javascripts/admin.js.php:506
msgid "Emphasis"
msgstr "Vet"
@@ -150,8 +150,8 @@ msgstr "Citaat"
msgid "~~Strikethrough~~"
msgstr "~~Doorhalen~~"
-#: admin/help/markdown.twig:40 admin/javascripts/admin.js.php:525
-#: admin/javascripts/admin.js.php:526
+#: admin/help/markdown.twig:40 admin/javascripts/admin.js.php:530
+#: admin/javascripts/admin.js.php:531
msgid "Strikethrough"
msgstr "Doorhalen"
@@ -159,8 +159,8 @@ msgstr "Doorhalen"
msgid "`Code`"
msgstr "`Code`"
-#: admin/help/markdown.twig:44 admin/javascripts/admin.js.php:575
-#: admin/javascripts/admin.js.php:576
+#: admin/help/markdown.twig:44 admin/javascripts/admin.js.php:580
+#: admin/javascripts/admin.js.php:581
msgid "Code"
msgstr "Code"
@@ -168,8 +168,8 @@ msgstr "Code"
msgid "==Highlight=="
msgstr "==Markeren=="
-#: admin/help/markdown.twig:48 admin/javascripts/admin.js.php:550
-#: admin/javascripts/admin.js.php:551
+#: admin/help/markdown.twig:48 admin/javascripts/admin.js.php:555
+#: admin/javascripts/admin.js.php:556
msgid "Highlight"
msgstr "Markeren"
@@ -201,8 +201,8 @@ msgstr "Nieuwe paragraaf"
msgid "[title](URL)"
msgstr "[titel](URL)"
-#: admin/help/markdown.twig:65 admin/javascripts/admin.js.php:600
-#: admin/javascripts/admin.js.php:601
+#: admin/help/markdown.twig:65 admin/javascripts/admin.js.php:605
+#: admin/javascripts/admin.js.php:606
msgid "Hyperlink"
msgstr "Hyperlink"
@@ -210,8 +210,8 @@ msgstr "Hyperlink"
msgid "![description](URL)"
msgstr "![beschrijving](URL)"
-#: admin/help/markdown.twig:69 admin/javascripts/admin.js.php:625
-#: admin/javascripts/admin.js.php:626
+#: admin/help/markdown.twig:69 admin/javascripts/admin.js.php:630
+#: admin/javascripts/admin.js.php:631
msgid "Image"
msgstr "Afbeelding"
@@ -327,91 +327,104 @@ msgstr "Alles selecteren"
msgid "Are you sure you want to proceed?"
msgstr "Weet je zeker dat je wilt doorgaan?"
-#: admin/javascripts/admin.js.php:295 admin/javascripts/admin.js.php:383
-#: admin/javascripts/admin.js.php:1171
-msgid "Modal window"
-msgstr "Voorscherm"
-
-#: admin/javascripts/admin.js.php:304 admin/pages/manage_uploads.twig:18
-msgid "Uploads"
-msgstr "Uploads"
-
-#: admin/javascripts/admin.js.php:330 admin/javascripts/admin.js.php:409
-#: admin/javascripts/admin.js.php:1199
-msgid "Close"
-msgstr "Sluit"
-
-#: admin/javascripts/admin.js.php:344 admin/javascripts/admin.js.php:423
-#: admin/javascripts/admin.js.php:1213
-msgid "close"
-msgstr "sluit"
-
-#: admin/javascripts/admin.js.php:392
-msgid "Help content"
-msgstr "Help inhoud"
-
-#: admin/javascripts/admin.js.php:464
-msgid "heading"
-msgstr "kop"
-
-#: admin/javascripts/admin.js.php:489
-msgid "strong"
-msgstr "sterk"
-
-#: admin/javascripts/admin.js.php:514
-msgid "emphasis"
-msgstr "vet"
-
-#: admin/javascripts/admin.js.php:539
-msgid "strikethrough"
-msgstr "doorhalen"
-
-#: admin/javascripts/admin.js.php:564
-msgid "highlight"
-msgstr "markeren"
-
-#: admin/javascripts/admin.js.php:589
-msgid "code"
-msgstr "code"
-
-#: admin/javascripts/admin.js.php:614
-msgid "hyperlink"
-msgstr "hyperlink"
-
-#: admin/javascripts/admin.js.php:639 admin/javascripts/admin.js.php:705
-msgid "image"
-msgstr "afbeelding"
-
-#: admin/javascripts/admin.js.php:654 admin/javascripts/admin.js.php:655
-msgid "Upload"
-msgstr "Upload"
-
-#: admin/javascripts/admin.js.php:682 admin/javascripts/admin.js.php:928
+#: admin/javascripts/admin.js.php:244
msgid "Uploading..."
msgstr "Aan het uploaden..."
-#: admin/javascripts/admin.js.php:718 admin/javascripts/admin.js.php:719
+#: admin/javascripts/admin.js.php:245
+msgid "File upload failed!"
+msgstr "Het uploaden van bestanden is mislukt!"
+
+#: admin/javascripts/admin.js.php:246
+msgid "File type not supported!"
+msgstr "Bestandstype wordt niet ondersteund!"
+
+#: admin/javascripts/admin.js.php:247
+#, php-format
+msgid "Maximum file size: %d Megabytes!"
+msgstr "Maximale bestandsgrootte: %d Megabytes!"
+
+#: admin/javascripts/admin.js.php:300 admin/javascripts/admin.js.php:388
+#: admin/javascripts/admin.js.php:1186
+msgid "Modal window"
+msgstr "Voorscherm"
+
+#: admin/javascripts/admin.js.php:309 admin/pages/manage_uploads.twig:18
+msgid "Uploads"
+msgstr "Uploads"
+
+#: admin/javascripts/admin.js.php:335 admin/javascripts/admin.js.php:414
+#: admin/javascripts/admin.js.php:1214
+msgid "Close"
+msgstr "Sluit"
+
+#: admin/javascripts/admin.js.php:349 admin/javascripts/admin.js.php:428
+#: admin/javascripts/admin.js.php:1228
+msgid "close"
+msgstr "sluit"
+
+#: admin/javascripts/admin.js.php:397
+msgid "Help content"
+msgstr "Help inhoud"
+
+#: admin/javascripts/admin.js.php:469
+msgid "heading"
+msgstr "kop"
+
+#: admin/javascripts/admin.js.php:494
+msgid "strong"
+msgstr "sterk"
+
+#: admin/javascripts/admin.js.php:519
+msgid "emphasis"
+msgstr "vet"
+
+#: admin/javascripts/admin.js.php:544
+msgid "strikethrough"
+msgstr "doorhalen"
+
+#: admin/javascripts/admin.js.php:569
+msgid "highlight"
+msgstr "markeren"
+
+#: admin/javascripts/admin.js.php:594
+msgid "code"
+msgstr "code"
+
+#: admin/javascripts/admin.js.php:619
+msgid "hyperlink"
+msgstr "hyperlink"
+
+#: admin/javascripts/admin.js.php:644 admin/javascripts/admin.js.php:716
+msgid "image"
+msgstr "afbeelding"
+
+#: admin/javascripts/admin.js.php:659 admin/javascripts/admin.js.php:660
+msgid "Upload"
+msgstr "Upload"
+
+#: admin/javascripts/admin.js.php:729 admin/javascripts/admin.js.php:730
msgid "Insert"
msgstr "Invoegen"
-#: admin/javascripts/admin.js.php:747
+#: admin/javascripts/admin.js.php:758
msgid "insert"
msgstr "invoegen"
-#: admin/javascripts/admin.js.php:766 admin/javascripts/admin.js.php:767
+#: admin/javascripts/admin.js.php:777 admin/javascripts/admin.js.php:778
#: admin/pages/themes.twig:24
msgid "Preview"
msgstr "Vooruitblik"
-#: admin/javascripts/admin.js.php:792
+#: admin/javascripts/admin.js.php:803
msgid "preview"
msgstr "vooruitblik"
-#: admin/javascripts/admin.js.php:824
+#: admin/javascripts/admin.js.php:835
msgid "Words:"
msgstr "Woorden:"
-#: admin/javascripts/admin.js.php:1181
+#: admin/javascripts/admin.js.php:1196
msgid "Preview content"
msgstr "Vooruitblik inhoud"
diff --git a/admin/locale/zh_CN/LC_MESSAGES/admin.mo b/admin/locale/zh_CN/LC_MESSAGES/admin.mo
index 922b1d3..1ee285c 100644
Binary files a/admin/locale/zh_CN/LC_MESSAGES/admin.mo and b/admin/locale/zh_CN/LC_MESSAGES/admin.mo differ
diff --git a/admin/locale/zh_CN/LC_MESSAGES/admin.po b/admin/locale/zh_CN/LC_MESSAGES/admin.po
index 3be7754..c540e36 100644
--- a/admin/locale/zh_CN/LC_MESSAGES/admin.po
+++ b/admin/locale/zh_CN/LC_MESSAGES/admin.po
@@ -100,7 +100,7 @@ msgid "## Heading"
msgstr ""
#: admin/help/markdown.twig:20 admin/help/markdown.twig:24
-#: admin/javascripts/admin.js.php:450 admin/javascripts/admin.js.php:451
+#: admin/javascripts/admin.js.php:455 admin/javascripts/admin.js.php:456
msgid "Heading"
msgstr ""
@@ -112,8 +112,8 @@ msgstr ""
msgid "**Strong**"
msgstr ""
-#: admin/help/markdown.twig:28 admin/javascripts/admin.js.php:475
-#: admin/javascripts/admin.js.php:476
+#: admin/help/markdown.twig:28 admin/javascripts/admin.js.php:480
+#: admin/javascripts/admin.js.php:481
msgid "Strong"
msgstr ""
@@ -121,8 +121,8 @@ msgstr ""
msgid "*Emphasis*"
msgstr ""
-#: admin/help/markdown.twig:32 admin/javascripts/admin.js.php:500
-#: admin/javascripts/admin.js.php:501
+#: admin/help/markdown.twig:32 admin/javascripts/admin.js.php:505
+#: admin/javascripts/admin.js.php:506
msgid "Emphasis"
msgstr ""
@@ -138,8 +138,8 @@ msgstr ""
msgid "~~Strikethrough~~"
msgstr ""
-#: admin/help/markdown.twig:40 admin/javascripts/admin.js.php:525
-#: admin/javascripts/admin.js.php:526
+#: admin/help/markdown.twig:40 admin/javascripts/admin.js.php:530
+#: admin/javascripts/admin.js.php:531
msgid "Strikethrough"
msgstr ""
@@ -147,8 +147,8 @@ msgstr ""
msgid "`Code`"
msgstr ""
-#: admin/help/markdown.twig:44 admin/javascripts/admin.js.php:575
-#: admin/javascripts/admin.js.php:576
+#: admin/help/markdown.twig:44 admin/javascripts/admin.js.php:580
+#: admin/javascripts/admin.js.php:581
msgid "Code"
msgstr ""
@@ -156,8 +156,8 @@ msgstr ""
msgid "==Highlight=="
msgstr ""
-#: admin/help/markdown.twig:48 admin/javascripts/admin.js.php:550
-#: admin/javascripts/admin.js.php:551
+#: admin/help/markdown.twig:48 admin/javascripts/admin.js.php:555
+#: admin/javascripts/admin.js.php:556
msgid "Highlight"
msgstr ""
@@ -189,8 +189,8 @@ msgstr "新行"
msgid "[title](URL)"
msgstr ""
-#: admin/help/markdown.twig:65 admin/javascripts/admin.js.php:600
-#: admin/javascripts/admin.js.php:601
+#: admin/help/markdown.twig:65 admin/javascripts/admin.js.php:605
+#: admin/javascripts/admin.js.php:606
msgid "Hyperlink"
msgstr ""
@@ -198,8 +198,8 @@ msgstr ""
msgid "![description](URL)"
msgstr ""
-#: admin/help/markdown.twig:69 admin/javascripts/admin.js.php:625
-#: admin/javascripts/admin.js.php:626
+#: admin/help/markdown.twig:69 admin/javascripts/admin.js.php:630
+#: admin/javascripts/admin.js.php:631
msgid "Image"
msgstr "图像"
@@ -311,91 +311,104 @@ msgstr "全部切换"
msgid "Are you sure you want to proceed?"
msgstr "确定继续?"
-#: admin/javascripts/admin.js.php:295 admin/javascripts/admin.js.php:383
-#: admin/javascripts/admin.js.php:1171
-msgid "Modal window"
-msgstr "模态窗口"
-
-#: admin/javascripts/admin.js.php:304 admin/pages/manage_uploads.twig:18
-msgid "Uploads"
-msgstr "上传"
-
-#: admin/javascripts/admin.js.php:330 admin/javascripts/admin.js.php:409
-#: admin/javascripts/admin.js.php:1199
-msgid "Close"
-msgstr "关闭"
-
-#: admin/javascripts/admin.js.php:344 admin/javascripts/admin.js.php:423
-#: admin/javascripts/admin.js.php:1213
-msgid "close"
-msgstr "关闭"
-
-#: admin/javascripts/admin.js.php:392
-msgid "Help content"
-msgstr "帮助内容"
-
-#: admin/javascripts/admin.js.php:464
-msgid "heading"
-msgstr "标题"
-
-#: admin/javascripts/admin.js.php:489
-msgid "strong"
-msgstr "强"
-
-#: admin/javascripts/admin.js.php:514
-msgid "emphasis"
-msgstr "重点"
-
-#: admin/javascripts/admin.js.php:539
-msgid "strikethrough"
-msgstr "穿越"
-
-#: admin/javascripts/admin.js.php:564
-msgid "highlight"
-msgstr "突出"
-
-#: admin/javascripts/admin.js.php:589
-msgid "code"
-msgstr "代码"
-
-#: admin/javascripts/admin.js.php:614
-msgid "hyperlink"
-msgstr "链接"
-
-#: admin/javascripts/admin.js.php:639 admin/javascripts/admin.js.php:705
-msgid "image"
-msgstr "图像"
-
-#: admin/javascripts/admin.js.php:654 admin/javascripts/admin.js.php:655
-msgid "Upload"
-msgstr "上传"
-
-#: admin/javascripts/admin.js.php:682 admin/javascripts/admin.js.php:928
+#: admin/javascripts/admin.js.php:244
msgid "Uploading..."
msgstr "上传中..."
-#: admin/javascripts/admin.js.php:718 admin/javascripts/admin.js.php:719
+#: admin/javascripts/admin.js.php:245
+msgid "File upload failed!"
+msgstr "文件上传失败!"
+
+#: admin/javascripts/admin.js.php:246
+msgid "File type not supported!"
+msgstr "不支持文件类型!"
+
+#: admin/javascripts/admin.js.php:247
+#, php-format
+msgid "Maximum file size: %d Megabytes!"
+msgstr "最大文件大小:%d兆字节!"
+
+#: admin/javascripts/admin.js.php:300 admin/javascripts/admin.js.php:388
+#: admin/javascripts/admin.js.php:1186
+msgid "Modal window"
+msgstr "模态窗口"
+
+#: admin/javascripts/admin.js.php:309 admin/pages/manage_uploads.twig:18
+msgid "Uploads"
+msgstr "上传"
+
+#: admin/javascripts/admin.js.php:335 admin/javascripts/admin.js.php:414
+#: admin/javascripts/admin.js.php:1214
+msgid "Close"
+msgstr "关闭"
+
+#: admin/javascripts/admin.js.php:349 admin/javascripts/admin.js.php:428
+#: admin/javascripts/admin.js.php:1228
+msgid "close"
+msgstr "关闭"
+
+#: admin/javascripts/admin.js.php:397
+msgid "Help content"
+msgstr "帮助内容"
+
+#: admin/javascripts/admin.js.php:469
+msgid "heading"
+msgstr "标题"
+
+#: admin/javascripts/admin.js.php:494
+msgid "strong"
+msgstr "强"
+
+#: admin/javascripts/admin.js.php:519
+msgid "emphasis"
+msgstr "重点"
+
+#: admin/javascripts/admin.js.php:544
+msgid "strikethrough"
+msgstr "穿越"
+
+#: admin/javascripts/admin.js.php:569
+msgid "highlight"
+msgstr "突出"
+
+#: admin/javascripts/admin.js.php:594
+msgid "code"
+msgstr "代码"
+
+#: admin/javascripts/admin.js.php:619
+msgid "hyperlink"
+msgstr "链接"
+
+#: admin/javascripts/admin.js.php:644 admin/javascripts/admin.js.php:716
+msgid "image"
+msgstr "图像"
+
+#: admin/javascripts/admin.js.php:659 admin/javascripts/admin.js.php:660
+msgid "Upload"
+msgstr "上传"
+
+#: admin/javascripts/admin.js.php:729 admin/javascripts/admin.js.php:730
msgid "Insert"
msgstr "插入"
-#: admin/javascripts/admin.js.php:747
+#: admin/javascripts/admin.js.php:758
msgid "insert"
msgstr "插入"
-#: admin/javascripts/admin.js.php:766 admin/javascripts/admin.js.php:767
+#: admin/javascripts/admin.js.php:777 admin/javascripts/admin.js.php:778
#: admin/pages/themes.twig:24
msgid "Preview"
msgstr "预览"
-#: admin/javascripts/admin.js.php:792
+#: admin/javascripts/admin.js.php:803
msgid "preview"
msgstr "预览"
-#: admin/javascripts/admin.js.php:824
+#: admin/javascripts/admin.js.php:835
msgid "Words:"
msgstr ""
-#: admin/javascripts/admin.js.php:1181
+#: admin/javascripts/admin.js.php:1196
msgid "Preview content"
msgstr "预览内容"
diff --git a/admin/partials/page_fields.twig b/admin/partials/page_fields.twig
index 838bf10..d599a62 100644
--- a/admin/partials/page_fields.twig
+++ b/admin/partials/page_fields.twig
@@ -25,7 +25,7 @@
{{- icon_img("help.svg", "help" | translate) -}}
-
+
diff --git a/admin/partials/post_fields.twig b/admin/partials/post_fields.twig
index 7f6b613..4c29e4e 100644
--- a/admin/partials/post_fields.twig
+++ b/admin/partials/post_fields.twig
@@ -124,7 +124,7 @@
{{- icon_img("help.svg", "help" | translate) -}}
-
+
diff --git a/admin/stylesheets/all.css b/admin/stylesheets/all.css
index e43e2e5..f6ad72d 100644
--- a/admin/stylesheets/all.css
+++ b/admin/stylesheets/all.css
@@ -825,7 +825,7 @@ a.prev_page {
color: #1f1f23;
text-align: center;
margin: 0rem;
- padding: 0.5rem;
+ padding: 0.5rem 1rem;
background-color: #f2fbff;
border: 2px solid #b8cdd9;
border-radius: 0.25em;
@@ -1083,9 +1083,11 @@ a.emblem:focus > img,
button.emblem:focus > img,
label.emblem.toolbar > input:focus + img {
outline: #ff7f00 dashed 2px;
+ outline-offset: 1px;
}
input.toolbar.hidden {
display: inline !important;
+ opacity: 0 !important;
font: inherit !important;
width: 1px !important;
height: 16px !important;
@@ -1093,7 +1095,6 @@ input.toolbar.hidden {
border: none !important;
padding: 0rem !important;
margin: 0rem !important;
- visibility: hidden !important;
}
input.toolbar.hidden::file-selector-button {
display: none !important;
@@ -1133,6 +1134,7 @@ input.toolbar.hidden::file-selector-button {
}
.iframe_foreground:focus {
outline: #ff7f00 dashed 2px;
+ outline-offset: 1px;
}
.iframe_close_gadget {
display: block;
@@ -1262,7 +1264,7 @@ input.toolbar.hidden::file-selector-button {
}
button:not(.toolbar):has(img),
a.button:not(.toolbar):has(img) {
- padding-right: calc(16px + 0.5rem) !important;
+ padding-right: calc(16px + 1rem) !important;
}
div.more_options {
grid-template-columns: 1fr;
diff --git a/feathers/audio/audio.php b/feathers/audio/audio.php
index 063ede3..57667b8 100644
--- a/feathers/audio/audio.php
+++ b/feathers/audio/audio.php
@@ -85,7 +85,7 @@
"captions" => fallback($captions, ""),
"description" => $_POST['description']
),
- clean:sanitize($_POST['slug']),
+ clean:sanitize($_POST['slug'], true, SLUG_STRICT, 128),
feather:"audio",
pinned:!empty($_POST['pinned']),
status:$_POST['status'],
@@ -98,7 +98,7 @@
public function update($post): Post|false {
fallback($_POST['title'], "");
fallback($_POST['description'], "");
- fallback($_POST['slug'], $post->clean);
+ fallback($_POST['slug'], "");
fallback($_POST['status'], $post->status);
fallback($_POST['created_at'], $post->created_at);
fallback($_POST['option'], array());
@@ -111,6 +111,12 @@
$this->audio_extensions()
);
+ if (isset($_FILES['captions']) and upload_tester($_FILES['captions']))
+ $captions = upload(
+ $_FILES['captions'],
+ array("vtt")
+ );
+
return $post->update(
values:array(
"title" => $_POST['title'],
@@ -120,7 +126,7 @@
),
pinned:!empty($_POST['pinned']),
status:$_POST['status'],
- clean:sanitize($_POST['slug']),
+ clean:sanitize($_POST['slug'], true, SLUG_STRICT, 128),
created_at:datetime($_POST['created_at']),
options:$_POST['option']
);
diff --git a/feathers/audio/info.php b/feathers/audio/info.php
index 7d1ee53..dc6ba53 100644
--- a/feathers/audio/info.php
+++ b/feathers/audio/info.php
@@ -2,7 +2,7 @@
return array(
"name" => __("Audio", "audio"),
"url" => "http://chyrplite.net/",
- "version" => "2024.01",
+ "version" => "2024.03",
"description" => __("A feather for audio.", "audio"),
"author" => array(
"name" => "Daniel Pimley",
diff --git a/feathers/audio/locale/de_DE/LC_MESSAGES/audio.mo b/feathers/audio/locale/de_DE/LC_MESSAGES/audio.mo
index 3f526c8..4033af0 100644
Binary files a/feathers/audio/locale/de_DE/LC_MESSAGES/audio.mo and b/feathers/audio/locale/de_DE/LC_MESSAGES/audio.mo differ
diff --git a/feathers/audio/locale/de_DE/LC_MESSAGES/audio.po b/feathers/audio/locale/de_DE/LC_MESSAGES/audio.po
index 43c1d15..49335d6 100644
--- a/feathers/audio/locale/de_DE/LC_MESSAGES/audio.po
+++ b/feathers/audio/locale/de_DE/LC_MESSAGES/audio.po
@@ -9,7 +9,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Generator: Poedit 3.4.2\n"
+"X-Generator: Poedit 3.4.4\n"
#. This file is distributed under the same license as the Chyrp Lite package.
#: feathers/audio/audio.php:10
@@ -32,7 +32,7 @@ msgstr "Beschreibung"
msgid "You did not select any audio to upload."
msgstr "Sie haben kein Audio zum Hochladen ausgewählt."
-#: feathers/audio/audio.php:186
+#: feathers/audio/audio.php:192
msgid "Your web browser does not support the audio
element."
msgstr "Ihr Webbrowser unterstützt das Audioelement
nicht."
diff --git a/feathers/audio/locale/en_US/LC_MESSAGES/audio.pot b/feathers/audio/locale/en_US/LC_MESSAGES/audio.pot
index 3719e2f..3c4d3c8 100644
--- a/feathers/audio/locale/en_US/LC_MESSAGES/audio.pot
+++ b/feathers/audio/locale/en_US/LC_MESSAGES/audio.pot
@@ -20,7 +20,7 @@ msgstr ""
msgid "You did not select any audio to upload."
msgstr ""
-#: feathers/audio/audio.php:186
+#: feathers/audio/audio.php:192
msgid "Your web browser does not support the audio
element."
msgstr ""
diff --git a/feathers/audio/locale/fr_FR/LC_MESSAGES/audio.mo b/feathers/audio/locale/fr_FR/LC_MESSAGES/audio.mo
index b53f891..4edfbc9 100644
Binary files a/feathers/audio/locale/fr_FR/LC_MESSAGES/audio.mo and b/feathers/audio/locale/fr_FR/LC_MESSAGES/audio.mo differ
diff --git a/feathers/audio/locale/fr_FR/LC_MESSAGES/audio.po b/feathers/audio/locale/fr_FR/LC_MESSAGES/audio.po
index 6da063a..7899f64 100644
--- a/feathers/audio/locale/fr_FR/LC_MESSAGES/audio.po
+++ b/feathers/audio/locale/fr_FR/LC_MESSAGES/audio.po
@@ -10,7 +10,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
-"X-Generator: Poedit 3.0.1\n"
+"X-Generator: Poedit 3.4.4\n"
#. This file is distributed under the same license as the Chyrp Lite package.
#: feathers/audio/audio.php:10
@@ -33,7 +33,7 @@ msgstr "Description"
msgid "You did not select any audio to upload."
msgstr "Vous n'avez sélectionné aucun fichier audio à télécharger."
-#: feathers/audio/audio.php:186
+#: feathers/audio/audio.php:192
msgid "Your web browser does not support the audio
element."
msgstr "Votre navigateur ne supporte pas cet élément audio."
diff --git a/feathers/audio/locale/it_IT/LC_MESSAGES/audio.mo b/feathers/audio/locale/it_IT/LC_MESSAGES/audio.mo
index eae2c6d..8f5f522 100644
Binary files a/feathers/audio/locale/it_IT/LC_MESSAGES/audio.mo and b/feathers/audio/locale/it_IT/LC_MESSAGES/audio.mo differ
diff --git a/feathers/audio/locale/it_IT/LC_MESSAGES/audio.po b/feathers/audio/locale/it_IT/LC_MESSAGES/audio.po
index e2905a3..fe4d5b2 100644
--- a/feathers/audio/locale/it_IT/LC_MESSAGES/audio.po
+++ b/feathers/audio/locale/it_IT/LC_MESSAGES/audio.po
@@ -10,7 +10,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-"X-Generator: Poedit 3.4.2\n"
+"X-Generator: Poedit 3.4.4\n"
#. This file is distributed under the same license as the Chyrp Lite package.
#: feathers/audio/audio.php:10
@@ -33,7 +33,7 @@ msgstr "Descrizione"
msgid "You did not select any audio to upload."
msgstr "Non è stato selezionato alcun audio da caricare."
-#: feathers/audio/audio.php:186
+#: feathers/audio/audio.php:192
msgid "Your web browser does not support the audio
element."
msgstr "Il browser web non supporta l'elemento audio
."
diff --git a/feathers/audio/locale/nl_NL/LC_MESSAGES/audio.mo b/feathers/audio/locale/nl_NL/LC_MESSAGES/audio.mo
index b054592..5e01ee9 100644
Binary files a/feathers/audio/locale/nl_NL/LC_MESSAGES/audio.mo and b/feathers/audio/locale/nl_NL/LC_MESSAGES/audio.mo differ
diff --git a/feathers/audio/locale/nl_NL/LC_MESSAGES/audio.po b/feathers/audio/locale/nl_NL/LC_MESSAGES/audio.po
index 7db08ad..bb904c6 100644
--- a/feathers/audio/locale/nl_NL/LC_MESSAGES/audio.po
+++ b/feathers/audio/locale/nl_NL/LC_MESSAGES/audio.po
@@ -9,7 +9,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Generator: Poedit 3.4.2\n"
+"X-Generator: Poedit 3.4.4\n"
#. This file is distributed under the same license as the Chyrp Lite package.
#: feathers/audio/audio.php:10
@@ -32,7 +32,7 @@ msgstr "Beschrijving"
msgid "You did not select any audio to upload."
msgstr "Je hebt geen audio geselecteerd om te uploaden."
-#: feathers/audio/audio.php:186
+#: feathers/audio/audio.php:192
msgid "Your web browser does not support the audio
element."
msgstr "Je webbrowser ondersteunt het audio
element niet."
diff --git a/feathers/audio/locale/zh_CN/LC_MESSAGES/audio.mo b/feathers/audio/locale/zh_CN/LC_MESSAGES/audio.mo
index 862384f..7378755 100644
Binary files a/feathers/audio/locale/zh_CN/LC_MESSAGES/audio.mo and b/feathers/audio/locale/zh_CN/LC_MESSAGES/audio.mo differ
diff --git a/feathers/audio/locale/zh_CN/LC_MESSAGES/audio.po b/feathers/audio/locale/zh_CN/LC_MESSAGES/audio.po
index 171a7a1..3755c43 100644
--- a/feathers/audio/locale/zh_CN/LC_MESSAGES/audio.po
+++ b/feathers/audio/locale/zh_CN/LC_MESSAGES/audio.po
@@ -10,7 +10,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Poedit 3.4.2\n"
+"X-Generator: Poedit 3.4.4\n"
#. This file is distributed under the same license as the Chyrp Lite package.
#: feathers/audio/audio.php:10
@@ -33,7 +33,7 @@ msgstr "描述"
msgid "You did not select any audio to upload."
msgstr "你灭有选择任何上传的音频文件。"
-#: feathers/audio/audio.php:186
+#: feathers/audio/audio.php:192
msgid "Your web browser does not support the audio
element."
msgstr "你的浏览器不支持 audio
元素。"
diff --git a/feathers/link/info.php b/feathers/link/info.php
index ad66f9d..dffb428 100644
--- a/feathers/link/info.php
+++ b/feathers/link/info.php
@@ -2,7 +2,7 @@
return array(
"name" => __("Link", "link"),
"url" => "http://chyrplite.net/",
- "version" => "2023.01",
+ "version" => "2024.03",
"description" => __("Link to other sites and add an optional description.", "link"),
"author" => array(
"name" => "Alex Suraci",
diff --git a/feathers/link/link.php b/feathers/link/link.php
index 24b1696..22154c9 100644
--- a/feathers/link/link.php
+++ b/feathers/link/link.php
@@ -65,7 +65,7 @@
"source" => $_POST['source'],
"description" => $_POST['description']
),
- clean:sanitize($_POST['slug']),
+ clean:sanitize($_POST['slug'], true, SLUG_STRICT, 128),
feather:"link",
pinned:!empty($_POST['pinned']),
status:$_POST['status'],
@@ -91,7 +91,7 @@
fallback($_POST['name'], "");
fallback($_POST['description'], "");
- fallback($_POST['slug'], $post->clean);
+ fallback($_POST['slug'], "");
fallback($_POST['status'], $post->status);
fallback($_POST['created_at'], $post->created_at);
fallback($_POST['option'], array());
@@ -106,7 +106,7 @@
),
pinned:!empty($_POST['pinned']),
status:$_POST['status'],
- clean:sanitize($_POST['slug']),
+ clean:sanitize($_POST['slug'], true, SLUG_STRICT, 128),
created_at:datetime($_POST['created_at']),
options:$_POST['option']
);
diff --git a/feathers/photo/info.php b/feathers/photo/info.php
index a5c7c7c..406e050 100644
--- a/feathers/photo/info.php
+++ b/feathers/photo/info.php
@@ -2,7 +2,7 @@
return array(
"name" => __("Photo", "photo"),
"url" => "http://chyrplite.net/",
- "version" => "2024.01",
+ "version" => "2024.03",
"description" => __("Upload and display an image with a caption.", "photo"),
"author" => array(
"name" => "Alex Suraci",
diff --git a/feathers/photo/locale/de_DE/LC_MESSAGES/photo.mo b/feathers/photo/locale/de_DE/LC_MESSAGES/photo.mo
index 53580b1..a4dfd78 100644
Binary files a/feathers/photo/locale/de_DE/LC_MESSAGES/photo.mo and b/feathers/photo/locale/de_DE/LC_MESSAGES/photo.mo differ
diff --git a/feathers/photo/locale/de_DE/LC_MESSAGES/photo.po b/feathers/photo/locale/de_DE/LC_MESSAGES/photo.po
index 84dd227..dde11ab 100644
--- a/feathers/photo/locale/de_DE/LC_MESSAGES/photo.po
+++ b/feathers/photo/locale/de_DE/LC_MESSAGES/photo.po
@@ -9,11 +9,11 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Generator: Poedit 3.4.2\n"
+"X-Generator: Poedit 3.4.4\n"
#. This file is distributed under the same license as the Chyrp Lite package.
#: feathers/photo/admin/help/photo_alt_text.twig:3
-#: feathers/photo/admin/help/photo_alt_text.twig:6 feathers/photo/photo.php:154
+#: feathers/photo/admin/help/photo_alt_text.twig:6 feathers/photo/photo.php:156
msgid "Alternative Text"
msgstr "Alternativer Text"
@@ -59,6 +59,6 @@ msgstr "Bildunterschrift"
msgid "You did not select a photo to upload."
msgstr "Sie haben kein Foto zum Hochladen ausgewählt."
-#: feathers/photo/photo.php:162
+#: feathers/photo/photo.php:164
msgid "Source"
msgstr "Quelle"
diff --git a/feathers/photo/locale/en_US/LC_MESSAGES/photo.pot b/feathers/photo/locale/en_US/LC_MESSAGES/photo.pot
index 1fcc74c..4747cd4 100644
--- a/feathers/photo/locale/en_US/LC_MESSAGES/photo.pot
+++ b/feathers/photo/locale/en_US/LC_MESSAGES/photo.pot
@@ -2,7 +2,7 @@
#: feathers/photo/admin/help/photo_alt_text.twig:3
#: feathers/photo/admin/help/photo_alt_text.twig:6
-#: feathers/photo/photo.php:154
+#: feathers/photo/photo.php:156
msgid "Alternative Text"
msgstr ""
@@ -40,7 +40,7 @@ msgstr ""
msgid "You did not select a photo to upload."
msgstr ""
-#: feathers/photo/photo.php:162
+#: feathers/photo/photo.php:164
msgid "Source"
msgstr ""
diff --git a/feathers/photo/locale/fr_FR/LC_MESSAGES/photo.mo b/feathers/photo/locale/fr_FR/LC_MESSAGES/photo.mo
index 8adfe1a..f8bfc56 100644
Binary files a/feathers/photo/locale/fr_FR/LC_MESSAGES/photo.mo and b/feathers/photo/locale/fr_FR/LC_MESSAGES/photo.mo differ
diff --git a/feathers/photo/locale/fr_FR/LC_MESSAGES/photo.po b/feathers/photo/locale/fr_FR/LC_MESSAGES/photo.po
index 1bf3ea8..9bd649b 100644
--- a/feathers/photo/locale/fr_FR/LC_MESSAGES/photo.po
+++ b/feathers/photo/locale/fr_FR/LC_MESSAGES/photo.po
@@ -10,11 +10,11 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
-"X-Generator: Poedit 3.0.1\n"
+"X-Generator: Poedit 3.4.4\n"
#. This file is distributed under the same license as the Chyrp Lite package.
#: feathers/photo/admin/help/photo_alt_text.twig:3
-#: feathers/photo/admin/help/photo_alt_text.twig:6 feathers/photo/photo.php:154
+#: feathers/photo/admin/help/photo_alt_text.twig:6 feathers/photo/photo.php:156
msgid "Alternative Text"
msgstr "Texte alternatif"
@@ -59,6 +59,6 @@ msgstr "Légende"
msgid "You did not select a photo to upload."
msgstr "Vous n'avez pas sélectionné de photo à télécharger."
-#: feathers/photo/photo.php:162
+#: feathers/photo/photo.php:164
msgid "Source"
msgstr "Source"
diff --git a/feathers/photo/locale/it_IT/LC_MESSAGES/photo.mo b/feathers/photo/locale/it_IT/LC_MESSAGES/photo.mo
index 0c8e3be..786d956 100644
Binary files a/feathers/photo/locale/it_IT/LC_MESSAGES/photo.mo and b/feathers/photo/locale/it_IT/LC_MESSAGES/photo.mo differ
diff --git a/feathers/photo/locale/it_IT/LC_MESSAGES/photo.po b/feathers/photo/locale/it_IT/LC_MESSAGES/photo.po
index 154e95f..46d578e 100644
--- a/feathers/photo/locale/it_IT/LC_MESSAGES/photo.po
+++ b/feathers/photo/locale/it_IT/LC_MESSAGES/photo.po
@@ -10,11 +10,11 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-"X-Generator: Poedit 3.4.2\n"
+"X-Generator: Poedit 3.4.4\n"
#. This file is distributed under the same license as the Chyrp Lite package.
#: feathers/photo/admin/help/photo_alt_text.twig:3
-#: feathers/photo/admin/help/photo_alt_text.twig:6 feathers/photo/photo.php:154
+#: feathers/photo/admin/help/photo_alt_text.twig:6 feathers/photo/photo.php:156
msgid "Alternative Text"
msgstr "Testo Alternative"
@@ -59,6 +59,6 @@ msgstr "Didascalia"
msgid "You did not select a photo to upload."
msgstr "Non é stata selezionata alcuna foto da caricare."
-#: feathers/photo/photo.php:162
+#: feathers/photo/photo.php:164
msgid "Source"
msgstr "Sorgente"
diff --git a/feathers/photo/locale/nl_NL/LC_MESSAGES/photo.mo b/feathers/photo/locale/nl_NL/LC_MESSAGES/photo.mo
index fb2a7aa..4991bbd 100644
Binary files a/feathers/photo/locale/nl_NL/LC_MESSAGES/photo.mo and b/feathers/photo/locale/nl_NL/LC_MESSAGES/photo.mo differ
diff --git a/feathers/photo/locale/nl_NL/LC_MESSAGES/photo.po b/feathers/photo/locale/nl_NL/LC_MESSAGES/photo.po
index eaa3146..f180210 100644
--- a/feathers/photo/locale/nl_NL/LC_MESSAGES/photo.po
+++ b/feathers/photo/locale/nl_NL/LC_MESSAGES/photo.po
@@ -9,11 +9,11 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Generator: Poedit 3.4.2\n"
+"X-Generator: Poedit 3.4.4\n"
#. This file is distributed under the same license as the Chyrp Lite package.
#: feathers/photo/admin/help/photo_alt_text.twig:3
-#: feathers/photo/admin/help/photo_alt_text.twig:6 feathers/photo/photo.php:154
+#: feathers/photo/admin/help/photo_alt_text.twig:6 feathers/photo/photo.php:156
msgid "Alternative Text"
msgstr "Alternatieve tekst"
@@ -58,6 +58,6 @@ msgstr "Toelichting"
msgid "You did not select a photo to upload."
msgstr "Je hebt geen afbeelding geslecteerd om te uploaden."
-#: feathers/photo/photo.php:162
+#: feathers/photo/photo.php:164
msgid "Source"
msgstr "Bron"
diff --git a/feathers/photo/locale/zh_CN/LC_MESSAGES/photo.mo b/feathers/photo/locale/zh_CN/LC_MESSAGES/photo.mo
index 1a21b35..d458ae1 100644
Binary files a/feathers/photo/locale/zh_CN/LC_MESSAGES/photo.mo and b/feathers/photo/locale/zh_CN/LC_MESSAGES/photo.mo differ
diff --git a/feathers/photo/locale/zh_CN/LC_MESSAGES/photo.po b/feathers/photo/locale/zh_CN/LC_MESSAGES/photo.po
index e824133..a9afc46 100644
--- a/feathers/photo/locale/zh_CN/LC_MESSAGES/photo.po
+++ b/feathers/photo/locale/zh_CN/LC_MESSAGES/photo.po
@@ -10,11 +10,11 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Poedit 3.4.2\n"
+"X-Generator: Poedit 3.4.4\n"
#. This file is distributed under the same license as the Chyrp Lite package.
#: feathers/photo/admin/help/photo_alt_text.twig:3
-#: feathers/photo/admin/help/photo_alt_text.twig:6 feathers/photo/photo.php:154
+#: feathers/photo/admin/help/photo_alt_text.twig:6 feathers/photo/photo.php:156
msgid "Alternative Text"
msgstr "替代文本"
@@ -57,6 +57,6 @@ msgstr "标题"
msgid "You did not select a photo to upload."
msgstr "您没有选择上传的照片。"
-#: feathers/photo/photo.php:162
+#: feathers/photo/photo.php:164
msgid "Source"
msgstr "来源"
diff --git a/feathers/photo/photo.php b/feathers/photo/photo.php
index 837fba9..060e431 100644
--- a/feathers/photo/photo.php
+++ b/feathers/photo/photo.php
@@ -55,15 +55,16 @@
code:422
);
- if (isset($_POST['option']['source']) and is_url($_POST['option']['source']))
- $_POST['option']['source'] = add_scheme($_POST['option']['source']);
-
fallback($_POST['title'], "");
fallback($_POST['caption'], "");
fallback($_POST['slug'], $_POST['title']);
fallback($_POST['status'], "public");
fallback($_POST['created_at'], datetime());
fallback($_POST['option'], array());
+ fallback($_POST['option']['source'], "");
+
+ if (is_url($_POST['option']['source']))
+ $_POST['option']['source'] = add_scheme($_POST['option']['source']);
return Post::add(
values:array(
@@ -71,7 +72,7 @@
"filename" => $filename,
"caption" => $_POST['caption']
),
- clean:sanitize($_POST['slug']),
+ clean:sanitize($_POST['slug'], true, SLUG_STRICT, 128),
feather:"photo",
pinned:!empty($_POST['pinned']),
status:$_POST['status'],
@@ -84,13 +85,14 @@
public function update($post): Post|false {
fallback($_POST['title'], "");
fallback($_POST['caption'], "");
- fallback($_POST['slug'], $post->clean);
+ fallback($_POST['slug'], "");
fallback($_POST['status'], $post->status);
fallback($_POST['created_at'], $post->created_at);
fallback($_POST['option'], array());
+ fallback($_POST['option']['source'], "");
$filename = $post->filename;
- if (isset($_POST['option']['source']) and is_url($_POST['option']['source']))
+ if (is_url($_POST['option']['source']))
$_POST['option']['source'] = add_scheme($_POST['option']['source']);
if (isset($_FILES['filename']) and upload_tester($_FILES['filename']))
@@ -107,7 +109,7 @@
),
pinned:!empty($_POST['pinned']),
status:$_POST['status'],
- clean:sanitize($_POST['slug']),
+ clean:sanitize($_POST['slug'], true, SLUG_STRICT, 128),
created_at:datetime($_POST['created_at']),
options:$_POST['option']
);
diff --git a/feathers/quote/info.php b/feathers/quote/info.php
index f269758..f9e33a8 100644
--- a/feathers/quote/info.php
+++ b/feathers/quote/info.php
@@ -2,7 +2,7 @@
return array(
"name" => __("Quote", "quote"),
"url" => "http://chyrplite.net/",
- "version" => "2023.01",
+ "version" => "2024.03",
"description" => __("Post quotes and cite sources.", "quote"),
"author" => array(
"name" => "Alex Suraci",
diff --git a/feathers/quote/quote.php b/feathers/quote/quote.php
index 02ce434..1731cf6 100644
--- a/feathers/quote/quote.php
+++ b/feathers/quote/quote.php
@@ -47,7 +47,7 @@
"quote" => $_POST['quote'],
"source" => $_POST['source']
),
- clean:sanitize($_POST['slug']),
+ clean:sanitize($_POST['slug'], true, SLUG_STRICT, 128),
feather:"quote",
pinned:!empty($_POST['pinned']),
status:$_POST['status'],
@@ -66,7 +66,7 @@
);
fallback($_POST['source'], "");
- fallback($_POST['slug'], $post->clean);
+ fallback($_POST['slug'], "");
fallback($_POST['status'], $post->status);
fallback($_POST['created_at'], $post->created_at);
fallback($_POST['option'], array());
@@ -78,7 +78,7 @@
),
pinned:!empty($_POST['pinned']),
status:$_POST['status'],
- clean:sanitize($_POST['slug']),
+ clean:sanitize($_POST['slug'], true, SLUG_STRICT, 128),
created_at:datetime($_POST['created_at']),
options:$_POST['option']
);
diff --git a/feathers/text/info.php b/feathers/text/info.php
index d1aa43f..a732f2f 100644
--- a/feathers/text/info.php
+++ b/feathers/text/info.php
@@ -2,7 +2,7 @@
return array(
"name" => __("Text", "text"),
"url" => "http://chyrplite.net/",
- "version" => "2023.01",
+ "version" => "2024.03",
"description" => __("A basic text feather.", "text"),
"author" => array(
"name" => "Chyrp Team",
diff --git a/feathers/text/text.php b/feathers/text/text.php
index e625c2f..9ae5959 100644
--- a/feathers/text/text.php
+++ b/feathers/text/text.php
@@ -46,7 +46,7 @@
"title" => $_POST['title'],
"body" => $_POST['body']
),
- clean:sanitize($_POST['slug']),
+ clean:sanitize($_POST['slug'], true, SLUG_STRICT, 128),
feather:"text",
pinned:!empty($_POST['pinned']),
status:$_POST['status'],
@@ -65,7 +65,7 @@
);
fallback($_POST['title'], "");
- fallback($_POST['slug'], $post->clean);
+ fallback($_POST['slug'], "");
fallback($_POST['status'], $post->status);
fallback($_POST['created_at'], $post->created_at);
fallback($_POST['option'], array());
@@ -77,7 +77,7 @@
),
pinned:!empty($_POST['pinned']),
status:$_POST['status'],
- clean:sanitize($_POST['slug']),
+ clean:sanitize($_POST['slug'], true, SLUG_STRICT, 128),
created_at:datetime($_POST['created_at']),
options:$_POST['option']
);
diff --git a/feathers/uploader/info.php b/feathers/uploader/info.php
index b3e4ff6..e4d75df 100644
--- a/feathers/uploader/info.php
+++ b/feathers/uploader/info.php
@@ -2,7 +2,7 @@
return array(
"name" => __("Uploader", "uploader"),
"url" => "http://chyrplite.net/",
- "version" => "2024.01",
+ "version" => "2024.03",
"description" => __("Upload files and make them available for visitors to download.", "uploader"),
"author" => array(
"name" => "Daniel Pimley",
diff --git a/feathers/uploader/locale/de_DE/LC_MESSAGES/uploader.mo b/feathers/uploader/locale/de_DE/LC_MESSAGES/uploader.mo
index bd12f87..5880464 100644
Binary files a/feathers/uploader/locale/de_DE/LC_MESSAGES/uploader.mo and b/feathers/uploader/locale/de_DE/LC_MESSAGES/uploader.mo differ
diff --git a/feathers/uploader/locale/de_DE/LC_MESSAGES/uploader.po b/feathers/uploader/locale/de_DE/LC_MESSAGES/uploader.po
index fdedc2c..37eeae4 100644
--- a/feathers/uploader/locale/de_DE/LC_MESSAGES/uploader.po
+++ b/feathers/uploader/locale/de_DE/LC_MESSAGES/uploader.po
@@ -9,7 +9,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Generator: Poedit 3.4.2\n"
+"X-Generator: Poedit 3.4.4\n"
#. This file is distributed under the same license as the Chyrp Lite package.
#: feathers/uploader/admin/help/uploader_source.twig:3
@@ -45,6 +45,6 @@ msgstr "Unterschrift"
msgid "You did not select any files to upload."
msgstr "Sie haben keine Dateien zum hochladen selektiert."
-#: feathers/uploader/uploader.php:214
+#: feathers/uploader/uploader.php:216
msgid "Source"
msgstr "Quelle"
diff --git a/feathers/uploader/locale/en_US/LC_MESSAGES/uploader.pot b/feathers/uploader/locale/en_US/LC_MESSAGES/uploader.pot
index 6136dc6..0919cd0 100644
--- a/feathers/uploader/locale/en_US/LC_MESSAGES/uploader.pot
+++ b/feathers/uploader/locale/en_US/LC_MESSAGES/uploader.pot
@@ -33,7 +33,7 @@ msgstr ""
msgid "You did not select any files to upload."
msgstr ""
-#: feathers/uploader/uploader.php:214
+#: feathers/uploader/uploader.php:216
msgid "Source"
msgstr ""
diff --git a/feathers/uploader/locale/fr_FR/LC_MESSAGES/uploader.mo b/feathers/uploader/locale/fr_FR/LC_MESSAGES/uploader.mo
index 1968c0a..58715e7 100644
Binary files a/feathers/uploader/locale/fr_FR/LC_MESSAGES/uploader.mo and b/feathers/uploader/locale/fr_FR/LC_MESSAGES/uploader.mo differ
diff --git a/feathers/uploader/locale/fr_FR/LC_MESSAGES/uploader.po b/feathers/uploader/locale/fr_FR/LC_MESSAGES/uploader.po
index 2dcd8eb..8a492d1 100644
--- a/feathers/uploader/locale/fr_FR/LC_MESSAGES/uploader.po
+++ b/feathers/uploader/locale/fr_FR/LC_MESSAGES/uploader.po
@@ -10,7 +10,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
-"X-Generator: Poedit 3.0.1\n"
+"X-Generator: Poedit 3.4.4\n"
#. This file is distributed under the same license as the Chyrp Lite package.
#: feathers/uploader/admin/help/uploader_source.twig:3
@@ -46,6 +46,6 @@ msgstr "Légende"
msgid "You did not select any files to upload."
msgstr "Vous n'avez pas sélectionné de fichier à télécharger."
-#: feathers/uploader/uploader.php:214
+#: feathers/uploader/uploader.php:216
msgid "Source"
msgstr "Source"
diff --git a/feathers/uploader/locale/it_IT/LC_MESSAGES/uploader.mo b/feathers/uploader/locale/it_IT/LC_MESSAGES/uploader.mo
index d22d37f..8db354d 100644
Binary files a/feathers/uploader/locale/it_IT/LC_MESSAGES/uploader.mo and b/feathers/uploader/locale/it_IT/LC_MESSAGES/uploader.mo differ
diff --git a/feathers/uploader/locale/it_IT/LC_MESSAGES/uploader.po b/feathers/uploader/locale/it_IT/LC_MESSAGES/uploader.po
index 92740bb..9d7890e 100644
--- a/feathers/uploader/locale/it_IT/LC_MESSAGES/uploader.po
+++ b/feathers/uploader/locale/it_IT/LC_MESSAGES/uploader.po
@@ -10,7 +10,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-"X-Generator: Poedit 3.4.2\n"
+"X-Generator: Poedit 3.4.4\n"
#. This file is distributed under the same license as the Chyrp Lite package.
#: feathers/uploader/admin/help/uploader_source.twig:3
@@ -46,6 +46,6 @@ msgstr "Didascalia"
msgid "You did not select any files to upload."
msgstr "Non è stato selezionato alcun file da caricare."
-#: feathers/uploader/uploader.php:214
+#: feathers/uploader/uploader.php:216
msgid "Source"
msgstr "Sorgente"
diff --git a/feathers/uploader/locale/nl_NL/LC_MESSAGES/uploader.mo b/feathers/uploader/locale/nl_NL/LC_MESSAGES/uploader.mo
index 32bcc14..44b3496 100644
Binary files a/feathers/uploader/locale/nl_NL/LC_MESSAGES/uploader.mo and b/feathers/uploader/locale/nl_NL/LC_MESSAGES/uploader.mo differ
diff --git a/feathers/uploader/locale/nl_NL/LC_MESSAGES/uploader.po b/feathers/uploader/locale/nl_NL/LC_MESSAGES/uploader.po
index 3bbb293..8a2b8da 100644
--- a/feathers/uploader/locale/nl_NL/LC_MESSAGES/uploader.po
+++ b/feathers/uploader/locale/nl_NL/LC_MESSAGES/uploader.po
@@ -9,7 +9,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Generator: Poedit 3.4.2\n"
+"X-Generator: Poedit 3.4.4\n"
#. This file is distributed under the same license as the Chyrp Lite package.
#: feathers/uploader/admin/help/uploader_source.twig:3
@@ -45,6 +45,6 @@ msgstr "Toelichting"
msgid "You did not select any files to upload."
msgstr "Je hebt geen bestanden geselecteerd om te uploaden."
-#: feathers/uploader/uploader.php:214
+#: feathers/uploader/uploader.php:216
msgid "Source"
msgstr "Bron"
diff --git a/feathers/uploader/locale/zh_CN/LC_MESSAGES/uploader.mo b/feathers/uploader/locale/zh_CN/LC_MESSAGES/uploader.mo
index 737fff4..b10131c 100644
Binary files a/feathers/uploader/locale/zh_CN/LC_MESSAGES/uploader.mo and b/feathers/uploader/locale/zh_CN/LC_MESSAGES/uploader.mo differ
diff --git a/feathers/uploader/locale/zh_CN/LC_MESSAGES/uploader.po b/feathers/uploader/locale/zh_CN/LC_MESSAGES/uploader.po
index 0c44dc2..47f7248 100644
--- a/feathers/uploader/locale/zh_CN/LC_MESSAGES/uploader.po
+++ b/feathers/uploader/locale/zh_CN/LC_MESSAGES/uploader.po
@@ -10,7 +10,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Poedit 3.4.2\n"
+"X-Generator: Poedit 3.4.4\n"
#. This file is distributed under the same license as the Chyrp Lite package.
#: feathers/uploader/admin/help/uploader_source.twig:3
@@ -46,6 +46,6 @@ msgstr "说明"
msgid "You did not select any files to upload."
msgstr "您没有选择任何文件上传。"
-#: feathers/uploader/uploader.php:214
+#: feathers/uploader/uploader.php:216
msgid "Source"
msgstr "来源"
diff --git a/feathers/uploader/uploader.php b/feathers/uploader/uploader.php
index 8c3d461..2a8a3cd 100644
--- a/feathers/uploader/uploader.php
+++ b/feathers/uploader/uploader.php
@@ -78,15 +78,16 @@
code:422
);
- if (isset($_POST['option']['source']) and is_url($_POST['option']['source']))
- $_POST['option']['source'] = add_scheme($_POST['option']['source']);
-
fallback($_POST['title'], "");
fallback($_POST['caption'], "");
fallback($_POST['slug'], $_POST['title']);
fallback($_POST['status'], "public");
fallback($_POST['created_at'], datetime());
fallback($_POST['option'], array());
+ fallback($_POST['option']['source'], "");
+
+ if (is_url($_POST['option']['source']))
+ $_POST['option']['source'] = add_scheme($_POST['option']['source']);
return Post::add(
values:array(
@@ -94,7 +95,7 @@
"caption" => $_POST['caption'],
"title" => $_POST['title']
),
- clean:sanitize($_POST['slug']),
+ clean:sanitize($_POST['slug'], true, SLUG_STRICT, 128),
feather:"uploader",
pinned:!empty($_POST['pinned']),
status:$_POST['status'],
@@ -107,13 +108,14 @@
public function update($post): Post|false {
fallback($_POST['title'], "");
fallback($_POST['caption'], "");
- fallback($_POST['slug'], $post->clean);
+ fallback($_POST['slug'], "");
fallback($_POST['status'], $post->status);
fallback($_POST['created_at'], $post->created_at);
fallback($_POST['option'], array());
+ fallback($_POST['option']['source'], "");
$filenames = $post->filenames;
- if (isset($_POST['option']['source']) and is_url($_POST['option']['source']))
+ if (is_url($_POST['option']['source']))
$_POST['option']['source'] = add_scheme($_POST['option']['source']);
if (isset($_FILES['filenames']) and upload_tester($_FILES['filenames'])) {
@@ -143,7 +145,7 @@
),
pinned:!empty($_POST['pinned']),
status:$_POST['status'],
- clean:sanitize($_POST['slug']),
+ clean:sanitize($_POST['slug'], true, SLUG_STRICT, 128),
created_at:datetime($_POST['created_at']),
options:$_POST['option']
);
diff --git a/feathers/video/info.php b/feathers/video/info.php
index fd06796..f93a345 100644
--- a/feathers/video/info.php
+++ b/feathers/video/info.php
@@ -2,7 +2,7 @@
return array(
"name" => __("Video", "video"),
"url" => "http://chyrplite.net/",
- "version" => "2024.01",
+ "version" => "2024.03",
"description" => __("A feather for video.", "video"),
"author" => array(
"name" => "Daniel Pimley",
diff --git a/feathers/video/video.php b/feathers/video/video.php
index f89a142..39dbead 100644
--- a/feathers/video/video.php
+++ b/feathers/video/video.php
@@ -102,7 +102,7 @@
"poster_image" => fallback($poster_image, ""),
"description" => $_POST['description']
),
- clean:sanitize($_POST['slug']),
+ clean:sanitize($_POST['slug'], true, SLUG_STRICT, 128),
feather:"video",
pinned:!empty($_POST['pinned']),
status:$_POST['status'],
@@ -115,7 +115,7 @@
public function update($post): Post|false {
fallback($_POST['title'], "");
fallback($_POST['description'], "");
- fallback($_POST['slug'], $post->clean);
+ fallback($_POST['slug'], "");
fallback($_POST['status'], $post->status);
fallback($_POST['created_at'], $post->created_at);
fallback($_POST['option'], array());
@@ -151,7 +151,7 @@
),
pinned:!empty($_POST['pinned']),
status:$_POST['status'],
- clean:sanitize($_POST['slug']),
+ clean:sanitize($_POST['slug'], true, SLUG_STRICT, 128),
created_at:datetime($_POST['created_at']),
options:$_POST['option']
);
diff --git a/includes/cacert.pem b/includes/cacert.pem
index d8fda7d..86d6cd8 100644
--- a/includes/cacert.pem
+++ b/includes/cacert.pem
@@ -1,7 +1,7 @@
##
## Bundle of CA Root Certificates
##
-## Certificate data from Mozilla as of: Tue Dec 12 04:12:04 2023 GMT
+## Certificate data from Mozilla as of: Tue Jul 2 03:12:04 2024 GMT
##
## This is a bundle of X.509 certificates of public Certificate Authorities
## (CA). These were automatically extracted from Mozilla's root certificates
@@ -14,7 +14,7 @@
## Just configure this file as the SSLCACertificateFile.
##
## Conversion done with mk-ca-bundle.pl version 1.29.
-## SHA256: 1970dd65858925d68498d2356aea6d03f764422523c5887deca8ce3ba9e1f845
+## SHA256: 456ff095dde6dd73354c5c28c73d9c06f53b61a803963414cb91a1d92945cdd3
##
@@ -2600,36 +2600,6 @@ vLtoURMMA/cVi4RguYv/Uo7njLwcAjA8+RHUjE7AwWHCFUyqqx0LMV87HOIAl0Qx5v5zli/altP+
CAezNIm8BZ/3Hobui3A=
-----END CERTIFICATE-----
-GLOBALTRUST 2020
-================
------BEGIN CERTIFICATE-----
-MIIFgjCCA2qgAwIBAgILWku9WvtPilv6ZeUwDQYJKoZIhvcNAQELBQAwTTELMAkGA1UEBhMCQVQx
-IzAhBgNVBAoTGmUtY29tbWVyY2UgbW9uaXRvcmluZyBHbWJIMRkwFwYDVQQDExBHTE9CQUxUUlVT
-VCAyMDIwMB4XDTIwMDIxMDAwMDAwMFoXDTQwMDYxMDAwMDAwMFowTTELMAkGA1UEBhMCQVQxIzAh
-BgNVBAoTGmUtY29tbWVyY2UgbW9uaXRvcmluZyBHbWJIMRkwFwYDVQQDExBHTE9CQUxUUlVTVCAy
-MDIwMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAri5WrRsc7/aVj6B3GyvTY4+ETUWi
-D59bRatZe1E0+eyLinjF3WuvvcTfk0Uev5E4C64OFudBc/jbu9G4UeDLgztzOG53ig9ZYybNpyrO
-VPu44sB8R85gfD+yc/LAGbaKkoc1DZAoouQVBGM+uq/ufF7MpotQsjj3QWPKzv9pj2gOlTblzLmM
-CcpL3TGQlsjMH/1WljTbjhzqLL6FLmPdqqmV0/0plRPwyJiT2S0WR5ARg6I6IqIoV6Lr/sCMKKCm
-fecqQjuCgGOlYx8ZzHyyZqjC0203b+J+BlHZRYQfEs4kUmSFC0iAToexIiIwquuuvuAC4EDosEKA
-A1GqtH6qRNdDYfOiaxaJSaSjpCuKAsR49GiKweR6NrFvG5Ybd0mN1MkGco/PU+PcF4UgStyYJ9OR
-JitHHmkHr96i5OTUawuzXnzUJIBHKWk7buis/UDr2O1xcSvy6Fgd60GXIsUf1DnQJ4+H4xj04KlG
-DfV0OoIu0G4skaMxXDtG6nsEEFZegB31pWXogvziB4xiRfUg3kZwhqG8k9MedKZssCz3AwyIDMvU
-clOGvGBG85hqwvG/Q/lwIHfKN0F5VVJjjVsSn8VoxIidrPIwq7ejMZdnrY8XD2zHc+0klGvIg5rQ
-mjdJBKuxFshsSUktq6HQjJLyQUp5ISXbY9e2nKd+Qmn7OmMCAwEAAaNjMGEwDwYDVR0TAQH/BAUw
-AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFNwuH9FhN3nkq9XVsxJxaD1qaJwiMB8GA1Ud
-IwQYMBaAFNwuH9FhN3nkq9XVsxJxaD1qaJwiMA0GCSqGSIb3DQEBCwUAA4ICAQCR8EICaEDuw2jA
-VC/f7GLDw56KoDEoqoOOpFaWEhCGVrqXctJUMHytGdUdaG/7FELYjQ7ztdGl4wJCXtzoRlgHNQIw
-4Lx0SsFDKv/bGtCwr2zD/cuz9X9tAy5ZVp0tLTWMstZDFyySCstd6IwPS3BD0IL/qMy/pJTAvoe9
-iuOTe8aPmxadJ2W8esVCgmxcB9CpwYhgROmYhRZf+I/KARDOJcP5YBugxZfD0yyIMaK9MOzQ0MAS
-8cE54+X1+NZK3TTN+2/BT+MAi1bikvcoskJ3ciNnxz8RFbLEAwW+uxF7Cr+obuf/WEPPm2eggAe2
-HcqtbepBEX4tdJP7wry+UUTF72glJ4DjyKDUEuzZpTcdN3y0kcra1LGWge9oXHYQSa9+pTeAsRxS
-vTOBTI/53WXZFM2KJVj04sWDpQmQ1GwUY7VA3+vA/MRYfg0UFodUJ25W5HCEuGwyEn6CMUO+1918
-oa2u1qsgEu8KwxCMSZY13At1XrFP1U80DhEgB3VDRemjEdqso5nCtnkn4rnvyOL2NSl6dPrFf4IF
-YqYK6miyeUcGbvJXqBUzxvd4Sj1Ce2t+/vdG6tHrju+IaFvowdlxfv1k7/9nR4hYJS8+hge9+6jl
-gqispdNpQ80xiEmEU5LAsTkbOYMBMMTyqfrQA71yN2BWHzZ8vTmR9W0Nv3vXkg==
------END CERTIFICATE-----
-
ANF Secure Server Root CA
=========================
-----BEGIN CERTIFICATE-----
@@ -3532,3 +3502,67 @@ dVwPaFsdZcJfMw8eD/A7hvWwTruc9+olBdytoptLFwG+Qt81IR2tq670v64fG9PiO/yzcnMcmyiQ
iRM9HcEARwmWmjgb3bHPDcK0RPOWlc4yOo80nOAXx17Org3bhzjlP1v9mxnhMUF6cKojawHhRUzN
lM47ni3niAIi9G7oyOzWPPO5std3eqx7
-----END CERTIFICATE-----
+
+Telekom Security TLS ECC Root 2020
+==================================
+-----BEGIN CERTIFICATE-----
+MIICQjCCAcmgAwIBAgIQNjqWjMlcsljN0AFdxeVXADAKBggqhkjOPQQDAzBjMQswCQYDVQQGEwJE
+RTEnMCUGA1UECgweRGV1dHNjaGUgVGVsZWtvbSBTZWN1cml0eSBHbWJIMSswKQYDVQQDDCJUZWxl
+a29tIFNlY3VyaXR5IFRMUyBFQ0MgUm9vdCAyMDIwMB4XDTIwMDgyNTA3NDgyMFoXDTQ1MDgyNTIz
+NTk1OVowYzELMAkGA1UEBhMCREUxJzAlBgNVBAoMHkRldXRzY2hlIFRlbGVrb20gU2VjdXJpdHkg
+R21iSDErMCkGA1UEAwwiVGVsZWtvbSBTZWN1cml0eSBUTFMgRUNDIFJvb3QgMjAyMDB2MBAGByqG
+SM49AgEGBSuBBAAiA2IABM6//leov9Wq9xCazbzREaK9Z0LMkOsVGJDZos0MKiXrPk/OtdKPD/M1
+2kOLAoC+b1EkHQ9rK8qfwm9QMuU3ILYg/4gND21Ju9sGpIeQkpT0CdDPf8iAC8GXs7s1J8nCG6NC
+MEAwHQYDVR0OBBYEFONyzG6VmUex5rNhTNHLq+O6zd6fMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0P
+AQH/BAQDAgEGMAoGCCqGSM49BAMDA2cAMGQCMHVSi7ekEE+uShCLsoRbQuHmKjYC2qBuGT8lv9pZ
+Mo7k+5Dck2TOrbRBR2Diz6fLHgIwN0GMZt9Ba9aDAEH9L1r3ULRn0SyocddDypwnJJGDSA3PzfdU
+ga/sf+Rn27iQ7t0l
+-----END CERTIFICATE-----
+
+Telekom Security TLS RSA Root 2023
+==================================
+-----BEGIN CERTIFICATE-----
+MIIFszCCA5ugAwIBAgIQIZxULej27HF3+k7ow3BXlzANBgkqhkiG9w0BAQwFADBjMQswCQYDVQQG
+EwJERTEnMCUGA1UECgweRGV1dHNjaGUgVGVsZWtvbSBTZWN1cml0eSBHbWJIMSswKQYDVQQDDCJU
+ZWxla29tIFNlY3VyaXR5IFRMUyBSU0EgUm9vdCAyMDIzMB4XDTIzMDMyODEyMTY0NVoXDTQ4MDMy
+NzIzNTk1OVowYzELMAkGA1UEBhMCREUxJzAlBgNVBAoMHkRldXRzY2hlIFRlbGVrb20gU2VjdXJp
+dHkgR21iSDErMCkGA1UEAwwiVGVsZWtvbSBTZWN1cml0eSBUTFMgUlNBIFJvb3QgMjAyMzCCAiIw
+DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAO01oYGA88tKaVvC+1GDrib94W7zgRJ9cUD/h3VC
+KSHtgVIs3xLBGYSJwb3FKNXVS2xE1kzbB5ZKVXrKNoIENqil/Cf2SfHVcp6R+SPWcHu79ZvB7JPP
+GeplfohwoHP89v+1VmLhc2o0mD6CuKyVU/QBoCcHcqMAU6DksquDOFczJZSfvkgdmOGjup5czQRx
+UX11eKvzWarE4GC+j4NSuHUaQTXtvPM6Y+mpFEXX5lLRbtLevOP1Czvm4MS9Q2QTps70mDdsipWo
+l8hHD/BeEIvnHRz+sTugBTNoBUGCwQMrAcjnj02r6LX2zWtEtefdi+zqJbQAIldNsLGyMcEWzv/9
+FIS3R/qy8XDe24tsNlikfLMR0cN3f1+2JeANxdKz+bi4d9s3cXFH42AYTyS2dTd4uaNir73Jco4v
+zLuu2+QVUhkHM/tqty1LkCiCc/4YizWN26cEar7qwU02OxY2kTLvtkCJkUPg8qKrBC7m8kwOFjQg
+rIfBLX7JZkcXFBGk8/ehJImr2BrIoVyxo/eMbcgByU/J7MT8rFEz0ciD0cmfHdRHNCk+y7AO+oML
+KFjlKdw/fKifybYKu6boRhYPluV75Gp6SG12mAWl3G0eQh5C2hrgUve1g8Aae3g1LDj1H/1Joy7S
+WWO/gLCMk3PLNaaZlSJhZQNg+y+TS/qanIA7AgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAdBgNV
+HQ4EFgQUtqeXgj10hZv3PJ+TmpV5dVKMbUcwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBS2
+p5eCPXSFm/c8n5OalXl1UoxtRzANBgkqhkiG9w0BAQwFAAOCAgEAqMxhpr51nhVQpGv7qHBFfLp+
+sVr8WyP6Cnf4mHGCDG3gXkaqk/QeoMPhk9tLrbKmXauw1GLLXrtm9S3ul0A8Yute1hTWjOKWi0Fp
+kzXmuZlrYrShF2Y0pmtjxrlO8iLpWA1WQdH6DErwM807u20hOq6OcrXDSvvpfeWxm4bu4uB9tPcy
+/SKE8YXJN3nptT+/XOR0so8RYgDdGGah2XsjX/GO1WfoVNpbOms2b/mBsTNHM3dA+VKq3dSDz4V4
+mZqTuXNnQkYRIer+CqkbGmVps4+uFrb2S1ayLfmlyOw7YqPta9BO1UAJpB+Y1zqlklkg5LB9zVtz
+aL1txKITDmcZuI1CfmwMmm6gJC3VRRvcxAIU/oVbZZfKTpBQCHpCNfnqwmbU+AGuHrS+w6jv/naa
+oqYfRvaE7fzbzsQCzndILIyy7MMAo+wsVRjBfhnu4S/yrYObnqsZ38aKL4x35bcF7DvB7L6Gs4a8
+wPfc5+pbrrLMtTWGS9DiP7bY+A4A7l3j941Y/8+LN+ljX273CXE2whJdV/LItM3z7gLfEdxquVeE
+HVlNjM7IDiPCtyaaEBRx/pOyiriA8A4QntOoUAw3gi/q4Iqd4Sw5/7W0cwDk90imc6y/st53BIe0
+o82bNSQ3+pCTE4FCxpgmdTdmQRCsu/WU48IxK63nI1bMNSWSs1A=
+-----END CERTIFICATE-----
+
+FIRMAPROFESIONAL CA ROOT-A WEB
+==============================
+-----BEGIN CERTIFICATE-----
+MIICejCCAgCgAwIBAgIQMZch7a+JQn81QYehZ1ZMbTAKBggqhkjOPQQDAzBuMQswCQYDVQQGEwJF
+UzEcMBoGA1UECgwTRmlybWFwcm9mZXNpb25hbCBTQTEYMBYGA1UEYQwPVkFURVMtQTYyNjM0MDY4
+MScwJQYDVQQDDB5GSVJNQVBST0ZFU0lPTkFMIENBIFJPT1QtQSBXRUIwHhcNMjIwNDA2MDkwMTM2
+WhcNNDcwMzMxMDkwMTM2WjBuMQswCQYDVQQGEwJFUzEcMBoGA1UECgwTRmlybWFwcm9mZXNpb25h
+bCBTQTEYMBYGA1UEYQwPVkFURVMtQTYyNjM0MDY4MScwJQYDVQQDDB5GSVJNQVBST0ZFU0lPTkFM
+IENBIFJPT1QtQSBXRUIwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAARHU+osEaR3xyrq89Zfe9MEkVz6
+iMYiuYMQYneEMy3pA4jU4DP37XcsSmDq5G+tbbT4TIqk5B/K6k84Si6CcyvHZpsKjECcfIr28jlg
+st7L7Ljkb+qbXbdTkBgyVcUgt5SjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUk+FD
+Y1w8ndYn81LsF7Kpryz3dvgwHQYDVR0OBBYEFJPhQ2NcPJ3WJ/NS7Beyqa8s93b4MA4GA1UdDwEB
+/wQEAwIBBjAKBggqhkjOPQQDAwNoADBlAjAdfKR7w4l1M+E7qUW/Runpod3JIha3RxEL2Jq68cgL
+cFBTApFwhVmpHqTm6iMxoAACMQD94vizrxa5HnPEluPBMBnYfubDl94cT7iJLzPrSA8Z94dGXSaQ
+pYXFuXqUPoeovQA=
+-----END CERTIFICATE-----
diff --git a/includes/caddyfile.conf b/includes/caddyfile.conf
index ff37063..f76835b 100644
--- a/includes/caddyfile.conf
+++ b/includes/caddyfile.conf
@@ -8,6 +8,10 @@
# #...
# }
+@twigs {
+ path *.twig
+}
+
@admin {
path /{chyrp_path}/admin/*
file {
@@ -22,6 +26,6 @@
}
}
-rewrite *.twig /{chyrp_path}/index.php
+rewrite @twigs /{chyrp_path}/index.php
rewrite @admin {http.matchers.file.relative}
rewrite @chyrp {http.matchers.file.relative}
diff --git a/includes/class/Model.php b/includes/class/Model.php
index 6581262..f1e3df7 100644
--- a/includes/class/Model.php
+++ b/includes/class/Model.php
@@ -56,7 +56,10 @@
$this->has_many = (array) $this->has_many;
$this->has_one = (array) $this->has_one;
- if (in_array($name, $this->belongs_to) or isset($this->belongs_to[$name])) {
+ if (
+ in_array($name, $this->belongs_to) or
+ isset($this->belongs_to[$name])
+ ) {
if (isset($this->belongs_to[$name])) {
$opts =& $this->belongs_to[$name];
@@ -68,7 +71,11 @@
$opts["by"] :
strtolower($name) ;
- fallback($opts["where"], array("id" => $this->data[$match."_id"]));
+ fallback(
+ $opts["where"],
+ array("id" => $this->data[$match."_id"])
+ );
+
$opts["where"] = (array) $opts["where"];
} else {
$model = $name;
@@ -80,7 +87,10 @@
$this->data[$name] = new $model(null, $opts);
return $this->data[$name];
- } elseif (in_array($name, $this->has_many) or isset($this->has_many[$name])) {
+ } elseif (
+ in_array($name, $this->has_many) or
+ isset($this->has_many[$name])
+ ) {
if (isset($this->has_many[$name])) {
$opts =& $this->has_many[$name];
@@ -92,7 +102,11 @@
$opts["by"] :
strtolower($name) ;
- fallback($opts["where"], array($match."_id" => $this->data["id"]));
+ fallback(
+ $opts["where"],
+ array($match."_id" => $this->data["id"])
+ );
+
$opts["where"] = (array) $opts["where"];
} else {
$model = depluralize($name);
@@ -105,7 +119,10 @@
$this->data[$name] = call_user_func(array($model, "find"), $opts);
return $this->data[$name];
- } elseif (in_array($name, $this->has_one) or isset($this->has_one[$name])) {
+ } elseif (
+ in_array($name, $this->has_one) or
+ isset($this->has_one[$name])
+ ) {
if (isset($this->has_one[$name])) {
$opts =& $this->has_one[$name];
@@ -117,7 +134,11 @@
$opts["by"] :
strtolower($name) ;
- fallback($opts["where"], array($match."_id" => $this->data["id"]));
+ fallback(
+ $opts["where"],
+ array($match."_id" => $this->data["id"])
+ );
+
$opts["where"] = (array) $opts["where"];
} else {
$model = depluralize($name);
@@ -126,7 +147,9 @@
"user" :
$model_name ;
- $opts = array("where" => array($match."_id" => $this->data["id"]));
+ $opts = array(
+ "where" => array($match."_id" => $this->data["id"])
+ );
}
$this->data[$name] = new $model(null, $opts);
@@ -150,9 +173,10 @@
* Handles model relationships, deferred and dynamic attributes.
*/
public function __isset($name): bool {
+ $trigger = Trigger::current();
$model_name = strtolower(get_class($this));
- if (Trigger::current()->exists($model_name."_".$name."_attr"))
+ if ($trigger->exists($model_name."_".$name."_attr"))
return true;
if (isset($this->data[$name]))
@@ -162,13 +186,22 @@
$this->has_many = (array) $this->has_many;
$this->has_one = (array) $this->has_one;
- if (in_array($name, $this->belongs_to) or isset($this->belongs_to[$name]))
+ if (
+ in_array($name, $this->belongs_to) or
+ isset($this->belongs_to[$name])
+ )
return true;
- if (in_array($name, $this->has_many) or isset($this->has_many[$name]))
+ if (
+ in_array($name, $this->has_many) or
+ isset($this->has_many[$name])
+ )
return true;
- if (in_array($name, $this->has_one) or isset($this->has_one[$name]))
+ if (
+ in_array($name, $this->has_one) or
+ isset($this->has_one[$name])
+ )
return true;
return false;
@@ -210,8 +243,10 @@
# Return cached results if available.
if (empty($options["read_from"])) {
- if (isset($cache_id) and isset(self::$caches[$model_name][$cache_id])) {
-
+ if (
+ isset($cache_id) and
+ isset(self::$caches[$model_name][$cache_id])
+ ) {
foreach (self::$caches[$model_name][$cache_id] as $attr => $val)
$model->$attr = $val;
@@ -237,10 +272,11 @@
$options["from"] = (array) $options["from"];
$options["select"] = (array) $options["select"];
- if (is_numeric($id))
+ if (is_numeric($id)) {
$options["where"]["id"] = $id;
- elseif (is_array($id))
+ } elseif (is_array($id)) {
$options["where"] = array_merge($options["where"], $id);
+ }
$sql = SQL::current();
$trigger = Trigger::current();
@@ -350,6 +386,7 @@
$options = array(),
$options_for_object = array()
): array {
+ $trigger = Trigger::current();
$model_name = strtolower($model);
fallback($options["select"], "*");
@@ -368,7 +405,7 @@
$options["from"] = (array) $options["from"];
$options["select"] = (array) $options["select"];
- Trigger::current()->filter($options, pluralize(strtolower($model_name))."_get");
+ $trigger->filter($options, pluralize(strtolower($model_name))."_get");
$grab = SQL::current()->select(
tables:$options["from"],
@@ -493,7 +530,11 @@
$name = strtolower(get_class($this));
- $url = url("edit_".$name."/id/".$this->id, AdminController::current());
+ $url = url(
+ "edit_".$name."/id/".$this->id,
+ AdminController::current()
+ );
+
$classes = $classes.' '.$name.'_edit_link edit_link';
echo $before.'id, AdminController::current());
+ $url = url(
+ "delete_".$name."/id/".$this->id,
+ AdminController::current()
+ );
+
$classes = $classes.' '.$name.'_delete_link delete_link';
echo $before.''.$text.''.$after;
}
+
+ /**
+ * Function: etag
+ * Generates an Etag for the object.
+ */
+ public function etag(): string|false {
+ if ($this->no_results)
+ return false;
+
+ $array = array(get_class($this), $this->id);
+
+ if (isset($this->created_at))
+ $array[] = $this->created_at;
+
+ if (isset($this->updated_at))
+ $array[] = $this->updated_at;
+
+ return (isset($this->updated_at) ? '"' : 'W/"').token($array).'"';
+ }
}
diff --git a/includes/class/Query.php b/includes/class/Query.php
index a6de6c6..71059af 100644
--- a/includes/class/Query.php
+++ b/includes/class/Query.php
@@ -13,7 +13,7 @@
public $result;
# Variable: $queryString
- # Holds the query statement.
+ # Logs a representation of the query statement.
public $queryString = "";
# Variable: $sql
@@ -38,7 +38,12 @@
* $params - An associative array of parameters used in the query.
* $throw_exceptions - Throw exceptions instead of calling error()?
*/
- public function __construct($sql, $query, $params = array(), $throw_exceptions = false) {
+ public function __construct(
+ $sql,
+ $query,
+ $params = array(),
+ $throw_exceptions = false
+ ) {
$this->sql = $sql;
# Don't count config setting queries.
@@ -51,6 +56,13 @@
$this->throw_exceptions = $throw_exceptions;
$this->queryString = $query;
+ foreach ($params as $name => $val)
+ $this->queryString = preg_replace(
+ "/{$name}([^a-zA-Z0-9_]|$)/",
+ "[".serialize($val)."]"."$1",
+ $this->queryString
+ );
+
if ($count and DEBUG) {
$trace = debug_backtrace();
$target = $trace[$index = 0];
@@ -68,24 +80,11 @@
break;
}
- $logQuery = $query;
-
- foreach ($params as $name => $val)
- $logQuery = preg_replace(
- "/{$name}([^a-zA-Z0-9_]|$)/",
- str_replace(
- "\\",
- "\\\\",
- $this->sql->escape($val, !is_int($val))
- )."$1",
- $logQuery
- );
-
$this->sql->debug[] = array(
"number" => $this->sql->queries,
- "file" => str_replace(MAIN_DIR."/", "", $target["file"]),
+ "file" => str_replace(MAIN_DIR.DIR, "", $target["file"]),
"line" => $target["line"],
- "query" => $logQuery,
+ "query" => $this->queryString,
"time" => timer_stop()
);
}
@@ -93,18 +92,6 @@
try {
$this->query = $this->sql->db->prepare($query);
$this->result = $this->query->execute($params);
- $this->queryString = $query;
-
- foreach ($params as $name => $val)
- $this->queryString = preg_replace(
- "/{$name}([^a-zA-Z0-9_]|$)/",
- str_replace(
- array("\\", "\$"),
- array("\\\\", "\\\$"),
- $this->sql->escape($val, !is_int($val))
- )."$1",
- $this->queryString
- );
if (!$this->result)
throw new PDOException(
diff --git a/includes/class/QueryBuilder.php b/includes/class/QueryBuilder.php
index 883e6ec..a746147 100644
--- a/includes/class/QueryBuilder.php
+++ b/includes/class/QueryBuilder.php
@@ -481,18 +481,31 @@
if (is_object($val) and !$val instanceof Stringable)
$val = null;
- if (is_bool($val))
- $val = (int) $val;
-
- if (is_float($val))
- $val = (string) $val;
-
- $return[] = isset($params[$val]) ?
- $val :
- SQL::current()->escape($val, !is_int($val)) ;
+ switch (gettype($val)) {
+ case "NULL":
+ $return[] = "NULL";
+ break;
+ case "boolean":
+ $return[] = (string) (int) $val;
+ break;
+ case "double":
+ $return[] = $sql->escape($val);
+ break;
+ case "integer":
+ $return[] = (string) $val;
+ break;
+ case "object":
+ $return[] = $sql->escape($val);
+ break;
+ case "string":
+ $return[] = isset($params[$val]) ?
+ $val :
+ $sql->escape($val) ;
+ break;
+ }
}
- return "(".join(", ", $return).")";
+ return "(".implode(", ", $return).")";
}
/**
@@ -547,13 +560,16 @@
# PostgreSQL: cast to text to enable LIKE operator.
$text = ($sql->adapter == "pgsql") ? "::text" : "" ;
+ # ESCAPE clause for LIKE.
+ $escape = " ESCAPE '|'";
+
foreach ($conds as $key => $val) {
if (is_int($key)) {
# Full expression.
$cond = $val;
} else {
# Key => Val expression.
- if (is_string($val) and strlen($val) and strpos($val, ":") === 0) {
+ if (is_string($val) and str_starts_with($val, ":")) {
$cond = self::safecol($sql, $key)." = ".$val;
} else {
if (is_object($val) and !$val instanceof Stringable)
@@ -596,7 +612,7 @@
"_",
$key
)."_".$index;
- $likes[] = $key.$text." LIKE :".$param;
+ $likes[] = $key.$text." LIKE :".$param.$escape;
$params[":".$param] = $match;
}
@@ -612,7 +628,7 @@
"_",
$key
)."_".$index;
- $likes[] = $key.$text." NOT LIKE :".$param;
+ $likes[] = $key.$text." NOT LIKE :".$param.$escape;
$params[":".$param] = $match;
}
@@ -628,7 +644,7 @@
"_",
$key
)."_".$index;
- $likes[] = $key.$text." LIKE :".$param;
+ $likes[] = $key.$text." LIKE :".$param.$escape;
$params[":".$param] = $match;
}
@@ -641,7 +657,7 @@
"_",
$key
);
- $cond = $key.$text." NOT LIKE :".$param;
+ $cond = $key.$text." NOT LIKE :".$param.$escape;
$params[":".$param] = $val;
} elseif (substr($uck, -5) == " LIKE") {
# LIKE.
@@ -651,7 +667,7 @@
"_",
$key
);
- $cond = $key.$text." LIKE :".$param;
+ $cond = $key.$text." LIKE :".$param.$escape;
$params[":".$param] = $val;
} elseif (substr_count($key, " ")) {
# Custom operation, e.g. array("foo >" => $bar).
diff --git a/includes/class/Route.php b/includes/class/Route.php
index f79f329..0932edc 100644
--- a/includes/class/Route.php
+++ b/includes/class/Route.php
@@ -220,7 +220,7 @@
$config->chyrp_url."/".$controller->base ;
# Assume this is a dirty URL and return it without translation.
- if (strpos($url, "/") === 0)
+ if (str_starts_with($url, "/"))
return fix($base.$url, true);
# Assume this is a clean URL and ensure it ends with a slash.
diff --git a/includes/class/SQL.php b/includes/class/SQL.php
index 0f20e9a..5f4c4cd 100644
--- a/includes/class/SQL.php
+++ b/includes/class/SQL.php
@@ -447,22 +447,26 @@
*
* Parameters:
* $string - String to escape.
- * $quotes - Wrap the string in single quotes?
*/
- public function escape(
- $string,
- $quotes = true
- ): string {
+ public function escape($string): string {
if (!isset($this->db))
$this->connect();
- $string = $this->db->quote($string);
- $string = str_replace('$', '\$', $string);
+ switch (gettype($string)) {
+ case "NULL":
+ $type = PDO::PARAM_NULL;
+ break;
+ case "boolean":
+ $type = PDO::PARAM_BOOL;
+ break;
+ case "integer":
+ $type = PDO::PARAM_INT;
+ break;
+ default:
+ $type = PDO::PARAM_STR;
+ }
- if (!$quotes)
- $string = trim($string, "'");
-
- return $string;
+ return $this->db->quote($string, $type);
}
/**
diff --git a/includes/class/Theme.php b/includes/class/Theme.php
index 6f50e05..b2d14d8 100644
--- a/includes/class/Theme.php
+++ b/includes/class/Theme.php
@@ -26,6 +26,7 @@
*/
private function __construct() {
$this->url = THEME_URL;
+
$this->safename = PREVIEWING ?
$_SESSION['theme'] :
Config::current()->theme ;
@@ -33,17 +34,20 @@
/**
* Function: pages_list
- * Returns a simple array of pages with @depth@ and @children@ attributes.
+ * Returns an array of pages with @depth@ and @children@ attributes.
*
* Parameters:
- * $page_id - Page ID to use as the basis.
- * $exclude - Page ID to exclude from the list.
+ * $page_id - Page ID to start from, or zero to return all pages.
+ * $exclude - Page ID/s to exclude, integer or array of integers.
*/
public function pages_list($page_id = 0, $exclude = null): array {
$cache_id = serialize(array($page_id, $exclude));
- if (isset($this->caches["pages_list"][$cache_id]))
+ if (
+ isset($this->caches["pages_list"][$cache_id])
+ ) {
return $this->caches["pages_list"][$cache_id];
+ }
$this->caches["pages"]["flat"] = array();
$this->caches["pages"]["children"] = array();
@@ -53,8 +57,12 @@
if (MAIN)
$where["show_in_list"] = true;
- $pages = Page::find(array("where" => $where,
- "order" => "list_order ASC"));
+ $pages = Page::find(
+ array(
+ "where" => $where,
+ "order" => "list_order ASC, title ASC"
+ )
+ );
if (empty($pages))
return $this->caches["pages_list"][$cache_id] = array();
@@ -72,30 +80,36 @@
$this->recurse_pages($page);
}
- return $this->caches["pages_list"][$cache_id] = $this->caches["pages"]["flat"];
+ $list = $this->caches["pages"]["flat"];
+ return $this->caches["pages_list"][$cache_id] = $list;
}
/**
* Function: recurse_pages
- * Populates the page cache and gives each page @depth@ and @children@ attributes.
+ * Populates the page cache and gives each page the attributes
+ * of @depth@ (integer, 1 or greater) and @children@ (boolean).
*
* Parameters:
* $page - Page to start recursion at.
*/
private function recurse_pages($page): void {
- $page->depth = isset($page->depth) ?
- $page->depth :
- 1 ;
+ if (!isset($page->depth))
+ $page->depth = 1;
- $page->children = isset($this->caches["pages"]["children"][$page->id]);
+ $page->children = isset(
+ $this->caches["pages"]["children"][$page->id]
+ );
$this->caches["pages"]["flat"][] = $page;
- if (isset($this->caches["pages"]["children"][$page->id]))
- foreach ($this->caches["pages"]["children"][$page->id] as $child) {
+ if ($page->children) {
+ foreach (
+ $this->caches["pages"]["children"][$page->id] as $child
+ ) {
$child->depth = $page->depth + 1;
$this->recurse_pages($child);
}
+ }
}
/**
@@ -106,8 +120,11 @@
* $limit - Maximum number of months to list.
*/
public function archives_list($limit = 12): array {
- if (isset($this->caches["archives_list"][$limit]))
+ if (
+ isset($this->caches["archives_list"][$limit])
+ ) {
return $this->caches["archives_list"][$limit];
+ }
$main = MainController::current();
$sql = SQL::current();
@@ -125,7 +142,10 @@
foreach ($results as $result) {
$created_at = strtotime($result["created_at"]);
- $this_month = strtotime("midnight first day of this month", $created_at);
+ $this_month = strtotime(
+ "midnight first day of this month",
+ $created_at
+ );
if (!isset($nums[$this_month])) {
if (count($nums) == $limit)
@@ -158,8 +178,11 @@
* $limit - Maximum number of recent posts to list.
*/
public function recent_posts($limit = 5): array {
- if (isset($this->caches["recent_posts"][$limit]))
+ if (
+ isset($this->caches["recent_posts"][$limit])
+ ) {
return $this->caches["recent_posts"][$limit];
+ }
$results = Post::find(
array(
@@ -171,12 +194,13 @@
$posts = array();
- for ($i = 0; $i < $limit; $i++)
+ for ($i = 0; $i < $limit; $i++) {
if (isset($results[0][$i]))
$posts[] = new Post(
null,
array("read_from" => $results[0][$i])
);
+ }
return $this->caches["recent_posts"][$limit] = $posts;
}
@@ -193,8 +217,11 @@
if ($post->no_results)
return array();
- if (isset($this->caches["related_posts"][$post->id][$limit]))
+ if (
+ isset($this->caches["related_posts"][$post->id][$limit])
+ ) {
return $this->caches["related_posts"][$post->id][$limit];
+ }
$ids = array();
@@ -206,7 +233,7 @@
$results = Post::find(
array(
"placeholders" => true,
- "where" => array("id" => $ids),
+ "where" => array("id" => array_unique($ids)),
"order" => "created_at DESC, id DESC")
);
@@ -253,7 +280,10 @@
fix($stylesheet, true).
'" type="text/css" media="all">';
- if (is_dir(THEME_DIR.DIR."stylesheets") or is_dir(THEME_DIR.DIR."css")) {
+ if (
+ is_dir(THEME_DIR.DIR."stylesheets") or
+ is_dir(THEME_DIR.DIR."css")
+ ) {
foreach (
array_merge(
(array) glob(THEME_DIR.DIR."stylesheets".DIR."*.css"),
@@ -262,7 +292,7 @@
) {
$filename = basename($filepath);
- if (empty($filename) or substr_count($filename, ".inc.css"))
+ if (empty($filename) or str_ends_with($filename, ".inc.css"))
continue;
$qdir = preg_quote(DIR, "/");
@@ -271,7 +301,10 @@
"$2",
$filepath
);
- $href = $config->chyrp_url."/themes/".str_replace(DIR, "/", $path);
+ $href = $config->chyrp_url.
+ "/themes/".
+ str_replace(DIR, "/", $path);
+
$tags[] = '';
@@ -298,9 +331,14 @@
$tags = array();
foreach ($scripts as $script)
- $tags[] = '';
+ $tags[] = '';
- if (is_dir(THEME_DIR.DIR."javascripts") or is_dir(THEME_DIR.DIR."js")) {
+ if (
+ is_dir(THEME_DIR.DIR."javascripts") or
+ is_dir(THEME_DIR.DIR."js")
+ ) {
foreach (
array_merge(
(array) glob(THEME_DIR.DIR."javascripts".DIR."*.js"),
@@ -309,7 +347,7 @@
) {
$filename = basename($filepath);
- if (empty($filename) or substr_count($filename, ".inc.js"))
+ if (empty($filename) or str_ends_with($filename, ".inc.js"))
continue;
$qdir = preg_quote(DIR, "/");
@@ -318,8 +356,14 @@
"$2",
$filepath
);
- $href = $config->chyrp_url."/themes/".str_replace(DIR, "/", $path);
- $tags[] = '';
+
+ $href = $config->chyrp_url.
+ "/themes/".
+ str_replace(DIR, "/", $path);
+
+ $tags[] = '';
}
}
@@ -356,14 +400,20 @@
self_url() ;
$feed_url = ($config->clean_urls) ?
- rtrim($page_url, "/")."/feed/" :
- $page_url.(substr_count($page_url, "?") ? "&feed" : "?feed") ;
+ rtrim($page_url, "/")."/feed/"
+ :
+ $page_url.(
+ substr_count($page_url, "?") ?
+ "&feed" :
+ "?feed"
+ )
+ ;
- $links[] = array(
- "href" => $feed_url,
- "type" => BlogFeed::type(),
- "title" => $this->title
- );
+ $links[] = array(
+ "href" => $feed_url,
+ "type" => BlogFeed::type(),
+ "title" => $this->title
+ );
}
# Ask extensions to provide additional links.
diff --git a/includes/common.php b/includes/common.php
index 69668b4..d24f45e 100644
--- a/includes/common.php
+++ b/includes/common.php
@@ -10,11 +10,11 @@
# Constant: CHYRP_VERSION
# Version number for this release.
- define('CHYRP_VERSION', "2024.02");
+ define('CHYRP_VERSION', "2024.03");
# Constant: CHYRP_CODENAME
# The codename for this version.
- define('CHYRP_CODENAME', "Miombo");
+ define('CHYRP_CODENAME', "Oak");
# Constant: CHYRP_IDENTITY
# The string identifying this version.
@@ -124,6 +124,10 @@
# Deny session storage to robots?
define('SESSION_DENY_BOT', true);
+ # Constant: SLUG_STRICT
+ # Use strict sanitization for slugs?
+ define('SLUG_STRICT', true);
+
# Constant: GET_REMOTE_UNSAFE
# Allow get_remote() to connect to private and reserved IP addresses?
define('GET_REMOTE_UNSAFE', false);
@@ -137,18 +141,31 @@
if (!defined('USE_OB'))
define('USE_OB', true);
+ # Constant: HTTP_ACCEPT_ZSTD
+ # Does the user agent accept Zstandard encoding?
+ define('HTTP_ACCEPT_ZSTD',
+ isset($_SERVER['HTTP_ACCEPT_ENCODING']) and
+ str_contains($_SERVER['HTTP_ACCEPT_ENCODING'], "zstd")
+ );
+
# Constant: HTTP_ACCEPT_DEFLATE
# Does the user agent accept deflate encoding?
define('HTTP_ACCEPT_DEFLATE',
isset($_SERVER['HTTP_ACCEPT_ENCODING']) and
- substr_count($_SERVER['HTTP_ACCEPT_ENCODING'], "deflate")
+ str_contains($_SERVER['HTTP_ACCEPT_ENCODING'], "deflate")
);
# Constant: HTTP_ACCEPT_GZIP
# Does the user agent accept gzip encoding?
define('HTTP_ACCEPT_GZIP',
isset($_SERVER['HTTP_ACCEPT_ENCODING']) and
- substr_count($_SERVER['HTTP_ACCEPT_ENCODING'], "gzip")
+ str_contains($_SERVER['HTTP_ACCEPT_ENCODING'], "gzip")
+ );
+
+ # Constant: CAN_USE_ZSTD
+ # Can we use zstd to compress output?
+ define('CAN_USE_ZSTD',
+ HTTP_ACCEPT_ZSTD and extension_loaded("zstd")
);
# Constant: CAN_USE_ZLIB
@@ -157,16 +174,27 @@
(HTTP_ACCEPT_DEFLATE or HTTP_ACCEPT_GZIP) and extension_loaded("zlib")
);
- # Constant: USE_ZLIB
- # Use zlib to provide content compression?
- if (!defined('USE_ZLIB'))
- define('USE_ZLIB', CAN_USE_ZLIB and !ini_get("zlib.output_compression"));
+ # Constant: USE_COMPRESSION
+ # Use content compression for responses?
+ if (!defined('USE_COMPRESSION'))
+ define('USE_COMPRESSION',
+ (CAN_USE_ZSTD or CAN_USE_ZLIB) and !ini_get("zlib.output_compression")
+ );
# Start output buffering and set the header.
if (USE_OB) {
- if (USE_ZLIB) {
- ob_start("ob_gzhandler");
- header("Content-Encoding: ".(HTTP_ACCEPT_GZIP ? "gzip" : "deflate"));
+ if (USE_COMPRESSION) {
+ if (CAN_USE_ZSTD) {
+ ob_start(
+ function ($data) {
+ return zstd_compress($data, ZSTD_COMPRESS_LEVEL_DEFAULT);
+ }
+ );
+ header("Content-Encoding: zstd");
+ } else {
+ ob_start("ob_gzhandler");
+ header("Content-Encoding: ".(HTTP_ACCEPT_GZIP ? "gzip" : "deflate"));
+ }
} else {
ob_start();
}
diff --git a/includes/controller/Admin.php b/includes/controller/Admin.php
index 772471d..ca0c4df 100644
--- a/includes/controller/Admin.php
+++ b/includes/controller/Admin.php
@@ -37,9 +37,12 @@
* Loads the Twig parser and sets up the l10n domain.
*/
private function __construct() {
- $chain = array(new \Twig\Loader\FilesystemLoader(MAIN_DIR.DIR."admin"));
$config = Config::current();
+ $chain = array(
+ new \Twig\Loader\FilesystemLoader(MAIN_DIR.DIR."admin")
+ );
+
foreach ($config->enabled_modules as $module) {
if (is_dir(MODULES_DIR.DIR.$module.DIR."admin"))
$chain[] = new \Twig\Loader\FilesystemLoader(
@@ -63,7 +66,9 @@
"strict_variables" => DEBUG,
"charset" => "UTF-8",
"cache" => CACHES_DIR.DIR."twig",
- "autoescape" => false)
+ "autoescape" => false,
+ "use_yield" => true
+ )
);
$this->twig->addExtension(
@@ -300,9 +305,9 @@
);
if ($post->no_results)
- Flash::warning(
- __("Post not found."),
- "manage_posts"
+ show_404(
+ __("Not Found"),
+ __("Post not found.")
);
if (!$post->editable())
@@ -408,9 +413,9 @@
);
if ($post->no_results)
- Flash::warning(
- __("Post not found."),
- "manage_posts"
+ show_404(
+ __("Not Found"),
+ __("Post not found.")
);
if (!$post->deletable())
@@ -483,7 +488,11 @@
if (isset($_POST['query']))
redirect(
"manage_posts/query/".
- str_ireplace("%2F", "", urlencode($_POST['query'])).
+ str_ireplace(
+ array("%2F", "%5C"),
+ "%5F",
+ urlencode($_POST['query'])
+ ).
"/"
);
@@ -655,7 +664,7 @@
public:$public,
show_in_list:$listed,
list_order:$list_order,
- clean:sanitize($_POST['slug'])
+ clean:sanitize($_POST['slug'], true, true, 128)
);
$page_redirect = ($visitor->group->can("edit_page", "delete_page")) ?
@@ -693,9 +702,9 @@
);
if ($page->no_results)
- Flash::warning(
- __("Page not found."),
- "manage_pages"
+ show_404(
+ __("Not Found"),
+ __("Page not found.")
);
if (!empty($_SESSION['redirect_to']))
@@ -772,7 +781,7 @@
fallback($_POST['parent_id'], 0);
fallback($_POST['status'], "public");
fallback($_POST['list_priority'], 0);
- fallback($_POST['slug'], $page->clean);
+ fallback($_POST['slug'], "");
$public = in_array(
$_POST['status'],
@@ -801,7 +810,7 @@
public:$public,
show_in_list:$listed,
list_order:$list_order,
- clean:sanitize($_POST['slug'])
+ clean:sanitize($_POST['slug'], true, true, 128)
);
Flash::notice(
@@ -832,9 +841,9 @@
$page = new Page($_GET['id']);
if ($page->no_results)
- Flash::warning(
- __("Page not found."),
- "manage_pages"
+ show_404(
+ __("Not Found"),
+ __("Page not found.")
);
$this->display(
@@ -917,7 +926,11 @@
if (isset($_POST['query']))
redirect(
"manage_pages/query/".
- str_ireplace("%2F", "", urlencode($_POST['query'])).
+ str_ireplace(
+ array("%2F", "%5C"),
+ "%5F",
+ urlencode($_POST['query'])
+ ).
"/"
);
@@ -1105,9 +1118,9 @@
$user = new User($_GET['id']);
if ($user->no_results)
- Flash::warning(
- __("User not found."),
- "manage_users"
+ show_404(
+ __("Not Found"),
+ __("User not found.")
);
$options = array(
@@ -1280,9 +1293,9 @@
$user = new User($_GET['id']);
if ($user->no_results)
- Flash::warning(
- __("User not found."),
- "manage_users"
+ show_404(
+ __("Not Found"),
+ __("User not found.")
);
if ($user->id == Visitor::current()->id)
@@ -1405,7 +1418,11 @@
if (isset($_POST['query']))
redirect(
"manage_users/query/".
- str_ireplace("%2F", "", urlencode($_POST['query'])).
+ str_ireplace(
+ array("%2F", "%5C"),
+ "%5F",
+ urlencode($_POST['query'])
+ ).
"/"
);
@@ -1520,9 +1537,9 @@
$group = new Group($_GET['id']);
if ($group->no_results)
- Flash::warning(
- __("Group not found."),
- "manage_groups"
+ show_404(
+ __("Not Found"),
+ __("Group not found.")
);
$this->display(
@@ -1789,7 +1806,11 @@
if (isset($_POST['search']))
redirect(
"manage_groups/search/".
- str_ireplace("%2F", "", urlencode($_POST['search'])).
+ str_ireplace(
+ array("%2F", "%5C"),
+ "%5F",
+ urlencode($_POST['search'])
+ ).
"/"
);
@@ -1837,9 +1858,9 @@
$filepath = uploaded($filename, false);
if (!is_readable($filepath) or !is_file($filepath))
- Flash::warning(
- __("File not found."),
- "manage_uploads"
+ show_404(
+ __("Not Found"),
+ __("File not found.")
);
$post_count = $sql->count(
@@ -1899,9 +1920,9 @@
$filepath = uploaded($filename, false);
if (!is_readable($filepath) or !is_file($filepath))
- Flash::warning(
- __("File not found."),
- "manage_uploads"
+ show_404(
+ __("Not Found"),
+ __("File not found.")
);
if (!delete_upload($filename))
@@ -1931,7 +1952,11 @@
if (isset($_POST['search']))
redirect(
"manage_uploads/search/".
- str_ireplace("%2F", "", urlencode($_POST['search'])).
+ str_ireplace(
+ array("%2F", "%5C"),
+ "%5F",
+ urlencode($_POST['search'])
+ ).
"/"
);
@@ -2032,7 +2057,8 @@
''."\n".
''.
- fix($config->name).' | Posts'."\n".
+ fix($config->name).
+ ''."\n".
''.
fix($config->description).
''."\n".
@@ -2045,7 +2071,7 @@
''."\n".
- 'Chyrp'."\n";
@@ -2069,6 +2095,9 @@
''.
when(DATE_ATOM, $post->created_at).
''."\n".
+ ''.
+ fix($post->etag(), false, true).
+ ''."\n".
''."\n".
''.
fix(oneof($post->user->full_name, $post->user->login)).
@@ -2133,7 +2162,7 @@
''."\n".
''.
- fix($title, false, true).
+ fix($config->name).
''."\n".
''.
fix($config->description).
@@ -2147,7 +2176,7 @@
''."\n".
- 'Chyrp'."\n";
@@ -2170,6 +2199,9 @@
''.
when(DATE_ATOM, $page->created_at).
''."\n".
+ ''.
+ fix($page->etag(), false, true).
+ ''."\n".
''."\n".
''.
fix(oneof($page->user->full_name, $page->user->login)).
@@ -2411,6 +2443,15 @@
set_max_time();
set_max_memory();
+ if (!empty($_POST['media_url'])) {
+ $match_url = preg_quote($_POST['media_url'], "/");
+ $media_url = fix(
+ $config->chyrp_url.
+ str_replace(DIR, "/", $config->uploads_path)
+ );
+ $media_exp = "/{$match_url}([^\.\!,\?;\"\'<>\(\)\[\]\{\}\s\t ]+)\.([a-zA-Z0-9]+)/";
+ }
+
if (isset($imports["groups"])) {
foreach ($imports["groups"] as $name => $permissions) {
$group = new Group(
@@ -2465,7 +2506,10 @@
if (isset($imports["posts"])) {
foreach ($imports["posts"]->entry as $entry) {
$chyrp = $entry->children("http://chyrp.net/export/1.0/");
- $login = $entry->author->children("http://chyrp.net/export/1.0/")->login;
+
+ $login = $entry->author->children(
+ "http://chyrp.net/export/1.0/"
+ )->login;
$user = new User(
array("login" => unfix((string) $login))
@@ -2477,18 +2521,22 @@
$values[$value->getName()] = unfix((string) $value);
if (!empty($_POST['media_url']))
- array_walk_recursive($values, function (&$value) {
- $config = Config::current();
- $uploads_path = str_replace(DIR, "/", $config->uploads_path);
- $old_url = preg_quote($_POST['media_url'], "/");
- $new_url = fix($config->chyrp_url.$uploads_path);
- $regex = "/{$old_url}([^\.\!,\?;\"\'<>\(\)\[\]\{\}\s\t ]+)\.([a-zA-Z0-9]+)/";
- $value = preg_replace($regex, $new_url."$1.$2", $value);
- });
+ array_walk_recursive(
+ $values,
+ function (&$value) use ($media_exp, $media_url) {
+ $value = preg_replace(
+ $media_exp,
+ $media_url."$1.$2",
+ $value
+ );
+ }
+ );
$values["imported_from"] = "chyrp";
- $updated = ((string) $entry->updated != (string) $entry->published);
+ $updated = (
+ (string) $entry->updated != (string) $entry->published
+ );
$post = Post::add(
values:$values,
@@ -2512,9 +2560,11 @@
$chyrp = $entry->children(
"http://chyrp.net/export/1.0/"
);
+
$attr = $entry->attributes(
"http://chyrp.net/export/1.0/"
);
+
$login = $entry->author->children(
"http://chyrp.net/export/1.0/"
)->login;
@@ -2523,11 +2573,22 @@
array("login" => unfix((string) $login))
);
- $updated = ((string) $entry->updated != (string) $entry->published);
+ $body = unfix((string) $entry->content);
+
+ if (!empty($_POST['media_url']))
+ $body = preg_replace(
+ $media_exp,
+ $media_url."$1.$2",
+ $body
+ );
+
+ $updated = (
+ (string) $entry->updated != (string) $entry->published
+ );
$page = Page::add(
title:unfix((string) $entry->title),
- body:unfix((string) $entry->content),
+ body:$body,
user:(!$user->no_results) ? $user->id : $visitor->id,
parent_id:(int) unfix((string) $attr->parent_id),
public:(bool) unfix((string) $chyrp->public),
diff --git a/includes/controller/Main.php b/includes/controller/Main.php
index 3dcf755..abdf0fb 100644
--- a/includes/controller/Main.php
+++ b/includes/controller/Main.php
@@ -47,9 +47,9 @@
* Loads the Twig parser and sets up the l10n domain.
*/
private function __construct() {
- $loader = new \Twig\Loader\FilesystemLoader(THEME_DIR);
$config = Config::current();
$theme = Theme::current();
+ $loader = new \Twig\Loader\FilesystemLoader(THEME_DIR);
$this->twig = new \Twig\Environment(
$loader,
@@ -58,7 +58,9 @@
"strict_variables" => DEBUG,
"charset" => "UTF-8",
"cache" => CACHES_DIR.DIR."twig",
- "autoescape" => false)
+ "autoescape" => false,
+ "use_yield" => true
+ )
);
$this->twig->addExtension(
@@ -92,7 +94,7 @@
return $route->action = "index";
# Serve the index if the first arg is a query and action is unset.
- if (empty($route->action) and strpos($route->arg[0], "?") === 0)
+ if (empty($route->action) and str_starts_with($route->arg[0], "?"))
return $route->action = "index";
# Discover feed requests.
@@ -271,9 +273,9 @@
$user = new User($_GET['id']);
if ($user->no_results)
- Flash::warning(
- __("User not found."),
- "/"
+ show_404(
+ __("Not Found"),
+ __("User not found.")
);
$author = (object) array(
@@ -479,7 +481,11 @@
if (isset($_POST['query']))
redirect(
"search/".
- str_ireplace("%2F", "", urlencode($_POST['query'])).
+ str_ireplace(
+ array("%2F", "%5C"),
+ "%5F",
+ urlencode($_POST['query'])
+ ).
"/"
);
@@ -1217,6 +1223,13 @@
* Webmention receiver endpoint.
*/
public function main_webmention(): void {
+ if (!Config::current()->send_pingbacks)
+ error(
+ __("Error"),
+ __("Webmention support is disabled for this site."),
+ code:503
+ );
+
webmention_receive(
fallback($_POST['source']),
fallback($_POST['target'])
diff --git a/includes/download.php b/includes/download.php
index d4de8e6..32f2df6 100644
--- a/includes/download.php
+++ b/includes/download.php
@@ -41,10 +41,7 @@
if (DEBUG)
error_log("DOWNLOAD served ".$filename);
- if (
- !in_array("ob_gzhandler", ob_list_handlers()) and
- !ini_get("zlib.output_compression")
- )
+ if (!USE_COMPRESSION and !ini_get("zlib.output_compression"))
header("Content-Length: ".filesize($filepath));
$safename = addslashes($filename);
diff --git a/includes/error.php b/includes/error.php
index c6b23d4..76a62d1 100644
--- a/includes/error.php
+++ b/includes/error.php
@@ -110,17 +110,26 @@
case 405:
header($_SERVER['SERVER_PROTOCOL']." 405 Method Not Allowed");
break;
+ case 406:
+ header($_SERVER['SERVER_PROTOCOL']." 406 Not Acceptable");
+ break;
case 409:
header($_SERVER['SERVER_PROTOCOL']." 409 Conflict");
break;
case 410:
header($_SERVER['SERVER_PROTOCOL']." 410 Gone");
break;
+ case 412:
+ header($_SERVER['SERVER_PROTOCOL']." 412 Precondition Failed");
+ break;
case 413:
header($_SERVER['SERVER_PROTOCOL']." 413 Payload Too Large");
break;
+ case 415:
+ header($_SERVER['SERVER_PROTOCOL']." 415 Unsupported Media Type");
+ break;
case 422:
- header($_SERVER['SERVER_PROTOCOL']." 422 Unprocessable Entity");
+ header($_SERVER['SERVER_PROTOCOL']." 422 Unprocessable Content");
break;
case 429:
header($_SERVER['SERVER_PROTOCOL']." 429 Too Many Requests");
@@ -375,7 +384,7 @@
color: #1f1f23;
text-decoration: none;
margin: 1rem 0rem;
- padding: 0.5rem;
+ padding: 0.5rem 1rem;
background-color: #f2fbff;
border: 2px solid #b8cdd9;
border-radius: 0.25em;
diff --git a/includes/helpers.php b/includes/helpers.php
index 27fbced..a9ef33c 100644
--- a/includes/helpers.php
+++ b/includes/helpers.php
@@ -592,7 +592,7 @@
*
* Parameters:
* $formatting - The date()-compatible formatting.
- * $when - A time value to be strtotime() converted.
+ * $when - A time() value or string to be strtotime() converted.
*
* Returns:
* An internationalized time/date string with the supplied formatting.
@@ -632,7 +632,7 @@
*
* Parameters:
* $formatting - The formatting for date().
- * $when - A time value to be strtotime() converted.
+ * $when - A time() value or string to be strtotime() converted.
*
* Returns:
* A time/date string with the supplied formatting.
@@ -1131,6 +1131,7 @@
* Returns:
* An array containing an array of "WHERE" conditions, an array
* of "WHERE" parameters, and "ORDER BY" clause for the results.
+ * Non-keyword text will be parameterized as array[1][":query"].
*/
function keywords($query, $plain, $table = null): array {
$trimmed = trim($query);
@@ -1141,6 +1142,13 @@
$sql = SQL::current();
$trigger = Trigger::current();
+ # Add ESCAPE clause to LIKE operators without one.
+ $plain = preg_replace(
+ "/( LIKE :query(?! ESCAPE))($| )/",
+ "$1 ESCAPE '|'$2",
+ $plain
+ );
+
# PostgreSQL: use ILIKE operator for case-insensitivity.
if ($sql->adapter == "pgsql")
$plain = str_replace(" LIKE ", " ILIKE ", $plain);
@@ -1542,8 +1550,11 @@
$parser->convertTabsToSpaces = false;
$parser->html5 = true;
$parser->keepListStartNumber = true;
+ $parser->keepReversedList = true;
$parser->headlineAnchors = true;
$parser->enableNewlines = false;
+ $parser->renderCheckboxInputs = false;
+ $parser->disallowedRawHTML = false;
}
if ($context instanceof Model) {
@@ -1933,6 +1944,7 @@
if (!function_exists("curl_version"))
return false;
+ $cver = curl_version();
$curl = @curl_init($url);
if ($curl === false)
@@ -1954,6 +1966,13 @@
)
);
+ if (
+ defined('CURLSSLOPT_NATIVE_CA') and
+ version_compare($cver["version"], "7.71", ">=")
+ ) {
+ $opts[CURLOPT_SSL_OPTIONS] = CURLSSLOPT_NATIVE_CA;
+ }
+
if ($post) {
$opts[CURLOPT_POST] = true;
$opts[CURLOPT_POSTFIELDS] = $data;
@@ -2237,7 +2256,7 @@
$path = substr($path, 0, $end + 1);
# Append the relative path, or replace the path if rel begins with "/".
- if (strpos($rel, "/") === 0)
+ if (str_starts_with($rel, "/"))
$path = $rel;
else
$path.= $rel;
@@ -2473,7 +2492,8 @@
if ($filename === false)
error(
__("Error"),
- __("Uploaded file is of an unsupported type.")
+ __("Uploaded file is of an unsupported type."),
+ code:415
);
if (!is_uploaded_file($file['tmp_name']))
@@ -3171,10 +3191,7 @@
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"".$safename."\"");
- if (
- !in_array("ob_gzhandler", ob_list_handlers()) and
- !ini_get("zlib.output_compression")
- )
+ if (!USE_COMPRESSION and !ini_get("zlib.output_compression"))
header("Content-Length: ".strlen($contents));
echo $contents;
diff --git a/includes/lib/Leaf.php b/includes/lib/Leaf.php
index 02e6861..f1ab722 100644
--- a/includes/lib/Leaf.php
+++ b/includes/lib/Leaf.php
@@ -29,6 +29,7 @@
new \Twig\TwigFunction("icon_img", "twig_function_icon_img"),
new \Twig\TwigFunction("copyright_notice", "twig_function_copyright_notice"),
new \Twig\TwigFunction("uploaded_search", "twig_function_uploaded_search"),
+ new \Twig\TwigFunction("slug_pattern", "twig_function_slug_pattern"),
new \Twig\TwigFunction("javascripts_nonce", "twig_function_javascripts_nonce"),
new \Twig\TwigFunction("stylesheets_nonce", "twig_function_stylesheets_nonce")
);
@@ -67,9 +68,9 @@
# Custom filters:
new \Twig\TwigFilter("translate", "twig_filter_translate"),
new \Twig\TwigFilter("translate_plural", "twig_filter_translate_plural"),
+ new \Twig\TwigFilter("translate_time", "twig_filter_translate_time"),
new \Twig\TwigFilter("time", "twig_filter_time"),
new \Twig\TwigFilter("dateformat", "twig_filter_date_format"),
- new \Twig\TwigFilter("strftimeformat", "twig_filter_strftime_format"),
new \Twig\TwigFilter("filesizeformat", "twig_filter_filesize_format"),
new \Twig\TwigFilter("preg_match", "twig_filter_preg_match"),
new \Twig\TwigFilter("preg_replace", "twig_filter_preg_replace"),
@@ -351,6 +352,16 @@
return uploaded_search($search, $filter);
}
+ /**
+ * Function: twig_function_slug_pattern
+ * Returns a HTML @pattern@ attribute if strict slugs are enabled.
+ */
+ function twig_function_slug_pattern(): string {
+ return SLUG_STRICT ?
+ ' pattern="^[a-z0-9\\-]*$"' :
+ ' pattern="^[^\\u0021-\\u002f\\u003a-\\u0040\\u005b-\\u0060\\u007b-\\u007e]*$"' ;
+ }
+
/**
* Function: twig_function_javascripts_nonce
* Returns a nonce value to enable inline JavaScript with a Content Security Policy.
@@ -413,23 +424,61 @@
return _p($single, $plural, $number, $domain);
}
+
/**
- * Function: twig_filter_time
- * Returns a