Gallery behavior
Hello, I was building my custom gallery behavior to enable "attaching" images for any other model.
My behavior uses model named 'Photo' as storage for saving uploaded photos. Here's schema:
CREATE TABLE IF NOT EXISTS `photos` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`foreign_key` int(10) unsigned NOT NULL,
`model` varchar(255) NOT NULL,
`association` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8Each model that need to support image uploading has something like this in $actsAs var:
var $actsAs = array('Gallery'=>array('limit'=>10, 'association'=>'titlePic', 'rules'=>array(
array('suffix'=>'_title', 'options'=>array('x' => 240, 'ratio_no_zoom_in' => true)),
array('suffix'=>'_catalog', 'options'=>array('x' => 110, 'y' => 93, 'ratio_crop' => true)),
array('suffix'=>'_big', 'options'=>array('x' => 1000, 'y' => 700, 'ratio_no_zoom_in' => true))
)));So, for example, if I upload image for Article model, its being saved to webroot/img/articles/titlePic/ in three versions: one for each 'resize rule' as defined in Article Model. So-called association is needed to enable multiple sets of rules for 1 model. Resizing is made using 3-rd party image resizing class.
Then, when a I fetch an Article data ($this->find('All')) for example, I get result with picture info, prepared by some callback in gallery behavior.
Behaviour provides some number of methods for model, like
$this->getImages($id_of_row_of_model_with_gallery_behaviour);
$this->deleteImage($id_of_image_in_photo_table);
$this->deleteImages($id_of_row_of_model_with_gallery_behaviour);...
I use ajax like upload of pics using iframe. Such 'ajax' request goes to current's model controller, 'admin_ajaxupload'.
So basicly to use gallery behavior on my app I need following:
a table in database
a model file Photo (actually I dont need one as its empty)
behavior itself
helper that generates all html and javascript that needed for uploading photos
and some methods in controller to handle uploads/deletes and so on.
Now, when I described it to you, I will proceed to my questions.
One thing that bug me a lot is code repeation in my controllers, 6 of my 9 controllers has almost the same code. Its bad, but Im not sure should I extract it to AppController or move to component?
Another thing that bother me, as properties for photos. For example, I need to add some sort of title for each photo. It's not hard add a 'title' column to photos table, but if I needed to add more columns its can become messy - for example some models would need to use 3 additional properties, while others dont' need them at all. Also, I would like to use one table for all my apps. The best solution I could think of so far is to add one new column called "properties" or smthng like that. It's value would be some serialized properties, which would be processed by galleryBehavior. Although I'm not sure if its correct way.
The last thing is image resizing class. I looked at it, and thought about transforming it into Photo model, as currently I have pretty much dummy model, and it seems to be correctly putting image processing logic to Photo model.
That's my 3 questions at one time, your comments are welcome!
Asked by DmitriySpb, on 10/11/09
2 Answers
A component is the wrong place to process data. The uploaded file should be processed in an upload behavior. Later you can, if well implemented, create another behavior like VideoUpload or ImageUpload inheriting the Upload behavior to post-process the upload (do resizing, whatever).
Depending on your needs you have two options in my opinion:
Have many different tables extending the generic media table depending on what is needed, for example a video_properties table vs a photo_properties table.
OR
Create one join table and a HABTM association and populate the jointable with additional fields. This would also allow you to attach one file to many things.
Anyways, whatever you do it depends on your requirements and needs. But i can tell you that both designs and the upload behaviors work. We've already implemented everything i just described. :)
Answered by burzumon 10/11/09
1. I would use component in this case.
2. The serialized field would bring new problem when you want to sort by one of key/value pair inside it. Keep it simpler would be better if you hope to reuse your code after three or more months.
3. If the operations could be shared in models, put it into behavior would be better.
Answered by kiangon 10/11/09
Tagged with
Rating
2
Viewed
663 times
Last Activity
on 10/11/09