Adding a TinyMCE image browser to CakePHP 2.+

This article is also available in the following languages:
By jwilcox09
This is just and update to Adding a TinyMCE image browser the CakePHP way as applicable to the 2.+ versions of Cake. Nothing major, just following with the api changes to make this work smoothly.
Here is the updated Model code:
<?php  
App
::uses('Folder''Utility');
App::uses('File''Utility');

class 
Imageupload extends AppModel 

    var 
$name 'Imageupload'

    var 
$validate = array( 
        
'imageupload' => array( 
            
'rule' => array( 
                
'validFile'
                array( 
                    
'required' => true
                    
'extensions' => array( 
                        
'jpg'
                        
'jpeg'
                        
'gif'
                        
'png' 
                    

                ) 
            ) 
        ) 
    ); 

    var 
$useTable false

    function 
readFolder($folderName null) { 
        
$folder = new Folder($folderName); 
        
$images $folder->read
            
true
            array( 
                
'.'
                
'..'
                
'Thumbs.db' 
            
), 
            
true 
        
); 
        
$images $images[1]; // We are only interested in files 

        // Get more infos about the images 
        
$retVal = array(); 
        foreach (
$images as $the_image
        { 
            
$the_image = new File($the_image); 
            
$retVal[] = array_merge
                
$the_image->info(), 
                array( 
                    
'size' => $the_image->size(), 
                    
'last_changed' => $the_image->lastChange() 
                ) 
            ); 
        } 

        return 
$retVal
    } 

    function 
upload($data null) { 
        
$this->set($data); 

        if(empty(
$this->data)) { 
            return 
false
        } 

        
// Validation 
        
if(!$this->validates()) { 
            return 
false
        } 
        
//print_r($this->data);
        // Move the file to the uploads folder 
        
if(!move_uploaded_file($this->data['Imageupload']['Image']['image']['tmp_name'], WWW_ROOT.DS.'uploads'.DS.$this->data['Imageupload']['Image']['image']['name'])) { 
            return 
false
        } 

        return 
true
    } 



    function 
validFile($check$settings) { 
        
$_default = array( 
            
'required' => false
            
'extensions' => array( 
                
'jpg'
                
'jpeg'
                
'gif'
                
'png' 
            

        ); 

        
$_settings array_merge
            
$_default
            
ife
                
is_array($settings), 
                
$settings
                array() 
            ) 
        ); 

        
// Remove first level of Array 
        
$_check array_shift($check); 

        if(
$_settings['required'] == false && $_check['size'] == 0) { 
            return 
true
        } 

        
// No file uploaded. 
        
if($_settings['required'] && $_check['size'] == 0) { 
            return 
false
        } 

        
// Check for Basic PHP file errors. 
        
if($_check['error'] !== 0) { 
            return 
false
        } 

        
// Use PHPs own file validation method. 
        
if(is_uploaded_file($_check['tmp_name']) == false) { 
            return 
false
        } 

        
// Valid extension 
        
return Validation::extension
            
$_check
            
$_settings['extensions'
        ); 
    } 

?>

You'll notice a couple of small changes, mainly addin the App:uses functionality before the class declaration, and also i renamed it to Imageuploads, as Images redirected to the webroot/images folders.

And here is the updated Controller code


<?php  
class ImageuploadsController extends AppController 

    var 
$name 'Imageuploads'

    var 
$uses = array('Imageupload'); 

    var 
$helpers = array( 
        
'Html'
        
'Form'
        
'Js'
        
'Number' // Used to show readable filesizes 
    
); 

    function 
admin_index() { 
        
$this->layout 'admin';
        
$this->set
            
'images'
            
$this->Imageupload->readFolder(WWW_ROOT.DS.'uploads'
        ); 
    } 

    function 
admin_upload() { 
        
// Upload an image 
        
if (!empty($this->data)) { 
            
// Validate and move the file 
            
if($this->Imageupload->upload($this->data)) { 
                
$this->Session->setFlash('The image was successfully uploaded.'); 
            } else { 
                
$this->Session->setFlash('There was an error with the uploaded file.'); 
            } 
             
            
$this->redirect
                array( 
                    
'action' => 'index' 
                

            ); 
        } else { 
            
$this->redirect
                array( 
                    
'action' => 'index' 
                

            ); 
        } 
    } 

?>
<p>I added the admin_ part because this functionality is behind an auth system and I wanted consistent URI's but that is up to to you.</p>
<p>Here is the tinymce.ctp code</p>
<?php echo $this->Html->script("tiny_mce/tiny_mce.js"); ?> 

<?php 
    
echo $this->Html->scriptBlock
        
"function fileBrowserCallBack(field_name, url, type, win) { 
            browserField = field_name; 
            browserWin = win; 
            window.open('"
.Helper::url(array('controller' => 'imageuploads'))."', 'browserWindow', 'modal,width=600,height=400,scrollbars=yes');
        }" 
    
); 
?> 

<?php 
    
echo $this->Html->scriptBlock
        
"tinyMCE.init({ 
            mode : 'textareas', 
            theme : 'advanced', 
            theme_advanced_buttons1 : 'forecolor, bold,italic,underline,|,justifyleft,justifycenter,justifyright,justifyfull,|,bullist,numlist,|,undo,redo,|,link,unlink,|,image,emotions,code',
            theme_advanced_buttons2 : '', 
            theme_advanced_buttons3 : '', 
            theme_advanced_toolbar_location : 'top', 
            theme_advanced_toolbar_align : 'left', 
            theme_advanced_path_location : 'bottom', 
            extended_valid_elements : 'a[name|href|target|title|onclick],img[class|src|border=0|alt|title|hspace|vspace|width|height|align|onmouseover|onmouseout|name],hr[class|width|size|noshade],font[face|size|color|style],span[class|align|style]',
            file_browser_callback: 'fileBrowserCallBack', 
            width: '620', 
            height: '480', 
            relative_urls : false 
        });" 
    
); 
?> 

And lastly the the index (or admin_index in my case) view located in View/imageuploads/


<?php 
    
echo $this->Html->scriptBlock
        
"function selectURL(url) { 
            if (url == '') return false; 

            url = '"
.Helper::url('/uploads/')."' + url; 

            field = window.top.opener.browserWin.document.forms[0].elements[window.top.opener.browserField]; 
            field.value = url; 
            if (field.onchange != null) field.onchange(); 
            window.top.close(); 
            window.top.opener.browserWin.focus(); 
        }" 
    
); 
?> 

<?php 
    
echo $this->Form->create
        
null
        array( 
            
'type' => 'file'
            
'url' => array( 
                
'action' => 'upload' 
            

        ) 
    ); 
    echo 
$this->Form->label
        
'Image.image'
        
'Upload image' 
    
); 
    echo 
$this->Form->file
        
'Image.image' 
    
);     
    echo 
$this->Form->end('Upload'); 
?> 

<?php if(isset($images[0])) { 
    
$tableCells = array(); 

    foreach(
$images As $the_image) { 
        
$tableCells[] = array( 
            
$this->Html->link
                
$the_image['basename'], 
                
'#'
                array( 
                    
'onclick' => 'selectURL("'.$the_image['basename'].'");' 
                

            ), 
            
$this->Number->toReadableSize($the_image['size']), 
            
date('m/d/Y H:i'$the_image['last_changed']) 
        ); 
    } 

    echo 
$this->Html->tag
        
'table'
        
$this->Html->tableHeaders
            array( 
                
'File name'
                
'Size'
                
'Date created' 
            

        ).
$this->Html->tableCells
            
$tableCells 
        

    ); 
?>

You'll notice a few small differences, like $this->Html->scriptBlock

Finally just make sure you add

Element('tinymce'); ?>

to the form you want to add this to.

Cheers!

Comments

Please login to post a comment.