Collections functions
Encryption functions
General functions
Theme permission functions
Resource functions

write_metadata()

Parameters

ColumnTypeDefaultDescription
$path
$ref
$uniqid ""

Location

include/resource_functions.php lines 3550 to 3723

Definition

 
function write_metadata($path$ref$uniqid="")
    {
    
// copys the file to tmp and runs exiftool on it    
    // uniqid tells the tmp file to be placed in an isolated folder within tmp
    
global $exiftool_remove_existing$storagedir$exiftool_write$exiftool_write_option$exiftool_no_process$mysql_charset$exiftool_write_omit_utf8_conversion;

    
# Fetch file extension and resource type.
    
$resource_data=get_resource_data($ref);
    
$extension=$resource_data["file_extension"];
    
$resource_type=$resource_data["resource_type"];

    
$exiftool_fullpath get_utility_path("exiftool");

    
# Check if an attempt to write the metadata shall be performed.
    
if(false != $exiftool_fullpath && $exiftool_write && $exiftool_write_option && !in_array($extension$exiftool_no_process))
        {
        
// Trust Exiftool's list of writable formats 
        
$writable_formats run_command("{$exiftool_fullpath} -listwf");
        
$writable_formats str_replace("\n"""$writable_formats);
        
$writable_formats_array explode(" "$writable_formats);
        if(!
in_array(strtoupper($extension), $writable_formats_array))
            {
            return 
false;
            }

        
$tmpfile createTempFile($path$uniqid'');
        if(
$tmpfile === false)
            {
            return 
false;
            }

        
# Add the call to exiftool and some generic arguments to the command string.
        # Argument -overwrite_original: Now that we have already copied the original file, we can use exiftool's overwrite_original on the tmpfile.
        # Argument -E: Escape values for HTML. Used for handling foreign characters in shells not using UTF-8.
        # Arguments -EXIF:all= -XMP:all= -IPTC:all=: Remove the metadata in the tag groups EXIF, XMP and IPTC.
        
$command $exiftool_fullpath " -m -overwrite_original -E ";
        if(
$exiftool_remove_existing)
            {
            
$command stripMetadata(null) . ' ';
            }

        
$metadata_all=get_resource_field_data($reffalse,true,NULL,getval("k","")!=""); // Using get_resource_field_data means we honour field permissions
        
$read_only_fields array_column(array_filter($metadata_all, function($value) {
            return ((bool) 
$value['read_only'] == true);
        }), 
'ref');

        
$write_to=array();
        foreach(
$metadata_all as $metadata_item)
            {
            if(
trim($metadata_item["exiftool_field"]) != "" && !in_array($metadata_item['ref'], $read_only_fields))
                {
                
$write_to[] = $metadata_item;
                }
            }

        
$writtenfields=array(); // Need to check if we are writing to an embedded field from more than one RS field, in which case subsequent values need to be appended, not replaced
           
        
for($i 0$i<count($write_to); $i++) # Loop through all the found fields.
        
{
            
$fieldtype $write_to[$i]['type'];
            
$writevalue $write_to[$i]['value'];
            
# Formatting and cleaning of the value to be written - depending on the RS field type.
            
switch ($fieldtype)
                {
                case 
2:
                case 
3:
                case 
9:
                case 
12:
                    
# Check box list, drop down, radio buttons or dynamic keyword list: remove initial comma if present
                    
if (substr($writevalue01)==",") {$writevalue substr($writevalue1);}
                    break;                   
                case 
4:
                case 
6:
                case 
10:
                    
# Date / Expiry Date: write datetype fields in exiftool preferred format
                    
if($writevalue!='')
                        {
                        
$writevalue_to_time=strtotime($writevalue);
                        if(
$writevalue_to_time!='')
                            {
                            
$writevalue date("Y:m:d H:i:sP"strtotime($writevalue));
                            }
                        }                
                    break;
                    
# Other types, already set
                
}
            
$filtervalue=hook("additionalmetadatafilter""", Array($write_to[$i]["exiftool_field"], $writevalue));
            if (
$filtervalue$writevalue=$filtervalue;
            
# Add the tag name(s) and the value to the command string.
            
$group_tags explode(","$write_to[$i]['exiftool_field']); # Each 'exiftool field' may contain more than one tag.
            
foreach ($group_tags as $group_tag)
                {                
                
$group_tag strtolower($group_tag); # E.g. IPTC:Keywords -> iptc:keywords
                
if (strpos($group_tag,":")===false) {$tag $group_tag;} # E.g. subject -> subject
                
else {$tag substr($group_tagstrpos($group_tag,":")+1);} # E.g. iptc:keywords -> keywords
                
                
$exifappend=false// Need to replace values by default
                
if(isset($writtenfields[$group_tag])) 
                        { 
                        
// This embedded field is already being updated, we need to append values from this field                          
                        
$exifappend=true;
                        
debug("write_metadata - more than one field mappped to the tag '" $group_tag "'. Enabling append mode for this tag. ");
                        }
                        
                switch (
$tag)
                    {
                    case 
"filesize":
                        
# Do nothing, no point to try to write the filesize.
                        
break;
                    case 
"filename":
                        
# Do nothing, no point to try to write the filename either as ResourceSpace controls this.
                        
break;
                    case 
"directory":
                        
# Do nothing, we don't want metadata to control this
                        
break;
                    case 
"keywords":                  
                        
# Keywords shall be written one at a time and not all together.
                        
if(!isset($writtenfields["keywords"])){$writtenfields["keywords"]="";} 
                        
$keywords explode(","$writevalue); # "keyword1,keyword2, keyword3" (with or without spaces)
                        
if (implode(""$keywords) != "")
                            {
                            
# Only write non-empty keywords/ may be more than one field mapped to keywords so we don't want to overwrite with blank
                            
foreach ($keywords as $keyword)
                                {
                                
$keyword trim($keyword);
                                if (
$keyword != "")
                                    {    
                                    
debug("write_metadata - writing keyword:" $keyword);
                                    
$writtenfields[$group_tag].="," $keyword;
                                         
                                    
# Convert the data to UTF-8 if not already.
                                    
if (!$exiftool_write_omit_utf8_conversion && (!isset($mysql_charset) || (isset($mysql_charset) && strtolower($mysql_charset)!="utf8"))){$keyword mb_convert_encoding($keywordmb_detect_encoding($keyword), 'UTF-8');}
                                    
$command.= escapeshellarg("-" $group_tag "-=" htmlentities($keywordENT_QUOTES"UTF-8")) . " "// In case value is already embedded, need to manually remove it to prevent duplication
                                    
$command.= escapeshellarg("-" $group_tag "+=" htmlentities($keywordENT_QUOTES"UTF-8")) . " ";
                                    }
                                }
                            }
                        break;
                    default:
                        if(
$exifappend && ($writevalue=="" || ($writevalue!="" && strpos($writtenfields[$group_tag],$writevalue)!==false)))
                            {                                                            
                            
// The new value is blank or already included in what is being written, skip to next group tag
                            
continue 2# @see https://www.php.net/manual/en/control-structures.continue.php note
                            
}                               
                        
$writtenfields[$group_tag]=$writevalue;                          
                        
debug ("write_metadata - updating tag " $group_tag);
                        
# Write as is, convert the data to UTF-8 if not already.
                        
                        
global $strip_rich_field_tags;
                        if (!
$exiftool_write_omit_utf8_conversion && (!isset($mysql_charset) || (isset($mysql_charset) && strtolower($mysql_charset)!="utf8"))){$writevalue mb_convert_encoding($writevaluemb_detect_encoding($writevalue), 'UTF-8');}
                            if (
$strip_rich_field_tags)
                            {
                                
$command.= escapeshellarg("-" $group_tag "=" trim(strip_tags(i18n_get_translated($writevalue,false)))) . " ";
                            }
                            else
                            {
                                
$command.= escapeshellarg("-" $group_tag "=" htmlentities(i18n_get_translated($writevalue), ENT_QUOTES"UTF-8")) . " ";
                            }
                    }
                }
            }
            
            
# Add the filename to the command string.
            
$command.= " " escapeshellarg($tmpfile);
            
            
# Perform the actual writing - execute the command string.
            
$output run_command($command);
        return 
$tmpfile;
       }
    else
        {
        return 
false;
        }
    }

This article was last updated 10th July 2020 23:35 Europe/London time based on the source file dated 10th July 2020 16:06 Europe/London time.