function copy_resource($from, $resource_type = -1)
{
    # Create a new resource, copying all data from the resource with reference $from.
    # Note this copies only the data and not any attached file. It's very unlikely the
    # same file would be in the system twice, however users may want to clone an existing resource
    # to avoid reentering data if the resource is very similar.
    # If $resource_type if specified then the resource type for the new resource will be set to $resource_type
    # rather than simply copied from the $from resource.
    # Check that the resource exists
    if (sql_value("select count(*) value from resource where ref='{$from}'", 0) == 0) {
        return false;
    }
    # copy joined fields to the resource column
    $joins = get_resource_table_joins();
    // Filter the joined columns so we only have the ones relevant to this resource type
    $query = sprintf('
			    SELECT rtf.ref AS value
			      FROM resource_type_field AS rtf
			INNER JOIN resource AS r ON (rtf.resource_type != r.resource_type AND rtf.resource_type != 0)
			     WHERE r.ref = "%s";
		', $from);
    $irrelevant_rtype_fields = sql_array($query);
    $irrelevant_rtype_fields = array_values(array_intersect($joins, $irrelevant_rtype_fields));
    $filtered_joins = array_values(array_diff($joins, $irrelevant_rtype_fields));
    $joins_sql = "";
    foreach ($filtered_joins as $join) {
        $joins_sql .= ",field{$join} ";
    }
    $add = "";
    # Determine if the user has access to the template archive status
    $archive = sql_value("select archive value from resource where ref='{$from}'", 0);
    if (!checkperm("e" . $archive)) {
        # Find the right permission mode to use
        for ($n = -2; $n < 3; $n++) {
            if (checkperm("e" . $n)) {
                $archive = $n;
                break;
            }
        }
    }
    # First copy the resources row
    sql_query("insert into resource({$add} resource_type,creation_date,rating,archive,access,created_by {$joins_sql}) select {$add}" . ($resource_type == -1 ? "resource_type" : "'" . $resource_type . "'") . ",now(),rating,'" . $archive . "',access,created_by {$joins_sql} from resource where ref='{$from}';");
    $to = sql_insert_id();
    # Set that this resource was created by this user.
    # This needs to be done if either:
    # 1) The user does not have direct 'resource create' permissions and is therefore contributing using My Contributions directly into the active state
    # 2) The user is contributiting via My Contributions to the standard User Contributed pre-active states.
    global $userref;
    global $always_record_resource_creator;
    if (!checkperm("c") || $archive < 0 || isset($always_record_resource_creator) && $always_record_resource_creator) {
        # Update the user record
        sql_query("update resource set created_by='{$userref}' where ref='{$to}'");
        # Also add the user's username and full name to the keywords index so the resource is searchable using this name.
        global $username, $userfullname;
        add_keyword_mappings($to, $username . " " . $userfullname, -1);
    }
    # Now copy all data
    sql_query("insert into resource_data(resource,resource_type_field,value) select '{$to}',rd.resource_type_field,rd.value from resource_data rd join resource r on rd.resource=r.ref join resource_type_field rtf on rd.resource_type_field=rtf.ref and (rtf.resource_type=r.resource_type or rtf.resource_type=999 or rtf.resource_type=0) where rd.resource='{$from}'");
    # Copy relationships
    sql_query("insert into resource_related(resource,related) select '{$to}',related from resource_related where resource='{$from}'");
    # Copy access
    sql_query("insert into resource_custom_access(resource,usergroup,access) select '{$to}',usergroup,access from resource_custom_access where resource='{$from}'");
    # Set any resource defaults
    set_resource_defaults($to);
    # Autocomplete any blank fields.
    autocomplete_blank_fields($to);
    # Reindex the resource so the resource_keyword entries are created
    reindex_resource($to);
    # Copying a resource of the 'pending review' state? Notify, if configured.
    global $send_collection_to_admin;
    if ($archive == -1 && !$send_collection_to_admin) {
        notify_user_contributed_submitted(array($to));
    }
    # Log this
    daily_stat("Create resource", $to);
    resource_log($to, 'c', 0);
    hook("afternewresource", "", array($to));
    return $to;
}
function save_resource_data($ref,$multi)
	{
	# Save all submitted data for resource $ref.
	# Also re-index all keywords from indexable fields.
		
	global $auto_order_checkbox,$userresourcedefaults,$multilingual_text_fields,$languages,$language;

	hook("befsaveresourcedata", "", array($ref));

	# save resource defaults
	# (do this here so that user can override them if the fields are visible.)
	set_resource_defaults($ref);	 

	# Loop through the field data and save (if necessary)
	$errors=array();
	$fields=get_resource_field_data($ref,$multi);
	$expiry_field_edited=false;
	$resource_data=get_resource_data($ref);
		
	for ($n=0;$n<count($fields);$n++)
		{
		if (!(
		
		# Not if field has write access denied
		checkperm("F" . $fields[$n]["ref"])
		||
		(checkperm("F*") && !checkperm("F-" . $fields[$n]["ref"]))
			
		))
			{
			if ($fields[$n]["type"]==2)
				{
				# construct the value from the ticked boxes
				$val=","; # Note: it seems wrong to start with a comma, but this ensures it is treated as a comma separated list by split_keywords(), so if just one item is selected it still does individual word adding, so 'South Asia' is split to 'South Asia','South','Asia'.
				$options=trim_array(explode(",",$fields[$n]["options"]));

				for ($m=0;$m<count($options);$m++)
					{
					$name=$fields[$n]["ref"] . "_" . md5($options[$m]);
					if (getval($name,"")=="yes")
						{
						if ($val!=",") {$val.=",";}
						$val.=$options[$m];
						}
					}
				}
			elseif ($fields[$n]["type"]==4 || $fields[$n]["type"]==6 || $fields[$n]["type"]==10)
				{
				# date type, construct the value from the date/time dropdowns
				$val=sprintf("%04d", getvalescaped("field_" . $fields[$n]["ref"] . "-y",""));
				if ((int)$val<=0) 
					{
					$val="";
					}
				elseif (($field=getvalescaped("field_" . $fields[$n]["ref"] . "-m",""))!="") 
					{
					$val.="-" . $field;
					if (($field=getvalescaped("field_" . $fields[$n]["ref"] . "-d",""))!="") 
						{
						$val.="-" . $field;
						if (($field=getval("field_" . $fields[$n]["ref"] . "-h",""))!="")
							{
							$val.=" " . $field . ":";
							if (($field=getvalescaped("field_" . $fields[$n]["ref"] . "-i",""))!="") 
								{
									$val.=$field;
								} 
							else 
								{
									$val.="00";
								}
							}
						}
					}
				}
			elseif ($multilingual_text_fields && ($fields[$n]["type"]==0 || $fields[$n]["type"]==1 || $fields[$n]["type"]==5))
				{
				# Construct a multilingual string from the submitted translations
				$val=getvalescaped("field_" . $fields[$n]["ref"],"");
				$val="~" . $language . ":" . $val;
				reset ($languages);
				foreach ($languages as $langkey => $langname)
					{
					if ($language!=$langkey)
						{
						$val.="~" . $langkey . ":" . getvalescaped("multilingual_" . $n . "_" . $langkey,"");
						}
					}
				}
			elseif ($fields[$n]["type"] == 3)
				{
				$val=getvalescaped("field_" . $fields[$n]["ref"],"");				
				// if it doesn't already start with a comma, add one
				if (substr($val,0,1) != ',')
					{
					$val = ','.$val;
					}
				}
			else
				{
				# Set the value exactly as sent.
				$val=getvalescaped("field_" . $fields[$n]["ref"],"");
				} 
			
			# Check for regular expression match
			if (trim(strlen($fields[$n]["regexp_filter"]))>=1 && strlen($val)>0)
				{
				if(preg_match("#^" . $fields[$n]["regexp_filter"] . "$#",$val,$matches)<=0)
					{
					global $lang;
					debug($lang["information-regexp_fail"] . ": -" . "reg exp: " . $fields[$n]["regexp_filter"] . ". Value passed: " . $val);
					if (getval("autosave","")!="")
						{
						exit();
						}
					$errors[$fields[$n]["ref"]]=$lang["information-regexp_fail"] . " : " . $val;
					continue;
					}
				}
			
			if (str_replace("\r\n","\n",$fields[$n]["value"])!== str_replace("\r\n","\n",unescape($val)))
				{
				//$testvalue=$fields[$n]["value"];var_dump($testvalue);$val=unescape($val);var_dump($val);
				//echo "FIELD:".$fields[$n]["value"]."!==ORIG:".unescape($val); 
				
				# This value is different from the value we have on record.

				# Write this edit to the log (including the diff) (unescaped is safe because the diff is processed later)
				resource_log($ref,'e',$fields[$n]["ref"],"",$fields[$n]["value"],unescape($val));

				# Expiry field? Set that expiry date(s) have changed so the expiry notification flag will be reset later in this function.
				if ($fields[$n]["type"]==6) {$expiry_field_edited=true;}

				# If 'resource_column' is set, then we need to add this to a query to back-update
				# the related columns on the resource table
				$resource_column=$fields[$n]["resource_column"];	

				# Purge existing data and keyword mappings, decrease keyword hitcounts.
				sql_query("delete from resource_data where resource='$ref' and resource_type_field='" . $fields[$n]["ref"] . "'");
				
				# Insert new data and keyword mappings, increase keyword hitcounts.
				sql_query("insert into resource_data(resource,resource_type_field,value) values('$ref','" . $fields[$n]["ref"] . "','" . escape_check($val) ."')");
	
				$oldval=$fields[$n]["value"];
				
				if ($fields[$n]["type"]==3 && substr($oldval,0,1) != ',')
					{
					# Prepend a comma when indexing dropdowns
					$oldval="," . $oldval;
					}
				
				if ($fields[$n]["keywords_index"]==1)
					{
					# Date field? These need indexing differently.
					$is_date=($fields[$n]["type"]==4 || $fields[$n]["type"]==6);
					
					remove_keyword_mappings($ref, i18n_get_indexable($oldval), $fields[$n]["ref"], $fields[$n]["partial_index"],$is_date);
					add_keyword_mappings($ref, i18n_get_indexable($val), $fields[$n]["ref"], $fields[$n]["partial_index"],$is_date);
					}
				
					# If this is a 'joined' field we need to add it to the resource column
					$joins=get_resource_table_joins();
					if (in_array($fields[$n]["ref"],$joins)){
						$val=strip_leading_comma($val);	
						sql_query("update resource set field".$fields[$n]["ref"]."='".escape_check($val)."' where ref='$ref'");
					}	
				
				}
			
			# Check required fields have been entered.
			$exemptfields = getvalescaped("exemptfields","");
			$exemptfields = explode(",",$exemptfields);
			if ($fields[$n]["required"]==1 && ($val=="" || $val==",") && !in_array($fields[$n]["ref"],$exemptfields))
				{
				global $lang;
				$errors[$fields[$n]["ref"]]=i18n_get_translated($fields[$n]["title"]).": ".$lang["requiredfield"];
				}
			}
		}
    //die();
	# Always index the resource ID as a keyword
	remove_keyword_mappings($ref, $ref, -1);
	add_keyword_mappings($ref, $ref, -1);
	
	# Autocomplete any blank fields.
	autocomplete_blank_fields($ref);
	
	# Also save related resources field
	sql_query("delete from resource_related where resource='$ref' or related='$ref'"); # remove existing related items
	$related=explode(",",getvalescaped("related",""));
	# Make sure all submitted values are numeric
	$ok=array();for ($n=0;$n<count($related);$n++) {if (is_numeric(trim($related[$n]))) {$ok[]=trim($related[$n]);}}
	if (count($ok)>0) {sql_query("insert into resource_related(resource,related) values ($ref," . join("),(" . $ref . ",",$ok) . ")");}
					
	// Notify the resources team ($email_notify) if moving from pending review->submission.
	$archive=getvalescaped("archive",0,true);
	$oldarchive=sql_value("select archive value from resource where ref='$ref'",0);
	if ($oldarchive==-2 && $archive==-1 && $ref>0)
		{
		notify_user_contributed_submitted(array($ref));
		}
	if ($oldarchive==-1 && $archive==-2 && $ref>0)
		{
		notify_user_contributed_unsubmitted(array($ref));
		}	

	# Expiry field(s) edited? Reset the notification flag so that warnings are sent again when the date is reached.
	$expirysql="";
	if ($expiry_field_edited) {$expirysql=",expiry_notification_sent=0";}

	# Also update archive status and access level
	$oldaccess=sql_value("select access value from resource where ref='$ref'",0);
	$access=getvalescaped("access",$oldaccess,true);
	if (getvalescaped("archive","")!="") # Only if archive has been sent
		{
		sql_query("update resource set archive='" . $archive . "',access='" . $access . "' $expirysql where ref='$ref'");
		
		if ($archive!=$oldarchive)
			{
			resource_log($ref,"s",0,"",$oldarchive,$archive);
			}

		if ($access!=$oldaccess)
			{
			resource_log($ref,"a",0,"",$oldaccess,$access);
			}

		
		}
		
	# For access level 3 (custom) - also save custom permissions
	if (getvalescaped("access",0)==3) {save_resource_custom_access($ref);}

	# Update XML metadata dump file
	update_xml_metadump($ref);		
	
	hook("aftersaveresourcedata");

	if (count($errors)==0) {return true;} else {return $errors;}
	}
function extract_exif_comment($ref, $extension = "")
{
    # Extract the EXIF comment from either the ImageDescription field or the UserComment
    # Also parse IPTC headers and insert
    # EXIF headers
    $exifoption = getval("no_exif", "");
    // This may have been set to a non-standard value if allowing per field selection
    if ($exifoption == "yes") {
        $exifoption = "no";
    }
    // Sounds odd but previously was no_exif so logic reversed
    if ($exifoption == "") {
        $exifoption = "yes";
    }
    $image = get_resource_path($ref, true, "", false, $extension);
    if (!file_exists($image)) {
        return false;
    }
    hook("pdfsearch");
    global $exif_comment, $exiftool_no_process, $exiftool_resolution_calc, $disable_geocoding, $embedded_data_user_select_fields, $filename_field;
    $exiftool_fullpath = get_utility_path("exiftool");
    if ($exiftool_fullpath != false && !in_array($extension, $exiftool_no_process)) {
        $resource = get_resource_data($ref);
        # Field 8 is used in a special way for staticsync; don't overwrite.
        if ($resource['file_path'] != "") {
            $omit_title_for_staticsync = true;
        } else {
            $omit_title_for_staticsync = false;
        }
        hook("beforeexiftoolextraction");
        if ($exiftool_resolution_calc) {
            # see if we can use exiftool to get resolution/units, and dimensions here.
            # Dimensions are normally extracted once from the view page, but for the original file, it should be done here if possible,
            # and exiftool can provide more data.
            $command = $exiftool_fullpath . " -s -s -s -t -composite:imagesize -xresolution -resolutionunit " . escapeshellarg($image);
            $dimensions_resolution_unit = explode("\t", run_command($command));
            # if dimensions resolution and unit could be extracted, add them to the database.
            # they can be used in view.php to give more accurate data.
            if (count($dimensions_resolution_unit) == 3) {
                $dru = $dimensions_resolution_unit;
                $filesize = filesize_unlimited($image);
                $wh = explode("x", $dru[0]);
                $width = $wh[0];
                $height = $wh[1];
                $resolution = $dru[1];
                $unit = $dru[2];
                sql_query("insert into resource_dimensions (resource, width, height, resolution, unit, file_size) values ('{$ref}', '{$width}', '{$height}', '{$resolution}', '{$unit}', '{$filesize}')");
            }
        }
        $read_from = get_exiftool_fields($resource['resource_type']);
        # run exiftool to get all the valid fields. Use -s -s option so that
        # the command result isn't printed in columns, which will help in parsing
        # We then split the lines in the result into an array
        $command = $exiftool_fullpath . " -s -s -f -m -d \"%Y-%m-%d %H:%M:%S\" -G " . escapeshellarg($image);
        $metalines = explode("\n", run_command($command));
        $metadata = array();
        # an associative array to hold metadata field/value pairs
        # go through each line and split field/value using the first
        # occurrance of ": ".  The keys in the associative array is converted
        # into uppercase for easier lookup later
        foreach ($metalines as $metaline) {
            # Use stripos() if available, but support earlier PHP versions if not.
            if (function_exists("stripos")) {
                $pos = stripos($metaline, ": ");
            } else {
                $pos = strpos($metaline, ": ");
            }
            if ($pos) {
                # add to the associative array, also clean up leading/trailing space & single quote (on windows sometimes)
                # Extract group name and tag name.
                $s = explode("]", substr($metaline, 0, $pos));
                if (count($s) > 1 && strlen($s[0]) > 1) {
                    # Extract value
                    $value = trim(substr($metaline, $pos + 2));
                    # Replace '..' with line feed - either Exiftool itself or Adobe Bridge replaces line feeds with '..'
                    $value = str_replace('....', '\\n\\n', $value);
                    // Two new line feeds in ExifPro are replaced with 4 dots '....'
                    $value = str_replace('...', '.\\n', $value);
                    # Three dots together is interpreted as a full stop then line feed, not the other way round
                    $value = str_replace('..', '\\n', $value);
                    # Extract group name and tag name
                    $groupname = strtoupper(substr($s[0], 1));
                    $tagname = strtoupper(trim($s[1]));
                    # Store both tag data under both tagname and groupname:tagname, to support both formats when mapping fields.
                    $metadata[$tagname] = $value;
                    $metadata[$groupname . ":" . $tagname] = $value;
                    debug("Exiftool: extracted field '{$groupname}:{$tagname}', value is '{$value}'");
                }
            }
        }
        // We try to fetch the original filename from database.
        $resources = sql_query("SELECT resource.file_path FROM resource WHERE resource.ref = " . $ref);
        if ($resources) {
            $resource = $resources[0];
            if ($resource['file_path']) {
                $metadata['FILENAME'] = mb_basename($resource['file_path']);
            }
        }
        if (isset($metadata['FILENAME'])) {
            $metadata['STRIPPEDFILENAME'] = strip_extension($metadata['FILENAME']);
        }
        # Geolocation Metadata Support
        if (!$disable_geocoding && isset($metadata['GPSLATITUDE'])) {
            # Set vars
            $dec_long = 0;
            $dec_lat = 0;
            #Convert latititude to decimal.
            if (preg_match("/^(?<degrees>\\d+) deg (?<minutes>\\d+)' (?<seconds>\\d+\\.?\\d*)\"/", $metadata['GPSLATITUDE'], $latitude)) {
                $dec_lat = $latitude['degrees'] + $latitude['minutes'] / 60 + $latitude['seconds'] / (60 * 60);
            }
            if (preg_match("/^(?<degrees>\\d+) deg (?<minutes>\\d+)' (?<seconds>\\d+\\.?\\d*)\"/", $metadata['GPSLONGITUDE'], $longitude)) {
                $dec_long = $longitude['degrees'] + $longitude['minutes'] / 60 + $longitude['seconds'] / (60 * 60);
            }
            if (strpos($metadata['GPSLATITUDE'], 'S') !== false) {
                $dec_lat = -1 * $dec_lat;
            }
            if (strpos($metadata['GPSLONGITUDE'], 'W') !== false) {
                $dec_long = -1 * $dec_long;
            }
            if ($dec_long != 0 && $dec_lat != 0) {
                sql_query("update resource set geo_long='" . escape_check($dec_long) . "',geo_lat='" . escape_check($dec_lat) . "' where ref='{$ref}'");
            }
        }
        # Update portrait_landscape_field (when reverting metadata this was getting lost)
        update_portrait_landscape_field($ref);
        # now we lookup fields from the database to see if a corresponding value
        # exists in the uploaded file
        $exif_updated_fields = array();
        for ($i = 0; $i < count($read_from); $i++) {
            $field = explode(",", $read_from[$i]['exiftool_field']);
            foreach ($field as $subfield) {
                $subfield = strtoupper($subfield);
                // convert to upper case for easier comparision
                if (in_array($subfield, array_keys($metadata)) && $metadata[$subfield] != "-" && trim($metadata[$subfield]) != "") {
                    $read = true;
                    $value = $metadata[$subfield];
                    # Dropdown box or checkbox list?
                    if ($read_from[$i]["type"] == 2 || $read_from[$i]["type"] == 3) {
                        # Check that the value is one of the options and only insert if it is an exact match.
                        # The use of safe_file_name and strtolower ensures matching takes place on alphanumeric characters only and ignores case.
                        # First fetch all options in all languages
                        $options = trim_array(explode(",", strtolower($read_from[$i]["options"])));
                        for ($n = 0; $n < count($options); $n++) {
                            $options[$n] = $options[$n];
                        }
                        # If not in the options list, do not read this value
                        $s = trim_array(explode(",", $value));
                        $value = "";
                        # blank value
                        for ($n = 0; $n < count($s); $n++) {
                            if (trim($s[0]) != "" && in_array(strtolower($s[$n]), $options)) {
                                $value .= "," . $s[$n];
                            }
                        }
                        #echo($read_from[$i]["ref"] . " = " . $value . "<br>");
                    }
                    # Read the data.
                    if ($read) {
                        $plugin = dirname(__FILE__) . "/../plugins/exiftool_filter_" . $read_from[$i]['name'] . ".php";
                        if ($read_from[$i]['exiftool_filter'] != "") {
                            eval($read_from[$i]['exiftool_filter']);
                        }
                        if (file_exists($plugin)) {
                            include $plugin;
                        }
                        # Field 8 is used in a special way for staticsync; don't overwrite field 8 in this case
                        if (!($omit_title_for_staticsync && $read_from[$i]['ref'] == 8)) {
                            $exiffieldoption = $exifoption;
                            if ($exifoption == "custom" || isset($embedded_data_user_select_fields) && in_array($read_from[$i]['ref'], $embedded_data_user_select_fields)) {
                                debug("EXIF - custom option for field " . $read_from[$i]['ref'] . " : " . $exifoption);
                                $exiffieldoption = getval("exif_option_" . $read_from[$i]['ref'], $exifoption);
                            }
                            debug("EXIF - option for field " . $read_from[$i]['ref'] . " : " . $exiffieldoption);
                            if ($exiffieldoption == "no") {
                                continue;
                            } elseif ($exiffieldoption == "append") {
                                $spacechar = $read_from[$i]["type"] == 2 || $read_from[$i]["type"] == 3 ? ", " : " ";
                                $oldval = get_data_by_field($ref, $read_from[$i]['ref']);
                                if (strpos($oldval, $value) !== false) {
                                    continue;
                                }
                                $newval = $oldval . $spacechar . iptc_return_utf8($value);
                            } elseif ($exiffieldoption == "prepend") {
                                $spacechar = $read_from[$i]["type"] == 2 || $read_from[$i]["type"] == 3 ? ", " : " ";
                                $oldval = get_data_by_field($ref, $read_from[$i]['ref']);
                                if (strpos($oldval, $value) !== false) {
                                    continue;
                                }
                                $newval = iptc_return_utf8($value) . $spacechar . $oldval;
                            } else {
                                $newval = iptc_return_utf8($value);
                            }
                            global $merge_filename_with_title, $lang;
                            if ($merge_filename_with_title) {
                                $merge_filename_with_title_option = urlencode(getval('merge_filename_with_title_option', ''));
                                $merge_filename_with_title_include_extensions = urlencode(getval('merge_filename_with_title_include_extensions', ''));
                                $merge_filename_with_title_spacer = urlencode(getval('merge_filename_with_title_spacer', ''));
                                $original_filename = '';
                                if (isset($_REQUEST['name'])) {
                                    $original_filename = $_REQUEST['name'];
                                } else {
                                    $original_filename = $processfile['name'];
                                }
                                if ($merge_filename_with_title_include_extensions == 'yes') {
                                    $merged_filename = $original_filename;
                                } else {
                                    $merged_filename = strip_extension($original_filename);
                                }
                                $oldval = get_data_by_field($ref, $read_from[$i]['ref']);
                                if (strpos($oldval, $value) !== FALSE) {
                                    continue;
                                }
                                switch ($merge_filename_with_title_option) {
                                    case $lang['merge_filename_title_do_not_use']:
                                        // Do nothing since the user doesn't want to use this feature
                                        break;
                                    case $lang['merge_filename_title_replace']:
                                        $newval = $merged_filename;
                                        break;
                                    case $lang['merge_filename_title_prefix']:
                                        $newval = $merged_filename . $merge_filename_with_title_spacer . $oldval;
                                        if ($oldval == '') {
                                            $newval = $merged_filename;
                                        }
                                        break;
                                    case $lang['merge_filename_title_suffix']:
                                        $newval = $oldval . $merge_filename_with_title_spacer . $merged_filename;
                                        if ($oldval == '') {
                                            $newval = $merged_filename;
                                        }
                                        break;
                                    default:
                                        // Do nothing
                                        break;
                                }
                            }
                            update_field($ref, $read_from[$i]['ref'], $newval);
                            $exif_updated_fields[] = $read_from[$i]['ref'];
                            hook("metadata_extract_addition", "all", array($ref, $newval, $read_from, $i));
                        }
                    }
                } else {
                    // Process if no embedded title is found:
                    global $merge_filename_with_title, $lang;
                    if ($merge_filename_with_title && $read_from[$i]['ref'] == 8) {
                        $merge_filename_with_title_option = urlencode(getval('merge_filename_with_title_option', ''));
                        $merge_filename_with_title_include_extensions = urlencode(getval('merge_filename_with_title_include_extensions', ''));
                        $merge_filename_with_title_spacer = urlencode(getval('merge_filename_with_title_spacer', ''));
                        $original_filename = '';
                        if (isset($_REQUEST['name'])) {
                            $original_filename = $_REQUEST['name'];
                        } else {
                            $original_filename = $processfile['name'];
                        }
                        if ($merge_filename_with_title_include_extensions == 'yes') {
                            $merged_filename = $original_filename;
                        } else {
                            $merged_filename = strip_extension($original_filename);
                        }
                        $oldval = get_data_by_field($ref, $read_from[$i]['ref']);
                        if (strpos($oldval, $value) !== FALSE) {
                            continue;
                        }
                        switch ($merge_filename_with_title_option) {
                            case $lang['merge_filename_title_do_not_use']:
                                // Do nothing since the user doesn't want to use this feature
                                break;
                            case $lang['merge_filename_title_replace']:
                                $newval = $merged_filename;
                                break;
                            case $lang['merge_filename_title_prefix']:
                                $newval = $merged_filename . $merge_filename_with_title_spacer . $oldval;
                                if ($oldval == '') {
                                    $newval = $merged_filename;
                                }
                                break;
                            case $lang['merge_filename_title_suffix']:
                                $newval = $oldval . $merge_filename_with_title_spacer . $merged_filename;
                                if ($oldval == '') {
                                    $newval = $merged_filename;
                                }
                                break;
                            default:
                                // Do nothing
                                break;
                        }
                        update_field($ref, $read_from[$i]['ref'], $newval);
                        $exif_updated_fields[] = $read_from[$i]['ref'];
                    }
                }
            }
        }
        if (!in_array($filename_field, $exif_updated_fields)) {
            $exiffilenameoption = getval("exif_option_" . $filename_field, $exifoption);
            debug("EXIF - custom option for filename field " . $filename_field . " : " . $exiffilenameoption);
            if ($exiffilenameoption != "yes") {
                $uploadedfilename = isset($_REQUEST['name']) ? $_REQUEST['name'] : $processfile['name'];
                global $userref, $amended_filename;
                $entered_filename = get_data_by_field(-$userref, $filename_field);
                debug("EXIF - got entered file name " . $entered_filename);
                if ($exiffilenameoption == "no") {
                    $amended_filename = $entered_filename;
                    if (trim($amended_filename) == '') {
                        $amended_filename = $uploadedfilename;
                    }
                    if (strpos($amended_filename, $extension) === FALSE) {
                        $amended_filename .= '.' . $extension;
                    }
                } elseif ($exiffilenameoption == "append") {
                    $amended_filename = $entered_filename . $uploadedfilename;
                } elseif ($exiffilenameoption == "prepend") {
                    $amended_filename = strip_extension($uploadedfilename) . $entered_filename . "." . $extension;
                }
                debug("EXIF - created new file name " . $amended_filename);
            }
        }
    } elseif (isset($exif_comment)) {
        #
        # Exiftool is not installed. As a fallback we grab some predefined basic fields using the PHP function
        # exif_read_data()
        #
        if (function_exists("exif_read_data")) {
            $data = @exif_read_data($image);
        } else {
            $data = false;
        }
        if ($data !== false) {
            $comment = "";
            #echo "<pre>EXIF\n";print_r($data);exit();
            if (isset($data["ImageDescription"])) {
                $comment = $data["ImageDescription"];
            }
            if ($comment == "" && isset($data["COMPUTED"]["UserComment"])) {
                $comment = $data["COMPUTED"]["UserComment"];
            }
            if ($comment != "") {
                # Convert to UTF-8
                $comment = iptc_return_utf8($comment);
                # Save comment
                global $exif_comment;
                update_field($ref, $exif_comment, $comment);
            }
            if (isset($data["Model"])) {
                # Save camera make/model
                global $exif_model;
                update_field($ref, $exif_model, $data["Model"]);
            }
            if (isset($data["DateTimeOriginal"])) {
                # Save camera date/time
                global $exif_date;
                $date = $data["DateTimeOriginal"];
                # Reformat date to ISO standard
                $date = substr($date, 0, 4) . "-" . substr($date, 5, 2) . "-" . substr($date, 8, 11);
                update_field($ref, $exif_date, $date);
            }
        }
        # Try IPTC headers
        $size = getimagesize($image, $info);
        if (isset($info["APP13"])) {
            $iptc = iptcparse($info["APP13"]);
            #echo "<pre>IPTC\n";print_r($iptc);exit();
            # Look for iptc fields, and insert.
            $fields = sql_query("select * from resource_type_field where length(iptc_equiv)>0");
            for ($n = 0; $n < count($fields); $n++) {
                $iptc_equiv = $fields[$n]["iptc_equiv"];
                if (isset($iptc[$iptc_equiv][0])) {
                    # Found the field
                    if (count($iptc[$iptc_equiv]) > 1) {
                        # Multiple values (keywords)
                        $value = "";
                        for ($m = 0; $m < count($iptc[$iptc_equiv]); $m++) {
                            if ($m > 0) {
                                $value .= ", ";
                            }
                            $value .= $iptc[$iptc_equiv][$m];
                        }
                    } else {
                        $value = $iptc[$iptc_equiv][0];
                    }
                    $value = iptc_return_utf8($value);
                    # Date parsing
                    if ($fields[$n]["type"] == 4) {
                        $value = substr($value, 0, 4) . "-" . substr($value, 4, 2) . "-" . substr($value, 6, 2);
                    }
                    if (trim($value) != "") {
                        update_field($ref, $fields[$n]["ref"], $value);
                    }
                }
            }
        }
    }
    # Update the XML metadata dump file.
    update_xml_metadump($ref);
    # Auto fill any blank fields.
    autocomplete_blank_fields($ref);
}