Changeset 3365915
- Timestamp:
- 09/22/2025 03:14:07 PM (6 months ago)
- Location:
- krea3-client-for-citykomi/trunk
- Files:
-
- 3 edited
-
krea3-citykomi-client.php (modified) (2 diffs)
-
public/Krea3_Citykomi_Client_Public.php (modified) (4 diffs)
-
readme.txt (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
krea3-client-for-citykomi/trunk/krea3-citykomi-client.php
r3365736 r3365915 3 3 * Plugin Name: Krea3 Client for Citykomi 4 4 * Description: Lightweight client to relay WordPress content to the Citykomi service via a remote Krea3 gateway. Not affiliated with Citykomi. 5 * Version: 1. 1.95 * Version: 1.2.0 6 6 * Author: Krea3 7 7 * Author URI: https://www.krea3.fr/ … … 23 23 24 24 // Définir une constante pour la version du plugin 25 define( 'KREA3_CITYKOMI_CLIENT_VERSION', '1. 1.9' );25 define( 'KREA3_CITYKOMI_CLIENT_VERSION', '1.2.0' ); 26 26 27 27 $uploads = wp_upload_dir(); -
krea3-client-for-citykomi/trunk/public/Krea3_Citykomi_Client_Public.php
r3360604 r3365915 183 183 $cache_key = '_krea3citykomi_msg_' . md5( wp_json_encode( $args ) ); 184 184 185 if ( false !== ( $output = get_transient( $cache_key ) ) ) {186 //echo "on charge le cache $cache_key <br><br><br><br>";185 if ( false !== ( $output = get_transient( $cache_key ) ) && ! current_user_can("administrator") ) { 186 echo "le cache"; 187 187 return $output; 188 188 } … … 275 275 } 276 276 277 protected function decode_piece_jointe($message) { 277 protected function decode_piece_jointe_old($message) { 278 echo "<pre>"; print_r($message); echo "</pre>"; 278 279 $pj = false; 279 280 if( array_key_exists("content", $message) && is_array($message["content"])){ … … 288 289 wp_mkdir_p(KREA3_CITYKOMI_UPLOADS. $message["id_channel"]); 289 290 } 290 291 $dataBase64 = base64_decode($file); 291 $dataBase64 = base64_decode($file); 292 292 if( file_put_contents(str_replace("pdf", "jpg", $pathImage), $dataBase64) ){ 293 file_put_contents($pathImage, base64_decode($imageSource["small_base64"]) ); 293 294 $pj = array("type" => $imageSource["type"], "src" => str_replace(WP_CONTENT_DIR, WP_CONTENT_URL, $pathImage) ); 294 295 296 297 295 if( $imageSource["type"] == "pdf" && array_key_exists("asset", $message) ){ 298 if( is_array($message["asset"]) && array_key_exists("data", $message["asset"]) ){296 if( array_key_exists("asset", $message) && is_array($message["asset"]) && array_key_exists("data", $message["asset"]) ){ 299 297 if( $this->uploadFileFromBlobString($message["asset"]["data"], $imageSource["real_name"], KREA3_CITYKOMI_UPLOADS . $message["id_channel"] . "/") ){ 300 298 $pj["fichier"] = str_replace(WP_CONTENT_DIR, WP_CONTENT_URL, $pathImage); 301 299 } 302 303 300 } 304 301 } … … 309 306 return $pj; 310 307 } 308 309 protected function decode_piece_jointe($message) { 310 $pj = false; 311 312 if (empty($message['content']['imageSource']) || !is_array($message['content']['imageSource'])) { 313 return $pj; 314 } 315 316 $imageSource = $message['content']['imageSource']; 317 $type = isset($imageSource['type']) ? strtolower($imageSource['type']) : 'image'; 318 $realName = !empty($imageSource['real_name']) ? basename($imageSource['real_name']) : 'piece-jointe.pdf'; 319 $baseName = pathinfo($realName, PATHINFO_FILENAME); 320 $channel = isset($message['id_channel']) ? preg_replace('~[^0-9]~', '', (string)$message['id_channel']) : '0'; 321 322 // Dossier / URL basés sur wp_upload_dir() + ta constante 323 $uploads = wp_upload_dir(); 324 $baseDir = trailingslashit(KREA3_CITYKOMI_UPLOADS) . $channel . '/'; // .../uploads/krea3citykomi/<channel>/ 325 $baseUrl = trailingslashit($uploads['baseurl']) . 'krea3citykomi/' . $channel . '/'; // URL publique 326 327 if (!is_dir($baseDir)) { 328 wp_mkdir_p($baseDir); 329 } 330 331 // Cibles 332 $thumbExt = '.jpg'; // on ajustera si PNG 333 $thumbPath = $baseDir . $baseName . $thumbExt; 334 $thumbUrl = $baseUrl . $baseName . $thumbExt; 335 336 $pdfPath = $baseDir . $baseName . '.pdf'; 337 $pdfUrl = $baseUrl . $baseName . '.pdf'; 338 339 /* 1) VIGNETTE depuis small_base64 */ 340 if (!empty($imageSource['small_base64'])) { 341 $raw = $imageSource['small_base64']; 342 if (strpos($raw, 'base64,') !== false) { 343 $raw = substr($raw, strpos($raw, 'base64,') + 7); 344 } 345 $rem = strlen($raw) % 4; 346 if ($rem) $raw .= str_repeat('=', 4 - $rem); 347 348 $thumbBytes = base64_decode($raw, true); 349 if ($thumbBytes !== false) { 350 // Détecter le format pour l’extension 351 if (function_exists('finfo_open')) { 352 $f = finfo_open(FILEINFO_MIME_TYPE); 353 $mime = finfo_buffer($f, $thumbBytes); 354 finfo_close($f); 355 if ($mime === 'image/png') { 356 $thumbExt = '.png'; 357 $thumbPath = $baseDir . $baseName . $thumbExt; 358 $thumbUrl = $baseUrl . $baseName . $thumbExt; 359 } 360 } 361 file_put_contents($thumbPath, $thumbBytes); 362 @chmod($thumbPath, 0644); 363 } 364 } 365 366 /* 2) PDF “officiel” si on a le binaire (asset.data ou imageSource.data) */ 367 $savedPdf = false; 368 if ($type === 'pdf') { 369 $rawPdf = ''; 370 if (!empty($message['asset']['data'])) { 371 $rawPdf = $message['asset']['data']; 372 } elseif (!empty($imageSource['data'])) { 373 $rawPdf = $imageSource['data']; 374 } 375 376 if ($rawPdf !== '') { 377 if (is_string($rawPdf)) { 378 if (strpos($rawPdf, 'base64,') !== false) { 379 $rawPdf = substr($rawPdf, strpos($rawPdf, 'base64,') + 7); 380 } 381 $rem = strlen($rawPdf) % 4; 382 if ($rem) $rawPdf .= str_repeat('=', 4 - $rem); 383 $pdfBytes = base64_decode($rawPdf, true); 384 } elseif (is_array($rawPdf)) { 385 $pdfBytes = pack('C*', ...$rawPdf); 386 } else { 387 $pdfBytes = false; 388 } 389 390 if ($pdfBytes !== false) { 391 $isPdf = (strncmp($pdfBytes, '%PDF', 4) === 0) && (strpos(substr($pdfBytes, -2048), '%%EOF') !== false); 392 if ($isPdf) { 393 file_put_contents($pdfPath, $pdfBytes); 394 @chmod($pdfPath, 0644); 395 $savedPdf = true; 396 } 397 } 398 } 399 } 400 401 /* 3) Si on a besoin d’un PDF mais qu’on ne l’a pas, on le FABRIQUE depuis l’image */ 402 if ($type === 'pdf' && !$savedPdf && file_exists($thumbPath)) { 403 $genOk = $this->generatePdfFromImage($thumbPath, $pdfPath); 404 if ($genOk) { 405 $savedPdf = true; 406 } 407 } 408 409 /* 4) Préparer le retour */ 410 if (file_exists($thumbPath)) { 411 $pj = [ 412 'type' => $type, 413 'src' => $thumbUrl, // vignette à afficher 414 ]; 415 } 416 417 if ($type === 'pdf' && $savedPdf && file_exists($pdfPath) && filesize($pdfPath) > 0) { 418 $pj['fichier'] = $pdfUrl; // lien PDF cliquable 419 } elseif ($type !== 'pdf' && file_exists($thumbPath)) { 420 $pj['fichier'] = $thumbUrl; 421 } 422 423 return $pj; 424 } 425 426 /** 427 * Génère un PDF 1 page à partir d’une image (jpg/png). 428 * Essaie d’abord IMAGICK, sinon FPDF (si disponible). 429 * @return bool true si le PDF a été créé. 430 */ 431 protected function generatePdfFromImage(string $imagePath, string $pdfPath): bool { 432 if (!file_exists($imagePath) || !is_readable($imagePath)) { 433 return false; 434 } 435 436 // 1) IMAGICK (simple et qualitatif) 437 if (extension_loaded('imagick')) { 438 try { 439 $img = new \Imagick(); 440 $img->readImage($imagePath); 441 442 // (Option) améliorer la sortie si besoin 443 $img->setImageUnits(\Imagick::RESOLUTION_PIXELSPERINCH); 444 $img->setImageResolution(300, 300); 445 @$img->resampleImage(300, 300, \Imagick::FILTER_LANCZOS, 1); 446 447 $img->setImageFormat('pdf'); 448 $ok = $img->writeImage($pdfPath); 449 $img->clear(); 450 $img->destroy(); 451 452 if ($ok && file_exists($pdfPath) && filesize($pdfPath) > 0) { 453 @chmod($pdfPath, 0644); 454 return true; 455 } 456 } catch (\Throwable $e) { 457 // error_log('Imagick PDF gen error: '.$e->getMessage()); 458 } 459 } 460 461 // 2) FPDF (lib PHP à inclure/installer) 462 if (!class_exists('\FPDF')) { 463 // Essaie un include local si tu l’as rangé quelque part 464 // require_once __DIR__ . '/fpdf.php'; 465 } 466 if (class_exists('\FPDF')) { 467 [$pxW, $pxH, $imgType] = @getimagesize($imagePath); 468 if (!$pxW || !$pxH) return false; 469 470 // On place l’image sur une page A4 en gardant le ratio 471 $dpi = 96; // hypothèse simple si on ne lit pas l’EXIF 472 if (function_exists('exif_read_data')) { 473 $exif = @exif_read_data($imagePath); 474 if (!empty($exif['XResolution']) && !empty($exif['YResolution'])) { 475 $unit = (!empty($exif['ResolutionUnit']) && (int)$exif['ResolutionUnit'] === 3) ? 'cm' : 'inch'; 476 $dpiX = is_array($exif['XResolution']) ? ($exif['XResolution'][0] / max(1,$exif['XResolution'][1])) : floatval($exif['XResolution']); 477 $dpiY = is_array($exif['YResolution']) ? ($exif['YResolution'][0] / max(1,$exif['YResolution'][1])) : floatval($exif['YResolution']); 478 if ($dpiX > 0 && $dpiY > 0) { 479 if ($unit === 'cm') { $dpiX *= 2.54; $dpiY *= 2.54; } 480 $dpi = (int)round(($dpiX + $dpiY)/2); 481 } 482 } 483 } 484 485 // Conversion px -> mm 486 $wmm = $pxW * 25.4 / max(1,$dpi); 487 $hmm = $pxH * 25.4 / max(1,$dpi); 488 489 $pageW = 210; $pageH = 297; // A4 portrait 490 $margin = 10; 491 $maxW = $pageW - 2*$margin; 492 $maxH = $pageH - 2*$margin; 493 494 $scale = min($maxW/$wmm, $maxH/$hmm, 1); 495 $imgW = $wmm * $scale; 496 $imgH = $hmm * $scale; 497 $x = ($pageW - $imgW)/2; 498 $y = ($pageH - $imgH)/2; 499 500 $pdf = new \FPDF('P', 'mm', 'A4'); 501 $pdf->AddPage(); 502 $pdf->Image($imagePath, $x, $y, $imgW, $imgH); 503 $pdf->Output('F', $pdfPath); 504 505 if (file_exists($pdfPath) && filesize($pdfPath) > 0) { 506 @chmod($pdfPath, 0644); 507 return true; 508 } 509 } 510 511 // 3) Pas d’outil dispo → impossible de fabriquer un PDF proprement 512 return false; 513 } 514 515 516 protected function decode_piece_jointe__old($message) { 517 $pj = false; 518 519 if (empty($message['content']['imageSource']) || !is_array($message['content']['imageSource'])) { 520 return $pj; 521 } 522 523 $imageSource = $message['content']['imageSource']; 524 $type = isset($imageSource['type']) ? strtolower($imageSource['type']) : 'image'; 525 $realName = !empty($imageSource['real_name']) ? basename($imageSource['real_name']) : 'piece-jointe.pdf'; 526 $baseName = pathinfo($realName, PATHINFO_FILENAME); 527 $channel = isset($message['id_channel']) ? preg_replace('~[^0-9]~', '', (string)$message['id_channel']) : '0'; 528 529 // Dossiers / URLs via wp_upload_dir() + ta constante 530 $uploads = wp_upload_dir(); 531 $baseDir = trailingslashit(KREA3_CITYKOMI_UPLOADS) . $channel . '/'; // ex: wp-uploads/krea3citykomi/<channel>/ 532 $baseUrl = trailingslashit($uploads['baseurl']) . 'krea3citykomi/' . $channel . '/'; // URL publique correspondante 533 534 if (!is_dir($baseDir)) { 535 wp_mkdir_p($baseDir); 536 } 537 538 // Chemins/URLs cibles 539 $thumbExt = '.jpg'; // on adaptera si PNG 540 $thumbPath = $baseDir . $baseName . $thumbExt; 541 $thumbUrl = $baseUrl . $baseName . $thumbExt; 542 543 $pdfPath = $baseDir . $baseName . '.pdf'; 544 $pdfUrl = $baseUrl . $baseName . '.pdf'; 545 546 // --- 1) VIGNETTE : small_base64 => image (JPEG/PNG) 547 if (!empty($imageSource['small_base64'])) { 548 $raw = $imageSource['small_base64']; 549 // nettoie un éventuel data URI 550 if (strpos($raw, 'base64,') !== false) { 551 $raw = substr($raw, strpos($raw, 'base64,') + 7); 552 } 553 // padding 554 $rem = strlen($raw) % 4; 555 if ($rem) $raw .= str_repeat('=', 4 - $rem); 556 557 $thumbBytes = base64_decode($raw, true); 558 if ($thumbBytes !== false) { 559 // Détection MIME pour l’extension 560 if (function_exists('finfo_open')) { 561 $f = finfo_open(FILEINFO_MIME_TYPE); 562 $mime = finfo_buffer($f, $thumbBytes); 563 finfo_close($f); 564 if ($mime === 'image/png') { 565 $thumbExt = '.png'; 566 $thumbPath = $baseDir . $baseName . $thumbExt; 567 $thumbUrl = $baseUrl . $baseName . $thumbExt; 568 } 569 } 570 file_put_contents($thumbPath, $thumbBytes); 571 @chmod($thumbPath, 0644); 572 } 573 } 574 575 // --- 2) PDF : UNIQUEMENT si on a les octets du PDF (asset.data ou imageSource.data) 576 $savedPdf = false; 577 if ($type === 'pdf') { 578 $rawPdf = ''; 579 if (!empty($message['asset']['data'])) { 580 $rawPdf = $message['asset']['data']; 581 } elseif (!empty($imageSource['data'])) { 582 $rawPdf = $imageSource['data']; 583 } 584 585 if ($rawPdf !== '') { 586 if (is_string($rawPdf)) { 587 if (strpos($rawPdf, 'base64,') !== false) { 588 $rawPdf = substr($rawPdf, strpos($rawPdf, 'base64,') + 7); 589 } 590 $rem = strlen($rawPdf) % 4; 591 if ($rem) $rawPdf .= str_repeat('=', 4 - $rem); 592 $pdfBytes = base64_decode($rawPdf, true); 593 } elseif (is_array($rawPdf)) { 594 // au cas où l’API enverrait un tableau d’octets 595 $pdfBytes = pack('C*', ...$rawPdf); 596 } else { 597 $pdfBytes = false; 598 } 599 600 if ($pdfBytes !== false) { 601 // Vérif rapide PDF : %PDF en tête + %%EOF dans la fin 602 $isPdf = (strncmp($pdfBytes, '%PDF', 4) === 0) && (strpos(substr($pdfBytes, -2048), '%%EOF') !== false); 603 if ($isPdf) { 604 file_put_contents($pdfPath, $pdfBytes); 605 @chmod($pdfPath, 0644); 606 $savedPdf = true; 607 } 608 } 609 } 610 } 611 612 // --- 3) Retour (on n’expose jamais une URL PDF invalide) 613 if (file_exists($thumbPath)) { 614 $pj = [ 615 'type' => $type, 616 'src' => $thumbUrl, 617 ]; 618 } 619 620 if ($type === 'pdf' && $savedPdf && file_exists($pdfPath) && filesize($pdfPath) > 0) { 621 $pj['fichier'] = $pdfUrl; 622 } elseif ($type !== 'pdf' && file_exists($thumbPath)) { 623 $pj['fichier'] = $thumbUrl; 624 } 625 626 return $pj; 627 } 628 629 311 630 312 631 // The working solution for converting a base64 string to a PDF file with PHP. -
krea3-client-for-citykomi/trunk/readme.txt
r3365736 r3365915 5 5 Tested up to: 6.8 6 6 Requires PHP: 7.4 7 Stable tag: 1. 1.97 Stable tag: 1.2.0 8 8 License: GPLv2 or later 9 9 License URI: https://www.gnu.org/licenses/gpl-2.0.html … … 77 77 78 78 == Changelog == 79 = 1.2.0 = 80 * Correctif : création du pdf lors d'un affichage distant 79 81 = 1.1.9 = 80 82 * Ajout : qty_by_page accepte désormais des valeurs de 1 à 50.
Note: See TracChangeset
for help on using the changeset viewer.