| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 | <?php declare(strict_types=1); error_reporting(0); ini_set('display_errors', '0'); header('Content-Type: text/plain; charset=UTF-8'); /* ============================================================ CONFIG ============================================================ */ $config = [ 'upload_dir' => __DIR__ . '/uploads/', 'base_url' => ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http') . '://' . $_SERVER['HTTP_HOST'] . rtrim(dirname($_SERVER['REQUEST_URI']), '/\\') . '/uploads/', 'max_size' => 5 * 1024 * 1024, // 5 MB 'allowed_types' => [ 'image/jpeg' => 'jpg', 'image/png' => 'png', 'image/gif' => 'gif', 'image/webp' => 'webp', ], 'jpeg_quality' => 85, 'webp_quality' => 85, 'thumb_enabled' => true, 'thumb_max_w' => 300, 'thumb_max_h' => 300, 'thumb_trigger_w' => 800, 'thumb_trigger_h' => 800, ]; /* ============================================================ ERROR HANDLING ============================================================ */ function fail(int $httpCode, string $message): never { http_response_code($httpCode); exit($message); } function saveImage($image, string $mime, string $filename, array $config): bool { return match ($mime) { 'image/jpeg' => imagejpeg($image, $filename, $config['jpeg_quality']), 'image/png' => imagepng($image, $filename), 'image/gif' => imagegif($image, $filename), 'image/webp' => imagewebp($image, $filename, $config['webp_quality']), default => false, }; } function loadImage(string $filename, string $mime) { return match ($mime) { 'image/jpeg' => @imagecreatefromjpeg($filename), 'image/png' => @imagecreatefrompng($filename), 'image/gif' => @imagecreatefromgif($filename), 'image/webp' => function_exists('imagecreatefromwebp') ? @imagecreatefromwebp($filename) : false, default => false, }; } /* ============================================================ 1. CHECK UPLOAD ============================================================ */ if (!isset($_FILES['file'])) { fail(400, 'Geen bestand ontvangen.'); } $file = $_FILES['file']; if (!is_array($file)) { fail(400, 'Ongeldige upload.'); } switch ($file['error']) { case UPLOAD_ERR_OK: break; case UPLOAD_ERR_INI_SIZE: case UPLOAD_ERR_FORM_SIZE: fail(400, 'Bestand is te groot.'); case UPLOAD_ERR_PARTIAL: fail(400, 'Upload is onvolledig.'); case UPLOAD_ERR_NO_FILE: fail(400, 'Geen bestand geselecteerd.'); case UPLOAD_ERR_NO_TMP_DIR: fail(500, 'Tijdelijke uploadmap ontbreekt.'); case UPLOAD_ERR_CANT_WRITE: fail(500, 'Bestand kon niet worden opgeslagen.'); case UPLOAD_ERR_EXTENSION: fail(400, 'Upload geblokkeerd door serverextensie.'); default: fail(500, 'Onbekende uploadfout.'); } /* ============================================================ 2. CHECK SIZE ============================================================ */ if ($file['size'] <= 0) { fail(400, 'Leeg bestand.'); } if ($file['size'] > $config['max_size']) { fail(400, 'Bestand overschrijdt de maximale grootte.'); } /* ============================================================ 3. CHECK MIME TYPE ============================================================ */ $finfo = new finfo(FILEINFO_MIME_TYPE); $mime = $finfo->file($file['tmp_name']); if ($mime === false) { fail(400, 'Bestandstype kon niet worden bepaald.'); } if (!isset($config['allowed_types'][$mime])) { fail(400, 'Bestandstype niet toegestaan.'); } $extension = $config['allowed_types'][$mime]; /* ============================================================ 4. VERIFY IMAGE ============================================================ */ $imageInfo = @getimagesize($file['tmp_name']); if ($imageInfo === false) { fail(400, 'Bestand is geen geldige afbeelding.'); } [$originalWidth, $originalHeight] = $imageInfo; /* ============================================================ 5. LOAD IMAGE (EXIF/METADATA STRIPPING) ============================================================ */ $image = loadImage($file['tmp_name'], $mime); if ($image === false) { fail(400, 'Afbeelding kon niet worden verwerkt.'); } /* ============================================================ PREPARE DIRECTORY ============================================================ */ if (!is_dir($config['upload_dir'])) { if (!mkdir($config['upload_dir'], 0755, true)) { fail(500, 'Uploadmap kon niet worden aangemaakt.'); } } if (!is_writable($config['upload_dir'])) { fail(500, 'Uploadmap is niet schrijfbaar.'); } /* ============================================================ FILE NAMES ============================================================ */ try { $id = bin2hex(random_bytes(16)); } catch (Throwable) { $id = uniqid('', true); } $filename = $id . '.' . $extension; $thumbFilename = 'thumb_' . $filename; $fullPath = $config['upload_dir'] . $filename; $thumbPath = $config['upload_dir'] . $thumbFilename; /* ============================================================ SAVE CLEANED FULL IMAGE ============================================================ */ if (!saveImage($image, $mime, $fullPath, $config)) { imagedestroy($image); fail(500, 'Afbeelding kon niet worden opgeslagen.'); } /* ============================================================ URLS ============================================================ */ $fullUrl = $config['base_url'] . $filename; $thumbUrl = $config['base_url'] . $thumbFilename; /* ============================================================ THUMBNAIL REQUIRED? ============================================================ */ $useThumb = $config['thumb_enabled'] && ( $originalWidth > $config['thumb_trigger_w'] || $originalHeight > $config['thumb_trigger_h'] ); /* ============================================================ CREATE THUMBNAIL ============================================================ */ if ($useThumb) { $ratio = min( $config['thumb_max_w'] / $originalWidth, $config['thumb_max_h'] / $originalHeight ); $thumbWidth = max(1, (int) round($originalWidth * $ratio)); $thumbHeight = max(1, (int) round($originalHeight * $ratio)); $thumb = imagecreatetruecolor($thumbWidth, $thumbHeight); if ($thumb === false) { imagedestroy($image); fail(500, 'Thumbnail kon niet worden aangemaakt.'); } if (in_array($mime, ['image/png', 'image/gif', 'image/webp'], true)) { imagealphablending($thumb, false); imagesavealpha($thumb, true); $transparent = imagecolorallocatealpha($thumb, 0, 0, 0, 127); imagefilledrectangle($thumb, 0, 0, $thumbWidth, $thumbHeight, $transparent); } if (!imagecopyresampled( $thumb, $image, 0, 0, 0, 0, $thumbWidth, $thumbHeight, $originalWidth, $originalHeight )) { imagedestroy($thumb); imagedestroy($image); fail(500, 'Thumbnail kon niet worden geschaald.'); } if (!saveImage($thumb, $mime, $thumbPath, $config)) { imagedestroy($thumb); imagedestroy($image); fail(500, 'Thumbnail kon niet worden opgeslagen.'); } imagedestroy($thumb); echo "[url={$fullUrl}][img]{$thumbUrl}[/img][/url]"; } else { echo "[img]{$fullUrl}[/img]"; } /* ============================================================ CLEANUP ============================================================ */ imagedestroy($image); exit; ?> |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | // ==UserScript== // @ name FOK Image Paste Uploader (PRO) // @ namespace http://tampermonkey.net/ // @ version 2.0 // @ match https://forum.fok.nl/* // @ grant GM_xmlhttpRequest // @ connect * // ==/UserScript== (function () { 'use strict'; const UPLOAD_URL = "https://<joudomein.nl>/<jouscriptnaam.php>"; // <-- aanpassen document.addEventListener("paste", function (e) { const items = (e.clipboardData || window.clipboardData).items; for (let i = 0; i < items.length; i++) { const item = items[i]; if (item.type.indexOf("image") !== -1) { e.preventDefault(); const file = item.getAsFile(); if (!file) return; const formData = new FormData(); formData.append("file", file, "upload.png"); GM_xmlhttpRequest({ method: "POST", url: UPLOAD_URL, data: formData, onload: function (response) { const text = (response.responseText || "").trim(); console.log("UPLOAD RESPONSE:", text); if (response.status !== 200) { alert("Upload failed: " + response.status); return; } // simpele validatie: moet BBCode bevatten if (!text.includes("[") || !text.includes("]")) { alert("Invalid response from server"); return; } insertAtCursor(text); }, onerror: function (err) { console.log(err); alert("Upload error"); } }); return; } } }); function insertAtCursor(text) { const textarea = document.querySelector("textarea[name='message']") || document.querySelector("textarea"); if (!textarea) { alert("No editor found"); return; } const start = textarea.selectionStart; const end = textarea.selectionEnd; textarea.value = textarea.value.substring(0, start) + text + textarea.value.substring(end); textarea.selectionStart = textarea.selectionEnd = start + text.length; textarea.focus(); } })(); |
Dat kan, en zou je kunnen maken. Echter zit je met imgur en andere hosters vaak vast aan een API, en vaak ook kosten. Zelf hosten kost vaak niets meer dan je al betaaldquote:Op zondag 26 april 2026 09:16 schreef FlippingCoin het volgende:
Ik zou zelf, al eerste ingeving wanneer ik zo iets zou moeten maken, denken in de richting van een cloud functie die de imgur api aanspreekt en bb code teruggeeft, en dan lokaal inderdaad iets van een browser extensie die checkt of je een afbeelding in clipboard heeft en of het domein forum.fok.nl is en als dat zo is dat uitvoert voor je.
Volgens mij is imgur gratis zolang je er geen geld mee verdient, en dit maakt het bruikbaar voor anderen zonder server dat was mijn rationale voor die keuze. Verder denk ik dat het heel goedkoop op te zetten is tegenwoordig als je zelf de hosting wil doen, als ik bij google cloud projects kijk zie ik dat je een tb aan afbeeldingen kan opslaan voor 20$ per maand, en dan staat het nog in Nederland ook. Als je dan wat restrictief bent in welke formaten je toestaat kan je zo 1 miljoen afbeeldingen opslaan.quote:Op zondag 26 april 2026 09:35 schreef Chandler het volgende:
[..]
Dat kan, en zou je kunnen maken. Echter zit je met imgur en andere hosters vaak vast aan een API, en vaak ook kosten. Zelf hosten kost vaak niets meer dan je al betaald(in mijn geval wel)
En ik snap dat FOK! deze optie niet kan bieden, de hoeveelheid is gewoon te groot daarvoor.
Ik heb zelf een iets andere versie die ook werkt op andere domeinen en andere textveld namen. Werkt vrij simpel en allemaal met het zelfde upload scriptje. Al kan de output per domein anders zijn.
Zou best leuk zijn als er iemand zou opstaan en dit voor FOK! beschikbaar zou maken, wel met het idee dat het net zolang blijft gehost worden als FOK! blijft bestaan!quote:Op zondag 26 april 2026 09:44 schreef FlippingCoin het volgende:
[..]
Volgens mij is imgur gratis zolang je er geen geld mee verdient, en dit maakt het bruikbaar voor anderen zonder server dat was mijn rationale voor die keuze. Verder denk ik dat het heel goedkoop op te zetten is tegenwoordig als je zelf de hosting wil doen, als ik bij google cloud projects kijk zie ik dat je een tb aan afbeeldingen kan opslaan voor 20$ per maand, en dan staat het nog in Nederland ook. Als je dan wat restrictief bent in welke formaten je toestaat kan je zo 1 miljoen afbeeldingen opslaan.
Ik vermoed dat het grootste probleem voor fok is dat het oude software is die nog moeilijk te onderhouden en beheren is.
Maar misschien denk ik er te makkelijk over doordat ik dagelijks met zulke dingen werk en budget eigenlijk pas gaat spelen bij opties vanaf tienduizenden euro's per maand.
Het probleem met dit als third party ontwikkelen voor fok is dat je het heel erg moeilijk kan openen voor fok gebruik maar kan afsluiten voor de rest van de wereld denk ik, en de integratie zal nooit ideaal worden.quote:Op zondag 26 april 2026 09:48 schreef Chandler het volgende:
[..]
Zou best leuk zijn als er iemand zou opstaan en dit voor FOK! beschikbaar zou maken, wel met het idee dat het net zolang blijft gehost worden als FOK! blijft bestaan!
En wees vrij om een nieuw script te bouwen op basis van het idee natuurlijk!ben heel benieuwd wat er uit andere mouwen geschud kan worden. De mogelijkheden zijn oneindig!
Nee, maar je kunt wel heel veel afvangen!quote:Op zondag 26 april 2026 11:01 schreef FlippingCoin het volgende:
[..]
Het probleem met dit als third party ontwikkelen voor fok is dat je het heel erg moeilijk kan openen voor fok gebruik maar kan afsluiten voor de rest van de wereld denk ik, en de integratie zal nooit ideaal worden.
Ja en hoe doe je dat met een stukje scherm? eerst opslaan, dan hoster zoeken, dan uploaden, dan de juiste ubb code selecteren dan weer terug naar het forum..quote:Op dinsdag 28 april 2026 15:47 schreef nelaeryn het volgende:
Ik waardeer de moeite die je erin hebt gestopt, maar zo ingewikkeld is een plaatje invoegen toch niet?
Klik op "voeg afbeelding toe", plak de URL in de dialoog box, klik OK, en klaar is Kees.
Google eens op ShareXquote:Op dinsdag 28 april 2026 15:53 schreef Chandler het volgende:
[..]
Ja en hoe doe je dat met een stukje scherm? eerst opslaan, dan hoster zoeken, dan uploaden, dan de juiste ubb code selecteren dan weer terug naar het forum..
Kan allemaal, maar dit maakt het voor mij net even wat handiger!
Hiermee sluit je ongeveer 99,9999% van de Fokkers uit.quote:Op zondag 26 april 2026 08:49 schreef Chandler het volgende:
Wat is er nodig voor het gebruik maken van het tooltje.
2. Een eigen hosting/website met PHP ondersteuning.
Hebben jullie suggesties? tips? verbeteringen? voeg ze vooral toe aan dit topic!![]()
jammer genoeg heeft Imgur zijn API om zeep geholpen waardoor tools zoals ShareX niet meer werkenquote:Op zondag 26 april 2026 09:16 schreef FlippingCoin het volgende:
Ik zou zelf, al eerste ingeving wanneer ik zo iets zou moeten maken, denken in de richting van een cloud functie die de imgur api aanspreekt en bb code teruggeeft, en dan lokaal inderdaad iets van een browser extensie die checkt of je een afbeelding in clipboard heeft en of het domein forum.fok.nl is en als dat zo is dat uitvoert voor je.
ah dat is jammer, lang sharex gebruikt toen ik nog op windows zatquote:Op donderdag 4 juni 2026 21:04 schreef mschol het volgende:
[..]
jammer genoeg heeft Imgur zijn API om zeep geholpen waardoor tools zoals ShareX niet meer werken
|
|
| Forum Opties | |
|---|---|
| Forumhop: | |
| Hop naar: | |