Plugin Directory

Changeset 3365915


Ignore:
Timestamp:
09/22/2025 03:14:07 PM (6 months ago)
Author:
krea3
Message:

Release 1.2.0: bump version, changelog, fixes

Location:
krea3-client-for-citykomi/trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • krea3-client-for-citykomi/trunk/krea3-citykomi-client.php

    r3365736 r3365915  
    33 * Plugin Name:       Krea3 Client for Citykomi
    44 * Description:       Lightweight client to relay WordPress content to the Citykomi service via a remote Krea3 gateway. Not affiliated with Citykomi.
    5  * Version:           1.1.9
     5 * Version:           1.2.0
    66 * Author:            Krea3
    77 * Author URI:        https://www.krea3.fr/
     
    2323
    2424// Définir une constante pour la version du plugin
    25 define( 'KREA3_CITYKOMI_CLIENT_VERSION', '1.1.9' );
     25define( 'KREA3_CITYKOMI_CLIENT_VERSION', '1.2.0' );
    2626
    2727$uploads = wp_upload_dir();
  • krea3-client-for-citykomi/trunk/public/Krea3_Citykomi_Client_Public.php

    r3360604 r3365915  
    183183        $cache_key = '_krea3citykomi_msg_' . md5( wp_json_encode( $args ) );
    184184       
    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";
    187187            return $output;
    188188        }
     
    275275    }
    276276   
    277     protected function decode_piece_jointe($message) {
     277    protected function decode_piece_jointe_old($message) {
     278        echo "<pre>"; print_r($message); echo "</pre>";
    278279        $pj = false;
    279280        if( array_key_exists("content", $message) && is_array($message["content"])){
     
    288289                        wp_mkdir_p(KREA3_CITYKOMI_UPLOADS. $message["id_channel"]);
    289290                    }
    290                    
    291                     $dataBase64 = base64_decode($file);
     291                    $dataBase64 = base64_decode($file);                   
    292292                    if( file_put_contents(str_replace("pdf", "jpg", $pathImage), $dataBase64) ){
     293                        file_put_contents($pathImage, base64_decode($imageSource["small_base64"]) );
    293294                        $pj = array("type" => $imageSource["type"], "src" => str_replace(WP_CONTENT_DIR, WP_CONTENT_URL, $pathImage) );
    294                        
    295                        
    296                        
    297295                        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"]) ){
    299297                                if( $this->uploadFileFromBlobString($message["asset"]["data"], $imageSource["real_name"], KREA3_CITYKOMI_UPLOADS . $message["id_channel"] . "/") ){
    300298                                    $pj["fichier"] = str_replace(WP_CONTENT_DIR, WP_CONTENT_URL, $pathImage);
    301299                                }
    302                                
    303300                            }
    304301                        }
     
    309306        return $pj;
    310307    }
     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   
    311630   
    312631    // The working solution for converting a base64 string to a PDF file with PHP.
  • krea3-client-for-citykomi/trunk/readme.txt

    r3365736 r3365915  
    55Tested up to: 6.8
    66Requires PHP: 7.4
    7 Stable tag: 1.1.9
     7Stable tag: 1.2.0
    88License: GPLv2 or later
    99License URI: https://www.gnu.org/licenses/gpl-2.0.html
     
    7777
    7878== Changelog ==
     79= 1.2.0 =
     80* Correctif : création du pdf lors d'un affichage distant
    7981= 1.1.9 =
    8082* Ajout : qty_by_page accepte désormais des valeurs de 1 à 50.
Note: See TracChangeset for help on using the changeset viewer.