0*XkK(9#9>b|eUh7RD
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
VEAyw;Y_3`H|AQq}l?><^`(M>>!k7R6
delta 6309
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
LLW=r#Opp9Oq3~?o
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 a07d1bfd546e5580115f1d5f32b54c657ad46bfa..527c42db1bb1eebb58f5b76963a615959c75b1c4 100644
GIT binary patch
delta 6571
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
delta 6309
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
Gs{bG20DCt8
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 8cd13dd7916fea03deced35e118ba8b584b43896..4c4da3cfde0830db161bcd58446cb37080073ceb 100644
GIT binary patch
delta 6530
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
F{08kqZG8X$
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 394878f51847df4d887723fe03bd312081a9a938..96c77536c6f7ff5d76eb8f4bd28f290853aed761 100644
GIT binary patch
delta 6549
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
Y4V%Z1c1=amoU$^%|NlmReOP+*AN|6-r2qf`
delta 6309
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
delta 5458
zcmYk=30PNE9>(#5JA$|%BH)4xhL#wpp+*Qgm=4kij^-LVsF}+s8KYz6bc99Ynku+zdxSG`}p!X=iGblIrrQJ9*@lmIz1!E
zJ6osHGRO8KX&|dQmmTEXnVM>KE;hose%J(C<7AA&wHShXF&IBKzp(ZTR=;81HY?Qg
z`-NhtbDpbj4RKhP6D49acEjp86zS{6U{joqwXw+dZ$nLBuXzNkQ7P
zCSHu{zYi-jzB@{x9hM-g??RZSt~eZZ!j`Bj>V*BVE9$sH)Rh&X2H1gh@Br%g)7D;!
zEVU~$f59;7p)9kf9WfL%P(13y9Z^@7ZuKnG3Hx9(dM=h?1j4WL8uEEWlluyo||d)
zm8hj(hnnb4)CKR0Vf{6;5*jq4o2Y^Bp*mFHmCyw0VmEAn8YmBS&&Q)CT!32ADcFs-
zXFlqD$GBXb?-a)3d8=1oP+fSiM?nWPLY*kiOh8>(GHSpK)I@SnCmvw!L$D(Cv6zDS
zsD7Jl|1R?&YJw$Jzl0jkE2A)m!adYPMmF{b8i!hjjMX2LfV=}Ho?ut8)I$sd)uFfBVI$tgH)UhE2bxc6bxIOm9$51P=2;;B_
zb&C$;&v+JjmED)k{rJtP5372LVmLLuom*z^%VEC_C8i0fSO32wU5SN>f_DHs1we#{c}+RF0l6HsQxQa5B2M|-+PNf
zMH;qi2TS!XvTE+|L%wCGPia(Z|F}d9q2At1N4*tURv&CWV-{cy_D@5t$O5acLT*+QZV~brxLsx`
zHrM+f+Qz?vL^IvYMlIn`)KZT`4g9RNd#DM{M!jaQTKjg?@q19mA2Lta{!-*|ao5z&
z_%4DcPBU(b>d*l-a0WhsJ*|BO>bSL5-;Fh?A4Uy$8a1IysN-(i{xIH29oNWAK#h}%
zo;qey(13l+L8$gTWR=`lYhP*Yuc1z`(cEEvhU+$OQ0F~m_4BA_;0EfUuh*9K*MQM&
z{V!c}4BP_jOnZjaXQ4VQMxAguYDo*RE^p07Yv0?>-+vJG{Wxm%GSowS2X+2B?fr2Z
zdlYoSmZ%dxj1icIIYo`q55sb2;7G{?lh|Z4XfWny(Dom<_A{sfub>9HWBWrnSYOC+)cKN7E8EfRiaLLm)dwK`
zJvWSkI!v?!rl4l}ihqDxYVB*V9_?FD#~(I7Gf$!hJcsIk6*a-{kiX_!l@9&{nwo8}
zp5Ffy3Ob-S*1~b90j8p6{F3coYVDg*_ja4rPg?yPY62Db)u;ZUW;p5t7j5-q)Ok}?
z*ZZGo4LNo|uGL4F6Hu?wR1Cva*1i!n&<<>g?;{^ecMUa>s80U=W*9-em6>MkeKGL<
z52m1p>1oseD^M%49(Awx<0n{xwegKd{S&`~T8Z~iuhn^L4^HtXPzyD|Xw(%qv3de(
zLhVyn|8NSKwjGsnQgWq7_-lh3749EJkw?wsfK^@lvwKBu;T`WMYT-$WtE~sC}*{I)^
zPonzgnWM~n&kB>w^7?G6&o`HvE6mmAI&-tR&D?G7GmoI&_s`7}7)0H>!w>xdvYh;r
z^dkJd=>9=;kN!vIl47E53fV)(5LP*`_2K6!vV+_px5@Wp7}-m@5v|gPMBfN)D}7jh
zwkzb%#QobcwL2p1$@=^H?Tx{ie$TRE;$$v3TpTjhgOL(dS|79^2@84dhGRhkCc;CMjP|-)=k~MBaJ?Z7!aSAoa
zNqvLgprFTf6ZxF1CM(F37&ZZW&Sn@m>NMcC&Hp2=-&B5h6Z~{rSdR@G3R-`xi
zBiTR#o33U7IYTy*N6A$(pA07x$)}`zYe6B-Di7fUWIKtrwkFt-{GR;D+CIaDB!SE!
zee3O~rS}1XQqrGj3nBZ-H^l`JU8)q9##FCVTr)O0ytrT6n-z=m
Ilk-CU55E`{0ssI2
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 3f526c8a57fefe18611aabcdce5096cf6f39b67b..4033af084880dd4ecd6921551a4bdd3380b17523 100644
GIT binary patch
delta 13
UcmX@ic9?BLJrkqJaudio 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 b53f891278a6b72202701950c271f9acb88c37bd..4edfbc9f9c7a6ed8efe39c5e531e2ed7e6173bf0 100644
GIT binary patch
delta 15
Xcmey&_L*(NA|_@NJ(I~xna%+KG2R8}
delta 15
Xcmey&_L*(NA|_@7J;TXMna%+KF|!5X
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 eae2c6de47b7683c90f79610e51ccffec28f0eeb..8f5f5222646cf1f39f8c8ab492ad64ae77eadea4 100644
GIT binary patch
delta 13
VcmX@fc9LzwL?%X)$&;A20{|oT1oZ#_
delta 13
VcmX@fc9LzwL?%X~$&;A20{|oJ1oHp@
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 b054592fb6b998c342b524a982ae912065ee87bc..5e01ee9e5fe541b29e53402a8c80f1b9e0ba571d 100644
GIT binary patch
delta 13
UcmbQiHiKaudio
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 862384f74001cc5d5bd3e94126902a3028de72ab..73787558d219850a483718eb6814a19646f8e410 100644
GIT binary patch
delta 13
Ucmeyx`ipf#9229-(EtDd
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 53580b180f869fa6122bda36f4b1848636fcb97f..a4dfd786ce8f9daa67bc0d3794cc6802c93003a0 100644
GIT binary patch
delta 14
WcmZ3;y^wpu7G_41&0Cq@FaiK5Fa=Ej
delta 14
WcmZ3;y^wpu7G_4H&0Cq@FaiK5Bn3+V
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 8adfe1ae8f415c3f204cc9da0038c37d4872d864..f8bfc56aa81553bc2e615a6ffe3e386626ec5192 100644
GIT binary patch
delta 16
YcmX@ceT;j 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 0c8e3be121f4de9d1ba4392a2af4065615e8180b..786d956909402e58e7c43d42efd89ec9c58043d5 100644
GIT binary patch
delta 14
WcmZ3)y@-3mF=j@S&BvKx$
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 1a21b35750a7700559a452058f4ec42b0a8126c3..d458ae1a71e3e524377dc0d19ffd4176a9cfda17 100644
GIT binary patch
delta 14
Vcmeyv`G<2uH#4Kj<{st(MgT4`1u*~s
delta 14
Vcmeyv`G<2uH#4Kr<{st(MgT4)1up;q
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 bd12f87423f075163adfad9be6503dbddad47f0f..5880464b71630b2090fe30e584f15ad212b5ff1f 100644
GIT binary patch
delta 14
VcmX@YeuRC)UM5D9&HI?x7y&8#1hoJF
delta 14
VcmX@YeuRC)UM5DP&HI?x7y&8p1hW7D
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 1968c0a49a7ad4d34410e040c023feb1026d9dd3..58715e7a6705434b355b98830e35ff20e4f82bb0 100644
GIT binary patch
delta 16
Xcmeyt{)2tP114q@J(JCknM4@@J4prD
delta 16
Xcmeyt{)2tP114qzJ;Tk9nM4@@I~N7f
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 d22d37fa5a7891a44cc3dc3529a56d2c4c9d4a89..8db354d53d938c63627005ab65b421a9a0335e3e 100644
GIT binary patch
delta 13
VcmX@cevEy?c_v1a$rqTu0RSeg1*`x7
delta 13
VcmX@cevEy?c_v1q$rqTu0RSeW1*!l5
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 32bcc14e8d50358f7becd34d20a41bbad141f15f..44b3496be636f2aa4ea6563e5cbe3a42751024b0 100644
GIT binary patch
delta 13
Vcmeyz_K$7DG$uxq$ $_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-----
+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
+-----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