Media Plugin of CakePHP Tutorial

Media plugin by David Persson is the easiest way to handle the attached file in CakePHP. However, this plugin has few documents on the web, and its wiki was removed.

This is a tutorial of media plugin.  I’m happy if this article helps you.

Requirements

This turorial used following versions.

  • CakePHP 1.3.6 Stable
  • Media plugin 1.3 Beta

Plugin Initial Setup

After the CakePHP initial setup, download the plugin , and move to the app/plugin, rename the folder to ‘media’. You need to type only this command using git.

git clone git://github.com/davidpersson/media.git app/plugins/media

Add this line to the core.php or bootstrap.php.

require_once(APP.'plugins'.DS.'media'.DS.'config'.DS.'core.php');

Media plugin needs the folders for storing the files. Plugin provides the cake shell. Type this command.

cake media init
chmod -R a+rwX app/webroot/media/{transfar,filter}

Make Table

Sample Table is located at plugins/media/config/sql/media.php . Type command to create this table.

cake/console/cake schema create media -path app/plugins/media/config/sql/

Table structure is

CREATE TABLE IF NOT EXISTS `attachments` (
    `id` int(10) unsigned NOT NULL auto_increment,
    `model` varchar(255) NOT NULL,
    `foreign_key` int(10) NOT NULL,
    `dirname` varchar(255) default NULL,
    `basename` varchar(255) NOT NULL,
    `checksum` varchar(255) NOT NULL,
    `alternative` varchar(50) default NULL,
    `group` varchar(255) default NULL,
    `created` datetime default NULL,
    `modified` datetime default NULL,
    PRIMARY KEY  (`id`)
);

You can use other table you defined insted of plugin’s sample.

Model

Sample model is located at plugins/media/models/attachement.php , and you can copy this. Media.Transfer Behavior is need to transfer files to the server.

<?php
class Attachment extends AppModel {

  var $name = 'Attachment';
  var $useTable = 'attachments';
  var $actsAs = array(
    'Media.Transfer' => array(
      'trustClient' => false,
      'transferDirectory' => MEDIA_TRANSFER,
      'createDirectory' => true,
      'alternativeFile' => 100
    ),
    'Media.Generator' => array(
      'baseDirectory' => MEDIA_TRANSFER,
      'filterDirectory' => MEDIA_FILTER,
      'createDirectory' => true,
    ),
    'Media.Polymorphic',
      'Media.Coupler' => array(
      'baseDirectory' => MEDIA_TRANSFER
    ),
    'Media.Meta' => array(
      'level' => 2
    )
  );

  var $validate = array(
    'file' => array(
      'resource'   => array('rule' => 'checkResource'),
      'access'     => array('rule' => 'checkAccess'),
      'location'   => array('rule' => array('checkLocation', array(
      MEDIA_TRANSFER, '/tmp/'
    ))),
    'permission' => array('rule' => array('checkPermission', '*')),
    'size'       => array('rule' => array('checkSize', '5M')),
    'pixels'     => array('rule' => array('checkPixels', '1600x1600')),
    'extension'  => array('rule' => array('checkExtension', false, array(
      'jpg', 'jpeg', 'png', 'tif', 'tiff', 'gif', 'pdf', 'tmp'
    ))),
    'mimeType'   => array('rule' => array('checkMimeType', false, array(
      'image/jpeg', 'image/png', 'image/tiff', 'image/gif', 'application/pdf'
    )))),
    'alternative' => array(
    'rule'       => 'checkRepresent',
    'on'         => 'create',
    'required'   => false,
    'allowEmpty' => true,
  ));
}

Controller and View

I created base controller and view with bake command.

Upload Form

Replace default form with following code at view/add.ctp

<?php echo $this->Form->create('Attachment', array('type' => 'file'));?>
    <fieldset>
    <legend><?php __('Add Attachment'); ?></legend>
    <?php
        echo $form->input('file', array('type' => 'file'));
    ?>
    </fieldset>
<?php echo $this->Form->end(__('Submit', true));?>
File Upload Form

File Upload Form

Show the attached file at the view

Add MediaHelper to AttachmentsController

    var $helpers = array('Media.Media');

Add this code to show the attached file at the views/attachments/view.ctp.

</pre>
<dt<?php if ($i % 2 == 0) echo $class;?>><?php __('Attached File'); ?></dt>
 <dd<?php if ($i++ % 2 == 0) echo $class;?>>
<?php echo $media->embed($media->file(
's'.DS.$attachment['Attachment']['dirname'].DS.$attachment['Attachment']['basename']));
?>
&nbsp;
 </dd>

‘s’ means a type of filter. Filter setting is written in plugins/media/config/core.php


$s = array('convert' => 'image/png', 'zoomCrop' => array(100, 100));
$m = array('convert' => 'image/png', 'fitCrop' => array(300, 300));
$l = array('convert' => 'image/png', 'fit' => array(600, 440));
<pre>

If you want a no conversion filter which doesn’t convert size and image type, you can define like this

$org = array('convert' => 'original');

Configure::write('Media.filter', array(
    'audio' => compact('s', 'm'),
    'document' => compact('s', 'm'),
    'generic' => array(),
    'image' => compact('s', 'm', 'l', 'org'),
    'video' => compact('s', 'm')
));

Have a nice cake!