ml_image.module in Media Library 6
Media Library Image module.
File
ml_image/ml_image.moduleView source
<?php
/**
* @file
* Media Library Image module.
*/
/**
* Drupal Hooks
*/
/**
* Implementation of hook_theme()
*/
function ml_image_theme($existing, $type, $theme, $path) {
return array(
'ml_image' => array(
'arguments' => array(
'image' => NULL,
'preview' => FALSE,
),
),
);
}
/**
* Implementation of hook_init()
*/
function ml_image_init() {
drupal_add_css(drupal_get_path('module', 'ml_image') . '/ml_image.css');
drupal_add_js(drupal_get_path('module', 'ml_image') . '/ml_image.js');
}
/**
* Implementation of hook_menu()
*/
function ml_image_menu() {
$items = array();
return $items;
}
/**
* Implementation of hook_nodeapi()
*/
function ml_image_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
// We keep a record of all imagefield submitted images to use later
if ($op == 'presave' && module_exists('imagefield')) {
$type = content_types($node->type);
foreach ($type['fields'] as $field => $field_info) {
if ($field_info['module'] == 'filefield' && $field_info['widget']['module'] == 'imagefield') {
foreach ($node->{$field} as $item) {
if ($item['fid'] && !ml_image_get_image($item['fid'])) {
$metatags = new stdClass();
$metatags->title = $item['data']['title'];
$metatags->fid = $item['fid'];
$metatags->source = 'imagefield';
ml_image_save_metatags($metatags);
}
}
}
}
}
}
/**
* Implementation of hook_flush_caches()
*/
function ml_image_flush_caches() {
// Wipe orphaned entries
db_query('DELETE FROM {ml_image_metadata} WHERE fid NOT IN (SELECT fid FROM {files})');
}
/**
* Media Library Hooks
*/
/**
* Implementation of hook_media_types()
*/
function ml_image_media_types() {
$types = array();
$types['image'] = array(
'title' => t('Image'),
'description' => t('Inline images'),
//TODO: Is this being used?
'steps' => 1,
'settings' => 'ml_image_settings',
'icon' => drupal_get_path('module', 'ml_image') . '/drupalimage.gif',
);
return $types;
}
/**
* Implementation of hook_filter_media()
*/
function ml_image_filter_media($content, $preview = FALSE) {
if ($content['type'] == 'image') {
return theme('ml_image', $content, $preview);
}
}
/**
* Implementation of hook_filter_media_alter()
* Just for fun. We add a dummy attribute.
*/
function ml_image_filter_media_alter(&$content, $preview = FALSE) {
}
/**
* Implementation of hook_media_forms()
*/
function ml_image_media_forms($type) {
switch ($type) {
case 'image':
$steps = array(
'source_select' => array(
'label' => t('Source selection'),
'form id' => 'ml_image_source_selection_form',
),
'source_image' => array(
'label' => t('Image select from source'),
'form id' => 'ml_image_source_options_form',
),
'image_attributes' => array(
'label' => t('Image Attributes'),
'form id' => 'ml_image_attributes_form',
),
);
return $steps;
}
}
/**
* Implementation of hook_media_tag()
*/
function ml_image_media_tag($object) {
if ($object->type == 'image') {
$tag['filepath'] = $object->filepath;
if (is_array($object->attributes)) {
foreach ($object->attributes as $attr => $value) {
$tag[$attr] = $value;
}
}
if (is_array($object->metatags)) {
foreach ($object->metatags as $key => $value) {
// To avoid namespace conflitcts, we prefix metatag names with 'meta-'
$tag['meta-' . $key] = $value;
}
}
}
return $tag;
}
/**
* Forms
*/
/**
* Form for our image source selection. Handles both steps of source
* selection process.
*/
function ml_image_source_selection_form(&$form, &$form_state) {
// Check for update and skip step
if ($form_state['action'] == 'update') {
media_library_modal_skip_step($form_state);
}
$sources = ml_image_get_sources();
if (empty($sources)) {
// No sources activated. Snap the admin
drupal_set_message(t('No sources were configured for this media. Please contact the site administrator'), 'error');
// Disable buttons so user won't be able to go ahead
unset($form['buttons']['next']);
unset($form['buttons']['return']);
return;
}
// Proper source selection
foreach ($sources as $source => $info) {
$form[$source] = array(
'#type' => 'fieldset',
'#title' => $info['label'],
);
// Our main radio
$form[$source]['select'] = array(
'#type' => 'radio',
'#return_value' => $source,
'#attributes' => array(
'class' => 'ml-image-source-choice',
),
);
// Get basic form from each source module
$func_name = $info['module'] . '_' . $source . '_source_form';
if (function_exists($func_name)) {
$form[$source][$source] = $func_name($form_state);
}
$form[$source][$source]['#tree'] = TRUE;
}
// We set this so we can be sure that file uploads work in ctools modal.
// See here: http://drupal.org/node/451928
$form['#attributes']['enctype'] = 'multipart/form-data';
$form_state['no buttons'] = TRUE;
}
/**
* Validate Callback for ml_image_source_selection_form()
* This only validates if a source was properly selected.
* Cleans the other options.
* It then calls our validate function for the selected source module.
*/
function ml_image_source_selection_form_validate(&$form, &$form_state) {
// Check op
if ($form_state['clicked_button']['#value'] != t('Next')) {
return;
}
$sources = ml_image_get_sources();
// Find out our source
$option = $form_state['values']['select'];
//$form_state['values'] = $form_state['values'][$source];
$form_state_new = $form_state;
$form_state_new['values'] = $form_state['values'][$source];
if (!$option) {
form_set_error('', t('No source selected.'));
}
$validate_func = $sources[$option]['module'] . '_' . $option . '_source_form_validate';
// Execute validation callbacks
if (function_exists($validate_func)) {
$validate_func($form, $form_state_new);
}
$form_state['source'] = $option;
}
/**
* Submit Callback for ml_image_source_selection_form()
*/
function ml_image_source_selection_form_submit(&$form, &$form_state) {
// Check op
if ($form_state['clicked_button']['#value'] != t('Next')) {
return;
}
$sources = ml_image_get_sources();
$source = $form_state['source'];
$form_state_new = $form_state;
$form_state_new['values'] = $form_state['values'][$source];
$submit_func = $sources[$source]['module'] . '_' . $source . '_source_form_submit';
if (function_exists($submit_func)) {
$submit_func($form, $form_state_new);
}
$form_state['media_obj']->source = $source;
}
/**
* Form for selection source options
*/
function ml_image_source_options_form(&$form, &$form_state) {
if ($form_state['action'] == 'update') {
media_library_modal_skip_step($form_state);
}
$sources = ml_image_get_sources();
// Source options
$source = $form_state['media_obj']->source;
$func_name = $sources[$source]['module'] . '_' . $source . '_options_form';
if (function_exists($func_name)) {
$form[$source] = $func_name($form_state);
}
else {
// Skip the step
media_library_modal_skip_step($form_state);
}
$form[$source]['#tree'] = TRUE;
}
/**
* Validate callback for ml_image_source_options_form()
*/
function ml_image_source_options_form_validate(&$form, &$form_state) {
// Check op
if ($form_state['clicked_button']['#value'] != t('Next')) {
return;
}
$sources = ml_image_get_sources();
// Find out our source
$option = $form_state['media_obj']->source;
$form_state_new = $form_state;
$form_state_new['values'] = $form_state['values'][$option];
$validate_func = $sources[$option]['module'] . '_' . $option . '_options_form_validate';
// Execute validation callbacks
if (function_exists($validate_func)) {
$validate_func($form, $form_state_new);
}
}
/**
* Submit callback for ml_image_source_options_form()
*/
function ml_image_source_options_form_submit(&$form, &$form_state) {
// Check op
if ($form_state['clicked_button']['#value'] != t('Next')) {
return;
}
$sources = ml_image_get_sources();
$source = $form_state['media_obj']->source;
$form_state_new = $form_state;
$form_state_new['values'] = $form_state['values'][$source];
$submit_func = $sources[$source]['module'] . '_' . $source . '_options_form_submit';
if (function_exists($submit_func)) {
$submit_func($form, $form_state_new);
}
}
/**
* Form for modal dialog
* For updating media, use the contents of $form_state['update']
* You can form_alter this safely to add any attributes you like
* They will show in the tag and will be available at the theme
* function automatically
*/
function ml_image_attributes_form(&$form, &$form_state) {
// Check for default value from content being updated
if (isset($form_state['update'])) {
$image = $form_state['update'];
}
else {
$image = '';
}
// Put elements inside attributes array so we can separate
// from form API elements such as form_id
$form['attributes'] = array(
'#tree' => TRUE,
);
$options = array_filter(variable_get('ml_image_imagecache_presets', array()));
$options['none'] = t('Original Size');
// Generates preview for image
$option = isset($image['preset']) ? $image['preset'] : key($options);
if ($option == 'none') {
$imgtag = theme('image', $form_state['media_obj']->filepath);
}
else {
$imgtag = theme('imagecache', $option, $form_state['media_obj']->filepath);
}
$form['preview'] = array(
'#value' => '<div class="ml-image-edit preview">' . $imgtag . '</div>',
'#weight' => -1,
);
// Size. Imagecache presets enabled
$form['attributes']['preset'] = array(
'#type' => 'select',
'#title' => t('Image size'),
'#description' => t('Predefined image size choice'),
'#options' => $options,
'#default_value' => isset($image['preset']) ? array(
$image['preset'],
) : array(),
);
// Image alignment. This can be easily overriden by theme
$form['attributes']['align'] = array(
'#type' => 'select',
'#title' => t('Image Alignment'),
'#options' => array(
'center' => t('Center'),
'left' => t('Left'),
'right' => t('Right'),
),
'#default_value' => isset($image['align']) ? $image['align'] : 'center',
);
// Title of the block, primarily, but can be used for img title or alt
$form['attributes']['title'] = array(
'#type' => 'textfield',
'#title' => t('Title'),
'#default_value' => isset($image['title']) ? $image['title'] : '',
);
// Legend. Small text to appear inside block
$form['attributes']['label'] = array(
'#type' => 'textfield',
'#title' => t('Label'),
'#default_value' => isset($image['label']) ? $image['label'] : '',
);
$form_state['no buttons'] = TRUE;
}
/**
* Validate Callback for ml_image_attributes_form()
*/
function ml_image_attributes_form_validate(&$form, &$form_state) {
}
/**
* Submit Callback for ml_image_attributes_form()
*/
function ml_image_attributes_form_submit(&$form, &$form_state) {
foreach ($form_state['values']['attributes'] as $attr => $value) {
$form_state['media_obj']->attributes[$attr] = $value;
}
}
/**
* Settings form for Media Library settings page
*/
function ml_image_settings($form_state) {
$form = array();
// General settings
$form['main'] = array(
'#type' => 'fieldset',
'#title' => t('General Settings'),
'#collapsible' => TRUE,
);
// Get imagecache data
$presets = imagecache_presets();
$options = array();
foreach ($presets as $preset) {
$options[$preset['presetname']] = $preset['presetname'];
}
$options['none'] = t('Original Size');
$form['main']['ml_image_imagecache_presets'] = array(
'#type' => 'checkboxes',
'#title' => t('Imagecache presets'),
'#description' => t('Select wich imagecache presets should be available for the user to insert an image'),
'#options' => $options,
'#default_value' => variable_get('ml_image_imagecache_presets', array(
0,
)),
'#required' => TRUE,
);
// Term relationship
$vocabularies = taxonomy_get_vocabularies();
$options = array();
foreach ($vocabularies as $vid => $data) {
$options[$vid] = $data->name;
}
array_unshift($options, t('<< None >>'));
$form['main']['ml_image_vocabulary'] = array(
'#type' => 'select',
'#title' => t('Vocabulary for term relation'),
'#description' => t('Use this to be able to select tags to images'),
'#options' => $options,
'#default_value' => array(
variable_get('ml_image_vocabulary', 0),
),
);
// Sources settings
$sources = ml_image_get_sources();
foreach ($sources as $source => $info) {
if (isset($info['settings'])) {
$form_func = $info['settings'];
if (function_exists($form_func)) {
$form['sources'][$type] = $form_func($form_state);
$form['sources'][$type] += array(
'#type' => 'fieldset',
'#title' => 'Source: ' . $info['label'],
'#collapsible' => TRUE,
);
}
}
}
return system_settings_form($form);
}
/**
* Helpers and callbacks
*/
/**
* Loads all sources implemented on other modules
*/
function ml_image_get_sources() {
static $sources;
if (!is_array($sources)) {
$sources = module_invoke_all('ml_image_source');
}
return $sources;
}
/**
* Get all metadata items to relate do an image.
* TODO: add flexibility to metadata items to allow modules to add their own
*/
function ml_image_get_metadata() {
$metadata = array(
'title' => array(
'type' => 'textfield',
'label' => t('Title'),
'description' => t('Descriptive short title'),
),
'copyright' => array(
'type' => 'textfield',
'label' => t('Copyright'),
'description' => t('Copyright information.'),
),
'author' => array(
'type' => 'textfield',
'label' => t('Photographer'),
'description' => t('Picture author name.'),
),
);
if ($vid = variable_get('ml_image_vocabulary', 0)) {
$vocab = taxonomy_vocabulary_load($vid);
$metadata['tags'] = array(
'type' => 'term',
'label' => $vocab->name,
'description' => $vocab->description,
'vocabulary' => $vocab,
);
}
return $metadata;
}
/**
* Saves metatags according to fields returned from ml_image_get_metadata()
* @param
* metatags - object with properties. Must have 'fid' property
*/
function ml_image_save_metatags($metatags) {
$metadata = ml_image_get_metadata();
foreach ($metadata as $field => $data) {
switch ($data['type']) {
case 'textfield':
case 'textarea':
break;
case 'term':
if (isset($metatags->{$field})) {
foreach (array_keys($metatags->{$field}) as $tid) {
// Save each term
$relation = new stdClass();
$relation->tid = $tid;
$relation->fid = $metatags->fid;
drupal_write_record('ml_image_term', $relation);
}
unset($metatags->{$field});
}
}
}
// TODO: implement hook here
// Saves all remaining fields (base)
drupal_write_record('ml_image_metadata', $metatags);
}
/**
* Load existing images according to filters
* @param
* terms - array of tids for filtering
* source - image source for filtering
* @return
* array of images
*/
function ml_image_get_images($terms = array(), $source = 0, $limit = 10, $page = 0) {
// Base query
$query = '
SELECT
metadata.*,
files.filepath,
files.uid,
files.timestamp,
GROUP_CONCAT(tags.tid) as tags
FROM {ml_image_metadata} metadata
INNER JOIN {files} files ON metadata.fid = files.fid
LEFT JOIN {ml_image_term} tags ON metadata.fid = tags.fid';
$count_query = '
SELECT
COUNT(metadata.fid)
FROM {ml_image_metadata} metadata
INNER JOIN {files} files ON metadata.fid = files.fid';
// Terms filtering
if (!empty($terms)) {
$term_filter = '';
foreach ($terms as $tid) {
$term_filter .= ' INNER JOIN ml_image_term tags_filter' . $tid . ' ON metadata.fid = tags_filter' . $tid . '.fid AND tags_filter' . $tid . '.tid = ' . $tid;
}
$query .= $term_filter;
$count_query .= $term_filter;
}
// Source filtering
if ($source) {
$query .= ' WHERE source = "%s" ';
$count_query .= ' WHERE source = "%s" ';
}
// Group multiple terms
$query .= ' GROUP BY metadata.fid';
// Prepare range
//$from = $page * $limit;
//$result = db_query_range($query, $from, $limit);
$result = pager_query($query, $limit, 0, $count_query, $source);
$images = array();
while ($item = db_fetch_object($result)) {
$item->tags = explode(',', $item->tags);
$images[] = $item;
}
return $images;
}
/**
* Load single image object by fid
*/
function ml_image_get_image($fid) {
static $images;
if (!is_array($images)) {
$images = array();
}
if (!isset($images[$fid])) {
// Base query
$query = '
SELECT
metadata.*,
files.filepath,
files.uid,
files.timestamp,
GROUP_CONCAT(tags.tid) as tags
FROM {ml_image_metadata} metadata
INNER JOIN {files} files ON metadata.fid = files.fid
LEFT JOIN {ml_image_term} tags ON metadata.fid = tags.fid
WHERE metadata.fid = %d
GROUP BY metadata.fid';
$image = db_fetch_object(db_query($query, $fid));
if ($image) {
$images[$fid] = $image;
}
}
return $images[$fid];
}
/**
* Theme functions
*/
/**
* Renders the image tag
* @param
* image - The image array with its properties
* preview - wether this is being generated on wysiwyg preview.
*/
function theme_ml_image($image, $preview = FALSE) {
$classes = 'ml-image';
$output = '';
// Preview class
if ($preview) {
$classes .= ' ml-image-preview';
// We may receive the object with array structures;
if (is_array($image['attributes'])) {
foreach ($image['attributes'] as $attr => $value) {
$image[$attr] = $value;
}
}
if (is_array($object->metatags)) {
foreach ($object->metatags as $key => $value) {
// To avoid namespace conflitcts, we prefix metatag names with 'meta-'
$tag['meta-' . $key] = $value;
}
}
}
if (!empty($image)) {
// As an example, we use title for everything, but you could use metadata
// like copyright and author info
$alt = $title = $image['title'];
$filepath = $image['filepath'];
// Render the img tag
if ($image['preset'] == 'none') {
$imgtag = theme('image', $filepath, $alt, $title);
}
else {
$imgtag = theme('imagecache', $image['preset'], $filepath, $alt, $title);
}
// Alignment
if (isset($image['align'])) {
$classes .= ' align-' . $image['align'];
}
if (!empty($image['title']) || !empty($image['label'])) {
// Render a box
$classes .= ' box';
$label = !empty($image['label']) ? '<div class="label">' . $image['label'] . '</div>' : '';
$content = '<h2>' . $image['title'] . '</h2>' . $imgtag . $label;
}
else {
$content = $imgtag;
}
}
$output = "<div class=\"{$classes}\">{$content}</div>";
return $output;
}
Functions
Name | Description |
---|---|
ml_image_attributes_form | Form for modal dialog For updating media, use the contents of $form_state['update'] You can form_alter this safely to add any attributes you like They will show in the tag and will be available at the theme function automatically |
ml_image_attributes_form_submit | Submit Callback for ml_image_attributes_form() |
ml_image_attributes_form_validate | Validate Callback for ml_image_attributes_form() |
ml_image_filter_media | Implementation of hook_filter_media() |
ml_image_filter_media_alter | Implementation of hook_filter_media_alter() Just for fun. We add a dummy attribute. |
ml_image_flush_caches | Implementation of hook_flush_caches() |
ml_image_get_image | Load single image object by fid |
ml_image_get_images | Load existing images according to filters |
ml_image_get_metadata | Get all metadata items to relate do an image. TODO: add flexibility to metadata items to allow modules to add their own |
ml_image_get_sources | Loads all sources implemented on other modules |
ml_image_init | Implementation of hook_init() |
ml_image_media_forms | Implementation of hook_media_forms() |
ml_image_media_tag | Implementation of hook_media_tag() |
ml_image_media_types | Implementation of hook_media_types() |
ml_image_menu | Implementation of hook_menu() |
ml_image_nodeapi | Implementation of hook_nodeapi() |
ml_image_save_metatags | Saves metatags according to fields returned from ml_image_get_metadata() |
ml_image_settings | Settings form for Media Library settings page |
ml_image_source_options_form | Form for selection source options |
ml_image_source_options_form_submit | Submit callback for ml_image_source_options_form() |
ml_image_source_options_form_validate | Validate callback for ml_image_source_options_form() |
ml_image_source_selection_form | Form for our image source selection. Handles both steps of source selection process. |
ml_image_source_selection_form_submit | Submit Callback for ml_image_source_selection_form() |
ml_image_source_selection_form_validate | Validate Callback for ml_image_source_selection_form() This only validates if a source was properly selected. Cleans the other options. It then calls our validate function for the selected source module. |
ml_image_theme | Implementation of hook_theme() |
theme_ml_image | Renders the image tag |