1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Convert Image v1.1

Discussion in 'XenForo Development Discussions' started by AndyB, Nov 5, 2013.

  1. AndyB

    AndyB Well-Known Member

    Purpose:

    The purpose of this thread is to provide additional information on the Convert Image v1.0 add-on. To download and install this add-on please visit the following XenForo Resource:

    http://xenforo.com/community/resources/convert-image.2521/

    Description:

    The Convert Image add-on will convert linked images using the [ IMG ] tags to attachments.

    Key Features:
    • Converts images immediately to attachments after message is saved
    • Resizes images to maximum width and height settings
    • Setting for inserting full or thumbnail attachments
    • Setting for temporary image path
    • Setting for optional log file
    Requirements:
    • Requires XenForo v1.2 and above
    • Requires ImageMagick to be installed on your server
    Admin Settings:

    pic001.jpg
     
    Last edited: Nov 6, 2013
    BamaStangGuy likes this.
  2. AndyB

    AndyB Well-Known Member

    The directory structure

    library
    --Andy
    ----ConvertImage
    ------DataWriter.php
    ------Listener.php
     
  3. AndyB

    AndyB Well-Known Member

    library/Andy/ConvertImage/DataWriter.php (part 1)

    This code is needs to be put into two posts because it exceeds the 10,000 character limit per post.

    PHP:
    <?php

    class Andy_ConvertImage_DataWriter extends XFCP_Andy_ConvertImage_DataWriter
    {
        public function 
    save()
        {        
            
    // call parent function
            
    parent::save();
            
            
    // declare variable
            
    $tempImageDirectoryCheck '';
            
            
    // check for imagemagick option
            
    $imPecl XenForo_Application::get('options')->imageLibrary['class'];
            
            
    // get options from Admin CP -> Options -> Convert Image -> Temporary Image Directory   
            
    $temporaryImageDirectory XenForo_Application::get('options')->temporaryImageDirectory;
            
            
    // verify temporary directory exists 
            
    if (file_exists($temporaryImageDirectory))
            {
                
    $tempImageDirectoryCheck 'yes';
            }
            
            
    //#####################################
            // do basic checks before main loop
            // imagemagick must be installed and
            // temporary directory created
            //#####################################
            
            
    if ($imPecl == 'imPecl' AND $tempImageDirectoryCheck == 'yes')
            {
                
    // seacrh for [IMG] tag
                
    $pos1 stripos($this->get('message'), '[img]');
            
                
    // run only if [IMG] tag is found
                
    if (is_numeric($pos1))
                {                
                    
    // get current message
                    
    $currentMessage $this->get('message');
                    
                    
    // call mainLoop
                    
    $this->mainLoop($currentMessage);                
                }
            }
        }
        
        public function 
    mainLoop($currentMessage)
        {
            
    // define variables
            
    $done '';
            
    $newMessage '';
            
    $updateRequired '';
            
            
    // start loop        
            
    while ($done != 'yes')
            {
                
    //#####################################
                // parse the message that was just saved
                // look for [IMG] and [/IMG] tags
                // each loop will process one image tag
                // when the entire message has been parsed
                // the $done variable will be set to 'yes'
                //#####################################
                
                // clear variables for each loop
                
    $imglink '';
                
    $posStart '';
                
                
    //#####################################
                // find [IMG] and [/IMG] tags
                //#####################################
                
                // first loop
                
    if ($newMessage == '') {
                    
    $original_message $currentMessage;
                }            
                
                
    // looping again
                
    if ($newMessage != '') {
                    
    $original_message $newMessage;
                    
    $currentMessage $newMessage;
                }
            
                
    $pos1 stripos($currentMessage'[IMG]');
            
                if (
    $pos1 === false) {
                    
    $done 'yes';
                }            
                
                
    // used later to replace with [ATTACH] code
                
    if ($posStart == '') {
                    
    $posStart $pos1;
                }
                
                
    // start at beginning of url
                
    $pos1 $pos1 5;
                
                
    // delete $tempMessage up to beginning of image url
                
    $currentMessage substr($currentMessage$pos1);
                
                
    // get end of img tag 
                
    $pos1 stripos($currentMessage'[/IMG]');
                
                if (
    $pos1 === false) {
                    
    $done 'yes';
                }
                
                
    // $imglink will contain the link to the image
                
    $imglink substr($currentMessage$pos1);
            
                
    // only continue if we have an image link
                
    if ($imglink != '' AND $done != 'yes'
                {
                    
    //#####################################
                    // download image into temporary directory
                    //#####################################
                    
                    // get options from Admin CP -> Options -> Convert Image -> Temporary Image Directory   
                    
    $temporaryImageDirectory XenForo_Application::get('options')->temporaryImageDirectory;
                    
                    
    // define full path of download
                    
    $tempFullPath $temporaryImageDirectory 'convert' '_' rand();
                    
                    if (!
    file_exists($tempFullPath)) {
                        
    touch($tempFullPath); // create blank file
                        
    chmod($tempFullPath,0777);
                    }
            
                    
    $ch curl_init($imglink);
                    
    $fp fopen($tempFullPath"w");
                
                    
    curl_setopt($chCURLOPT_FILE$fp);
                    
    curl_setopt($chCURLOPT_HEADER0);
                    
    curl_setopt($chCURLOPT_TIMEOUT5); 
                    
                    
    // execute curl
                    
    curl_exec($ch);
                    
                    if (
    curl_errno($ch) > 0)
                    {
                        
    $done 'yes';
                    }                
                    
                    
    // close the file 
                    
    fclose($fp);
                    
                    
    //#####################################
                    // put image source into memory
                    // later we will save image to attachments directory
                    //#####################################
                    
                    
    $tempImage file_get_contents($tempFullPath);
                    
                    
    //#####################################
                    // make sure we have a valid image
                    //#####################################

                    // get dimensions - supress error message
                    
    @list($width$height) = getimagesize($tempFullPath);
                    
                    
    // if not image abort
                    
    if (is_null($width))
                    {
                        
    $done 'yes';    
                    }
                    
                    
    // only contunue if we have a valid image
                    
    if ($done != 'yes'
                    {                
                        
    //#####################################
                        // resize image
                        //#####################################
                        
                        // get options from Admin CP -> Options -> Attachments -> Maximum Attachment Image Dimensions
                        
    $attachmentMaxWidth XenForo_Application::get('options')->attachmentMaxDimensions['width'];
                        
                        
    // get options from Admin CP -> Options -> Attachments -> Maximum Attachment Image Dimensions
                        
    $attachmentMaxHeight XenForo_Application::get('options')->attachmentMaxDimensions['height'];                                        

                        
    // check if image width or height exceeds maximum allowed
                        
    if ($width $attachmentMaxWidth OR $height $attachmentMaxHeight) {
                            
                            
    // resize only if width or height exceed maximum - (use the '\>' flag)
                            
    exec("/usr/bin/convert $tempFullPath -resize $attachmentMaxWidth x $attachmentMaxHeight\> $tempFullPath");
                            
                            
    // get new image size
                            
    list($width$height) = getimagesize($tempFullPath);
                        }                
                        
                        
    //#####################################
                        // begin creating the attachment
                        // prepare data for SQL query.
                        //#####################################
                        
                        
    $currentUserId XenForo_Visitor::getUserId();
                        
                        
    $uploadDate time();
                        
    $basename basename($imglink);
                        
                        
    // make sure basename fits 100 character limit
                        
    if (strlen($basename) > 100)
                        {
                            
    $strlen strlen($basename);
                            
    $pos_start $strlen 100;
                            
    $basename substr($basename,$pos_start);
                        }
                        
                        
    $filesize filesize($tempFullPath);
                        
    $filehash hash_file('md5'$tempFullPath);
                        
                        
    $currentPostId $this->get('post_id');
                        
                        
    //#####################################
                        // run SQL query (attachment_data)
                        //#####################################            
                        
                        
    $db XenForo_Application::get('db');
        
                        
    $db->query("
                            INSERT INTO xf_attachment_data
                                (user_id, upload_date, filename, file_size, file_hash, width, height, thumbnail_width, thumbnail_height, attach_count)
                            VALUES
                                (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
                        "
    , array($currentUserId$uploadDate$basename$filesize$filehash$width$height'0''0''1'));
                        
                        
    // get the new data_id number (auto incremented) 
                        
    $dataId $db->lastInsertId();
                        
                        
    //#####################################
                        // run SQL query (attachment)
                        //#####################################                            
                        
                        
    $db->query("
                            INSERT INTO xf_attachment
                                (data_id, content_type, content_id, attach_date, temp_hash, unassociated, view_count)
                            VALUES
                                (?, ?, ?, ?, ?, ?, ?)
                        "
    , array($dataId'post'$currentPostId$uploadDate'''0''0'));
                        
                        
    // get the new attachment_id number (auto incremented) 
                        
    $attachmentId $db->lastInsertId();

     
    Last edited: Nov 6, 2013
    time likes this.
  4. AndyB

    AndyB Well-Known Member

    library/Andy/ConvertImage/DataWriter.php (part 2)

    This code is needs to be put into two posts because it exceeds the 10,000 character limit per post.

    PHP:
                        //#####################################
                        // define last folder name 
                        // 0-999 are stored in the 0 directory 
                        // 1000-1999 stored in the 1 directory etc 
                        //#####################################
                        
                        
    $lastfolder floor($dataId 1000);
                        
                        
    //#####################################
                        // define full path
                        //#####################################
                        
                        // get internal_data path
                        
    $internalDataPath XenForo_Helper_File::getInternalDataPath();
                        
                        
    // define full path
                        
    $attachmentFullPath $internalDataPath '/attachments/' $lastfolder '/' $dataId '-' $filehash '.data';
                
                        
    //#####################################
                        // create new internal_data and data
                        // directories if they don't exsist
                        //#####################################
                        
                        
    $directory $internalDataPath '/attachments/' $lastfolder;
                        
                        if (!
    file_exists($directory)) {
                            
                            
    // needed to make 0777
                            
    $old_umask umask(0);
                            
                            
    // make directories
                            
    mkdir($externalDataPath '/attachments/' $lastfolder0777);
                            
    mkdir($internalDataPath '/attachments/' $lastfolder0777);
                            
                            
    // create path for /data/index.html file
                            
    $indexpath $externalDataPath '/attachments/' $lastfolder '/index.html';
                            
    touch($indexpath); // Create index.html
                            
    chmod($indexpath,0666);    
                            
                            
    // create path for /internal_data/index.html file
                            
    $indexpath $internalDataPath '/attachments/' $lastfolder '/index.html';
                            
    touch($indexpath); // Create index.html
                            
    chmod($indexpath,0666);            
                        }
                                
                        
    //#####################################
                        // copy image from temporary directory 
                        // to attachment directory and
                        // delete temporary image
                        //#####################################
                        
                        // prepare new file
                        
    if (!file_exists($attachmentFullPath)) {
                            
    touch($attachmentFullPath); // Create blank file
                            
    chmod($attachmentFullPath,0777);
                        }
                                    
                        
    // save image to attachment directory
                        
    file_put_contents($attachmentFullPath$tempImage); 
                        
                        
    // remove temporary image
                        
    exec("rm $tempFullPath");
                        
                        
    //#####################################
                        // create thumbnail
                        //#####################################
                        
                        // get data path                    
                        
    $externalDataPath XenForo_Helper_File::getExternalDataPath();
                
                        
    $thumbpath $externalDataPath '/attachments/' $lastfolder '/' $dataId '-' $filehash '.jpg';
                            
                        if (!
    file_exists($thumbpath)) {
                            
    touch($thumbpath); // Create blank file
                            
    chmod($thumbpath,0777);
                        }
                        
                        
    // check if animated gif
                        
    $isAnimation exec("/usr/bin/identify -format '%n' $attachmentFullPath");    
                        
                        if (
    $isAnimation 1)
                        {    
                            
    $firstFrame $attachmentFullPath '[0]';
                            
    exec("/usr/bin/convert $firstFrame -coalesce -resize 100x100 $thumbpath");    
                        }
                        else
                        {
                            
    exec("/usr/bin/convert $attachmentFullPath -resize 100x100 $thumbpath");
                        }
                        
                        
    //#####################################
                        // update attachment_data table with dimensions
                        //#####################################
                        
                        // get dimensions of thumbnail
                        
    list($width$height) = getimagesize($thumbpath);
                        
                        
    $db->query('
                            UPDATE xf_attachment_data SET
                                thumbnail_width = ' 
    $width ',
                                thumbnail_height = ' 
    $height '
                            WHERE data_id = ' 
    $dataId '
                        '
    );                    
                                            
                        
    //#####################################
                        // update message with [ATTACH] tags
                        //#####################################
                        
                        // get options from Admin CP -> Options -> Convert Image -> Insert Thumbnail    
                        
    $insertThumbnail XenForo_Application::get('options')->insertThumbnail;
                        
                        
    // insert attach code
                        
    if ($insertThumbnail == 1)
                        {
                            
    $attachcode '[ATTACH]' $attachmentId '[/ATTACH]';    
                        }
                        else
                        {
                            
    $attachcode '[ATTACH=full]' $attachmentId '[/ATTACH]';    
                        }
                        
                        
    // calulate end position    
                        
    $posEnd strlen($imglink) + 11;
                        
                        
    // create new message
                        
    $newMessage substr_replace($original_message$attachcode$posStart$posEnd);
                        
                        
    //#####################################
                        // update optional log file
                        //#####################################
                        
                        // declare variable
                        
    $convertImageLogFile '';
                        
                        
    // get options from Admin CP -> Options -> Convert Image -> Log File   
                        
    $convertImageLogFile XenForo_Application::get('options')->convertImageLogFile;                    
                        
                        if (
    $convertImageLogFile != '')
                        {
                            
    // verify log file exists
                            
    if (file_exists($convertImageLogFile))
                            {
                                
                                
    // adjust for local timezone
                                
    $dateline time() + XenForo_Locale::getTimeZoneOffset();
                                
                                
    // format date
                                
    $formatedDate date("m/d/y h:ia"$dateline);
                                
                                
    // prepare data
                                
    $data $formatedDate ' / Post ' $currentPostId ' / ' $imglink '
    '
    ;
                                
    // update log file
                                
    $handle fopen($convertImageLogFile'a');
                                
    fwrite($handle$data);
                                
    fclose($handle);
                            }
                        }
                        
                        
    //#####################################
                        // set $updateRequired flag
                        //#####################################                                                        
                        
                        
    $updateRequired 'yes';
                    }
                }
            }
            
            if (
    $updateRequired == 'yes')
            {            
                
    //#####################################
                // update xf_post.message
                //#####################################            
                
                
    $db->query('
                    UPDATE xf_post SET
                        message = ?
                    WHERE post_id = ?
                '
    , array($newMessage$currentPostId));                            
                
                
    //#####################################
                // delete xf_bb_code_parse_cache
                //#####################################        
                
                
    $db->query('
                    DELETE FROM xf_bb_code_parse_cache
                    WHERE content_id = ?
                '
    $currentPostId);
                
                
    //#####################################
                // update ElasticSearch post index
                //#####################################
                
                // check if ElasticSearch is enabled
                
    if (XenForo_Application::get('options')->enableElasticsearch)
                {
                    
    // get ElasticSearch options    
                    
    $esServerOption XenForo_Application::get('options')->elasticSearchServer;
                    
                    
    // get ElasticSearch port number
                    
    $esPort $esServerOption['port'];
                    
                    
    // get ElasticSearch index name
                    
    $indexName XenES_Api::getInstance()->getIndex();

                    
    // delete current post data in ElasticSearch
                    
    exec("curl -XDELETE 'http://localhost:" $esPort "/" $indexName "/post/'" $currentPostId "'");
                    
                    
    // prepare data
                    
    $dataString '{
                        "message" : "' 
    $newMessage '"
                    }'
    ;
                    
                    
    $ch curl_init('http://localhost:' $esPort '/' $indexName '/post/' $currentPostId);
                    
    curl_setopt($chCURLOPT_RETURNTRANSFERTRUE);
                    
                    
    curl_setopt($chCURLOPT_HTTPHEADER, array(                                                                          
                    
    'Content-Type: application/json',                                                                                
                    
    'Content-Length: ' strlen($dataString))                                                                       
                    ); 
                     
                    
    curl_setopt($chCURLOPT_POSTFIELDS$dataString );
                    
    curl_setopt($chCURLOPT_CUSTOMREQUEST'PUT');
                    
                    
    // execute curl
                    
    curl_exec($ch);
                }
            }
        }
    }

    ?>
     
    Last edited: Nov 6, 2013
  5. AndyB

    AndyB Well-Known Member

    library/Andy/ConvertImage/Listener.php

    PHP:
    <?php

    class Andy_ConvertImage_Listener
    {    
        public static function 
    loadClassDatawriter($class, array &$extend)
        {
            
    $extend[] = 'Andy_ConvertImage_DataWriter';
        } 
    }

    ?>
     

Share This Page