11 May 2012

Membuat Simple File Manager CKEditor di CakePHP

follow article
 

Dengan pertimbangan user friendly, kita sering mengganti form textarea dengan HTML editor yang menganut konsep WYSIWYG (what you see is what you get). Salah satu HTML editor WYSIWYG yang cukup populer adalah CKEditor. Ketika masih bernama FCKeditor, kita masih merasakan kemudahan menggunakan file manager bawaan FCKeditor. Namun saat ini, tidak ada file manager bawaan khusus dari CKEditor.

Meski begitu, CKEditor dibuat untuk kompatibel dengan file manager manapun hanya dengan sedikit sentuhan. Karena itulah CKEditor menjadi sangat fleksibel terhadap apapun pilihan file manager-nya. Jika tidak keberatan mengeluarkan sejumlah uang, ada CKFinder, dimana harus mengeluarkan minimal US $59 untuk menggunakan-nya di website personal. Atau Anda perlu menyediakan waktu untuk browsing mencari file manager yang gratis, dan mengintegrasikannya dengan CKEditor. Atau malah membuat file manager sendiri. Ya, CKEditor menyediakan API jika Anda tertarik untuk membuat file manager sendiri.

Artikel ini menjelaskan tahap demi tahap untuk membuat file manager dengan CakePHP 2.x. Dan agar lebih mudah digunakan (portable), file manager akan dibuat dalam bentuk plugin. Untuk persiapan, silahkan buat app terlebih dahulu menggunakan perintah bake. Misalnya nama app adalah lat_file_managers.

Kemudian download CKEditor dari website CKEditor, dan extract di direktori APP/webroot/js/

Buat suatu form sederhana

Buat Controller APP/Controller/SimpleFormsController.php dengan kode berikut :

<?php
App::uses('AppController', 'Controller');
class SimpleFormsController extends AppController{
    var $name='SimpleForms';

    public function index(){
    }
}

Buat Model APP/Model/SimpleForm.php dengan kode berikut :

<?php
App::uses('AppModel','Model');
class SimpleForm extends AppModel{
    var $name='SimpleForm';
    var $useTable=false;
}

Buat View APP/View/SimpleForms/index.ctp dengan kode berikut :

<?php
    echo $this->Form->create('SimpleForm');
    echo $this->Form->textarea('text');
    echo $this->Form->end('Submit');
?>

Sekarang kita akan mereplace textarea dengan CKEditor:

echo $this->Html->script('ckeditor/ckeditor.js');
include_once(WWW_ROOT."js/ckeditor/ckeditor.php");
$CKEditor = new CKEditor();
$CKEditor->replace("SimpleFormText");

Coba buka image icon, jika ingin menambahkan tombol "Browse Server", ikuti manual yang ada dengan menghapus kode $CKEditor->replace("SimpleFormText"); kemudian tambahkan kode berikut:

<script>
    CKEDITOR.replace( 'SimpleFormText',
    {
        filebrowserBrowseUrl : '<?php echo $this->base;?>/file_managers',
        filebrowserImageBrowseUrl : '<?php echo $this->base;?>/file_managers?Type=Images',
    });
</script>

Jika kita coba membuka image icon, ada tombol "Browse Server", yang jika diklik akan muncul popup ke halaman yang menampilkan pesan error. Ini dikarenakan kita belum membuat halaman file_managers.

Membuat File Manager

File manager yang akan dibuat masih sangat sederhana dengan fitur:
- Hanya mengelola file image (jpg/jpeg, gif, dan png).
- Dilengkapi dengan fitur upload

Ide dasar halaman file manager adalah sebagai berikut:
1. Baca seluruh direktori /img/images
2. Ambil yang berupa image
3. Baca helper yang berfungsi : jika belum ada thumbnail, buat thumbnail, jika sudah ambil thumbnail
4. Tampilkan dalam bentuk hyperlink, jika dipilih close window

Sekarang kita akan memulainya, dari direktori APP/Plugin, buat folder berikut untuk membuat plugin file_managers:

Plugins
-- FileManagers
   -- Controller
   -- Model
   -- View
   -- webroot

Kemudian buat file APP/Plugins/FileManagers/Controller/FileManagersController.php

<?php
App::uses('AppController','Controller');
class FileManagersController extends AppController {
    var $name='FileManagers';
    var $layout=false;
    
    public function index(){
        // set relative path from WWW for image and thumbnail
        $path='img/images/';
        $this->set(compact('path'));        
    }
}

Kode di atas menginformasikan bahwa path image adalah "img/images/". Jadi jangan lupa untuk membuat folder images (APP/webroot/img/images/).

Kemudian buat file APP/Plugins/FileManagers/Model/FileManager.php

<?php
App::uses('AppModel', 'Model');
class FileManager extends AppModel{
    var $useTable=false;
}

Kemudian buat file APP/Plugins/FileManagers/View/FileManagers/index.ctp

<?php if ($this->request->query['Type']=='Images'):?>
    <?php
        $handle=opendir(WWW_ROOT.$path);
        $typeFile = array(1 => 'gif', 2 => 'jpg', 3 => 'png');
        $emptyFolder=1;
        while (($file = readdir($handle))!==false) {
            if( strlen($file)>3) {
                list($w, $h, $type) = getimagesize(WWW_ROOT.$path.$file);
                if($type) {
                    echo $file;
                }
            }
        }
        closedir($handle);
        if ($emptyFolder) echo __('Directory is empty');
    ?>
<?php endif;?>

Untuk mengaktifkan Plugins, jangan lupa buka file APP/Config/bootstrap.php dan aktifkan perintah CakePlugin::loadAll(); untuk meload seluruh plugins.

Coba sekarang kembali ke halaman yang dibuka melalui klik tombol "Browse Server" tadi, dan refresh / tekan tombol F5. Tampak tulisan di layar "Directory is empty". Sekarang coba  copy-kan beberapa file image ke direktori APP/webroot/img/images, lalu refresh lagi. Tampak di layar berisi nama-nama file image yang ada di direktori tersebut.

Sekarang edit file APP/Plugins/FileManagers/View/FileManagers/index.ctp, dan ganti kode echo $file; menjadi beberapa baris kode berikut :

$emptyFolder=0;
echo '<div id="divOutBox">';
    echo '<div id="divInBox">'.$this->Html->image('/'.$path.$file).'</div>';
    echo $file.'<br/>';
    echo filesize(WWW_ROOT.$path.$file).' Bytes';
echo '</div>';

Jika browser direfresh, sudah menampilkan image dengan ukuran sebenarnya. Tentu saja dalam prakteknya ini akan memberatkan server, cara yang umum adalah dengan membuat thumbnail dari image tersebut. Untuk itu kita akan membuat suatu helper dengan logic seperti berikut:

  1. Cek apakah sudah ada thumbnail untuk image tersebut, jika sudah beritahu kalau kalau image tersebut sudah punya thumbnail.
  2. Jika ternyata image tersebut belum punya thumbnail lakukan operasi pembuatan thumbnail untuk image tersebut.
  3. Jika operasi pembuatan thumbnail berhasil maka tampilkan thumbnail dari image tersebut.
  4. Jika operasi pembuatan thumbnail gagal, maka image tersebut akan diabaikan.

Adapun kode dari file helper APP/Plugins/FileManagers/View/Helper/FileManagerHelper.php adalah sebagai berikut :

<?php
App::uses('AppHelper', 'View/Helper');

class FileManagerHelper extends AppHelper{

    function thumbImage($filename, $filepath, $thumbpath, $acuan = 100) {
        if (file_exists($thumbpath.$filename)) return true;

        $file=$filepath.$filename;    
        $typeFile = array(1 => 'gif', 2 => 'jpg', 3 => 'png');
                
        // assure that file exists
        if(is_file($file)){
            list($w, $h, $type) = getimagesize($file);
            // if the file is an image and not a swf or undetermined file
            if($type){
                //loop through file type and prepare image for cropping
                $fileType = $typeFile[$type];
                switch($fileType) {
                    case 'gif':
                        $img = imagecreatefromgif($file);
                        break;
                    case 'jpg':
                        $img = imagecreatefromjpeg($file);
                        break;
                    case 'png':
                        $img = imagecreatefrompng($file);
                        break;
                }

                if ($w>$h){
                    $width=$acuan;
                    $height=($width*$h)/$w;
                }
                else {
                    $height=$acuan;
                    $width=($height*$w)/$h;
                }

                // create thumb resize placeholder and then create image
                $thumb = imagecreatetruecolor($width, $height);
                imagecopyresized($thumb, $img, 0, 0, 0, 0, $width, $height, $w, $h);
            
                imagejpeg($thumb, $thumbpath.$filename, 100);
            }
            return true;
        }

        return false;
    }

}

Setelah berhasil membuat helper, ubah fungsi index di file APP/Plugins/FileManagers/Controller/FileManagersController.php dengan kode di bawah ini :

$path='img/images/';
$pathThumb='img/thumbs';
$this->set(compact('path','pathThumb'));

Jangan lupa juga menambahkan variabel member helpers agar FileManagerHelper bisa dikenali : var $helpers=array('FileManagers.FileManager');

Kemudian buka kembali file APP/Plugins/FileManagers/View/FileManagers/index.ctp, dan ganti kode di bawah ini :

$emptyFolder=0;
echo '<div id="divOutBox">';
    echo '<div id="divInBox">'.$this->Html->image('/'.$path.$file).'</div>';
    echo $file.'<br/>';
    echo filesize(WWW_ROOT.$path.$file).' Bytes';
echo '</div>';

Menjadi kode berikut :

if ($this->FileManager->thumbImage($file, WWW_ROOT.$path, WWW_ROOT.$pathThumb)) {
    $emptyFolder=0;
    echo '<div id="divOutBox">';
        echo '<div id="divInBox">'.$this->Html->image('/'.$pathThumb.$file).'</div>';
        echo $file.'<br/>';
        echo filesize(WWW_ROOT.$path.$file).' Bytes';
    echo '</div>';
}

Kemudian browser di-refresh lagi, tampak sekarang yang dimunculkan adalah thumbnail dengan ukuran 100 x 100 pixel.

Untuk informasi ukuran file yang lebih sederhana, kita ubah kode : echo filesize(WWW_ROOT.$path.$file).' Bytes';

Menjadi :

$fileSize=filesize(WWW_ROOT.$path.$file);
if ($fileSize>(1024*1024)) echo ceil($fileSize/(1024*1024)).' MB';
elseif ($fileSize>(1024)) echo ceil($fileSize/(1024)).' KB';
else echo $fileSize.' Bytes';

Sekarang kita mempercantik tampilan, kita buat suatu layout file_manager.ctp beserta css-nya. Buatlah file APP/Plugins/FileManagers/View/Layouts/file_manager.ctp dengan isi sebagai berikut

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <?php
        echo $this->Html->meta('icon');

        echo $this->Html->css('/file_managers/css/cake.generic.filemanager');
    ?>
</head>
<body>
    <div id="container">
        <div id="header">
            <h1><?php echo __('File Manager for CKEditor'); ?></h1>
            <p>CakePHP Plugins</p>
        </div>
        <div id="uploadbar">
            <?php echo $this->Form->create('FileManager', array('type'=>'file', 'url'=>"/$fixUrl"));?>
            <?php echo $this->Form->input('file', array('type'=>'file', 'label'=>false, 'div'=>false));?>
            <input type="submit" value="Upload"/>
            <?php echo $this->Form->end();?>
        </div>
        <div id="content">
            <?php echo $this->Session->flash(); ?>
            <?php echo $content_for_layout; ?>
            <div style="height:0;clear:both;">&nbsp;</div>
        </div>
        <div id="footer">
            <?php echo __('2012 &copy; Copywrong by Rijal Asep Nugroho');?>
        </div>
    </div>
</body>
</html>

Layout di atas memanggil css cake.generic.filemanager, untuk itu perlu dibuat file APP/Plugins/FileManagers/webroot/css/cake.generic.filemanager.css dengan kode berikut:

* {margin:0;padding:0;}

/** General Style Info **/
body { background: #aaa; color: #fff; font-family:'lucida grande',verdana,helvetica,arial,sans-serif; font-size:90%; }
a { color: #000; text-decoration: underline; font-weight: bold; }
a:hover { color: #367889; text-decoration:none; }
a img { border:none;}

/** Layout **/
#container { text-align: left; width:800px; margin:0 auto; background:#000;}

#header{ height:110px;}
#header h1 { font-size:24px; color: #fff; position:relative; top:7px; left:20px; }
#header p {position:relative; top:0; left:20px;}

#uploadbar{background:#ccc;}

#content{ background: #fff; color: #333;}
#divOutBox {text-align:center;cursor:pointer;padding:10px;margin:5px;float:left;background:#ccc;width:120px;height:150px;}
#divInBox{height:100px;width:100px;}

#footer { padding: 6px 10px; text-align: right; background:#000; }

Layout file_manager.ctp juga memanggil suatu variabel $fixUrl. Padahal variabel $fixUrl belum dibuat, sehingga akan menyebabkan error. Variabel $fixUrl ini berisi alamat url beserta seluruh variabel-variabel $_GET-nya. Untuk itu kita edit halaman APP/Plugins/FileManagers/Controller/FileManagersController.php kita tambahkan dengan kode berikut:

// get phisical url
$fixUrl=$this->request->url.'?';
$begin=1;
foreach ($this->request->query as $i=>$v) {
    if ($begin>1) $fixUrl.='&';
    $fixUrl.=$i.'='.$v;
    $begin++;
}
$this->set(compact('fixUrl'));

Jangan lupa untuk mengedit nilai dari variabel member var $layout=false; menjadi var $layout='file_manager'; Kemudian refresh browser, tampak tampilan sudah terlihat cantik. Namun jika diklik, belum menghasilkan dampak apa-apa.

Untuk itu buka file APP/Plugins/FileManagers/View/FileManagers/index.ctp, edit kode echo '<div id="divOutBox">';  menjadi echo '<div id="divOutBox" onclick="selectme('."'{$this->base}/$path$file'".');">';

Karena kode tersebut memanggil suatu fungsi javascript "selectme()" maka kita perlu membuat fungsi ini, sisipkan di baris 27 (sebelum kode <?php endif;?>) kode javascript di bawah ini :

<script type="text/javascript">
    function selectme(fileUrl){
        window.opener.CKEDITOR.tools.callFunction(<?php echo $this->request->query['CKEditorFuncNum'];?>, fileUrl);
        window.close();
    }
</script>

Kita coba refresh browser, dan klik salah satu thumbnail. Window akan tertutup dan file yang diklik akan dipindahkan menjadi nilai dari image url.

Sampai di sini, proses file browser sudah selesai. Namun, kita masih akan melengkapi file manager ini dengan fitur upload sederhana. Jika kita lihat tampilan layout, pada bagian atas ada form upload. Namun jika tombol submit diklik belum berfungsi dengan baik, ini karena kita belum membuat script untuk menangani upload. Buka kembali file APP/Plugins/FileManagers/Controller/FileManagersController.php, pada fungsi index tambahkan kode di bawah ini :

if ($this->request->query['Type']=='Images') {
    if ($this->request->is('post')){
        if (isset($this->request->data['FileManager']['file']) and !$this->request->data['FileManager']['file']['error'] and substr($this->request->data['FileManager']['file']['type'], 0, 5)=='image'){
            $baseFilename=substr($this->request->data['FileManager']['file']['name'], 0, -4);
            $extFilename=strtolower(substr($this->request->data['FileManager']['file']['name'], -4));
            if ($extFilename=='jpeg') {
                $extFilename=='.jpeg';
                $baseFilename=substr($this->request->data['FileManager']['file']['name'], 0, -5);
            }
            $filename=WWW_ROOT.$path.$this->request->data['FileManager']['file']['name'];

            $c=1;                    
            while (file_exists($filename)){
                $filename=WWW_ROOT.$path.$baseFilename.'('.$c.')'.$extFilename;
                $c++;
            }

            if (move_uploaded_file($this->request->data['FileManager']['file']['tmp_name'], $filename)){
                $this->Session->setFlash('Proses Upload berhasil');
                $this->redirect('/'.$fixUrl);
            }
            else $this->Session->setFlash('Proses Upload gagal');
        }
    }
}

Pastikan direktori APP/webroot/img/images/ (yaitu path dari image CKEditor) permission-nya di-set chmod 0777. Sekarang coba lakukan upload. File manager sudah berjalan dengan baik sesuai perencanaan.

File manager ini masih sangat sederhana, masih banyak yang bisa dikembangkan sesuai dengan kreatifitas masing-masing. Seperti menambahkan direktori dan lain-lain. Anda juga bisa menambahkan fitur quick upload.

Selamat berkreatifitas....!

follow article


Ada 1 komentar untuk artikel ini

Produktif juga nih Bang. Di rumah produktif ngak bang wakakakak
 
Miranda
from (Unknown Country?)
on Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; SLCC1; .NET CLR 2.0.50727; .NET CLR 3.0.04506; InfoPath.2; .NET
 

Leave Comment

<i>, <u>, <b> and <a>

Captcha


Reload image