Exemplo n.º 1
0
 /**
  * Returns representation_id for the object representation with the specified name (and type) or idno (regardless of specified type.) If the object does
  * not already exist then it will be created with the specified name, type and locale, as well as with any specified values in the $pa_values array.
  * $pa_values keys should be either valid object fields or attributes.
  *
  * @param string $ps_representation_name Object label name
  * @param int $pn_type_id The type_id of the object type to use if the representation needs to be created
  * @param int $pn_locale_id The locale_id to use if the representation needs to be created (will be used for both the object locale as well as the label locale)
  * @param array $pa_values An optional array of additional values to populate newly created representation records with. These values are *only* used for newly created representation; they will not be applied if the representation named already exists. The array keys should be names of ca_object_representations fields or valid representation attributes. Values should be either a scalar (for single-value attributes) or an array of values for (multi-valued attributes)
  * @param array $pa_options An optional array of options, which include:
  *                outputErrors - if true, errors will be printed to console [default=false]
  *                matchOn = optional list indicating sequence of checks for an existing record; values of array can be "label" and "idno". Ex. array("idno", "label") will first try to match on idno and then label if the first match fails.
  *                dontCreate - if true then new representations will not be created [default=false]
  *                transaction - if Transaction object is passed, use it for all Db-related tasks [default=null]
  *                returnInstance = return ca_object_representations instance rather than representation_id. Default is false.
  *                generateIdnoWithTemplate = A template to use when setting the idno. The template is a value with automatically-set SERIAL values replaced with % characters. Eg. 2012.% will set the created row's idno value to 2012.121 (assuming that 121 is the next number in the serial sequence.) The template is NOT used if idno is passed explicitly as a value in $pa_values.
  *                importEvent = if ca_data_import_events instance is passed then the insert/update of the representation will be logged as part of the import
  *                importEventSource = if importEvent is passed, then the value set for importEventSource is used in the import event log as the data source. If omitted a default value of "?" is used
  *                nonPreferredLabels = an optional array of nonpreferred labels to add to any newly created representations. Each label in the array is an array with required representation label values.
  *                log = if KLogger instance is passed then actions will be logged
  *				  matchMediaFilesWithoutExtension = if media path is invalid, attempt to find media in referenced directory and sub-directories that has a matching name, regardless of file extension. [default=false] 
  * @return bool|ca_object_representations|mixed|null
  */
 static function getObjectRepresentationID($ps_representation_name, $pn_type_id, $pn_locale_id, $pa_values = null, $pa_options = null)
 {
     if (!is_array($pa_options)) {
         $pa_options = array();
     }
     if (!isset($pa_options['outputErrors'])) {
         $pa_options['outputErrors'] = false;
     }
     $vb_match_media_without_extension = caGetOption('matchMediaFilesWithoutExtension', $pa_options, false);
     $pa_match_on = caGetOption('matchOn', $pa_options, array('label', 'idno'), array('castTo' => "array"));
     /** @var ca_data_import_events $o_event */
     $o_event = isset($pa_options['importEvent']) && $pa_options['importEvent'] instanceof ca_data_import_events ? $pa_options['importEvent'] : null;
     $t_rep = new ca_object_representations();
     if (isset($pa_options['transaction']) && $pa_options['transaction'] instanceof Transaction) {
         $t_rep->setTransaction($pa_options['transaction']);
         if ($o_event) {
             $o_event->setTransaction($pa_options['transaction']);
         }
     }
     $vs_event_source = isset($pa_options['importEventSource']) && $pa_options['importEventSource'] ? $pa_options['importEventSource'] : "?";
     /** @var KLogger $o_log */
     $o_log = isset($pa_options['log']) && $pa_options['log'] instanceof KLogger ? $pa_options['log'] : null;
     $vs_idno = isset($pa_values['idno']) ? (string) $pa_values['idno'] : null;
     if (preg_match('!\\%!', $vs_idno)) {
         $pa_options['generateIdnoWithTemplate'] = $vs_idno;
         $vs_idno = null;
     }
     if (!$vs_idno) {
         if (isset($pa_options['generateIdnoWithTemplate']) && $pa_options['generateIdnoWithTemplate']) {
             $vs_idno = $t_rep->setIdnoWithTemplate($pa_options['generateIdnoWithTemplate'], array('dontSetValue' => true));
         }
     }
     $va_regex_list = caBatchGetMediaFilenameToIdnoRegexList(array('log' => $o_log));
     // Get list of replacements that user can use to transform file names to match object idnos
     $va_replacements_list = caBatchGetMediaFilenameReplacementRegexList(array('log' => $o_log));
     $vn_id = null;
     foreach ($pa_match_on as $vs_match_on) {
         switch (strtolower($vs_match_on)) {
             case 'label':
             case 'labels':
                 if (trim($ps_representation_name)) {
                     if ($vn_id = ca_object_representations::find(array('preferred_labels' => array('name' => $ps_representation_name), 'type_id' => $pn_type_id), array('returnAs' => 'firstId', 'transaction' => $pa_options['transaction']))) {
                         break 2;
                     }
                 }
                 break;
             case 'idno':
                 if (!$vs_idno) {
                     break;
                 }
                 if ($vs_idno == '%') {
                     break;
                 }
                 // don't try to match on an unreplaced idno placeholder
                 $va_idnos_to_match = array($vs_idno);
                 if (is_array($va_replacements_list)) {
                     foreach ($va_replacements_list as $vs_replacement_code => $va_replacement) {
                         if (isset($va_replacement['search']) && is_array($va_replacement['search'])) {
                             $va_replace = caGetOption('replace', $va_replacement);
                             $va_search = array();
                             foreach ($va_replacement['search'] as $vs_search) {
                                 $va_search[] = '!' . $vs_search . '!';
                             }
                             if ($vs_idno_proc = @preg_replace($va_search, $va_replace, $vs_idno)) {
                                 $va_idnos_to_match[] = $vs_idno_proc;
                             }
                         }
                     }
                 }
                 if (is_array($va_regex_list) && sizeof($va_regex_list)) {
                     foreach ($va_regex_list as $vs_regex_name => $va_regex_info) {
                         foreach ($va_regex_info['regexes'] as $vs_regex) {
                             foreach ($va_idnos_to_match as $vs_idno_match) {
                                 if (!$vs_idno_match) {
                                     continue;
                                 }
                                 if (preg_match('!' . $vs_regex . '!', $vs_idno_match, $va_matches)) {
                                     if ($vn_id = ca_object_representations::find(array('idno' => $va_matches[1]), array('returnAs' => 'firstId', 'transaction' => $pa_options['transaction']))) {
                                         break 5;
                                     }
                                 }
                             }
                         }
                     }
                 } else {
                     foreach ($va_idnos_to_match as $vs_idno_match) {
                         if (!$vs_idno_match) {
                             continue;
                         }
                         if ($vn_id = ca_object_representations::find(array('idno' => $vs_idno_match), array('returnAs' => 'firstId', 'transaction' => $pa_options['transaction']))) {
                             break 3;
                         }
                     }
                 }
                 break;
         }
     }
     if (!$vn_id) {
         if (isset($pa_options['dontCreate']) && $pa_options['dontCreate']) {
             return false;
         }
         if ($o_event) {
             $o_event->beginItem($vs_event_source, 'ca_object_representations', 'I');
         }
         $t_rep->setMode(ACCESS_WRITE);
         $t_rep->set('locale_id', $pn_locale_id);
         $t_rep->set('type_id', $pn_type_id);
         $t_rep->set('source_id', isset($pa_values['source_id']) ? $pa_values['source_id'] : null);
         $t_rep->set('access', isset($pa_values['access']) ? $pa_values['access'] : 0);
         $t_rep->set('status', isset($pa_values['status']) ? $pa_values['status'] : 0);
         if (isset($pa_values['media']) && $pa_values['media']) {
             if ($vb_match_media_without_extension && !isURL($pa_values['media']) && !file_exists($pa_values['media'])) {
                 $vs_dirname = pathinfo($pa_values['media'], PATHINFO_DIRNAME);
                 $vs_filename = preg_replace('!\\.[A-Za-z0-9]{1,4}$!', '', pathinfo($pa_values['media'], PATHINFO_BASENAME));
                 $vs_original_path = $pa_values['media'];
                 $pa_values['media'] = null;
                 $va_files_in_dir = caGetDirectoryContentsAsList($vs_dirname, true, false, false, false);
                 foreach ($va_files_in_dir as $vs_filepath) {
                     if ($o_log) {
                         $o_log->logDebug(_t("Trying media %1 in place of %2/%3", $vs_filepath, $vs_original_path, $vs_filename));
                     }
                     if (pathinfo($vs_filepath, PATHINFO_FILENAME) == $vs_filename) {
                         if ($o_log) {
                             $o_log->logNotice(_t("Found media %1 for %2/%3", $vs_filepath, $vs_original_path, $vs_filename));
                         }
                         $pa_values['media'] = $vs_filepath;
                         break;
                     }
                 }
             }
             $t_rep->set('media', $pa_values['media']);
         }
         $t_rep->set('idno', $vs_idno);
         $t_rep->insert();
         if ($t_rep->numErrors()) {
             if (isset($pa_options['outputErrors']) && $pa_options['outputErrors']) {
                 print "[Error] " . _t("Could not insert object %1: %2", $ps_representation_name, join('; ', $t_rep->getErrors())) . "\n";
             }
             if ($o_log) {
                 $o_log->logError(_t("Could not insert object %1: %2", $ps_representation_name, join('; ', $t_rep->getErrors())));
             }
             return null;
         }
         $vb_label_errors = false;
         $t_rep->addLabel(array('name' => $ps_representation_name), $pn_locale_id, null, true);
         if ($t_rep->numErrors()) {
             if (isset($pa_options['outputErrors']) && $pa_options['outputErrors']) {
                 print "[Error] " . _t("Could not set preferred label for object %1: %2", $ps_representation_name, join('; ', $t_rep->getErrors())) . "\n";
             }
             if ($o_log) {
                 $o_log->logError(_t("Could not set preferred label for object %1: %2", $ps_representation_name, join('; ', $t_rep->getErrors())));
             }
             $vb_label_errors = true;
         }
         /** @var IIDNumbering $o_idno */
         if ($o_idno = $t_rep->getIDNoPlugInInstance()) {
             $va_values = $o_idno->htmlFormValuesAsArray('idno', $vs_idno);
             if (!is_array($va_values)) {
                 $va_values = array($va_values);
             }
             if (!($vs_sep = $o_idno->getSeparator())) {
                 $vs_sep = '';
             }
             if (($vs_proc_idno = join($vs_sep, $va_values)) && $vs_proc_idno != $vs_idno) {
                 $t_rep->set('idno', $vs_proc_idno);
                 $t_rep->update();
                 if ($t_rep->numErrors()) {
                     if (isset($pa_options['outputErrors']) && $pa_options['outputErrors']) {
                         print "[Error] " . _t("Could not update idno for %1: %2", $ps_representation_name, join('; ', $t_rep->getErrors())) . "\n";
                     }
                     if ($o_log) {
                         $o_log->logError(_t("Could not object idno for %1: %2", $ps_representation_name, join('; ', $t_rep->getErrors())));
                     }
                     return null;
                 }
             }
         }
         unset($pa_values['access']);
         unset($pa_values['status']);
         unset($pa_values['idno']);
         unset($pa_values['source_id']);
         $vb_attr_errors = false;
         if (is_array($pa_values)) {
             foreach ($pa_values as $vs_element => $va_values) {
                 if (!caIsIndexedArray($va_values)) {
                     $va_values = array($va_values);
                 }
                 foreach ($va_values as $va_value) {
                     if (is_array($va_value)) {
                         // array of values (complex multi-valued attribute)
                         $t_rep->addAttribute(array_merge($va_value, array('locale_id' => $pn_locale_id)), $vs_element);
                     } else {
                         // scalar value (simple single value attribute)
                         if ($va_value) {
                             $t_rep->addAttribute(array('locale_id' => $pn_locale_id, $vs_element => $va_value), $vs_element);
                         }
                     }
                 }
             }
             $t_rep->update();
             if ($t_rep->numErrors()) {
                 if (isset($pa_options['outputErrors']) && $pa_options['outputErrors']) {
                     print "[Error] " . _t("Could not set values for representation %1: %2", $ps_representation_name, join('; ', $t_rep->getErrors())) . "\n";
                 }
                 if ($o_log) {
                     $o_log->logError(_t("Could not set values for representation %1: %2", $ps_representation_name, join('; ', $t_rep->getErrors())));
                 }
                 $vb_attr_errors = true;
             }
         }
         if (is_array($va_nonpreferred_labels = caGetOption("nonPreferredLabels", $pa_options, null))) {
             if (caIsAssociativeArray($va_nonpreferred_labels)) {
                 // single non-preferred label
                 $va_labels = array($va_nonpreferred_labels);
             } else {
                 // list of non-preferred labels
                 $va_labels = $va_nonpreferred_labels;
             }
             foreach ($va_labels as $va_label) {
                 $t_rep->addLabel($va_label, $pn_locale_id, null, false);
                 if ($t_rep->numErrors()) {
                     if (isset($pa_options['outputErrors']) && $pa_options['outputErrors']) {
                         print "[Error] " . _t("Could not set non-preferred label for representation %1: %2", $ps_representation_name, join('; ', $t_rep->getErrors())) . "\n";
                     }
                     if ($o_log) {
                         $o_log->logError(_t("Could not set non-preferred label for representation %1: %2", $ps_representation_name, join('; ', $t_rep->getErrors())));
                     }
                 }
             }
         }
         $vn_representation_id = $t_rep->getPrimaryKey();
         if ($o_event) {
             if ($vb_attr_errors || $vb_label_errors) {
                 $o_event->endItem($vn_representation_id, __CA_DATA_IMPORT_ITEM_PARTIAL_SUCCESS__, _t("Errors setting field values: %1", join('; ', $t_rep->getErrors())));
             } else {
                 $o_event->endItem($vn_representation_id, __CA_DATA_IMPORT_ITEM_SUCCESS__, '');
             }
         }
         if ($o_log) {
             $o_log->logInfo(_t("Created new representation %1", $ps_representation_name));
         }
         if (isset($pa_options['returnInstance']) && $pa_options['returnInstance']) {
             return $t_rep;
         }
     } else {
         if ($o_event) {
             $o_event->beginItem($vs_event_source, 'ca_object_representations', 'U');
         }
         $vn_representation_id = $vn_id;
         if ($o_event) {
             $o_event->endItem($vn_representation_id, __CA_DATA_IMPORT_ITEM_SUCCESS__, '');
         }
         if ($o_log) {
             $o_log->logDebug(_t("Found existing representation %1 in DataMigrationUtils::getObjectRepresentationID()", $ps_representation_name));
         }
         if (isset($pa_options['returnInstance']) && $pa_options['returnInstance']) {
             $t_rep = new ca_object_representations($vn_representation_id);
             if (isset($pa_options['transaction']) && $pa_options['transaction'] instanceof Transaction) {
                 $t_rep->setTransaction($pa_options['transaction']);
             }
             return $t_rep;
         }
     }
     return $vn_representation_id;
 }
Exemplo n.º 2
0
 /**
  * Returns id for the row with the specified name (and type) or idno (regardless of specified type.) If the row does not already
  * exist then it will be created with the specified name, type and locale, as well as with any specified values in the $pa_values array.
  * $pa_values keys should be either valid entity fields or attributes.
  *
  * @param string $ps_table The table to match and/or create rows in
  * @param array $pa_label Array with values for row label
  * @param int $pn_parent_id
  * @param int $pn_type_id The type_id or code of the type to use if the row needs to be created
  * @param int $pn_locale_id The locale_id to use if the row needs to be created (will be used for both the row locale as well as the label locale)
  * @param array $pa_values An optional array of additional values to populate newly created rows with. These values are *only* used for newly created rows; they will not be applied if the row named already exists unless the forceUpdate option is set, in which case attributes (but not intrinsics) will be updated. The array keys should be names of fields or valid attributes. Values should be either a scalar (for single-value attributes) or an array of values for (multi-valued attributes)
  * @param array $pa_options An optional array of options, which include:
  *                outputErrors - if true, errors will be printed to console [default=false]
  *                dontCreate - if true then new entities will not be created [default=false]
  *                matchOn = optional list indicating sequence of checks for an existing record; values of array can be "label" and "idno". Ex. array("idno", "label") will first try to match on idno and then label if the first match fails. For entities only you may also specifiy "displayname", "surname" and "forename" to match on the text of the those label fields exclusively.
  *                matchOnDisplayName  if true then entities are looked up exclusively using displayname, otherwise forename and surname fields are used [default=false]
  *                transaction - if Transaction instance is passed, use it for all Db-related tasks [default=null]
  *                returnInstance = return ca_entities instance rather than entity_id. Default is false.
  *                generateIdnoWithTemplate = A template to use when setting the idno. The template is a value with automatically-set SERIAL values replaced with % characters. Eg. 2012.% will set the created row's idno value to 2012.121 (assuming that 121 is the next number in the serial sequence.) The template is NOT used if idno is passed explicitly as a value in $pa_values.
  *                importEvent = if ca_data_import_events instance is passed then the insert/update of the entity will be logged as part of the import
  *                importEventSource = if importEvent is passed, then the value set for importEventSource is used in the import event log as the data source. If omitted a default value of "?" is used
  *                nonPreferredLabels = an optional array of nonpreferred labels to add to any newly created entities. Each label in the array is an array with required entity label values.
  *				  forceUpdate = update attributes set in $pa_values even if row already exists. [Default=false; no values are updated in existing rows]
  *				  matchMediaFilesWithoutExtension = For ca_object_representations, if media path is invalid, attempt to find media in referenced directory and sub-directories that has a matching name, regardless of file extension. [default=false] 
  *                log = if KLogger instance is passed then actions will be logged
  *				  ignoreParent = Don't take into account parent_id value when looking for matching rows [Default is false]
  * @return bool|BaseModel|mixed|null
  */
 private static function _getID($ps_table, $pa_label, $pn_parent_id, $pn_type_id, $pn_locale_id, $pa_values = null, $pa_options = null)
 {
     if (!is_array($pa_options)) {
         $pa_options = array();
     }
     $o_dm = Datamodel::load();
     /** @var KLogger $o_log */
     $o_log = isset($pa_options['log']) && $pa_options['log'] instanceof KLogger ? $pa_options['log'] : null;
     if (!($t_instance = $o_dm->getInstanceByTableName($ps_table, true))) {
         return null;
     }
     $vs_table_display_name = $t_instance->getProperty('NAME_SINGULAR');
     $vs_table_class = $t_instance->tableName();
     $vs_label_display_fld = $t_instance->getLabelDisplayField();
     $vs_label = $pa_label[$vs_label_display_fld];
     $pb_output_errors = caGetOption('outputErrors', $pa_options, false);
     $pb_match_on_displayname = caGetOption('matchOnDisplayName', $pa_options, false);
     $pa_match_on = caGetOption('matchOn', $pa_options, array('label', 'idno', 'displayname'), array('castTo' => "array"));
     $ps_event_source = caGetOption('importEventSource', $pa_options, '?');
     $pb_match_media_without_ext = caGetOption('matchMediaFilesWithoutExtension', $pa_options, false);
     $pb_ignore_parent = caGetOption('ignoreParent', $pa_options, false);
     $vn_parent_id = $pn_parent_id ? $pn_parent_id : caGetOption('parent_id', $pa_values, null);
     if (!$vn_parent_id) {
         $vn_parent_id = null;
     }
     $vs_idno_fld = $t_instance->getProperty('ID_NUMBERING_ID_FIELD');
     $vs_idno = caGetOption($vs_idno_fld, $pa_values, null);
     /** @var ca_data_import_events $o_event */
     $o_event = isset($pa_options['importEvent']) && $pa_options['importEvent'] instanceof ca_data_import_events ? $pa_options['importEvent'] : null;
     if (isset($pa_options['transaction']) && $pa_options['transaction'] instanceof Transaction) {
         $t_instance->setTransaction($pa_options['transaction']);
         if ($o_event) {
             $o_event->setTransaction($pa_options['transaction']);
         }
     }
     if (preg_match('!\\%!', $vs_idno)) {
         $pa_options['generateIdnoWithTemplate'] = $vs_idno;
         $vs_idno = null;
     }
     if (!$vs_idno) {
         if (isset($pa_options['generateIdnoWithTemplate']) && $pa_options['generateIdnoWithTemplate']) {
             $pa_values[$vs_idno_fld] = $vs_idno = $t_instance->setIdnoWithTemplate($pa_options['generateIdnoWithTemplate'], array('dontSetValue' => true));
         }
     }
     $va_regex_list = $va_replacements_list = null;
     if ($vs_table_class == 'ca_object_representations') {
         // Get list of regular expressions that user can use to transform file names to match object idnos
         $va_regex_list = caBatchGetMediaFilenameToIdnoRegexList(array('log' => $o_log));
         // Get list of replacements that user can use to transform file names to match object idnos
         $va_replacements_list = caBatchGetMediaFilenameReplacementRegexList(array('log' => $o_log));
     }
     $vn_id = null;
     foreach ($pa_match_on as $vs_match_on) {
         switch (strtolower($vs_match_on)) {
             case 'idno':
                 if ($vs_idno == '%') {
                     break;
                 }
                 // don't try to match on an unreplaced idno placeholder
                 switch ($vs_table_class) {
                     case 'ca_object_representations':
                         //
                         // idno lookups for representations use media batch importer rules
                         //
                         $va_idnos_to_match = array($vs_idno);
                         if (is_array($va_replacements_list)) {
                             foreach ($va_replacements_list as $vs_replacement_code => $va_replacement) {
                                 if (isset($va_replacement['search']) && is_array($va_replacement['search'])) {
                                     $va_replace = caGetOption('replace', $va_replacement);
                                     $va_search = array();
                                     foreach ($va_replacement['search'] as $vs_search) {
                                         $va_search[] = '!' . $vs_search . '!';
                                     }
                                     if ($vs_idno_proc = @preg_replace($va_search, $va_replace, $vs_idno)) {
                                         $va_idnos_to_match[] = $vs_idno_proc;
                                     }
                                 }
                             }
                         }
                         if (is_array($va_regex_list) && sizeof($va_regex_list)) {
                             foreach ($va_regex_list as $vs_regex_name => $va_regex_info) {
                                 foreach ($va_regex_info['regexes'] as $vs_regex) {
                                     foreach ($va_idnos_to_match as $vs_idno_match) {
                                         if (!$vs_idno_match) {
                                             continue;
                                         }
                                         if (preg_match('!' . $vs_regex . '!', $vs_idno_match, $va_matches)) {
                                             if ($vn_id = ca_object_representations::find(array('idno' => $va_matches[1]), array('returnAs' => 'firstId', 'purifyWithFallback' => true, 'transaction' => $pa_options['transaction']))) {
                                                 break 5;
                                             }
                                         }
                                     }
                                 }
                             }
                         } else {
                             foreach ($va_idnos_to_match as $vs_idno_match) {
                                 if (!$vs_idno_match) {
                                     continue;
                                 }
                                 if ($vn_id = ca_object_representations::find(array('idno' => $vs_idno_match), array('returnAs' => 'firstId', 'purifyWithFallback' => true, 'transaction' => $pa_options['transaction']))) {
                                     break 3;
                                 }
                             }
                         }
                         break;
                     default:
                         //
                         // Standard idno lookup for most tables
                         //
                         $va_find_vals = array($vs_idno_fld => $vs_idno ? $vs_idno : ($pa_label['_originalText'] ? $pa_label['_originalText'] : $vs_label), 'type_id' => $pn_type_id);
                         if (!$pb_ignore_parent && isset($pa_values['parent_id'])) {
                             $va_find_vals['parent_id'] = $pa_values['parent_id'];
                         }
                         if (($vs_idno || trim($pa_label['_originalText'] || $vs_label)) && ($vn_id = $vs_table_class::find($va_find_vals, array('returnAs' => 'firstId', 'purifyWithFallback' => true, 'transaction' => $pa_options['transaction'])))) {
                             break 2;
                         }
                         break;
                 }
                 break;
             case 'label':
             case 'labels':
                 if ($pb_match_on_displayname && strlen(trim($pa_label['displayname'])) > 0) {
                     // entities only
                     $va_params = array('preferred_labels' => array('displayname' => $pa_label['displayname']), 'type_id' => $pn_type_id);
                     if (!$pb_ignore_parent && isset($pa_values['parent_id'])) {
                         $va_params['parent_id'] = $vn_parent_id;
                     }
                     $vn_id = $vs_table_class::find($va_params, array('returnAs' => 'firstId', 'purifyWithFallback' => true, 'transaction' => $pa_options['transaction']));
                 } elseif ($vs_table_class == 'ca_entities') {
                     // entities only
                     $va_params = array('preferred_labels' => array('forename' => $pa_label['forename'], 'middlename' => $pa_label['middlename'], 'surname' => $pa_label['surname']), 'type_id' => $pn_type_id);
                     if (!$pb_ignore_parent) {
                         $va_params['parent_id'] = $vn_parent_id;
                     }
                     $vn_id = $vs_table_class::find($va_params, array('returnAs' => 'firstId', 'purifyWithFallback' => true, 'transaction' => $pa_options['transaction']));
                 } else {
                     $va_params = array('preferred_labels' => array($vs_label_display_fld => $pa_label[$vs_label_display_fld]), 'type_id' => $pn_type_id);
                     if (!$pb_ignore_parent && isset($pa_values['parent_id'])) {
                         $va_params['parent_id'] = $vn_parent_id;
                     }
                     $vn_id = $vs_table_class::find($va_params, array('returnAs' => 'firstId', 'purifyWithFallback' => true, 'transaction' => $pa_options['transaction']));
                 }
                 if ($vn_id) {
                     break 2;
                 }
                 break;
                 //
                 // For entities only
                 //
             //
             // For entities only
             //
             case 'surname':
                 $va_params = array('preferred_labels' => array('surname' => $pa_label['surname']), 'type_id' => $pn_type_id);
                 if (!$pb_ignore_parent && isset($pa_values['parent_id'])) {
                     $va_params['parent_id'] = $vn_parent_id;
                 }
                 $vn_id = $vs_table_class::find($va_params, array('returnAs' => 'firstId', 'purifyWithFallback' => true, 'transaction' => $pa_options['transaction']));
                 if ($vn_id) {
                     break 2;
                 }
                 break;
             case 'forename':
                 $va_params = array('preferred_labels' => array('forename' => $pa_label['forename']), 'type_id' => $pn_type_id);
                 if (!$pb_ignore_parent && isset($pa_values['parent_id'])) {
                     $va_params['parent_id'] = $vn_parent_id;
                 }
                 $vn_id = $vs_table_class::find($va_params, array('returnAs' => 'firstId', 'purifyWithFallback' => true, 'transaction' => $pa_options['transaction']));
                 if ($vn_id) {
                     break 2;
                 }
                 break;
             case 'displayname':
                 $va_params = array('preferred_labels' => array('displayname' => $pa_label['displayname']), 'type_id' => $pn_type_id);
                 if (!$pb_ignore_parent && isset($pa_values['parent_id'])) {
                     $va_params['parent_id'] = $vn_parent_id;
                 }
                 $vn_id = $vs_table_class::find($va_params, array('returnAs' => 'firstId', 'purifyWithFallback' => true, 'transaction' => $pa_options['transaction']));
                 if ($vn_id) {
                     break 2;
                 }
                 break;
         }
     }
     if (!$vn_id) {
         //
         // Create new row
         //
         if (caGetOption('dontCreate', $pa_options, false)) {
             return false;
         }
         if ($o_event) {
             $o_event->beginItem($ps_event_source, $vs_table_class, 'I');
         }
         // If we're creating a new item, it's probably a good idea to *NOT* use a
         // BaseModel instance from cache, because those cannot change their type_id
         if (!($t_instance = $o_dm->getInstanceByTableName($ps_table, false))) {
             return null;
         }
         if (isset($pa_options['transaction']) && $pa_options['transaction'] instanceof Transaction) {
             $t_instance->setTransaction($pa_options['transaction']);
         }
         $t_instance->setMode(ACCESS_WRITE);
         $t_instance->set('locale_id', $pn_locale_id);
         $t_instance->set('type_id', $pn_type_id);
         $va_intrinsics = array('source_id' => null, 'access' => 0, 'status' => 0, 'lifespan' => null, 'parent_id' => $vn_parent_id, 'lot_status_id' => null, '_interstitial' => null);
         if ($vs_hier_id_fld = $t_instance->getProperty('HIERARCHY_ID_FLD')) {
             $va_intrinsics[$vs_hier_id_fld] = null;
         }
         if ($vs_idno_fld) {
             $va_intrinsics[$vs_idno_fld] = $vs_idno ? $vs_idno : null;
         }
         foreach ($va_intrinsics as $vs_fld => $vm_fld_default) {
             if ($t_instance->hasField($vs_fld)) {
                 $t_instance->set($vs_fld, caGetOption($vs_fld, $pa_values, $vm_fld_default));
             }
             unset($pa_values[$vs_fld]);
         }
         if ($t_instance->hasField('media') && $t_instance->getFieldInfo('media', 'FIELD_TYPE') == FT_MEDIA && isset($pa_values['media']) && $pa_values['media']) {
             if (is_array($pa_values['media'])) {
                 $pa_values['media'] = array_shift($pa_values['media']);
             }
             if ($pb_match_media_without_ext && !isURL($pa_values['media']) && !file_exists($pa_values['media'])) {
                 $vs_dirname = pathinfo($pa_values['media'], PATHINFO_DIRNAME);
                 $vs_filename = preg_replace('!\\.[A-Za-z0-9]{1,4}$!', '', pathinfo($pa_values['media'], PATHINFO_BASENAME));
                 $vs_original_path = $pa_values['media'];
                 $pa_values['media'] = null;
                 $va_files_in_dir = caGetDirectoryContentsAsList($vs_dirname, true, false, false, false);
                 foreach ($va_files_in_dir as $vs_filepath) {
                     if ($o_log) {
                         $o_log->logDebug(_t("Trying media %1 in place of %2/%3", $vs_filepath, $vs_original_path, $vs_filename));
                     }
                     if (pathinfo($vs_filepath, PATHINFO_FILENAME) == $vs_filename) {
                         if ($o_log) {
                             $o_log->logNotice(_t("Found media %1 for %2/%3", $vs_filepath, $vs_original_path, $vs_filename));
                         }
                         $pa_values['media'] = $vs_filepath;
                         break;
                     }
                 }
             }
             $t_instance->set('media', $pa_values['media']);
         }
         $t_instance->insert();
         if ($t_instance->numErrors()) {
             if ($pb_output_errors) {
                 print "[Error] " . _t("Could not insert %1 %2: %3", $vs_table_display_name, $pa_label[$vs_label_display_fld], join('; ', $t_instance->getErrors())) . "\n";
             }
             if ($o_log) {
                 $o_log->logError(_t("Could not insert %1 %2: %3", $vs_table_display_name, $pa_label[$vs_label_display_fld], join('; ', $t_instance->getErrors())));
             }
             return null;
         }
         $vb_label_errors = false;
         $t_instance->addLabel($pa_label, $pn_locale_id, null, true);
         if ($t_instance->numErrors()) {
             if ($pb_output_errors) {
                 print "[Error] " . _t("Could not set preferred label for %1 %2: %3", $vs_table_display_name, $pa_label[$vs_label_display_fld], join('; ', $t_instance->getErrors())) . "\n";
             }
             if ($o_log) {
                 $o_log->logError(_t("Could not set preferred label for %1 %2: %3", $vs_table_display_name, $pa_label[$vs_label_display_fld], join('; ', $t_instance->getErrors())));
             }
             $vb_label_errors = true;
         }
         DataMigrationUtils::_setIdno($t_instance, $vs_idno, $pa_options);
         $vb_attr_errors = !DataMigrationUtils::_setAttributes($t_instance, $pn_locale_id, $pa_values, $pa_options);
         DataMigrationUtils::_setNonPreferredLabels($t_instance, $pn_locale_id, $pa_options);
         $vn_id = $t_instance->getPrimaryKey();
         if ($o_event) {
             if ($vb_attr_errors || $vb_label_errors) {
                 $o_event->endItem($vn_id, __CA_DATA_IMPORT_ITEM_PARTIAL_SUCCESS__, _t("Errors setting field values: %1", join('; ', $t_instance->getErrors())));
             } else {
                 $o_event->endItem($vn_id, __CA_DATA_IMPORT_ITEM_SUCCESS__, '');
             }
         }
         if ($o_log) {
             $o_log->logInfo(_t("Created new %1 %2", $vs_table_display_name, $pa_label[$vs_label_display_fld]));
         }
         if (isset($pa_options['returnInstance']) && $pa_options['returnInstance']) {
             return $t_instance;
         }
     } else {
         if ($o_event) {
             $o_event->beginItem($ps_event_source, $vs_table_class, 'U');
         }
         if ($o_log) {
             $o_log->logDebug(_t("Found existing %1 %2 in DataMigrationUtils::_getID()", $vs_table_display_name, $pa_label[$vs_label_display_fld]));
         }
         $vb_attr_errors = false;
         if (($vb_force_update = caGetOption('forceUpdate', $pa_options, false)) || ($vb_return_instance = caGetOption('returnInstance', $pa_options, false))) {
             if (!($t_instance = $o_dm->getInstanceByTableName($vs_table_class, false))) {
                 return null;
             }
             if (isset($pa_options['transaction']) && $pa_options['transaction'] instanceof Transaction) {
                 $t_instance->setTransaction($pa_options['transaction']);
             }
             $vb_has_attr = false;
             if ($vb_force_update) {
                 foreach ($pa_values as $vs_element => $va_values) {
                     if ($t_instance->hasElement($vs_element)) {
                         $vb_has_attr = true;
                         break;
                     }
                 }
             }
             if ($vb_return_instance || $vb_force_update && $vb_has_attr) {
                 $vn_rc = $t_instance->load($vn_id);
             } else {
                 $vn_rc = true;
             }
             if (!$vn_rc) {
                 if ($o_log) {
                     $o_log->logError(_t("Could not load existing %1 with id %2 (%3) in DataMigrationUtils::_getID() [THIS SHOULD NOT HAPPEN]", $vs_table_display_name, $vn_id, $pa_label[$vs_label_display_fld]));
                 }
                 return null;
             } else {
                 if ($vb_force_update && $vb_has_attr) {
                     if ($vb_attr_errors = !DataMigrationUtils::_setAttributes($t_instance, $pn_locale_id, $pa_values, $pa_options)) {
                         if ($o_log) {
                             $o_log->logError(_t("Could not set attributes for %1 with id %2 (%3) in DataMigrationUtils::_getID(): %4", $vs_table_display_name, $vn_id, $pa_label[$vs_label_display_fld], join("; ", $t_instance->getErrors())));
                         }
                     }
                 }
                 if ($o_event) {
                     if ($vb_attr_errors) {
                         $o_event->endItem($vn_id, __CA_DATA_IMPORT_ITEM_PARTIAL_SUCCESS__, _t("Errors setting field values: %1", join('; ', $t_instance->getErrors())));
                     } else {
                         $o_event->endItem($vn_id, __CA_DATA_IMPORT_ITEM_SUCCESS__, '');
                     }
                 }
                 if ($vb_return_instance) {
                     return $t_instance;
                 }
             }
         }
         if ($o_event) {
             $o_event->endItem($vn_id, __CA_DATA_IMPORT_ITEM_SUCCESS__, '');
         }
     }
     return $vn_id;
 }
Exemplo n.º 3
0
 /**
  * @param RequestHTTP $po_request
  * @param null|array $pa_options
  *		progressCallback =
  *		reportCallback =
  *		sendMail =
  *		log = log directory path
  *		logLevel = KLogger constant for minimum log level to record. Default is KLogger::INFO. Constants are, in descending order of shrillness:
  *			KLogger::EMERG = Emergency messages (system is unusable)
  *			KLogger::ALERT = Alert messages (action must be taken immediately)
  *			KLogger::CRIT = Critical conditions
  *			KLogger::ERR = Error conditions
  *			KLogger::WARN = Warnings
  *			KLogger::NOTICE = Notices (normal but significant conditions)
  *			KLogger::INFO = Informational messages
  *			KLogger::DEBUG = Debugging messages
  * @return array
  */
 public static function importMediaFromDirectory($po_request, $pa_options = null)
 {
     global $g_ui_locale_id;
     $vs_log_dir = caGetOption('log', $pa_options, __CA_APP_DIR__ . "/log");
     $vs_log_level = caGetOption('logLevel', $pa_options, "INFO");
     if (!is_writeable($vs_log_dir)) {
         $vs_log_dir = caGetTempDirPath();
     }
     $vn_log_level = BatchProcessor::_logLevelStringToNumber($vs_log_level);
     $o_log = new KLogger($vs_log_dir, $vn_log_level);
     $vs_import_target = caGetOption('importTarget', $pa_options, 'ca_objects');
     $t_instance = $po_request->getAppDatamodel()->getInstance($vs_import_target);
     $o_eventlog = new Eventlog();
     $t_set = new ca_sets();
     $va_notices = $va_errors = array();
     $vb_we_set_transaction = false;
     $o_trans = isset($pa_options['transaction']) && $pa_options['transaction'] ? $pa_options['transaction'] : null;
     if (!$o_trans) {
         $vb_we_set_transaction = true;
         $o_trans = new Transaction($t_set->getDb());
     }
     $o_batch_log = new Batchlog(array('user_id' => $po_request->getUserID(), 'batch_type' => 'MI', 'table_num' => (int) $t_instance->tableNum(), 'notes' => '', 'transaction' => $o_trans));
     if (!is_dir($pa_options['importFromDirectory'])) {
         $o_eventlog->log(array("CODE" => 'ERR', "SOURCE" => "mediaImport", "MESSAGE" => $vs_msg = _t("Specified import directory '%1' is invalid", $pa_options['importFromDirectory'])));
         $o_log->logError($vs_msg);
         return null;
     }
     $vs_batch_media_import_root_directory = $po_request->config->get('batch_media_import_root_directory');
     if (!preg_match("!^{$vs_batch_media_import_root_directory}!", $pa_options['importFromDirectory'])) {
         $o_eventlog->log(array("CODE" => 'ERR', "SOURCE" => "mediaImport", "MESSAGE" => $vs_msg = _t("Specified import directory '%1' is invalid", $pa_options['importFromDirectory'])));
         $o_log->logError($vs_msg);
         return null;
     }
     if (preg_match("!\\.\\./!", $pa_options['importFromDirectory'])) {
         $o_eventlog->log(array("CODE" => 'ERR', "SOURCE" => "mediaImport", "MESSAGE" => $vs_msg = _t("Specified import directory '%1' is invalid", $pa_options['importFromDirectory'])));
         $o_log->logError($vs_msg);
         return null;
     }
     $vb_include_subdirectories = (bool) $pa_options['includeSubDirectories'];
     $vb_delete_media_on_import = (bool) $pa_options['deleteMediaOnImport'];
     $vs_import_mode = $pa_options['importMode'];
     $vs_match_mode = $pa_options['matchMode'];
     $vn_type_id = $pa_options[$vs_import_target . '_type_id'];
     $vn_rep_type_id = $pa_options['ca_object_representations_type_id'];
     $va_limit_matching_to_type_ids = $pa_options[$vs_import_target . '_limit_matching_to_type_ids'];
     $vn_access = $pa_options[$vs_import_target . '_access'];
     $vn_object_representation_access = $pa_options['ca_object_representations_access'];
     $vn_status = $pa_options[$vs_import_target . '_status'];
     $vn_object_representation_status = $pa_options['ca_object_representations_status'];
     $vn_rel_type_id = isset($pa_options[$vs_import_target . '_representation_relationship_type']) ? $pa_options[$vs_import_target . '_representation_relationship_type'] : null;
     $vn_mapping_id = $pa_options[$vs_import_target . '_mapping_id'];
     $vn_object_representation_mapping_id = $pa_options['ca_object_representations_mapping_id'];
     $vs_idno_mode = $pa_options['idnoMode'];
     $vs_idno = $pa_options['idno'];
     $vs_representation_idno_mode = $pa_options['representationIdnoMode'];
     $vs_representation_idno = $pa_options['representation_idno'];
     $vs_set_mode = $pa_options['setMode'];
     $vs_set_create_name = $pa_options['setCreateName'];
     $vn_set_id = $pa_options['set_id'];
     $vn_locale_id = $pa_options['locale_id'];
     $vs_skip_file_list = $pa_options['skipFileList'];
     $vs_skip_file_list = $pa_options['skipFileList'];
     $vb_allow_duplicate_media = $pa_options['allowDuplicateMedia'];
     $va_relationship_type_id_for = array();
     if (is_array($va_create_relationship_for = $pa_options['create_relationship_for'])) {
         foreach ($va_create_relationship_for as $vs_rel_table) {
             $va_relationship_type_id_for[$vs_rel_table] = $pa_options['relationship_type_id_for_' . $vs_rel_table];
         }
     }
     if (!$vn_locale_id) {
         $vn_locale_id = $g_ui_locale_id;
     }
     $va_files_to_process = caGetDirectoryContentsAsList($pa_options['importFromDirectory'], $vb_include_subdirectories);
     $o_log->logInfo(_t('Found %1 files in directory \'%2\'', sizeof($va_files_to_process), $pa_options['importFromDirectory']));
     if ($vs_set_mode == 'add') {
         $t_set->load($vn_set_id);
     } else {
         if ($vs_set_mode == 'create' && $vs_set_create_name) {
             $va_set_ids = $t_set->getSets(array('user_id' => $po_request->getUserID(), 'table' => $t_instance->tableName(), 'access' => __CA_SET_EDIT_ACCESS__, 'setIDsOnly' => true, 'name' => $vs_set_create_name));
             $vn_set_id = null;
             if (is_array($va_set_ids) && sizeof($va_set_ids) > 0) {
                 $vn_possible_set_id = array_shift($va_set_ids);
                 if ($t_set->load($vn_possible_set_id)) {
                     $vn_set_id = $t_set->getPrimaryKey();
                 }
             } else {
                 $vs_set_code = mb_substr(preg_replace("![^A-Za-z0-9_\\-]+!", "_", $vs_set_create_name), 0, 100);
                 if ($t_set->load(array('set_code' => $vs_set_code))) {
                     $vn_set_id = $t_set->getPrimaryKey();
                 }
             }
             if (!$t_set->getPrimaryKey()) {
                 $t_set->setMode(ACCESS_WRITE);
                 $t_set->set('user_id', $po_request->getUserID());
                 $t_set->set('type_id', $po_request->config->get('ca_sets_default_type'));
                 $t_set->set('table_num', $t_instance->tableNum());
                 $t_set->set('set_code', $vs_set_code);
                 $t_set->insert();
                 if ($t_set->numErrors()) {
                     $va_notices['create_set'] = array('idno' => '', 'label' => _t('Create set %1', $vs_set_create_name), 'message' => $vs_msg = _t('Failed to create set %1: %2', $vs_set_create_name, join("; ", $t_set->getErrors())), 'status' => 'SET ERROR');
                     $o_log->logError($vs_msg);
                 } else {
                     $t_set->addLabel(array('name' => $vs_set_create_name), $vn_locale_id, null, true);
                     if ($t_set->numErrors()) {
                         $va_notices['add_set_label'] = array('idno' => '', 'label' => _t('Add label to set %1', $vs_set_create_name), 'message' => $vs_msg = _t('Failed to add label to set: %1', join("; ", $t_set->getErrors())), 'status' => 'SET ERROR');
                         $o_log->logError($vs_msg);
                     }
                     $vn_set_id = $t_set->getPrimaryKey();
                 }
             }
         } else {
             $vn_set_id = null;
             // no set
         }
     }
     if ($t_set->getPrimaryKey() && !$t_set->haveAccessToSet($po_request->getUserID(), __CA_SET_EDIT_ACCESS__)) {
         $va_notices['set_access'] = array('idno' => '', 'label' => _t('You do not have access to set %1', $vs_set_create_name), 'message' => $vs_msg = _t('Cannot add to set %1 because you do not have edit access', $vs_set_create_name), 'status' => 'SET ERROR');
         $o_log->logError($vs_msg);
         $vn_set_id = null;
         $t_set = new ca_sets();
     }
     $vn_num_items = sizeof($va_files_to_process);
     // Get list of regex packages that user can use to extract object idno's from filenames
     $va_regex_list = caBatchGetMediaFilenameToIdnoRegexList(array('log' => $o_log));
     // Get list of replacements that user can use to transform file names to match object idnos
     $va_replacements_list = caBatchGetMediaFilenameReplacementRegexList(array('log' => $o_log));
     // Get list of files (or file name patterns) to skip
     $va_skip_list = preg_split("![\r\n]+!", $vs_skip_file_list);
     foreach ($va_skip_list as $vn_i => $vs_skip) {
         if (!strlen($va_skip_list[$vn_i] = trim($vs_skip))) {
             unset($va_skip_list[$vn_i]);
         }
     }
     $vn_c = 0;
     $vn_start_time = time();
     $va_report = array();
     foreach ($va_files_to_process as $vs_file) {
         $va_tmp = explode("/", $vs_file);
         $f = array_pop($va_tmp);
         $d = array_pop($va_tmp);
         array_push($va_tmp, $d);
         $vs_directory = join("/", $va_tmp);
         // Skip file names using $vs_skip_file_list
         if (BatchProcessor::_skipFile($f, $va_skip_list)) {
             $o_log->logInfo(_t('Skipped file %1 because it was on the skipped files list', $f));
             continue;
         }
         $vs_relative_directory = preg_replace("!{$vs_batch_media_import_root_directory}[/]*!", "", $vs_directory);
         // does representation already exist?
         if (!$vb_allow_duplicate_media && ($t_dupe = ca_object_representations::mediaExists($vs_file))) {
             $va_notices[$vs_relative_directory . '/' . $f] = array('idno' => '', 'label' => $f, 'message' => $vs_msg = _t('Skipped %1 from %2 because it already exists %3', $f, $vs_relative_directory, caEditorLink($po_request, _t('(view)'), 'button', 'ca_object_representations', $t_dupe->getPrimaryKey())), 'status' => 'SKIPPED');
             $o_log->logInfo($vs_msg);
             continue;
         }
         $t_instance = $po_request->getAppDatamodel()->getInstance($vs_import_target, false);
         $t_instance->setTransaction($o_trans);
         $vs_modified_filename = $f;
         $va_extracted_idnos_from_filename = array();
         if (in_array($vs_import_mode, array('TRY_TO_MATCH', 'ALWAYS_MATCH')) || is_array($va_create_relationship_for) && sizeof($va_create_relationship_for)) {
             foreach ($va_regex_list as $vs_regex_name => $va_regex_info) {
                 $o_log->logDebug(_t("Processing mediaFilenameToObjectIdnoRegexes entry %1", $vs_regex_name));
                 foreach ($va_regex_info['regexes'] as $vs_regex) {
                     switch ($vs_match_mode) {
                         case 'DIRECTORY_NAME':
                             $va_names_to_match = array($d);
                             $o_log->logDebug(_t("Trying to match on directory '%1'", $d));
                             break;
                         case 'FILE_AND_DIRECTORY_NAMES':
                             $va_names_to_match = array($f, $d);
                             $o_log->logDebug(_t("Trying to match on directory '%1' and file name '%2'", $d, $f));
                             break;
                         default:
                         case 'FILE_NAME':
                             $va_names_to_match = array($f);
                             $o_log->logDebug(_t("Trying to match on file name '%1'", $f));
                             break;
                     }
                     // are there any replacements? if so, try to match each element in $va_names_to_match AND all results of the replacements
                     if (is_array($va_replacements_list) && sizeof($va_replacements_list) > 0) {
                         $va_names_to_match_copy = $va_names_to_match;
                         foreach ($va_names_to_match_copy as $vs_name) {
                             foreach ($va_replacements_list as $vs_replacement_code => $va_replacement) {
                                 if (isset($va_replacement['search']) && is_array($va_replacement['search'])) {
                                     $va_replace = caGetOption('replace', $va_replacement);
                                     $va_search = array();
                                     foreach ($va_replacement['search'] as $vs_search) {
                                         $va_search[] = '!' . $vs_search . '!';
                                     }
                                     $vs_replacement_result = @preg_replace($va_search, $va_replace, $vs_name);
                                     if (is_null($vs_replacement_result)) {
                                         $o_log->logError(_t("There was an error in preg_replace while processing replacement %1.", $vs_replacement_code));
                                     }
                                     if ($vs_replacement_result && strlen($vs_replacement_result) > 0) {
                                         $o_log->logDebug(_t("The result for replacement with code %1 applied to value '%2' is '%3' and was added to the list of file names used for matching.", $vs_replacement_code, $vs_name, $vs_replacement_result));
                                         $va_names_to_match[] = $vs_replacement_result;
                                     }
                                 } else {
                                     $o_log->logDebug(_t("Skipped replacement %1 because no search expression was defined.", $vs_replacement_code));
                                 }
                             }
                         }
                     }
                     $o_log->logDebug("Names to match: " . print_r($va_names_to_match, true));
                     foreach ($va_names_to_match as $vs_match_name) {
                         if (preg_match('!' . $vs_regex . '!', $vs_match_name, $va_matches)) {
                             $o_log->logDebug(_t("Matched name %1 on regex %2", $vs_match_name, $vs_regex));
                             if (!$vs_idno || strlen($va_matches[1]) < strlen($vs_idno)) {
                                 $vs_idno = $va_matches[1];
                             }
                             if (!$vs_modified_filename || strlen($vs_modified_filename) > strlen($va_matches[1])) {
                                 $vs_modified_filename = $va_matches[1];
                             }
                             $va_extracted_idnos_from_filename[] = $va_matches[1];
                             if (in_array($vs_import_mode, array('TRY_TO_MATCH', 'ALWAYS_MATCH'))) {
                                 if (!is_array($va_fields_to_match_on = $po_request->config->getList('batch_media_import_match_on')) || !sizeof($va_fields_to_match_on)) {
                                     $batch_media_import_match_on = array('idno');
                                 }
                                 $vs_bool = 'OR';
                                 $va_values = array();
                                 foreach ($va_fields_to_match_on as $vs_fld) {
                                     if (in_array($vs_fld, array('preferred_labels', 'nonpreferred_labels'))) {
                                         $va_values[$vs_fld] = array($vs_fld => array('name' => $va_matches[1]));
                                     } else {
                                         $va_values[$vs_fld] = $va_matches[1];
                                     }
                                 }
                                 if (is_array($va_limit_matching_to_type_ids) && sizeof($va_limit_matching_to_type_ids) > 0) {
                                     $va_values['type_id'] = $va_limit_matching_to_type_ids;
                                     $vs_bool = 'AND';
                                 }
                                 $o_log->logDebug("Trying to find records using boolean {$vs_bool} and values " . print_r($va_values, true));
                                 if (class_exists($vs_import_target) && ($vn_id = $vs_import_target::find($va_values, array('returnAs' => 'firstId', 'boolean' => $vs_bool)))) {
                                     if ($t_instance->load($vn_id)) {
                                         $va_notices[$vs_relative_directory . '/' . $vs_match_name . '_match'] = array('idno' => $t_instance->get($t_instance->getProperty('ID_NUMBERING_ID_FIELD')), 'label' => $t_instance->getLabelForDisplay(), 'message' => $vs_msg = _t('Matched media %1 from %2 to %3 using expression "%4"', $f, $vs_relative_directory, caGetTableDisplayName($vs_import_target, false), $va_regex_info['displayName']), 'status' => 'MATCHED');
                                         $o_log->logInfo($vs_msg);
                                     }
                                     break 3;
                                 }
                             }
                         } else {
                             $o_log->logDebug(_t("Couldn't match name %1 on regex %2", $vs_match_name, $vs_regex));
                         }
                     }
                 }
             }
         }
         if (!$t_instance->getPrimaryKey()) {
             // Use filename as idno if all else fails
             if ($t_instance->load(array('idno' => $f, 'deleted' => 0))) {
                 $va_notices[$vs_relative_directory . '/' . $f . '_match'] = array('idno' => $t_instance->get($t_instance->getProperty('ID_NUMBERING_ID_FIELD')), 'label' => $t_instance->getLabelForDisplay(), 'message' => $vs_msg = _t('Matched media %1 from %2 to %3 using filename', $f, $vs_relative_directory, caGetTableDisplayName($vs_import_target, false)), 'status' => 'MATCHED');
                 $o_log->logInfo($vs_msg);
             }
         }
         switch ($vs_representation_idno_mode) {
             case 'filename':
                 // use the filename as identifier
                 $vs_rep_idno = $f;
                 break;
             case 'filename_no_ext':
                 // use filename without extension as identifier
                 $vs_rep_idno = preg_replace('/\\.[^.\\s]{3,4}$/', '', $f);
                 break;
             case 'directory_and_filename':
                 // use the directory + filename as identifier
                 $vs_rep_idno = $d . '/' . $f;
                 break;
             default:
                 // use idno from form
                 $vs_rep_idno = $vs_representation_idno;
                 break;
         }
         $t_new_rep = null;
         if ($t_instance->getPrimaryKey() && $t_instance instanceof RepresentableBaseModel) {
             // found existing object
             $t_instance->setMode(ACCESS_WRITE);
             $t_new_rep = $t_instance->addRepresentation($vs_directory . '/' . $f, $vn_rep_type_id, $vn_locale_id, $vn_object_representation_status, $vn_object_representation_access, false, array('idno' => $vs_rep_idno), array('original_filename' => $f, 'returnRepresentation' => true, 'type_id' => $vn_rel_type_id));
             if ($t_instance->numErrors()) {
                 $o_eventlog->log(array("CODE" => 'ERR', "SOURCE" => "mediaImport", "MESSAGE" => _t("Error importing {$f} from {$vs_directory}: %1", join('; ', $t_instance->getErrors()))));
                 $va_errors[$vs_relative_directory . '/' . $f] = array('idno' => $t_instance->get($t_instance->getProperty('ID_NUMBERING_ID_FIELD')), 'label' => $t_instance->getLabelForDisplay(), 'errors' => $t_instance->errors(), 'message' => $vs_msg = _t("Error importing %1 from %2: %3", $f, $vs_relative_directory, join('; ', $t_instance->getErrors())), 'status' => 'ERROR');
                 $o_log->logError($vs_msg);
                 $o_trans->rollback();
                 continue;
             } else {
                 if ($vb_delete_media_on_import) {
                     @unlink($vs_directory . '/' . $f);
                 }
             }
         } else {
             // should we create new record?
             if (in_array($vs_import_mode, array('TRY_TO_MATCH', 'DONT_MATCH'))) {
                 $t_instance->setMode(ACCESS_WRITE);
                 $t_instance->set('type_id', $vn_type_id);
                 $t_instance->set('locale_id', $vn_locale_id);
                 $t_instance->set('status', $vn_status);
                 $t_instance->set('access', $vn_access);
                 // for places, take first hierarchy we can find. in most setups there is but one. we might wanna make this configurable via setup screen at some point
                 if ($t_instance->hasField('hierarchy_id')) {
                     $va_hierarchies = $t_instance->getHierarchyList();
                     reset($va_hierarchies);
                     $vn_hierarchy_id = key($va_hierarchies);
                     $t_instance->set('hierarchy_id', $vn_hierarchy_id);
                 }
                 switch ($vs_idno_mode) {
                     case 'filename':
                         // use the filename as identifier
                         $t_instance->set('idno', $f);
                         break;
                     case 'filename_no_ext':
                         // use filename without extension as identifier
                         $f_no_ext = preg_replace('/\\.[^.\\s]{3,4}$/', '', $f);
                         $t_instance->set('idno', $f_no_ext);
                         break;
                     case 'directory_and_filename':
                         // use the directory + filename as identifier
                         $t_instance->set('idno', $d . '/' . $f);
                         break;
                     default:
                         // Calculate identifier using numbering plugin
                         $o_numbering_plugin = $t_instance->getIDNoPlugInInstance();
                         if (!($vs_sep = $o_numbering_plugin->getSeparator())) {
                             $vs_sep = '';
                         }
                         if (!is_array($va_idno_values = $o_numbering_plugin->htmlFormValuesAsArray('idno', null, false, false, true))) {
                             $va_idno_values = array();
                         }
                         $t_instance->set('idno', join($vs_sep, $va_idno_values));
                         // true=always set serial values, even if they already have a value; this let's us use the original pattern while replacing the serial value every time through
                         break;
                 }
                 $t_instance->insert();
                 if ($t_instance->numErrors()) {
                     $o_eventlog->log(array("CODE" => 'ERR', "SOURCE" => "mediaImport", "MESSAGE" => _t("Error creating new record while importing %1 from %2: %3", $f, $vs_relative_directory, join('; ', $t_instance->getErrors()))));
                     $va_errors[$vs_relative_directory . '/' . $f] = array('idno' => $t_instance->get($t_instance->getProperty('ID_NUMBERING_ID_FIELD')), 'label' => $t_instance->getLabelForDisplay(), 'errors' => $t_instance->errors(), 'message' => $vs_msg = _t("Error creating new record while importing %1 from %2: %3", $f, $vs_relative_directory, join('; ', $t_instance->getErrors())), 'status' => 'ERROR');
                     $o_log->logError($vs_msg);
                     $o_trans->rollback();
                     continue;
                 }
                 if ($t_instance->tableName() == 'ca_entities') {
                     // entity labels deserve special treatment
                     $t_instance->addLabel(array('surname' => $f), $vn_locale_id, null, true);
                 } else {
                     $t_instance->addLabel(array($t_instance->getLabelDisplayField() => $f), $vn_locale_id, null, true);
                 }
                 if ($t_instance->numErrors()) {
                     $o_eventlog->log(array("CODE" => 'ERR', "SOURCE" => "mediaImport", "MESSAGE" => _t("Error creating record label while importing %1 from %2: %3", $f, $vs_relative_directory, join('; ', $t_instance->getErrors()))));
                     $va_errors[$vs_relative_directory . '/' . $f] = array('idno' => $t_instance->get($t_instance->getProperty('ID_NUMBERING_ID_FIELD')), 'label' => $t_instance->getLabelForDisplay(), 'errors' => $t_instance->errors(), 'message' => $vs_msg = _t("Error creating record label while importing %1 from %2: %3", $f, $vs_relative_directory, join('; ', $t_instance->getErrors())), 'status' => 'ERROR');
                     $o_log->logError($vs_msg);
                     $o_trans->rollback();
                     continue;
                 }
                 $t_new_rep = $t_instance->addRepresentation($vs_directory . '/' . $f, $vn_rep_type_id, $vn_locale_id, $vn_object_representation_status, $vn_object_representation_access, true, array('idno' => $vs_rep_idno), array('original_filename' => $f, 'returnRepresentation' => true, 'type_id' => $vn_rel_type_id));
                 if ($t_instance->numErrors()) {
                     $o_eventlog->log(array("CODE" => 'ERR', "SOURCE" => "mediaImport", "MESSAGE" => _t("Error importing %1 from %2: ", $f, $vs_relative_directory, join('; ', $t_instance->getErrors()))));
                     $va_errors[$vs_relative_directory . '/' . $f] = array('idno' => $t_instance->get($t_instance->getProperty('ID_NUMBERING_ID_FIELD')), 'label' => $t_instance->getLabelForDisplay(), 'errors' => $t_instance->errors(), 'message' => $vs_msg = _t("Error importing %1 from %2: %3", $f, $vs_relative_directory, join('; ', $t_instance->getErrors())), 'status' => 'ERROR');
                     $o_log->logError($vs_msg);
                     $o_trans->rollback();
                     continue;
                 } else {
                     if ($vb_delete_media_on_import) {
                         @unlink($vs_directory . '/' . $f);
                     }
                 }
             }
         }
         if ($t_instance->getPrimaryKey()) {
             // Perform import of embedded metadata (if required)
             if ($vn_mapping_id) {
                 ca_data_importers::importDataFromSource($vs_directory . '/' . $f, $vn_mapping_id, array('logLevel' => $vs_log_level, 'format' => 'exif', 'forceImportForPrimaryKeys' => array($t_instance->getPrimaryKey(), 'transaction' => $o_trans)));
             }
             if ($vn_object_representation_mapping_id) {
                 ca_data_importers::importDataFromSource($vs_directory . '/' . $f, $vn_object_representation_mapping_id, array('logLevel' => $vs_log_level, 'format' => 'exif', 'forceImportForPrimaryKeys' => array($t_new_rep->getPrimaryKey()), 'transaction' => $o_trans));
             }
             $va_notices[$t_instance->getPrimaryKey()] = array('idno' => $t_instance->get($t_instance->getProperty('ID_NUMBERING_ID_FIELD')), 'label' => $t_instance->getLabelForDisplay(), 'message' => $vs_msg = _t('Imported %1 as %2', $f, $t_instance->get($t_instance->getProperty('ID_NUMBERING_ID_FIELD'))), 'status' => 'SUCCESS');
             $o_log->logInfo($vs_msg);
             if ($vn_set_id) {
                 $t_set->addItem($t_instance->getPrimaryKey(), null, $po_request->getUserID());
             }
             $o_batch_log->addItem($t_instance->getPrimaryKey(), $t_instance->errors());
             // Create relationships?
             if (is_array($va_create_relationship_for) && sizeof($va_create_relationship_for) && is_array($va_extracted_idnos_from_filename) && sizeof($va_extracted_idnos_from_filename)) {
                 foreach ($va_extracted_idnos_from_filename as $vs_idno) {
                     foreach ($va_create_relationship_for as $vs_rel_table) {
                         if (!isset($va_relationship_type_id_for[$vs_rel_table]) || !$va_relationship_type_id_for[$vs_rel_table]) {
                             continue;
                         }
                         $t_rel = $t_instance->getAppDatamodel()->getInstanceByTableName($vs_rel_table);
                         if ($t_rel->load(array($t_rel->getProperty('ID_NUMBERING_ID_FIELD') => $vs_idno))) {
                             $t_instance->addRelationship($vs_rel_table, $t_rel->getPrimaryKey(), $va_relationship_type_id_for[$vs_rel_table]);
                             if (!$t_instance->numErrors()) {
                                 $va_notices[$t_instance->getPrimaryKey() . '_rel'] = array('idno' => $t_instance->get($t_instance->getProperty('ID_NUMBERING_ID_FIELD')), 'label' => $vs_label = $t_instance->getLabelForDisplay(), 'message' => $vs_msg = _t('Added relationship between <em>%1</em> and %2 <em>%3</em>', $vs_label, $t_rel->getProperty('NAME_SINGULAR'), $t_rel->getLabelForDisplay()), 'status' => 'RELATED');
                                 $o_log->logInfo($vs_msg);
                             } else {
                                 $va_notices[$t_instance->getPrimaryKey()] = array('idno' => $t_instance->get($t_instance->getProperty('ID_NUMBERING_ID_FIELD')), 'label' => $vs_label = $t_instance->getLabelForDisplay(), 'message' => $vs_msg = _t('Could not add relationship between <em>%1</em> and %2 <em>%3</em>: %4', $vs_label, $t_rel->getProperty('NAME_SINGULAR'), $t_rel->getLabelForDisplay(), join("; ", $t_instance->getErrors())), 'status' => 'ERROR');
                                 $o_log->logError($vs_msg);
                             }
                         }
                     }
                 }
             }
         } else {
             $va_notices[$vs_relative_directory . '/' . $f] = array('idno' => '', 'label' => $f, 'message' => $vs_msg = $vs_import_mode == 'ALWAYS_MATCH' ? _t('Skipped %1 from %2 because it could not be matched', $f, $vs_relative_directory) : _t('Skipped %1 from %2', $f, $vs_relative_directory), 'status' => 'SKIPPED');
             $o_log->logInfo($vs_msg);
         }
         if (isset($pa_options['progressCallback']) && ($ps_callback = $pa_options['progressCallback'])) {
             $ps_callback($po_request, $vn_c, $vn_num_items, _t("[%3/%4] Processing %1 (%3)", caTruncateStringWithEllipsis($vs_relative_directory, 20) . '/' . caTruncateStringWithEllipsis($f, 30), $t_instance->get($t_instance->getProperty('ID_NUMBERING_ID_FIELD')), $vn_c, $vn_num_items), $t_new_rep, time() - $vn_start_time, memory_get_usage(true), $vn_c, sizeof($va_errors));
         }
         $vn_c++;
     }
     if (isset($pa_options['progressCallback']) && ($ps_callback = $pa_options['progressCallback'])) {
         $ps_callback($po_request, $vn_num_items, $vn_num_items, _t("Processing completed"), null, time() - $vn_start_time, memory_get_usage(true), $vn_c, sizeof($va_errors));
     }
     $vn_elapsed_time = time() - $vn_start_time;
     if (isset($pa_options['reportCallback']) && ($ps_callback = $pa_options['reportCallback'])) {
         $va_general = array('elapsedTime' => $vn_elapsed_time, 'numErrors' => sizeof($va_errors), 'numProcessed' => $vn_c, 'batchSize' => $vn_num_items, 'table' => $t_instance->tableName(), 'set_id' => $t_set->getPrimaryKey(), 'setName' => $t_set->getLabelForDisplay());
         $ps_callback($po_request, $va_general, $va_notices, $va_errors);
     }
     $o_batch_log->close();
     if ($vb_we_set_transaction) {
         if (sizeof($va_errors) > 0) {
             $o_trans->rollback();
         } else {
             $o_trans->commit();
         }
     }
     $vs_set_name = $t_set->getLabelForDisplay();
     $vs_started_on = caGetLocalizedDate($vn_start_time);
     if (isset($pa_options['sendMail']) && $pa_options['sendMail']) {
         if ($vs_email = trim($po_request->user->get('email'))) {
             caSendMessageUsingView($po_request, array($vs_email => $po_request->user->get('fname') . ' ' . $po_request->user->get('lname')), __CA_ADMIN_EMAIL__, _t('[%1] Batch media import completed', $po_request->config->get('app_display_name')), 'batch_media_import_completed.tpl', array('notices' => $va_notices, 'errors' => $va_errors, 'directory' => $vs_relative_directory, 'numErrors' => sizeof($va_errors), 'numProcessed' => $vn_c, 'subjectNameSingular' => _t('file'), 'subjectNamePlural' => _t('files'), 'startedOn' => $vs_started_on, 'completedOn' => caGetLocalizedDate(time()), 'setName' => $vn_set_id ? $vs_set_name : null, 'elapsedTime' => caFormatInterval($vn_elapsed_time)));
         }
     }
     if (isset($pa_options['sendSMS']) && $pa_options['sendSMS']) {
         SMS::send($po_request->getUserID(), _t("[%1] Media import processing for directory %2 with %3 %4 begun at %5 is complete", $po_request->config->get('app_display_name'), $vs_relative_directory, $vn_num_items, $vn_num_items == 1 ? _t('file') : _t('files'), $vs_started_on));
     }
     $o_log->logInfo(_t("Media import processing for directory %1 with %2 %3 begun at %4 is complete", $vs_relative_directory, $vn_num_items, $vn_num_items == 1 ? _t('file') : _t('files')));
     return array('errors' => $va_errors, 'notices' => $va_notices, 'processing_time' => caFormatInterval($vn_elapsed_time));
 }