1
|
|
2
|
/**
|
3
|
* API documentation for the Media module.
|
4
|
*/
|
5
|
|
6
|
The Media module provides a robust API for developers to extend functionality
|
7
|
in useful and novel ways.
|
8
|
|
9
|
CAUTION: This is pretty old!
|
10
|
|
11
|
Architecture
|
12
|
------------
|
13
|
|
14
|
To understand the API, it is first important to understand the underlying
|
15
|
architecture and the decisions behind its current implementation.
|
16
|
|
17
|
Stream Wrappers
|
18
|
---------------
|
19
|
|
20
|
First, the Media module makes heavy use of the core Stream Wrappers now
|
21
|
provided with Drupal 7. Streams are classes that encapsulate PHP file
|
22
|
functions, allowing an automatic override when calling the basic function.
|
23
|
For instance, a wrapper implementing an Amazon S3 Stream might override the
|
24
|
file_get_contents() using ->stream_open(), or a Flickr Stream Wrapper might
|
25
|
implement its own ->getExternalUrl to return the HTML URI for a specific
|
26
|
Flickr image.
|
27
|
|
28
|
See http://api.drupal.org/file/includes/stream_wrappers.inc/7 for more
|
29
|
information about Stream Wrappers in Drupal.
|
30
|
|
31
|
Schemes
|
32
|
-------
|
33
|
|
34
|
All Stream Wrappers will be registered to handle a specific scheme, which is
|
35
|
the part of a URI before ://, such as core Drupal's public:// and private://
|
36
|
schemes. (Technically, a scheme only requires :, but a bug in PHP 5.2
|
37
|
requires ://, so Drupal currently keeps the same requirement.)
|
38
|
|
39
|
The target after the scheme:// will be a unique identifier that the
|
40
|
implementing Stream Wrapper will use to determine the file resource being
|
41
|
accessed. For instance, public://my-document.txt might refer to a local file
|
42
|
stored in the server at /sites/example.com/files/my-document.txt, while a URI
|
43
|
of youtube://fe3fg8u34i might be the video stored at
|
44
|
http://youtube.com/v/fe3fg8u34i, and flickr://photoset/224 might use a lookup
|
45
|
table to determine this is a photoset accessed at
|
46
|
http://flickr.com/user/markam/photoset/325hsd89.
|
47
|
|
48
|
All files in Drupal are stored in the database with this unique URI, in
|
49
|
addition to its unique serial FID. In general, file objects are accessed
|
50
|
and loaded by the URI, which will automatically use the correct stream wrapper
|
51
|
implementation for its scheme.
|
52
|
|
53
|
File Field Widget
|
54
|
-----------------
|
55
|
|
56
|
The Media module extends the core File field to make use of its browser for
|
57
|
editors, which is in turn exposed for other modules to extend. It does this
|
58
|
by create a new widget definition, defining a File (media) 'generic' file
|
59
|
widget, and suppressing the original File widget definition to avoid
|
60
|
confusion. All existing file fields will be converted to this new widget on
|
61
|
installation of the module, and if uninstalled, any defined media_generic file
|
62
|
fields will be reverted to their original definition to avoid loss of data.
|
63
|
|
64
|
Media Formatters
|
65
|
----------------
|
66
|
|
67
|
By default, the File (media) widget will use the original display behavior,
|
68
|
which is to display a generic icon followed by a link to the file. However, in
|
69
|
many (if not most) cases, a site administrator will want to display media in
|
70
|
very specific ways. For instance, they might want an image uploaded to be
|
71
|
displayed as a cropped thumbnail, as with any Flickr images attached to that
|
72
|
field, while a YouTube video might be displayed as a thumbnail that pops up
|
73
|
in a Shadowbox, and finally a PDF might be displayed in an iFrame. And that's
|
74
|
only when it's displayed in a node teaser...
|
75
|
|
76
|
To manage the various display formatting needs of an editor, the Media module
|
77
|
offers a Media Style API for other modules to implement and extend. Media
|
78
|
Styles of various mimetypes are grouped together and made available as new
|
79
|
formatters for field display, whether for a node, a comment, in a view, or
|
80
|
elsewhere.
|
81
|
|
82
|
To implement a new Media Style, a module needs to register itself for a
|
83
|
specific mimetype, with the following hook. Note that Media styles will be
|
84
|
properly namespaced by the module, to avoid conflicts.
|
85
|
|
86
|
function hook_media_styles($mimetype = NULL) {
|
87
|
switch ($mimetype) {
|
88
|
case 'video/x-youtube':
|
89
|
return array(
|
90
|
'youtube_video' => t('YouTube Video'),
|
91
|
'youtube_thumbnail' => t('YouTube Thumbnail'),
|
92
|
'youtube_shadowbox' => t('YouTube Shadowbox'),
|
93
|
'youtube_link' => t('Youtube (link to original)'),
|
94
|
case 'image/x-flickr':
|
95
|
$styles = array(
|
96
|
'flickr__original' => t('Flickr (Original size)'),
|
97
|
);
|
98
|
foreach (image_styles() as $style_name => $style) {
|
99
|
$styles[$style_name] = t('Flickr (@style)', array('@style' => $style->name));
|
100
|
}
|
101
|
return $styles;
|
102
|
}
|
103
|
}
|
104
|
|
105
|
These styles will be available from the Media Styles configuration page, where
|
106
|
multiple formatters can be grouped together to create new formatter Style
|
107
|
bundles, available and intelligently applied to files of the appropriate
|
108
|
mimetypes.
|
109
|
|
110
|
For instance, a new Media Style might be created, named 'Small image', which
|
111
|
will bundle an Image style for the various image mimetypes, another for Flickr
|
112
|
images, a shadowbox for YouTube thumbnails, and a fallback to a size styled
|
113
|
File icon. Then this style would be made available as a display formatter, and
|
114
|
the Media module will apply the correct style for the mimetype of the
|
115
|
particular instance.
|
116
|
|
117
|
A module may also define default Media styles to be made available, by
|
118
|
implementing hook_media_default_style_bundles(). Unlike the individual Media Styles,
|
119
|
Media Style bundles are not namespaced by module. If two or more modules use
|
120
|
the same Style bundle names, the behavior is undefined. Also note that the
|
121
|
administrator may override a specific Style bundle, for instance by replacing
|
122
|
the Style for a specific mimetype.
|
123
|
|
124
|
function hook_media_default_style_bundles() {
|
125
|
return array(
|
126
|
'shadowbox_images' => array(
|
127
|
'label' => t('Shadowbox images'),
|
128
|
'mimetypes' => array(
|
129
|
'image/*' => 'mymodule_image_shadowbox',
|
130
|
'video/*' => 'mymodule_video_shadowbox',
|
131
|
'*' => 'mymodule_default_shadowbox',
|
132
|
),
|
133
|
),
|
134
|
);
|
135
|
}
|
136
|
|
137
|
@TODO
|
138
|
convert existing file fields to media_generic on hook_install
|
139
|
convert existing media_generic to file fields on hook_uninstall
|
140
|
allow theme_file_icon file directory override in widget display settings
|
141
|
(Requires http://drupal.org/node/650732)
|
142
|
create new default file icons and set its folder as the new default
|
143
|
maybe instead/in addition have fallbacks if icon not present?
|
144
|
rename image style square_thumbnail to use the media_ namespace
|
145
|
review Media Styles for feasibility, usability, and architecture
|
146
|
create Media Styles UI .inc file
|
147
|
look at hook_field_info_alter to see if we can affect file widget that way
|
148
|
CLEAN CRUFT (lots of functions that no longer apply or need to be rethought)
|
149
|
why do we want to override the file field widget again?
|
150
|
should we also move 'media_styles' to its own module, perhaps file_styles?
|
151
|
in media_field_formatter_info(),
|
152
|
should 'field types' => array('media_generic', 'file'), be only one or other?
|