Hello,

I'm working on a module to manage tasks associated with managing uploading media in a DB-backed website projects. This includes resizing the image, creating thumbnails, storing the image attributes in the database wtih the actual file on disk, and retrieving the information in a way that's useful to pass to a templating system.

I already having a working implementation of this module that I'm pleased with. Based on what I've learned writing it, I'm improving the interface some to be a more scalable and re-useable. Below is the POD for the proposed module. I'm interesting in getting feedback on the architecture and design described here before I update the code and release it. Thanks!



SYNOPSIS

# Define your your image names, along with # any thumbnails they might need, and their max width and heights.
my %Media = { img_1 => { # scale down the image to this size if needed target_geometry => '200x200', thumbs => [ { name => 'img_1_thumb_1', w => 100, h => 100 +}, { name => 'img_1_thumb_2', w => 50 , h => 50 +}, ], },
# A simple syntax if you just want some thumbnails img_2 => [ { name => 'img_2_thumb_1', w => 100, h => 100 }, ], # And a very simple syntax if you want to store the image unto +uched. img_3 => [], }; # Create the accessor. This could be done once in a super class # and stored in a param variable. my $media_srv = CGI::ImageDB->new( media_url => '<a href="http://localhost/com/images/media">http +://localhost/com/images/media</a>', media_dir => '/home/user/www/images/media', dbh => $dbh, media_table => 'media', # defaults to 'media' media_def => \%Media, );


DESCRIPTION

This module is designed to help with the task of managing media uploaded through web based forms. The media files are stored on a file system, and the file attributes stored in a SQL database.

It expects that you have a table dedicated to storing media, which would be designed like this:

-- Note the MySQL specific syntax here create table media ( media_id int AUTO_INCREMENT primary key not nul +l, mime_type character varying(64), extension character varying(8), -- file extension width integer, height integer )

Other table names are allowed, bu these fields must be present.

Other entities that need attached media would reference the table by refering to the media_id, with names like:

img_1_id img_1_thumb_1_id

The field names can be arbitary, but are expected to end in '_id'.

Finally, the accesor needs a data structure that defines all the media that will be used in a given instance, and details about any thumbnails that should be auto-generated for the media. In the following example the data structure is hard coded. You could just as well select this information out of a database and then build this data structure on the fly to pass to the routine.

my %Media = { img_1 => [ { name => 'img_1_thumb_1', w => 100, h => 100 }, { name => 'img_1_thumb_2', w => 50 , h => 50 }, ], img_2 =< [ { name => 'img_2_thumb_1', w => 100, h => 100 }, ], img_3 => [], };


create_install_media($valid)

my ($add_to_valid,@rm_from_valid) = $media_srv-&gt;create_install_med +ia($valid);
$valid = { %$valid, %$add_to_valid } if $add_to_valid; map { delete $valid->{$_} } @$rm_from_valid;

This method is used to process uploaded images. Based on the media defined in the media_def, it does the following:

o
creates any needed thumbnails

o
installs all the media to the file system

o
inserts media details into the database, including media_id, width, height, mime_type and extension

As input, a hash reference is expected in the format of a Data::FormValidator valids hash, which includes additional _info fields, which would be added by the Data::FormValidator::Constraints::Upload manpage.

The expection is that you are validating some entity which has some images attached to it.

As output, it returns two parameters:

o
A hash reference of fields and values to add to the valid hash. This will include key value pairs like this:
img_id_1 => 23

o
A reference to an array of fields to delete from the valids hash. This will include fields like:
img_1_info


delete_checked_media

my @deleted_field_ids = $img_srv->delete_checked_media;

This module takes care of deleting all media, and any associated thumbnails based on form input. File system files as well as database rows are removed.

It looks through all the field names defined in media_defs. For a media field named img_1, a field named <img_1_delete> is checked to see if it has a true value.

A list of the field names is returned, prepended with '_id', such as:

img_1_id

The expectation is that you have colums with this name defined in another table, and by deleting these field names from the $valid hash, they will be set to NULL when that database table is updated.


delete_media()

my $field_id = $img_srv-&gt;delete_media('img_1');

This method is used to delete the database row and file system file associated with a single piece of media. It is usually not needed to be called directly.

It takes one required input, the prefix of the image name to delete. Additionally, it expects to find a field name with the same prefix and '_id' appended, such as:

img_1_id

This field should contain the media_id to delete. A field name in this format is returned after the media is deleted.


create_img_tmpl_vars()

my $tmpl_vars_ref = $media_srv->create_img_tmpl_vars($table,\% +where,@prefixes);

This method is used to return a hash reference suitable for sending to HTML::Template to display some images on a page. It is intended to create all data needed for a single entity.

Here's an example:

my $tmpl_vars_ref = $media_srv->create_img_tmpl_vars('news',{ +item_id => 23 },qw/img_1/);

This going to fetch the image information from the media table for using the media for img_1_id in the news table where item_id = 23. The result might look like this:

{ img_1_id => 523, img_1_width => 100, img_1_height => 200, img_1_url => '<a href="http://localhost/images/medi +a/523.jpg">http://localhost/images/media/523.jpg</a>', }

The %where hash mentioned here is a the SQL::Abstract manpage where clause. The complete SQL that used to fetch the data will be built like this:

SELECT media_id as id,width,height,extension FROM media, $table where (media_id = ${prefix}_id and (%where_ +clause_expanded here));


get_all_media_prefixes

Given the image definition object, it returns an array of all the image prefixes, both the primary images and any thumbnails

Mark

20030517 Edit by Corion: Fixed brackets,fixed links

Replies are listed 'Best First'.
Re: RFC: CGI::MediaDB
by markjugg (Curate) on May 18, 2003 at 20:53 UTC
    Ok,

    I've got a version of this to try out:

    CGI::MediaDB-0.02

    It could still use more documentation of example usage, but it includes a complete test suite that works with Mysql and Postgres. Just try:

    $ perl Makefile.PL --help $ make test

    Mark
Re: RFC: CGI::MediaDB
by markjugg (Curate) on May 19, 2003 at 18:37 UTC
    OK, I'm taking this lack of response to mean "It needs better documentation to be comprehensible". I have in mind to create a working HOWTO/demo page that illustrates the beauty and joy of how it works. Then you'll be hooked!

    Mark