Embed images anywhere in CakePHP
Inspired by the Ez publish’s way to embed images inside rich text fields, this CakePHP code takes the same principle in the true CakePHP way, with two helpers to extend David Persson’s Media Plugin.
Attahcments from David Persson’s Media Plugin
The CakePHP Media plugin by David Persson is very smooth, and with the Polymorphic behavior you use this as your main files store, creating hasMany relations to your other models. You can even create multiple relation form one single model by the Model.Group syntax:
var $hasMany = array(
'Image' => array(
'className' => 'Media.Attachment',
'foreignKey' => 'foreign_key',
'conditions' => array('Image.model' => 'Posts.Post', 'Image.group' => 'image'),
'dependent' => true),
'File' => array(
'className' => 'Media.Attachment',
'foreignKey' => 'foreign_key',
'conditions' => array('File.model' => 'Posts.Post', 'File.group' => 'file'),
'dependent' => true)
);
What I don’t like is the way it generate different sizes when new files is uploaded. Rather I want to generate both thumb (and cache the markup) when the media file is used. Also I prefer to be able to work with a variety of different sizes, instead to be locked in a small, medium, large sizes. To accomplish this I have created
How this works
First up you create a relation to the Attachment model in Media plugin, in your textfields you add this code:
[image:7 size:full align:right] // All options: // [image:7 size:thumb|full|original align:right|left lightbox]
In you view code you parse the content this way:
<?php
$body = $post['Post']['body'];
if (!empty($post['Image'])) {
//debug($post['Image']);
$body = $mediaEmbed->substituteEmbedTags($body);
}
echo $body;
?>
Inside the MediaEmbed helper the substituteEmbedTags() function parse the the text for the image markup and calls a element to display the resized version of the image:
<?php
// $id, $size and $align is sent to the element
App::import('Model', 'Media.Attachment');
$attachment = new Attachment();
$attachment->recursive = 0;
$image = $attachment->read(null, $id);
$image = $image['Attachment'];
$class= "embed-image embed-" . $size;
$div_pre = "";
$div_post = "";
if(!empty($align) and $align !== 0) {
$div_pre = '<div class="object-' . $align . '">';
$div_post = "</div>";
}
if($show_lightbox === 1) {
echo $div_pre . $mediaImage->lightbox($image, array('class'=>$class), array(), $size) . $div_post;
} else {
echo $div_pre . $mediaImage->resize($image, $size, array('class'=>$class)) . $div_post;
}
?>
The image size system
You define your image-sizes in app/config/core.php:
Configure::write('Image.full.height', 400);
Configure::write('Image.full.width', 500);
Configure::write('Image.thumb.height', 100);
Configure::write('Image.thumb.width', 100);
// And more images sizes if you need that..
What do you need
- The CakePHP Media plugin by David Persson
- My Extend plugin (I use this to hold all none-plugin spesific CakePHP helpers, components and behaviors)
Download an example app below to see it in action.
Download files
- embed_media_plugin.zip (Generic/1930542 Bytes)