Commit c7c0e143 authored by JacobSingh's avatar JacobSingh

Alpha field handling! Re-did a lot of the complexity after a chat session w/...

Alpha field handling!  Re-did a lot of the complexity after a chat session w/ bjaspan made it clear that having the bundle or type of media (for fielding purposes) determined dynamically was not going to work and making a new table would be a PITA - but can be done later.  Anyway, see the media.install for an extended description.  Fields works now! (kinda)
parent 9300c1b3
<?php
// $Id$
/**
* Default implementation of DrupalEntityControllerInterface.
*
* This class can be used as-is by most simple entity types. Entity types
* requiring special handling can extend the class.
*/
class MediaEntityController extends DrupalDefaultEntityController {
protected $entityCache;
protected $entityType;
protected $entityInfo;
protected $hookLoadArguments;
protected $idKey;
protected $revisionKey;
protected $revisionTable;
protected $query;
public function load($ids = array(), $conditions = array()) {
$this->ids = $ids;
$this->conditions = $conditions;
$entities = array();
// Revisions are not statically cached, and require a different query to
// other conditions, so separate the revision id into its own variable.
if ($this->revisionKey && isset($this->conditions[$this->revisionKey])) {
$this->revisionId = $this->conditions[$this->revisionKey];
unset($this->conditions[$this->revisionKey]);
}
else {
$this->revisionId = FALSE;
}
// Create a new variable which is either a prepared version of the $ids
// array for later comparison with the entity cache, or FALSE if no $ids
// were passed. The $ids array is reduced as items are loaded from cache,
// and we need to know if it's empty for this reason to avoid querying the
// database when all requested entities are loaded from cache.
$passed_ids = !empty($this->ids) ? array_flip($this->ids) : FALSE;
// Try to load entities from the static cache, if the entity type supports
// static caching.
if ($this->cache) {
$entities += $this->cacheGet($this->ids, $this->conditions);
// If any entities were loaded, remove them from the ids still to load.
if ($passed_ids) {
$this->ids = array_keys(array_diff_key($passed_ids, $entities));
}
}
// Load any remaining entities from the database. This is the case if $ids
// is set to FALSE (so we load all entities), if there are any ids left to
// load, if loading a revision, or if $conditions was passed without $ids.
if ($this->ids === FALSE || $this->ids || $this->revisionId || ($this->conditions && !$passed_ids)) {
// Build the query.
$this->buildQuery();
$queried_entities = $this->query
->execute()
->fetchAllAssoc($this->idKey);
}
foreach ($queried_entities as &$entity) {
$entity->type = self::getBundleName($entity->filemime);
}
// Pass all entities loaded from the database through $this->attachLoad(),
// which attaches fields (if supported by the entity type) and calls the
// entity type specific load callback, for example hook_node_load().
if (!empty($queried_entities)) {
$this->attachLoad($queried_entities);
$entities += $queried_entities;
}
if ($this->cache) {
// Add entities to the cache if we are not loading a revision.
if (!empty($queried_entities) && !$this->revisionId) {
$this->cacheSet($queried_entities);
}
// Ensure that the returned array is ordered the same as the original
// $ids array if this was passed in and remove any invalid ids.
if ($passed_ids) {
// Remove any invalid ids from the array.
$passed_ids = array_intersect_key($passed_ids, $entities);
foreach ($entities as $entity) {
$passed_ids[$entity->{$this->idKey}] = $entity;
}
$entities = $passed_ids;
}
}
return $entities;
}
public static function getBundleName($mime) {
$types = module_invoke_all('media_types');
$name = substr($mime, 0,strpos($mime, '/'));
if (in_array($name, array_keys($types))) {
return $name;
} else {
return FALSE;
}
// @todo: make this more flexible.
// $types = module_invoke_all('media_types');
// foreach ($types as $type) {
// if (preg_match($type->mimeTypes, ) {
//
// }
//
// }
}
}
\ No newline at end of file
......@@ -461,7 +461,7 @@ function media_media_operations() {
}
/**
* Menu callback; presents the node editing form, or redirects to delete confirmation.
* Menu callback; presents the Media editing form, or redirects to delete confirmation.
*/
function media_page_edit($file) {
drupal_set_title(t('Edit @title', array('@title' => drupal_set_title($file->filename))));
......@@ -472,35 +472,47 @@ function media_page_edit($file) {
* Form builder: Builds the edit file form.
*/
function media_edit($form, $form_state, $file) {
drupal_set_title($file->filename);
field_attach_form('media', $file, $form, $form_state);
$form['preview'] = array(
'#type' => 'markup',
'#markup' => 'PREVIEW GOES HERE',
'#prefix' => '<div style="padding:10px; border:3px solid #CCC; width:200px; height:200px">',
'#suffix' => '</div>',
'#weight' => -10,
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Save'),
);
$form['file'] = array(
$form['fid'] = array(
'#type' => 'hidden',
'#value' => $file->fid,
);
// I don't know wtf we're going to do here....'
$media = media_load($file->fid);
field_attach_form('media', $media, $form, $form_state, FIELD_LANGUAGE_NONE);
$form['#redirect'] = 'admin/content/media';
return $form;
}
function media_edit_validate($form, &$form_state) {
// TODO: validate the edit form.
$media = media_load($form_state['values']['fid']);
field_attach_form_validate('media', $media, $form, $form_state);
}
/**
* Process media_edit form submissions.
*/
function media_edit_submit($form, &$form_state) {
$file = file_load($form_state['values']['file']);
print_r($file);
$file->filename = $form_state['values']['title'];
file_save($file);
$media = media_load($form_state['values']['fid']);
field_attach_submit('media', $media, $form, $form_state);
media_save($media);
}
/**
......@@ -563,10 +575,6 @@ function media_add_files_submit($form, &$form_state) {
file_save($file);
drupal_set_message(t('The file @name was uploaded', array('@name' => $file->filename)));
$form_state['redirect'] = url('admin/content/media/' . $file->fid . '/edit');
$file->type = MediaEntityController::getBundleName($file->filemime);
$file->field_title[FIELD_LANGUAGE_NONE][0]['value'] = $file->fielname;
field_attach_insert('media', $file);
}
else {
......@@ -578,7 +586,7 @@ function media_add_files_submit($form, &$form_state) {
* Displays the content type admin overview page.
*/
function media_admin_type_list() {
$types = module_invoke_all('media_types');
$types = media_type_get_types();
$field_ui = module_exists('field_ui');
$header = array(t('Name'), array('data' => t('Operations'), 'colspan' => $field_ui ? '4' : '2'));
$rows = array();
......
......@@ -10,7 +10,7 @@ files[] = media.module
files[] = media_ahah.inc
files[] = media.admin.inc
files[] = media_theme.inc
files[] = media_types.inc
files[] = MediaReadOnlyStreamWrapper.inc
files[] = MediaEntityController.php
dependencies[] = file
dependencies[] = image
......@@ -7,10 +7,92 @@
* Install, update and uninstall functions for the Media module.
*/
function media_install() {
/**
* DISCLAIMER:
* Yes I am altering a core table.
* No I am not on crack.
* Basically, the problem we're facing is the media "type" which is not the mime type
* but is probably computed from it.
*
* the file table has no type field. As a result, we would have to either:
*
* 1). Create a media_files table to join them. This is nice and clean, however
* it requires keeping the tables in sync, and it also means we have to write our
* own SQL instead of using BaseEntityController, and that's kinda scary.
*
* 2). Make the media type a "computed" field. Wherein, everytime we loaded a piece
* of media, we would need to compute its type from the mime-type. This is unacceptable
* from a performance standpoint and also requires us override the Controller in ways
* we probably don't want to.
*
* I know it's a sin, but I think it is also excusable because:
*
* 1). This is hoping to be a core addition, so think of it as a core patch
* that will eventually go in.
*
* 2). It is adding a new field, so it shouldn't cause any conflicts. If it does
* that INSERT / SELECT code is badly written and should use complete INSERTS or column names.
*/
$keys = array('index' => array('type'));
db_add_field('file', 'type', _media_type_field_spec());
db_add_index('file', 'file_type', array('type'));
// Add the common media types.
$types = array();
$types['image'] = new StdClass();
$types['image']->machine_name = 'image';
$types['image']->label = "Image";
$types['image']->base = TRUE;
$types['image']->extensions = array('jpg', 'jpeg', 'gif', 'png', 'tiff');
// @todo:not implemented
$types['image']->mimeTypes = array('/^image/');
$types['audio'] = new StdClass();
$types['audio']->machine_name = 'audio';
$types['audio']->label = "Audio";
$types['audio']->base = TRUE;
$types['audio']->extensions = array('mp3', 'ogg', 'wma');
$types['audio']->mimeTypes = array('/^audio/');
$types['video'] = new StdClass();
$types['video']->machine_name = 'video';
$types['video']->label = "Video";
$types['video']->base = TRUE;
$types['video']->extensions = array('mov', 'mp4', 'avi');
$types['video']->mimeTypes = array('/^video/');
foreach ($types as $name => $type) {
media_type_save($type);
}
}
function _media_type_field_spec() {
return array(
'description' => 'Type of file for use in Media Bundles',
'type' => 'varchar',
'length' => 50,
'not null' => FALSE,
);
}
/**
* Implement hook_schema_alter();
*/
function media_schema_alter(&$schema) {
$schema['file']['fields']['type'] = _media_type_field_spec();
}
/**
* Implement hook_uninstall().
*/
function media_uninstall() {
/**
* See comment above in media_install.
*/
db_drop_field('file', 'type');
$types = node_type_get_types();
$global = new stdClass;
$global->fields = field_info_instances();
......@@ -31,4 +113,4 @@ function media_uninstall() {
variable_del('media_file_progress_image');
variable_del('media_file_list_size');
variable_del('media_file_progress_success');
}
}
\ No newline at end of file
This diff is collapsed.
<?php
// $Id$
/**
* Implement hook_entity_info().
*/
function media_entity_info() {
$return = array(
'media' => array(
'label' => t('Media'),
//'controller class' => 'MediaController',
'base table' => 'media_metadata',
'fieldable' => TRUE,
'object keys' => array(
'id' => 'mid',
'bundle' => 'media_type',
),
// 'bundle keys' => array(
// 'bundle' => 'machine_name',
// ),
'bundles' => array(),
),
);
$image_types = array (
'image' => array(
'label' => 'Image',
),
'audio' => array(
'label' => 'Audio',
),
'video' => array(
'label' => 'Video',
),
);
foreach ($image_types as $type => $bundle_info) {
$return['media']['bundles'][$type] = $bundle_info;
$return['media']['bundles'][$type]['admin'] = array(
'path' => 'admin/media/type/%media_type',
'real path' => 'admin/media/type/' . $type,
'bundle argument' => 3,
'access arguments' => array('administer taxonomy'),
);
}
return $return;
}
/**
* Implement hook_entity_info().
*
* @todo: This has a pretty serious flaw. In the case someone uploads
* a file without a known "type" fields will puke. We need to provide
* some "default type in the install probably".
*/
function media_entity_info() {
$return = array(
'media' => array(
'label' => t('Media'),
'controller class' => 'MediaEntityController',
'base table' => 'file',
'fieldable' => TRUE,
'object keys' => array(
'id' => 'fid',
'bundle' => 'type',
),
'bundle keys' => array(
'bundle' => 'machine_name',
),
'bundles' => array(),
),
);
$media_types = module_invoke_all('media_types');
$media_types = media_type_get_types();
foreach ($media_types as $type => $bundle_info) {
$return['media']['bundles'][$type] = (array)$bundle_info;
......@@ -76,11 +34,9 @@ function media_entity_info() {
'access arguments' => array('administer site configuration'),
);
}
return $return;
}
/**
* Implement hook_field_info().
*
......@@ -104,57 +60,69 @@ function media_field_info() {
}
/**
Implement hook_media_types
* Update an existing media type or create a new one.
*
* @param object $type
* @return void;
*/
function media_media_types() {
$types = array();
$types['image'] = new StdClass();
$types['image']->label = "Image";
$types['image']->base = TRUE;
$types['image']->extensions = array('jpg', 'jpeg', 'gif', 'png', 'tiff');
// @todo:not implement
$types['image']->mimeTypes = array('/$image/');
$types['audio'] = new StdClass();
$types['audio']->label = "Audio";
$types['image']->base = TRUE;
$types['image']->extensions = array('mp3', 'ogg', 'wma');
$types['image']->mimeTypes = array('/$audio/');
$types['video'] = new StdClass();
$types['video']->label = "Video";
$types['image']->base = TRUE;
$types['image']->extensions = array('mov', 'mp4', 'avi');
$types['image']->mimeTypes = array('/$video/');
return $types;
function media_type_save($type) {
$types = variable_get('media_types', array());
$types[$type->machine_name] = $type;
variable_set('media_types', $types);
// Clear the caches
drupal_static_reset('media_type_get_types');
drupal_static_reset('media_type_get_mime_map');
}
/**
* Menu argument handler. Loads a media type definition when %media_type is in the path.
* Loads a media type based on its machine name.
*
* @param string $type
* @param string $machine_name
* @return StdClass
*/
function media_type_load($type) {
return $type;
$media_types = module_invoke_all('media_types');
return $media_types[$type];
function media_type_load($machine_name) {
$types = media_type_get_types();
if (isset($types[$machine_name])) {
return $types[$machine_name];
}
}
function media_load($fid) {
return entity_load('media', array($fid));
/**
* Loads all media types into an array keyed by machine name.
*
* @return array
* Media types keyed by machine name.
*/
function media_type_get_types() {
$types =& drupal_static(__FUNCTION__);
if (!$types) {
$types = variable_get('media_types', array());
}
return $types;
}
/**
* Implement hook_permission().
* Returns a an associative array mapping mimeType patterns to media types.
*
* Example:
* return array(
* 'image/gif' => 'image',
* 'image/png' => 'image,
* );
*
* @return array
*/
function media_permission() {
return array(
'administer media' => array(
'title' => t('Administer media'),
'description' => t('Add, edit or delete media.'),
),
);
function media_type_get_mime_map() {
$map =& drupal_static(__FUNCTION__);
if (!$map) {
$map = array();
$types = media_type_get_types();
foreach ($types as $name => $type) {
$map += array_fill_keys($type->mimeTypes, $name);
}
}
return $map;
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment