imagefield.module

Tracking 6.x-3.x branch
  1. drupal
    1. 5 contributions/imagefield/imagefield.module
    2. 6 contributions/imagefield/imagefield.module

ImageField core hooks and menu callbacks.

Functions & methods

NameDescription
imagefield_default_valueImplementation of CCK's hook_default_value().
imagefield_elementsImplementation of hook_elements().
imagefield_field_formatter_infoImplementation of CCK's hook_field_formatter_info().
imagefield_filefield_data_infoImplementation of hook_filefield_data_info().
imagefield_file_downloadImplementation of hook_file_download.
imagefield_form_content_field_overview_form_alterImplementation of hook_form_[form_id]_alter().
imagefield_form_content_field_overview_submitSubmit handler to set a new field's formatter to "image_plain".
imagefield_nodeapiImplementation of hook_nodeapi().
imagefield_themeImplementation of hook_theme().
imagefield_widgetImplementation of CCK's hook_widget().
imagefield_widget_infoImplementation of CCK's hook_widget_info().
imagefield_widget_settingsImplementation of CCK's hook_widget_settings().
imagefield_widget_upload_validatorsGet the additional upload validators for an image field.
theme_imagefield_admin_thumbnail
theme_imagefield_image@defgroup "Theme Callbacks"
theme_imagefield_item
theme_imagefield_widget_item
theme_imagefield_widget_preview

File

View source
  1. <?php
  2. /**
  3. * @file
  4. * ImageField core hooks and menu callbacks.
  5. */
  6. require_once dirname(__FILE__) . '/imagefield_file.inc';
  7. require_once dirname(__FILE__) . '/imagefield_widget.inc';
  8. /**
  9. * Implementation of hook_theme().
  10. */
  11. function imagefield_theme() {
  12. return array(
  13. // Theme an image uploaded to ImageField with alt and title.
  14. // TODO: Switch to core theme image if possible.
  15. 'imagefield_image' => array(
  16. 'arguments' => array('file' => NULL, 'alt' => '', 'title' => '', 'attributes' => NULL, 'getsize' => TRUE),
  17. ),
  18. // Theme an ImageField field item. It calls imagefied_image with the proper
  19. // item properties as arguments.
  20. 'imagefield_item' => array(
  21. 'arguments' => array('item' => NULL),
  22. ),
  23. // imagefield_widget form element type theme function.
  24. 'imagefield_widget' => array(
  25. 'arguments' => array('element' => NULL),
  26. 'file' => 'imagefield_widget.inc',
  27. ),
  28. // Use to generate a preview (admin view) of an imagefield item for use in
  29. // field item forms and filefield widgets. Invoked by filefield_widget_process.
  30. 'imagefield_widget_preview' => array(
  31. 'arguments' => array('item' => NULL),
  32. ),
  33. // Theme function for the field item elements. allows you to place children
  34. // within the context of the parent.
  35. 'imagefield_widget_item' => array(
  36. 'arguments' => array('element' => NULL),
  37. ),
  38. // Generates and img tag to the admin thumbnail of an ImageField upload.
  39. 'imagefield_admin_thumbnail' => array(
  40. 'arguments' => array('item' => NULL),
  41. ),
  42. // ImageField formatter theme functions.
  43. 'imagefield_formatter_image_plain' => array(
  44. 'arguments' => array('element' => NULL),
  45. 'file' => 'imagefield_formatter.inc',
  46. ),
  47. 'imagefield_formatter_image_nodelink' => array(
  48. 'arguments' => array('element' => NULL),
  49. 'file' => 'imagefield_formatter.inc',
  50. ),
  51. 'imagefield_formatter_image_imagelink' => array(
  52. 'arguments' => array('element' => NULL),
  53. 'file' => 'imagefield_formatter.inc',
  54. ),
  55. );
  56. }
  57. /**
  58. * Implementation of hook_elements().
  59. */
  60. function imagefield_elements() {
  61. $elements = array();
  62. // Catch problems when this is called too early during installation or update.
  63. if (!module_exists('filefield')) {
  64. return $elements;
  65. }
  66. // An ImageField is really just a FileField with extra processing.
  67. $filefield_elements = module_invoke('filefield', 'elements');
  68. $elements['imagefield_widget'] = $filefield_elements['filefield_widget'];
  69. $elements['imagefield_widget']['#process'][] = 'imagefield_widget_process';
  70. // ImageField needs a separate value callback to save its alt and title texts.
  71. $elements['imagefield_widget']['#value_callback'] = 'imagefield_widget_value';
  72. return $elements;
  73. }
  74. /**
  75. * Implementation of hook_file_download.
  76. */
  77. function imagefield_file_download($filepath) {
  78. // Return headers for admin thumbnails if private files are enabled.
  79. if (strpos($filepath, 'imagefield_thumbs') !== FALSE) {
  80. $original_path = str_replace('imagefield_thumbs/', '', $filepath);
  81. $original_full_path = file_create_path($original_path);
  82. $thumb_full_path = file_create_path($filepath);
  83. // Allow access to temporary thumbnails, since they're not yet associated
  84. // with a node. If not temporary, check access on the original file.
  85. $status = db_result(db_query("SELECT status FROM {files} WHERE filepath = '%s'", $original_full_path));
  86. $access = ($status == 0 || !in_array(-1, module_invoke_all('file_download', $original_path)));
  87. if ($access && $info = getimagesize($thumb_full_path)) {
  88. return array(
  89. 'Content-Type: ' . $info['mime'],
  90. 'Content-Length: ' . filesize($thumb_full_path)
  91. );
  92. }
  93. }
  94. // Return headers for default images.
  95. if (strpos($filepath, 'imagefield_default_images') !== FALSE) {
  96. $full_path = file_create_path($filepath);
  97. if ($info = getimagesize($full_path)) {
  98. return array(
  99. 'Content-Type: ' . $info['mime'],
  100. 'Content-Length: ' . filesize($full_path)
  101. );
  102. }
  103. }
  104. }
  105. /**
  106. * Implementation of hook_nodeapi().
  107. *
  108. * Add ALT and title texts to the search index.
  109. */
  110. function imagefield_nodeapi($node, $op) {
  111. if ($op == 'update index') {
  112. static $fields;
  113. if (!isset($fields)) {
  114. $fields = filefield_get_field_list();
  115. }
  116. $texts = array();
  117. foreach ($fields as $field) {
  118. $name = $field['field_name'];
  119. // Check this node for ImageField alt and title data.
  120. if (isset($node->$name) && is_array($node->$name)) {
  121. foreach ($node->$name as $item) {
  122. $texts[] = isset($item['data']['alt']) ? $item['data']['alt'] : '';
  123. $texts[] = isset($item['data']['title']) ? $item['data']['title'] : '';
  124. }
  125. }
  126. }
  127. return implode(' ', $texts);
  128. }
  129. }
  130. /**
  131. * Implementation of CCK's hook_widget_info().
  132. */
  133. function imagefield_widget_info() {
  134. $module_path = drupal_get_path('module', 'imagefield');
  135. return array(
  136. 'imagefield_widget' => array(
  137. 'label' => t('Image'),
  138. 'field types' => array('filefield'),
  139. 'multiple values' => CONTENT_HANDLE_CORE,
  140. 'callbacks' => array('default value' => CONTENT_CALLBACK_CUSTOM),
  141. 'description' => t('An edit widget for image files, including a preview of the image.'),
  142. ),
  143. );
  144. }
  145. /**
  146. * Implementation of CCK's hook_widget_settings().
  147. */
  148. function imagefield_widget_settings($op, $widget) {
  149. switch ($op) {
  150. case 'form':
  151. return imagefield_widget_settings_form($widget);
  152. case 'validate':
  153. return imagefield_widget_settings_validate($widget);
  154. case 'save':
  155. return imagefield_widget_settings_save($widget);
  156. }
  157. }
  158. /**
  159. * Implementation of CCK's hook_widget().
  160. *
  161. * Assign default properties to item and delegate to FileField.
  162. */
  163. function imagefield_widget(&$form, &$form_state, $field, $items, $delta = 0) {
  164. // Add default values to items.
  165. // TODO: use CCK's default value callback.
  166. if (empty($items[$delta])) {
  167. $items[$delta] = array('alt' => '', 'title' => '');
  168. }
  169. // Start with the FileField widget as a basic start.
  170. // Note that FileField needs to modify $form by reference.
  171. $element = filefield_widget($form, $form_state, $field, $items, $delta);
  172. // Add ImageField specific validators.
  173. $element['#upload_validators'] = array_merge($element['#upload_validators'], imagefield_widget_upload_validators($field));
  174. return $element;
  175. }
  176. /**
  177. * Get the additional upload validators for an image field.
  178. *
  179. * @param $field
  180. * The CCK field array.
  181. * @return
  182. * An array suitable for passing to file_save_upload() or the file field
  183. * element's '#upload_validators' property.
  184. */
  185. function imagefield_widget_upload_validators($field) {
  186. $validators = array();
  187. // Match the default value if no file extensions have been saved at all.
  188. if (!isset($field['widget']['file_extensions'])) {
  189. $field['widget']['file_extensions'] = 'png gif jpg jpeg';
  190. }
  191. // Ensure that only web images are supported.
  192. $web_extensions = array('png', 'gif', 'jpg', 'jpeg');
  193. $extensions = array_filter(explode(' ', $field['widget']['file_extensions']));
  194. if (empty($extensions)) {
  195. $extensions = $web_extensions;
  196. }
  197. $validators['filefield_validate_extensions'][0] = implode(' ', array_intersect($extensions, $web_extensions));
  198. // Add the image validator as a basic safety check.
  199. $validators['filefield_validate_is_image'] = array();
  200. // Add validators for resolutions.
  201. if (!empty($field['widget']['max_resolution']) || !empty($field['widget']['min_resolution'])) {
  202. $validators['filefield_validate_image_resolution'] = array(
  203. $field['widget']['max_resolution'],
  204. $field['widget']['min_resolution'],
  205. );
  206. }
  207. return $validators;
  208. }
  209. /**
  210. * Implementation of CCK's hook_field_formatter_info().
  211. */
  212. function imagefield_field_formatter_info() {
  213. $module_path = drupal_get_path('module', 'imagefield');
  214. $formatters = array(
  215. 'image_plain' => array(
  216. 'label' => t('Image'),
  217. 'field types' => array('filefield'),
  218. 'description' => t('Displays image files in their original size.'),
  219. ),
  220. 'image_nodelink' => array(
  221. 'label' => t('Image linked to node'),
  222. 'field types' => array('filefield'),
  223. 'description' => t('Displays image files in their original size.'),
  224. ),
  225. 'image_imagelink' => array(
  226. 'label' => t('Image linked to file'),
  227. 'field types' => array('filefield'),
  228. 'description' => t('Displays image files in their original size.'),
  229. ),
  230. );
  231. return $formatters;
  232. }
  233. /**
  234. * Implementation of CCK's hook_default_value().
  235. */
  236. function imagefield_default_value(&$form, &$form_state, $field, $delta) {
  237. return filefield_default_value($form, $form_state, $field, $delta);
  238. }
  239. /**
  240. * Implementation of hook_form_[form_id]_alter().
  241. *
  242. * Modify the add new field form to make "Image" the default formatter.
  243. */
  244. function imagefield_form_content_field_overview_form_alter(&$form, &$form_state) {
  245. $form['#submit'][] = 'imagefield_form_content_field_overview_submit';
  246. }
  247. /**
  248. * Submit handler to set a new field's formatter to "image_plain".
  249. */
  250. function imagefield_form_content_field_overview_submit(&$form, &$form_state) {
  251. if (isset($form_state['fields_added']['_add_new_field']) && isset($form['#type_name'])) {
  252. $new_field = $form_state['fields_added']['_add_new_field'];
  253. $node_type = $form['#type_name'];
  254. $field = content_fields($new_field, $node_type);
  255. if ($field['widget']['module'] == 'imagefield') {
  256. foreach ($field['display_settings'] as $display_type => $display_settings) {
  257. if ($field['display_settings'][$display_type]['format'] == 'default') {
  258. $field['display_settings'][$display_type]['format'] = 'image_plain';
  259. }
  260. }
  261. content_field_instance_update($field);
  262. }
  263. }
  264. }
  265. /**
  266. * Implementation of hook_filefield_data_info().
  267. */
  268. function imagefield_filefield_data_info() {
  269. return array(
  270. 'alt' => array(
  271. 'title' => t('Alt text'),
  272. 'callback' => 'check_plain',
  273. ),
  274. 'title' => array(
  275. 'title' => t('Title'),
  276. 'callback' => 'check_plain',
  277. ),
  278. );
  279. }
  280. /**
  281. * @defgroup "Theme Callbacks"
  282. * @{
  283. * @see imagefield_theme().
  284. */
  285. function theme_imagefield_image($file, $alt = '', $title = '', $attributes = NULL, $getsize = TRUE) {
  286. $file = (array) $file;
  287. if ($getsize) {
  288. // Use cached width and height if available.
  289. if (!empty($file['data']['width']) && !empty($file['data']['height'])) {
  290. $attributes['width'] = $file['data']['width'];
  291. $attributes['height'] = $file['data']['height'];
  292. }
  293. // Otherwise pull the width and height from the file.
  294. elseif (list($width, $height, $type, $image_attributes) = @getimagesize($file['filepath'])) {
  295. $attributes['width'] = $width;
  296. $attributes['height'] = $height;
  297. }
  298. }
  299. if (!empty($title)) {
  300. $attributes['title'] = $title;
  301. }
  302. // Alt text should be added even if it is an empty string.
  303. $attributes['alt'] = $alt;
  304. // Add a timestamp to the URL to ensure it is immediately updated after editing.
  305. $query_string = '';
  306. if (isset($file['timestamp'])) {
  307. $query_character = (variable_get('file_downloads', FILE_DOWNLOADS_PUBLIC) == FILE_DOWNLOADS_PRIVATE && variable_get('clean_url', '0') == '0') ? '&' : '?';
  308. $query_string = $query_character . $file['timestamp'];
  309. }
  310. // Encode the path so that unusual characters are printed correctly.
  311. $path = field_file_urlencode_path($file['filepath']);
  312. // Construct the URL.
  313. $url = file_create_url($path) . $query_string;
  314. $attributes['src'] = $url;
  315. $attributes = drupal_attributes($attributes);
  316. return '<img '. $attributes .' />';
  317. }
  318. function theme_imagefield_item($item) {
  319. return theme('imagefield_image', $item, $item['alt'], $item['title']);
  320. }
  321. function theme_imagefield_widget_preview($item = NULL) {
  322. return '<div class="imagefield-preview">' . theme('imagefield_admin_thumbnail', $item) . '</div>';
  323. }
  324. function theme_imagefield_widget_item($element) {
  325. return theme('filefield_widget_item', $element);
  326. }
  327. function theme_imagefield_admin_thumbnail($item = NULL) {
  328. if (is_null($item) || empty($item['filepath'])) {
  329. return '<!-- link to default admin thumb -->';
  330. }
  331. $thumb_path = imagefield_file_admin_thumb_path($item);
  332. // Encode the path so that unusual characters are printed correctly.
  333. $thumb_path = field_file_urlencode_path($thumb_path);
  334. // Add a timestamp to the URL to ensure it is immediately updated after editing.
  335. $query_string = '';
  336. if (isset($item['timestamp'])) {
  337. $query_character = (variable_get('file_downloads', FILE_DOWNLOADS_PUBLIC) == FILE_DOWNLOADS_PRIVATE && variable_get('clean_url', '0') == '0') ? '&' : '?';
  338. $query_string = $query_character . $item['timestamp'];
  339. }
  340. return '<img src="'. file_create_url($thumb_path) . $query_string . '" title="' . check_plain($item['filename']) . '" alt="' . t('Image preview') . '" />';
  341. }
  342. /**
  343. * @} End defgroup "Theme Callbacks".
  344. */