diff --git modules/file/file.field.inc modules/file/file.field.inc index 5e509f6..49dab3c 100644 --- modules/file/file.field.inc +++ modules/file/file.field.inc @@ -51,8 +51,8 @@ function file_field_schema($field) { 'not null' => TRUE, 'default' => 1, ), - 'data' => array( - 'description' => 'Serialized additional data about the file, such as a description.', + 'description' => array( + 'description' => 'A description of the file.', 'type' => 'text', 'not null' => FALSE, 'serialize' => TRUE, @@ -230,9 +230,7 @@ function file_field_load($obj_type, $objects, $field, $instances, $langcode, &$i if (empty($item['fid']) || !isset($files[$item['fid']])) { $items[$obj_id][$delta] = NULL; } - // Unserialize the data column. else { - $item['data'] = unserialize($item['data']); $items[$obj_id][$delta] = array_merge($item, (array) $files[$item['fid']]); } } @@ -274,11 +272,6 @@ function file_field_insert($obj_type, $object, $field, $instance, $langcode, &$i * Implement hook_field_update(). */ function file_field_update($obj_type, $object, $field, $instance, $langcode, &$items) { - // Serialize the data column before storing. - foreach ($items as $delta => $item) { - $items[$delta]['data'] = serialize($item['data']); - } - // Check for files that have been removed from the object. // On new revisions, old files are always maintained in the previous revision. @@ -393,7 +386,7 @@ function file_field_displayed($item, $field) { function file_field_formatter_info() { return array( 'file_default' => array( - 'label' => t('Generic file'), + 'label' => t('File'), 'field types' => array('file'), ), 'file_table' => array( @@ -416,7 +409,7 @@ function file_field_formatter_info() { function file_field_widget_info() { return array( 'file_generic' => array( - 'label' => t('Generic file'), + 'label' => t('File'), 'field types' => array('file'), 'settings' => array( 'progress_indicator' => 'throbber', @@ -461,7 +454,7 @@ function file_field_widget_settings_form($field, $instance) { $form['additional']['description_field'] = array( '#type' => 'checkbox', '#title' => t('Enable Description field'), - '#default_value' => $settings['description_field'], + '#default_value' => isset($settings['description_field']) ? $settings['description_field'] : '', '#description' => t('The description field allows users to enter a description about the uploaded file.'), '#parents' => array('instance', 'widget', 'settings', 'description_field'), ); @@ -679,7 +672,7 @@ function file_field_widget_process($element, &$form_state, $form) { } // Add the description field if enabled. - if ($settings['description_field'] && $item['fid']) { + if (!empty($settings['description_field']) && $item['fid']) { $element['data']['description'] = array( '#type' => 'textfield', '#title' => t('Description'), diff --git modules/file/file.module modules/file/file.module index 7a2e263..3a07e0f 100644 --- modules/file/file.module +++ modules/file/file.module @@ -830,15 +830,17 @@ function file_icon_map($file) { */ /** - * Return an array of file fields in an bundle or by field name. + * Return an array of file fields. * * @param $bundle_type * (optional) The bundle type on which to filter the list of fields. In the * case of nodes, this is the node type. * @param $field * (optional) A field array or name on which to filter the list. + * @param $module + * (optional) A module name on which to filter the list. */ -function file_get_field_list($bundle_type = NULL, $field = NULL) { +function file_get_field_list($bundle_type = NULL, $field = NULL, $module = 'file') { // Build the list of fields to be used for retrieval. if (isset($field)) { if (is_string($field)) { @@ -857,9 +859,9 @@ function file_get_field_list($bundle_type = NULL, $field = NULL) { $fields = field_info_fields(); } - // Filter down the list to just file fields. + // Filter down the list to just fields used by $module. foreach ($fields as $key => $field) { - if ($field['type'] != 'file') { + if ($field['type'] != $module) { unset($fields[$key]); } } @@ -868,24 +870,28 @@ function file_get_field_list($bundle_type = NULL, $field = NULL) { } /** - * Count the number of times the file is referenced within a field. + * Count the number of times the file is referenced. * * @param $file * A file object. * @param $field - * Optional. The CCK field array or field name as a string. + * (optional) A CCK field array or field name as a string. If provided, + * limits the reference check to the given field. + * @param $module + * (optional) A module name. If provided, limits the reference check to the + * given module. * @return * An integer value. */ -function file_get_file_reference_count($file, $field = NULL) { - $fields = file_get_field_list(NULL, $field); +function file_get_file_reference_count($file, $field = NULL, $module = 'file') { + $fields = file_get_field_list(NULL, $field, $module); $types = field_info_fieldable_types(); $reference_count = 0; foreach ($fields as $field) { // TODO: Use a more efficient mechanism rather than actually retrieving // all the references themselves, such as using a COUNT() query. - $references = file_get_file_references($file, $field); + $references = file_get_file_references($file, $field, FIELD_LOAD_REVISION, $module); foreach ($references as $obj_type => $type_references) { $reference_count += count($type_references); } @@ -917,22 +923,26 @@ function file_get_file_reference_count($file, $field = NULL) { /** - * Get a list of references to a file by bundle and ID. + * Get a list of references to a file. * * @param $file * A file object. * @param $field - * (optional) A field array to be used for this check. + * (optional) A field array to be used for this check. If given, limits the + * reference check to the given field. * @param $age * (optional) A constant that specifies which references to count. Use * FIELD_LOAD_REVISION to retrieve all references within all revisions or * FIELD_LOAD_CURRENT to retrieve references only in the current revisions. + * @param $module + * Optional. A module name. If given, limits the reference check to the given + * module. * @return * An integer value. */ -function file_get_file_references($file, $field = NULL, $age = FIELD_LOAD_REVISION) { +function file_get_file_references($file, $field = NULL, $age = FIELD_LOAD_REVISION, $module = 'file') { $references = drupal_static(__FUNCTION__, array()); - $fields = file_get_field_list(NULL, $field); + $fields = file_get_field_list(NULL, $field, $module); foreach ($fields as $field_name => $file_field) { if (!isset($references[$field_name])) { diff --git modules/image/image.css modules/image/image.css new file mode 100644 index 0000000..23bbf31 --- /dev/null +++ modules/image/image.css @@ -0,0 +1,15 @@ +/* $Id$ */ + +/** + * Image widget. + */ +div.image-preview { + float: left; + padding: 0 10px 10px 0; +} +div.image-widget-data { + float: left; +} +div.image-widget-data input.text-field { + width: auto; +} diff --git modules/image/image.field.inc modules/image/image.field.inc new file mode 100644 index 0000000..29a5f59 --- /dev/null +++ modules/image/image.field.inc @@ -0,0 +1,513 @@ + array( + 'label' => t('Image'), + 'description' => t('This field stores the ID of an image file as an integer value.'), + 'settings' => array( + 'display_field' => 0, + 'display_default' => 0, + 'uri_scheme' => 'public', + 'default_file' => 0, + ), + 'instance_settings' => array( + 'file_extensions' => 'png gif jpg jpeg', + 'file_directory' => '', + 'max_filesize' => '', + 'alt_field' => 0, + 'title_field' => 0, + 'description_field' => 0, + 'max_resolution' => '', + 'min_resolution' => '', + 'preview_image_style' => 'thumbnail', + 'default_file_extensions' => 'png gif jpg jpeg', + ), + 'default_widget' => 'image_image', + 'default_formatter' => 'image', + ), + ); +} + +/** + * Implement hook_field_schema(). + */ +function image_field_schema($field) { + return array( + 'columns' => array( + 'fid' => array( + 'description' => 'The {files}.fid being referenced in this field.', + 'type' => 'int', + 'not null' => FALSE, + 'unsigned' => TRUE, + ), + 'display' => array( + 'description' => 'Flag to control whether this file should be displayed when viewing content.', + 'type' => 'int', + 'size' => 'tiny', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 1, + ), + 'alt' => array( + 'description' => "Alternative image text, for the image's 'alt' attribute.", + 'type' => 'varchar', + 'length' => 128, + 'not null' => FALSE, + ), + 'title' => array( + 'description' => "Image title text, for the image's 'title' attribute.", + 'type' => 'varchar', + 'length' => 128, + 'not null' => FALSE, + ), + ), + 'indexes' => array( + 'fid' => array('fid'), + ), + ); +} + +/** + * Implement hook_field_settings_form(). + */ +function image_field_settings_form($field, $instance) { + $defaults = field_info_field_settings($field['type']); + $settings = array_merge($defaults, $field['settings']); + + $form['#attached']['js'][] = drupal_get_path('module', 'file') . '/file.js'; + + $form['display_field'] = array( + '#type' => 'checkbox', + '#title' => t('Enable Display field'), + '#default_value' => $settings['display_field'], + '#description' => t('The display option allows users to choose if a file should be shown when viewing the content.'), + ); + $form['display_default'] = array( + '#type' => 'checkbox', + '#title' => t('Files displayed by default'), + '#default_value' => $settings['display_default'], + '#description' => t('This setting only has an effect if the display option is enabled.'), + ); + + $scheme_options = array(); + foreach (file_get_stream_wrappers() as $scheme => $stream_wrapper) { + if ($scheme != 'temporary') { + $scheme_options[$scheme] = $stream_wrapper['name']; + } + } + $form['uri_scheme'] = array( + '#type' => 'radios', + '#title' => t('Upload destination'), + '#options' => $scheme_options, + '#default_value' => $settings['uri_scheme'], + '#description' => t('Select where the final files should be stored. Private file storage has significantly more overhead than public files, but allows restricted access to files within this field.'), + ); + + $form['default_file'] = array( + '#title' => t('Default file'), + '#type' => 'managed_file', + '#description' => t('If no file is uploaded, this file will be used on display.'), + '#default_value' => $field['settings']['default_file'], + '#upload_location' => 'public://default_files/', + ); + + return $form; + +} + +/** + * Implement hook_field_instance_settings_form(). + */ +function image_field_instance_settings_form($field, $instance) { + $settings = $instance['settings']; + + // Use the file field instance settings form as a basis. + $form = file_field_instance_settings_form($field, $instance); + + // Add maximum and minimum resolution settings. + $max_resolution = explode('x', $settings['max_resolution']) + array('', ''); + $form['additional']['max_resolution'] = array( + '#title' => t('Maximum image resolution'), + '#element_validate' => array('_image_field_resolution_validate'), + '#theme_wrappers' => array('form_element'), + '#weight' => 3.1, + '#description' => t('The maximum allowed image size expressed as WIDTHxHEIGHT (e.g. 640x480). Leave blank for no restriction. If a larger image is uploaded, it will be resized to reflect the given width and height. Resizing images on upload will cause the loss of EXIF data in the image.'), + ); + $form['additional']['max_resolution']['x'] = array( + '#type' => 'textfield', + '#default_value' => $max_resolution[0], + '#size' => 5, + '#maxlength' => 5, + '#field_suffix' => ' x ', + '#theme_wrappers' => array(), + ); + $form['additional']['max_resolution']['y'] = array( + '#type' => 'textfield', + '#default_value' => $max_resolution[1], + '#size' => 5, + '#maxlength' => 5, + '#field_suffix' => ' ' . t('pixels'), + '#theme_wrappers' => array(), + ); + + $min_resolution = explode('x', $settings['min_resolution']) + array('', ''); + $form['additional']['min_resolution'] = array( + '#title' => t('Minimum image resolution'), + '#element_validate' => array('_image_field_resolution_validate'), + '#theme_wrappers' => array('form_element'), + '#weight' => 3.2, + '#description' => t('The minimum allowed image size expressed as WIDTHxHEIGHT (e.g. 640x480). Leave blank for no restriction. If a smaller image is uploaded, it will be rejected.'), + ); + $form['additional']['min_resolution']['x'] = array( + '#type' => 'textfield', + '#default_value' => $min_resolution[0], + '#size' => 5, + '#maxlength' => 5, + '#field_suffix' => ' x ', + '#theme_wrappers' => array(), + ); + $form['additional']['min_resolution']['y'] = array( + '#type' => 'textfield', + '#default_value' => $min_resolution[1], + '#size' => 5, + '#maxlength' => 5, + '#field_suffix' => ' ' . t('pixels'), + '#theme_wrappers' => array(), + ); + + // Add title and alt configuration options. + $form['additional']['alt_field'] = array( + '#type' => 'checkbox', + '#title' => t('Enable Alt field'), + '#default_value' => $settings['alt_field'], + '#description' => t('The alt attribute may be used by search engines, screen readers, and when the image cannot be loaded.'), + '#parents' => array('instance', 'widget', 'settings', 'alt_field'), + '#weight' => -2, + ); + $form['additional']['title_field'] = array( + '#type' => 'checkbox', + '#title' => t('Enable Title field'), + '#default_value' => $settings['title_field'], + '#description' => t('The title attribute is used as a tooltip when the mouse hovers over the image.'), + '#parents' => array('instance', 'widget', 'settings', 'title_field'), + '#weight' => -1, + ); + + // Add settings for preview image style. + $form['preview_image_style'] = array( + '#title' => t('Preview image style'), + '#type' => 'select', + '#options' => array('' => '<' . t('no preview') . '>') + image_style_options(FALSE), + '#default_value' => $settings['preview_image_style'], + '#description' => t('The preview image will be shown while editing the content.'), + ); + + return $form; +} + +/** + * Implement hook_field_load(). + */ +function image_field_load($obj_type, $objects, $field, $instances, $langcode, &$items, $age) { + file_field_load($obj_type, $objects, $field, $instances, $langcode, &$items, $age); +} + +/** + * Implement hook_field_sanitize(). + */ +function image_field_sanitize($obj_type, $object, $field, $instance, $langcode, &$items) { + file_field_sanitize($obj_type, $object, $field, $instance, $langcode, &$items); +} + +/** + * Implement hook_field_insert(). + */ +function image_field_insert($obj_type, $object, $field, $instance, $langcode, &$items) { + image_field_update($obj_type, $object, $field, $instance, $langcode, &$items); +} + +/** + * Implement hook_field_update(). + */ +function image_field_update($obj_type, $object, $field, $instance, $langcode, &$items) { + file_field_update($obj_type, $object, $field, $instance, $langcode, &$items); +} + +/** + * Implement hook_field_delete(). + */ +function image_field_delete($obj_type, $object, $field, $instance, $langcode, &$items) { + file_field_delete($obj_type, $object, $field, $instance, $langcode, &$items); +} + +/** + * Implement hook_field_delete_revision(). + */ +function image_field_delete_revision($obj_type, $object, $field, $instance, $langcode, &$items) { + file_field_delete_revision($obj_type, $object, $field, $instance, $langcode, &$items); +} + +/** + * Implement hook_field_is_empty(). + */ +function image_field_is_empty($item, $field) { + return file_field_is_empty($item, $field); +} + +// to make Images work with generic file formatters +function hook_field_formatter_info_alter() { + +} + +/** + * Implement hook_file_references(). + */ +function image_file_references($file) { + $count = file_get_file_reference_count($file, NULL, 'image'); + return $count ? array('image' => $count) : NULL; +} + +/** + * Implement hook_field_widget_settings_form(). + */ +function image_field_widget_settings_form($field, $instance) { + $widget = $instance['widget']; + $defaults = field_info_widget_settings($widget['type']); + $settings = array_merge($defaults, $widget['settings']); + + // Use the file widget settings form as a basis. + $form = file_field_widget_settings_form($field, $instance); + unset($form['additional']['description_field']); + + return $form; +} + +/** + * Element validate function for resolution fields. + */ +function _image_field_resolution_validate($element, &$form_state) { + if (!empty($element['x']['#value']) || !empty($element['y']['#value'])) { + foreach (array('x', 'y') as $dimension) { + $value = $element[$dimension]['#value']; + if (!is_numeric($value)) { + form_error($element[$dimension], t('Height and width values must be numeric.')); + return; + } + if (intval($value) == 0) { + form_error($element[$dimension], t('Both a height and width value must be specified in the !name field.', array('!name' => $element['#title']))); + return; + } + } + form_set_value($element, intval($element['x']['#value']) . 'x' . intval($element['y']['#value']), $form_state); + } + else { + form_set_value($element, '', $form_state); + } +} + +/** + * Implement hook_field_widget_info(). + */ +function image_field_widget_info() { + return array( + 'image_image' => array( + 'label' => t('Image'), + 'field types' => array('image'), + 'settings' => array( + 'progress_indicator' => 'throbber', + ), + 'behaviors' => array( + 'multiple values' => FIELD_BEHAVIOR_CUSTOM, + 'default value' => FIELD_BEHAVIOR_NONE, + ), + ), + ); +} + +/** + * Implementation of hook_field_widget(). + */ +function image_field_widget(&$form, &$form_state, $field, $instance, $items, $delta = 0) { + $elements = file_field_widget($form, $form_state, $field, $instance, $items, $delta); + $settings = $instance['settings']; + + foreach (element_children($elements) as $delta) { + // Add upload resolution validation. + if ($settings['max_resolution'] || $settings['min_resolution']) { + $elements[$delta]['#upload_validators']['file_validate_image_resolution'] = array($settings['max_resolution'], $settings['min_resolution']); + } + + // If not using custom extension validation, ensure this is an image. + $supported_extensions = array('png', 'gif', 'jpg', 'jpeg'); + $extensions = isset($elements[$delta]['#upload_validators']['file_validate_extensions'][0]) ? $elements[$delta]['#upload_validators']['file_validate_extensions'][0] : implode(' ', $supported_extensions); + $extensions = array_intersect(explode(' ', $extensions), $supported_extensions); + $elements[$delta]['#upload_validators']['file_validate_extensions'][0] = implode(' ', $extensions); + + // Add all extra functionality provided by the image widget. + $elements[$delta]['#process'][] = 'image_field_widget_process'; + } + + if ($field['cardinality'] == 1) { + // If there's only one field, return it as delta 0. + if (empty($elements[0]['#default_value']['fid'])) { + $elements[0]['#description'] = theme('file_upload_help', $instance['description'], $elements[0]['#upload_validators']); + } + } + else { + //$elements['#file_upload_description'] = theme('file_upload_help', '', $elements[0]['#upload_validators']); + } + return $elements; +} + +/** + * An element #process callback for the file_image field type. + * + * Expands the file_image type to include the alt, title, and caption fields. + */ +function image_field_widget_process($element, &$form_state, $form) { + $item = $element['#value']; + $item['fid'] = $element['fid']['#value']; + + $field = field_info_field($element['#field_name']); + $instance = field_info_instance($element['#field_name'], $element['#bundle']); + $settings = $instance['settings']; + + $element['#theme'] = 'image_widget'; + $element['#attached_css'][] = drupal_get_path('module', 'image') . '/image.css'; + + // Add the image preview. + if ($element['#file'] && $settings['preview_image_style']) { + $element['preview'] = array( + '#type' => 'markup', + '#markup' => theme('image_style', $settings['preview_image_style'], $element['#file']->uri, NULL, NULL, array(), FALSE), + ); + } + + // Add the additional alt and title fields. + $element['data']['alt'] = array( + '#title' => t('Alternate Text'), + '#type' => 'textfield', + '#default_value' => isset($item['data']['alt']) ? $item['data']['alt'] : '', + '#description' => t('This text will be used by screen readers, search engines, or when the image cannot be loaded.'), + '#maxlength' => variable_get('image_alt_length', 80), // See http://www.gawds.org/show.php?contentid=28. + '#weight' => -2, + ); + $element['data']['title'] = array( + '#type' => 'textfield', + '#title' => t('Title'), + '#default_value' => isset($item['data']['title']) ? $item['data']['title'] : '', + '#description' => t('The title is used as a tool tip when the user hovers the mouse over the image.'), + '#maxlength' => variable_get('image_title_length', 500), + '#weight' => -1, + ); + + // If fields are disabled, convert the type to "value" to save existing data. + if (!$settings['alt_field']) { + $element['data']['alt']['#type'] = 'value'; + $element['data']['alt']['#value'] = $element['data']['alt']['#default_value']; + } + if (!$settings['title_field']) { + $element['data']['title']['#type'] = 'value'; + $element['data']['title']['#value'] = $element['data']['title']['#default_value']; + } + + return $element; +} + +/** + * Implement hook_field_create_instance(). + */ + /* +function image_field_create_instance($instance) { + // If creating a new image widget, set some matching formatters. + if (isset($instance['widget']['type']) && $instance['widget']['type'] == 'file_image') { + if (!isset($instance['display'])) { + $instance['display']['full']['type'] = 'image'; + $instance['display']['teaser']['type'] = 'image'; + } + if (!isset($instance['settings']['file_extensions'])) { + $instance['settings']['file_extensions'] = 'png jpg gif'; + } + field_update_instance($instance); + } +} +*/ +/** + * Theme the display of the image field widget. + */ +function theme_image_widget($element) { + $output = ''; + $output .= '
'; + + if (isset($element['preview'])) { + $output .= '
'; + $output .= drupal_render($element['preview']); + $output .= '
'; + } + + $output .= '
'; + if ($element['fid']['#value'] != 0) { + $element['filename']['#markup'] .= ' (' . format_size($element['#file']->filesize) . ') '; + } + $output .= drupal_render_children($element); + $output .= '
'; + $output .= '
'; + + return $output; +} + +/** + * Implement hook_field_formatter_info(). + */ +function image_field_formatter_info() { + $formatters = array( + 'image' => array( + 'label' => t('Image'), + 'field types' => array('image'), + ), + 'image_link_content' => array( + 'label' => t('Image linked to content'), + 'field types' => array('image'), + ), + 'image_link_file' => array( + 'label' => t('Image linked to file'), + 'field types' => array('image'), + ), + ); + + // TODO: Add image style formatters. + + return $formatters; +} + +/** + * Theme function for 'image' file field formatter. + */ +function theme_field_formatter_image($element) { + return theme('image', $element['#item']['uri'], $element['#item']['alt'], $element['#item']['title']); +} + +/** + * Theme function for 'image_link_content' file field formatter. + */ +function theme_field_formatter_image_link_content($element) { + list($id, $vid, $bundle) = field_extract_ids($element['#object_type'], $element['#object']); + return l(theme('field_formatter_image', $element), $element['#object_type'] . '/' . $id, array('html' => TRUE)); +} + +/** + * Theme function for 'image_link_file' file field formatter. + */ +function theme_field_formatter_image_link_file($element) { + return l(theme('field_formatter_image', $element), file_create_url($element['#item']['uri']), array('html' => TRUE)); +} diff --git modules/image/image.info modules/image/image.info index 16225d2..0887153 100644 --- modules/image/image.info +++ modules/image/image.info @@ -7,5 +7,6 @@ core = 7.x files[] = image.module files[] = image.admin.inc files[] = image.effects.inc +files[] = image.field.inc files[] = image.install files[] = image.test diff --git modules/image/image.module modules/image/image.module index 2ec6c4b..584e6e2 100644 --- modules/image/image.module +++ modules/image/image.module @@ -6,6 +6,9 @@ * Exposes global functionality for creating image styles. */ +// Load all Field module hooks for Image. +require_once DRUPAL_ROOT . '/modules/image/image.field.inc'; + /** * Implement of hook_help(). */ @@ -126,6 +129,7 @@ function image_menu() { */ function image_theme() { return array( + // Theme functions in image.module. 'image_style' => array( 'arguments' => array( 'style' => NULL, @@ -136,6 +140,8 @@ function image_theme() { 'getsize' => TRUE, ), ), + + // Theme functions in image.admin.inc. 'image_style_list' => array( 'arguments' => array('styles' => NULL), ), @@ -160,6 +166,20 @@ function image_theme() { 'image_rotate_summary' => array( 'arguments' => array('data' => NULL), ), + + // Theme functions in image.field.inc. + 'image_widget' => array( + 'arguments' => array('element' => NULL), + ), + 'field_formatter_image' => array( + 'arguments' => array('element' => NULL), + ), + 'field_formatter_image_link_content' => array( + 'arguments' => array('element' => NULL), + ), + 'field_formatter_image_link_file' => array( + 'arguments' => array('element' => NULL), + ), ); } @@ -464,7 +484,7 @@ function image_style_generate() { // acquiring the lock. $success = file_exists($destination) || image_style_create_derivative($style, $path, $destination); - if ($lock_acquired) { + if (!empty($lock_acquired)) { lock_release($lock_name); } @@ -773,6 +793,7 @@ function image_effect_delete($effect) { * TRUE on success. FALSE if unable to perform the image effect on the image. */ function image_effect_apply($image, $effect) { + module_load_include('inc', 'image', 'image.effects'); if (function_exists($effect['effect callback'])) { return call_user_func($effect['effect callback'], $image, $effect['data']); } @@ -810,7 +831,7 @@ function theme_image_style($style_name, $path, $alt = '', $title = '', $attribut if (!file_exists($style_path)) { $style_path = image_style_url($style_name, $path); } - return theme('image', file_create_url($style_path), $alt, $title, $attributes, $getsize); + return theme('image', $style_path, $alt, $title, $attributes, $getsize); } /**