/** * Converts all accent characters to ASCII characters. * * If there are no accent characters, then the string given is just returned. * * @param string $string Text that might have accent characters * @return string Filtered string with replaced "nice" characters. */ function caRemoveAccents($string) { if (!preg_match('/[\\x80-\\xff]/', $string)) { return $string; } if (caSeemsUTF8($string)) { $chars = array(chr(195) . chr(128) => 'A', chr(195) . chr(129) => 'A', chr(195) . chr(130) => 'A', chr(195) . chr(131) => 'A', chr(195) . chr(132) => 'A', chr(195) . chr(133) => 'A', chr(195) . chr(135) => 'C', chr(195) . chr(136) => 'E', chr(195) . chr(137) => 'E', chr(195) . chr(138) => 'E', chr(195) . chr(139) => 'E', chr(195) . chr(140) => 'I', chr(195) . chr(141) => 'I', chr(195) . chr(142) => 'I', chr(195) . chr(143) => 'I', chr(195) . chr(145) => 'N', chr(195) . chr(146) => 'O', chr(195) . chr(147) => 'O', chr(195) . chr(148) => 'O', chr(195) . chr(149) => 'O', chr(195) . chr(150) => 'O', chr(195) . chr(153) => 'U', chr(195) . chr(154) => 'U', chr(195) . chr(155) => 'U', chr(195) . chr(156) => 'U', chr(195) . chr(157) => 'Y', chr(195) . chr(159) => 's', chr(195) . chr(160) => 'a', chr(195) . chr(161) => 'a', chr(195) . chr(162) => 'a', chr(195) . chr(163) => 'a', chr(195) . chr(164) => 'a', chr(195) . chr(165) => 'a', chr(195) . chr(167) => 'c', chr(195) . chr(168) => 'e', chr(195) . chr(169) => 'e', chr(195) . chr(170) => 'e', chr(195) . chr(171) => 'e', chr(195) . chr(172) => 'i', chr(195) . chr(173) => 'i', chr(195) . chr(174) => 'i', chr(195) . chr(175) => 'i', chr(195) . chr(177) => 'n', chr(195) . chr(178) => 'o', chr(195) . chr(179) => 'o', chr(195) . chr(180) => 'o', chr(195) . chr(181) => 'o', chr(195) . chr(182) => 'o', chr(195) . chr(182) => 'o', chr(195) . chr(185) => 'u', chr(195) . chr(186) => 'u', chr(195) . chr(187) => 'u', chr(195) . chr(188) => 'u', chr(195) . chr(189) => 'y', chr(195) . chr(191) => 'y', chr(196) . chr(128) => 'A', chr(196) . chr(129) => 'a', chr(196) . chr(130) => 'A', chr(196) . chr(131) => 'a', chr(196) . chr(132) => 'A', chr(196) . chr(133) => 'a', chr(196) . chr(134) => 'C', chr(196) . chr(135) => 'c', chr(196) . chr(136) => 'C', chr(196) . chr(137) => 'c', chr(196) . chr(138) => 'C', chr(196) . chr(139) => 'c', chr(196) . chr(140) => 'C', chr(196) . chr(141) => 'c', chr(196) . chr(142) => 'D', chr(196) . chr(143) => 'd', chr(196) . chr(144) => 'D', chr(196) . chr(145) => 'd', chr(196) . chr(146) => 'E', chr(196) . chr(147) => 'e', chr(196) . chr(148) => 'E', chr(196) . chr(149) => 'e', chr(196) . chr(150) => 'E', chr(196) . chr(151) => 'e', chr(196) . chr(152) => 'E', chr(196) . chr(153) => 'e', chr(196) . chr(154) => 'E', chr(196) . chr(155) => 'e', chr(196) . chr(156) => 'G', chr(196) . chr(157) => 'g', chr(196) . chr(158) => 'G', chr(196) . chr(159) => 'g', chr(196) . chr(160) => 'G', chr(196) . chr(161) => 'g', chr(196) . chr(162) => 'G', chr(196) . chr(163) => 'g', chr(196) . chr(164) => 'H', chr(196) . chr(165) => 'h', chr(196) . chr(166) => 'H', chr(196) . chr(167) => 'h', chr(196) . chr(168) => 'I', chr(196) . chr(169) => 'i', chr(196) . chr(170) => 'I', chr(196) . chr(171) => 'i', chr(196) . chr(172) => 'I', chr(196) . chr(173) => 'i', chr(196) . chr(174) => 'I', chr(196) . chr(175) => 'i', chr(196) . chr(176) => 'I', chr(196) . chr(177) => 'i', chr(196) . chr(178) => 'IJ', chr(196) . chr(179) => 'ij', chr(196) . chr(180) => 'J', chr(196) . chr(181) => 'j', chr(196) . chr(182) => 'K', chr(196) . chr(183) => 'k', chr(196) . chr(184) => 'k', chr(196) . chr(185) => 'L', chr(196) . chr(186) => 'l', chr(196) . chr(187) => 'L', chr(196) . chr(188) => 'l', chr(196) . chr(189) => 'L', chr(196) . chr(190) => 'l', chr(196) . chr(191) => 'L', chr(197) . chr(128) => 'l', chr(197) . chr(129) => 'L', chr(197) . chr(130) => 'l', chr(197) . chr(131) => 'N', chr(197) . chr(132) => 'n', chr(197) . chr(133) => 'N', chr(197) . chr(134) => 'n', chr(197) . chr(135) => 'N', chr(197) . chr(136) => 'n', chr(197) . chr(137) => 'N', chr(197) . chr(138) => 'n', chr(197) . chr(139) => 'N', chr(197) . chr(140) => 'O', chr(197) . chr(141) => 'o', chr(197) . chr(142) => 'O', chr(197) . chr(143) => 'o', chr(197) . chr(144) => 'O', chr(197) . chr(145) => 'o', chr(197) . chr(146) => 'OE', chr(197) . chr(147) => 'oe', chr(197) . chr(148) => 'R', chr(197) . chr(149) => 'r', chr(197) . chr(150) => 'R', chr(197) . chr(151) => 'r', chr(197) . chr(152) => 'R', chr(197) . chr(153) => 'r', chr(197) . chr(154) => 'S', chr(197) . chr(155) => 's', chr(197) . chr(156) => 'S', chr(197) . chr(157) => 's', chr(197) . chr(158) => 'S', chr(197) . chr(159) => 's', chr(197) . chr(160) => 'S', chr(197) . chr(161) => 's', chr(197) . chr(162) => 'T', chr(197) . chr(163) => 't', chr(197) . chr(164) => 'T', chr(197) . chr(165) => 't', chr(197) . chr(166) => 'T', chr(197) . chr(167) => 't', chr(197) . chr(168) => 'U', chr(197) . chr(169) => 'u', chr(197) . chr(170) => 'U', chr(197) . chr(171) => 'u', chr(197) . chr(172) => 'U', chr(197) . chr(173) => 'u', chr(197) . chr(174) => 'U', chr(197) . chr(175) => 'u', chr(197) . chr(176) => 'U', chr(197) . chr(177) => 'u', chr(197) . chr(178) => 'U', chr(197) . chr(179) => 'u', chr(197) . chr(180) => 'W', chr(197) . chr(181) => 'w', chr(197) . chr(182) => 'Y', chr(197) . chr(183) => 'y', chr(197) . chr(184) => 'Y', chr(197) . chr(185) => 'Z', chr(197) . chr(186) => 'z', chr(197) . chr(187) => 'Z', chr(197) . chr(188) => 'z', chr(197) . chr(189) => 'Z', chr(197) . chr(190) => 'z', chr(197) . chr(191) => 's', chr(226) . chr(130) . chr(172) => 'E', chr(194) . chr(163) => ''); $string = strtr($string, $chars); } else { // Assume ISO-8859-1 if not UTF-8 $chars['in'] = chr(128) . chr(131) . chr(138) . chr(142) . chr(154) . chr(158) . chr(159) . chr(162) . chr(165) . chr(181) . chr(192) . chr(193) . chr(194) . chr(195) . chr(196) . chr(197) . chr(199) . chr(200) . chr(201) . chr(202) . chr(203) . chr(204) . chr(205) . chr(206) . chr(207) . chr(209) . chr(210) . chr(211) . chr(212) . chr(213) . chr(214) . chr(216) . chr(217) . chr(218) . chr(219) . chr(220) . chr(221) . chr(224) . chr(225) . chr(226) . chr(227) . chr(228) . chr(229) . chr(231) . chr(232) . chr(233) . chr(234) . chr(235) . chr(236) . chr(237) . chr(238) . chr(239) . chr(241) . chr(242) . chr(243) . chr(244) . chr(245) . chr(246) . chr(248) . chr(249) . chr(250) . chr(251) . chr(252) . chr(253) . chr(255); $chars['out'] = "EfSZszYcYuAAAAAACEEEEIIIINOOOOOOUUUUYaaaaaaceeeeiiiinoooooouuuuyy"; $string = strtr($string, $chars['in'], $chars['out']); $double_chars['in'] = array(chr(140), chr(156), chr(198), chr(208), chr(222), chr(223), chr(230), chr(240), chr(254)); $double_chars['out'] = array('OE', 'oe', 'AE', 'DH', 'TH', 'ss', 'ae', 'dh', 'th'); $string = str_replace($double_chars['in'], $double_chars['out'], $string); } return $string; }
/** * Perform mapping of extracted media metadata to CollectiveAccess bundles. * * @param BundlableLabelableBaseModelWithAttributes $po_instance Model instance to insert extracted metadata into * @param array $pa_metadata Extracted metadata * @param int $pn_locale_id The current locale as a numeric locale_id * @return bool True extracted metadata was mapped and the model changed, false if no change was made to the model */ function caExtractEmbeddedMetadata($po_instance, $pa_metadata, $pn_locale_id) { if (!is_array($pa_metadata)) { return false; } $vb_did_mapping = false; if (!($vs_media_metadata_config = $po_instance->getAppConfig()->get('media_metadata'))) { return false; } $o_metadata_config = Configuration::load($vs_media_metadata_config); $va_mappings = $o_metadata_config->getAssoc('import_mappings'); $vs_tablename = $po_instance->tableName(); // set extracted georef? $va_georef_elements = $o_metadata_config->getList('extract_embedded_exif_georeferencing_to'); $va_georef_containers = $o_metadata_config->getAssoc('extract_embedded_exif_georeferencing_to_container'); $va_date_elements = $o_metadata_config->getList('extract_embedded_exif_creation_date_to'); $va_date_containers = $o_metadata_config->getAssoc('extract_embedded_exif_creation_date_to_container'); if (isset($pa_metadata['EXIF']) && is_array($pa_metadata['EXIF']) && (is_array($va_georef_elements) && sizeof($va_georef_elements) || is_array($va_georef_containers) && sizeof($va_georef_containers) || is_array($va_date_elements) && sizeof($va_date_elements) || is_array($va_date_containers) && sizeof($va_date_containers))) { $va_exif_data = $pa_metadata['EXIF']; if (is_array($va_georef_elements)) { if (is_array($va_coords = caParseEXIFLatLong($va_exif_data))) { foreach ($va_georef_elements as $vs_element) { $va_tmp = explode('.', $vs_element); $po_instance->addAttribute(array($va_tmp[1] => "[" . $va_coords['latitude'] . ", " . $va_coords['longitude'] . "]", 'locale_id' => $pn_locale_id), $va_tmp[1]); } $vb_did_mapping = true; } } if (is_array($va_georef_containers)) { if (is_array($va_coords = caParseEXIFLatLong($va_exif_data))) { foreach ($va_georef_containers as $vs_container => $va_info) { $va_tmp = explode('.', $vs_container); $vs_value_element = array_pop(explode('.', $va_info['value'])); $va_data = array($vs_value_element => "[" . $va_coords['latitude'] . ", " . $va_coords['longitude'] . "]", 'locale_id' => $pn_locale_id); if (isset($va_info['map']) && is_array($va_info['map'])) { foreach ($va_info['map'] as $vs_sub_element => $vs_value) { $va_tmp2 = explode('.', $vs_sub_element); $vs_sub_element = array_pop($va_tmp2); if ($t_element = $po_instance->_getElementInstance($vs_sub_element)) { switch ($t_element->get('datatype')) { case 3: // List $t_list = new ca_lists(); $va_data[$vs_sub_element] = $t_list->getItemIDFromList($t_element->get('list_id'), $vs_value); break; default: $va_data[$vs_sub_element] = $vs_value; break; } } } } $po_instance->addAttribute($va_data, $va_tmp[1]); } $vb_did_mapping = true; } } if (is_array($va_date_elements)) { if (($vs_raw_date = $va_exif_data['IFD0']['DateTimeOriginal']) || ($vs_raw_date = $va_exif_data['EXIF']['DateTimeOriginal']) || ($vs_raw_date = $va_exif_data['ExifIFD']['DateTimeOriginal'])) { $va_date_tmp = preg_split('![: ]+!', $vs_raw_date); $vs_date = $va_date_tmp[0] . '-' . $va_date_tmp[1] . '-' . $va_date_tmp[2] . 'T' . $va_date_tmp[3] . ':' . $va_date_tmp[4] . ':' . $va_date_tmp[5]; foreach ($va_date_elements as $vs_element) { $va_tmp = explode('.', $vs_element); if (strlen($po_instance->get($vs_element)) > 0) { $po_instance->addAttribute(array($va_tmp[1] => $vs_date, 'locale_id' => $pn_locale_id), $va_tmp[1]); } else { $po_instance->replaceAttribute(array($va_tmp[1] => $vs_date, 'locale_id' => $pn_locale_id), $va_tmp[1]); } } $vb_did_mapping = true; } } if (is_array($va_date_containers)) { $t_list = new ca_lists(); if (($vs_raw_date = $va_exif_data['IFD0']['DateTimeOriginal']) || ($vs_raw_date = $va_exif_data['EXIF']['DateTimeOriginal']) || ($vs_raw_date = $va_exif_data['ExifIFD']['DateTimeOriginal'])) { $va_date_tmp = preg_split('![: ]+!', $vs_raw_date); $vs_date = $va_date_tmp[0] . '-' . $va_date_tmp[1] . '-' . $va_date_tmp[2] . 'T' . $va_date_tmp[3] . ':' . $va_date_tmp[4] . ':' . $va_date_tmp[5]; foreach ($va_date_containers as $vs_container => $va_info) { $va_tmp = explode('.', $vs_container); $vs_value_element = array_pop(explode('.', $va_info['value'])); $va_data = array($vs_value_element => $vs_date, 'locale_id' => $pn_locale_id); if (isset($va_info['map']) && is_array($va_info['map'])) { foreach ($va_info['map'] as $vs_sub_element => $vs_value) { $va_tmp2 = explode('.', $vs_sub_element); $vs_sub_element = array_pop($va_tmp2); if ($t_element = $po_instance->_getElementInstance($vs_sub_element)) { switch ($t_element->get('datatype')) { case 3: // List $va_data[$vs_sub_element] = $t_list->getItemIDFromList($t_element->get('list_id'), $vs_value); break; default: $va_data[$vs_sub_element] = $vs_value; break; } } } } $po_instance->addAttribute($va_data, $va_tmp[1]); } $vb_did_mapping = true; } } } if (!isset($va_mappings[$po_instance->tableName()])) { return $vb_did_mapping; } $va_mapping = $va_mappings[$vs_tablename]; $vs_type = $po_instance->getTypeCode(); if (isset($va_mapping[$vs_type]) && is_array($va_mapping[$vs_type])) { $va_mapping = $va_mapping[$vs_type]; } else { if (isset($va_mapping['__default__']) && is_array($va_mapping['__default__'])) { $va_mapping = $va_mapping['__default__']; } else { return $vb_did_mapping; } } foreach ($va_mapping as $vs_metadata => $va_attr) { $va_tmp = explode(":", $vs_metadata); $vs_delimiter = caGetOption('delimiter', $va_attr, false); foreach ($va_attr as $vs_attr) { if ($vs_attr == 'delimiter') { continue; } $va_metadata =& $pa_metadata; foreach ($va_tmp as $vs_el) { if (isset($va_metadata[$vs_el])) { $va_metadata =& $va_metadata[$vs_el]; } else { continue 2; } } if (is_array($va_metadata)) { $va_metadata = join(";", $va_metadata); } if (!is_int($va_metadata)) { // pass ints through for values like WhiteBalance = 0 if (!trim($va_metadata)) { continue 2; } } if (!caSeemsUTF8($va_metadata)) { $va_metadata = caEncodeUTF8Deep($va_metadata); } $va_tmp2 = explode(".", $vs_attr); switch ($va_tmp2[0]) { case 'preferred_labels': $po_instance->replaceLabel(array($va_tmp2[1] => $va_metadata), $pn_locale_id, null, true); break; case 'nonpreferred_labels': $po_instance->replaceLabel(array($va_tmp2[1] => $va_metadata), $pn_locale_id, null, false); break; default: if ($po_instance->hasField($vs_attr)) { $po_instance->set($vs_attr, $va_metadata); } else { // try as attribute if (sizeof($va_tmp2) == 2) { // format ca_objects.foo, we only want "foo" if ($vs_delimiter) { $va_m = explode($vs_delimiter, $va_metadata); $po_instance->removeAttributes($va_tmp2[1]); foreach ($va_m as $vs_m) { $po_instance->addAttribute(array($va_tmp2[1] => trim($vs_m), 'locale_id' => $pn_locale_id), $va_tmp2[1]); } } else { $po_instance->replaceAttribute(array($va_tmp2[1] => $va_metadata, 'locale_id' => $pn_locale_id), $va_tmp2[1]); } } } } $vb_did_mapping = true; } } return $vb_did_mapping; }