Пример #1
0
 /**
  * Import SIPs from specified directory into CollectiveAccess Database
  */
 public function commandImportSIPs()
 {
     $o_conf = $this->getToolConfig();
     $t = new Timer();
     // Get locale from config and translate to numeric code
     $t_locale = new ca_locales();
     $pn_locale_id = $t_locale->localeCodeToID($o_conf->get('locale'));
     $o_log = $this->getLogger();
     $o_progress = $this->getProgressBar(0);
     if ($o_progress) {
         $o_progress->start("Starting import");
     }
     $vs_import_directory = $this->getSetting("import_directory");
     if (!is_readable($vs_import_directory)) {
         if ($o_log) {
             $o_log->logError($vs_err_msg = _t("Import directory %1 is not readable", $vs_import_directory));
         }
         if ($o_progress) {
             $o_progress->setError($vs_err_msg);
             $o_progress->finish();
         }
         return false;
     }
     if ($o_log) {
         $o_log->logDebug(_t("Started SIP import"));
     }
     //print "[1] ".$t->getTime(4)."\n";
     // Look for ZIP files or directories
     $va_files = caGetDirectoryContentsAsList($vs_import_directory, false, false, false, true);
     //print "[2] ".$t->getTime(4)."\n";
     $vn_count = 0;
     foreach ($va_files as $vs_file) {
         if (!preg_match("!\\.zip\$!i", $vs_file) && !is_dir($vs_file)) {
             continue;
         }
         $vn_count++;
     }
     $o_progress->setTotal($vn_count);
     //print "[3] ".$t->getTime(4)."\n";
     foreach ($va_files as $vs_file) {
         // Top level zips or directories
         $vb_is_dir = is_dir($vs_file);
         if (!preg_match("!\\.zip\$!i", $vs_file) && !$vb_is_dir) {
             continue;
         }
         //print "[4] ".$t->getTime(4)."\n";
         $o_progress->setMessage(_t('Processing %1', $vs_file));
         // unpack ZIP
         $va_package_files = caGetDirectoryContentsAsList($vb_is_dir ? $vs_file : 'phar://' . $vs_file . '/', false, false, false, true);
         // files in top level of directory or zip
         //foreach($va_package_files as $vs_package_path) {
         //$va_tmp = explode("/", $vs_package_path);
         //$vs_package_dir = array_pop($va_tmp);
         $va_archive_files = caGetDirectoryContentsAsList($vb_is_dir ? $vs_file : 'phar://' . $vs_file, true);
         // Does it look like a SIP?
         $vb_is_sip = false;
         $vs_idno = $vs_idno_padded = $vs_zip_path = $vs_category = null;
         $va_sides = array();
         foreach ($va_archive_files as $vs_archive_file) {
             if ($o_log) {
                 $o_log->logDebug(_t("Testing file %1 for SIP-ness", $vs_archive_file));
             }
             if (preg_match("!category.txt\$!", $vs_archive_file)) {
                 $vb_is_sip = true;
                 $va_tmp = explode("/", $vs_archive_file);
                 array_pop($va_tmp);
                 // pop category.txt
                 $vs_idno = array_pop($va_tmp);
                 $va_tmp_idno = explode("-", $vs_idno);
                 $va_tmp_idno[2] = str_pad($va_tmp_idno[2], 6, "0", STR_PAD_LEFT);
                 $vs_idno_padded = join("-", $va_tmp_idno);
                 $vs_category = strtolower(preg_replace("![^A-Z \\-a-z0-9]!", "", file_get_contents($vs_archive_file)));
                 // Translate categories
                 switch ($vs_category) {
                     case 'mixed':
                         $vs_category = 'unclassified';
                         break;
                 }
                 $vs_zip_path = join("/", $va_tmp);
                 if ($o_log) {
                     $o_log->logInfo(_t("Found SIP %1 with category %2", $vs_archive_dir, $vs_category));
                 }
                 continue;
             }
         }
         if (!$vb_is_sip) {
             if ($o_progress) {
                 $o_progress->setError(_t('File %1 is not a valid SIP', $vs_file));
             }
             if ($o_log) {
                 $o_log->logWarn(_t('File %1 is not a valid SIP', $vs_file));
             }
             continue;
         }
         //print "[5] ".$t->getTime(4)."\n";
         $va_track_audio_by_side = $va_track_xml_by_side = $va_side_audio = $va_side_xml = $va_artifacts = array();
         // Reset total # of SIPS with contents of ZIP
         $o_progress->setTotal((int) $o_progress->getTotal() - 1 + sizeof($va_archive_files));
         foreach ($va_archive_files as $vs_archive_file) {
             $vs_file_in_zip = str_replace($vb_is_dir ? "{$vs_file}" : "phar://{$vs_file}/{$vs_idno}", "", $vs_archive_file);
             $va_tmp = explode("/", $vs_file_in_zip);
             switch ($va_tmp[1]) {
                 case 'sides':
                     if ($va_tmp[4]) {
                         $vs_ext = pathinfo($va_tmp[4], PATHINFO_EXTENSION);
                         switch ($vs_ext) {
                             case 'mp3':
                                 $va_track_audio_by_side[$va_tmp[2]][] = ($vb_is_dir ? "{$vs_file}/sides/" : "phar://{$vs_file}/{$vs_idno}/sides/") . $va_tmp[2] . "/" . $va_tmp[3] . "/" . $va_tmp[4];
                                 break;
                             case 'xml':
                                 $va_track_xml_by_side[$va_tmp[2]][] = ($vb_is_dir ? "{$vs_file}/sides/" : "phar://{$vs_file}/{$vs_idno}/sides/") . $va_tmp[2] . "/" . $va_tmp[3] . "/" . $va_tmp[4];
                                 break;
                         }
                     } else {
                         if ($va_tmp[2]) {
                             $vs_ext = pathinfo($va_tmp[3], PATHINFO_EXTENSION);
                             switch ($vs_ext) {
                                 case 'mp3':
                                     $va_side_audio[$va_tmp[2]] = $va_tmp[3];
                                     break;
                                 case 'xml':
                                     if (preg_match('!meta!', $va_tmp[3])) {
                                         $va_side_xml[$va_tmp[2]] = ($vb_is_dir ? "{$vs_file}/sides/" : "phar://{$vs_file}/{$vs_idno}/sides/") . $va_tmp[2] . "/" . $va_tmp[3];
                                     }
                                     break;
                             }
                         }
                     }
                     break;
                 case 'artifacts':
                     if (sizeof($va_tmp) == 3) {
                         $va_artifacts[] = ($vb_is_dir ? "{$vs_file}/artifacts/" : "phar://{$vs_file}/{$vs_idno}/artifacts/") . $va_tmp[2];
                     }
                     break;
             }
         }
         //print "[6] ".$t->getTime(4)."\n";
         //print_R($va_side_xml); die;
         // Process
         // Create parent record
         $vn_image_count = 0;
         $o_progress->next(_t('Processing %1', $vs_archive_file));
         $o_progress->setMessage(_t("Creating reel for %1", $vs_idno));
         $va_ids = ca_objects::find(array('idno' => $vs_idno, 'deleted' => 0, 'type_id' => 'reel'), array('returnAs' => 'ids'));
         if (!is_array($va_ids) || !sizeof($va_ids)) {
             $t_object = new ca_objects();
             $t_object->setMode(ACCESS_WRITE);
             $t_object->set(array('status' => 5, 'type_id' => 'reel', 'idno' => $vs_idno));
             $vn_object_id = $t_object->insert();
             if ($t_object->numErrors()) {
                 if ($o_log) {
                     $o_log->logError(_t("Could not add reel record %1: %2", $vs_idno, join("; ", $t_object->getErrors())));
                 }
             }
             $t_object->addLabel(array('name' => $vs_idno_padded), $pn_locale_id, null, true);
             if ($t_object->numErrors()) {
                 if ($o_log) {
                     $o_log->logError(_t("Could not add label to reel record %1: %2", $vs_idno, join("; ", $t_object->getErrors())));
                 }
             }
             if ($t_object->numErrors()) {
                 if ($o_log) {
                     $o_log->logError(_t("Could not add artifct media %1 to reel %2: %3", pathinfo($vs_artifact, PATHINFO_BASENAME), $vs_idno, join("; ", $t_object->getErrors())));
                 }
             }
         } else {
             if ($o_log) {
                 $o_log->logDebug(_t("Found existing reel record %1 for %2", $va_ids[0], $vs_idno));
             }
             $t_object = new ca_objects($vn_object_id = $va_ids[0]);
             $t_object->setMode(ACCESS_WRITE);
             $t_object->set('status', 5);
             $t_object->update();
             if (($vn_image_count = $t_object->numberOfRepresentationsOfClass("image")) > 0) {
                 // skip reels that have images already
                 //if ($o_log) { $o_log->logDebug(_t("Skipped existing reel record %1 because it already has %2 images", $vs_idno, $vn_image_count)); }
                 //if ($o_progress) { $o_progress->setError(_t("Skipped existing reel record %1 because it already has %2 images", $vs_idno, $vn_image_count)); }
                 //continue;
             }
             $t_object->setMode(ACCESS_WRITE);
         }
         //print "[7] ".$t->getTime(4)."\n";
         if ($vn_image_count > 0) {
             $t_object->removeAllRepresentations();
             if ($t_object->numErrors()) {
                 if ($o_log) {
                     $o_log->logError(_t("Could not add remove existing media from reel %1: %2", $vs_idno, join("; ", $t_object->getErrors())));
                 }
             }
         }
         $o_progress->setMessage(_t("Linking artifact images for %1", $vs_idno));
         foreach ($va_artifacts as $vs_artifact) {
             $o_progress->next(_t('Processing artifact image %1', $vs_artifact));
             copy($vs_artifact, $vs_tmp_filepath = "/tmp/pbc" . md5(time()));
             $t_object->addRepresentation($vs_tmp_filepath, 'front', $pn_locale_id, 0, 1, 1);
             $o_progress->setMessage(_t("Added artifact image %1 for %2", $vs_artifact, $vs_idno));
             if ($t_object->numErrors()) {
                 if ($o_log) {
                     $o_log->logError(_t("Could not add artifact media %1 to reel %2: %3", pathinfo($vs_artifact, PATHINFO_BASENAME), $vs_idno, join("; ", $t_object->getErrors())));
                 }
             }
             // remove tmp file
             @unlink($vs_tmp_filepath);
         }
         //
         // Add XML
         //
         $o_progress->setMessage(_t("Adding XML for %1", $vs_track_idno));
         $t_object->removeAttributes('sip_metadata');
         foreach ($va_side_xml as $vs_side => $vs_xml_path) {
             copy($vs_xml_path, $vs_xml_tmppath = "/tmp/" . pathinfo($vs_xml_path, PATHINFO_BASENAME));
             $o_progress->next(_t('Processing XML %1', $vs_xml_tmppath));
             $t_object->addAttribute(array('sip_metadata' => $vs_xml_tmppath, 'locale_id' => $pn_locale_id), 'sip_metadata');
             $t_object->update();
             if ($t_object->numErrors()) {
                 if ($o_log) {
                     $o_log->logError(_t("Could not import XML file %1 into reel %2: %3", pathinfo($va_track_xml_by_side[$vs_side][$vn_i], PATHINFO_BASENAME), $vs_track_idno, join("; ", $t_object->getErrors())));
                 }
             }
         }
         //print "[8] ".$t->getTime(4)."\n";
         // Create tracks
         $o_progress->setMessage(_t("Creating tracks for %1", $vs_idno));
         foreach ($va_track_audio_by_side as $vs_side => $va_tracks) {
             foreach ($va_tracks as $vn_i => $vs_audio) {
                 $o_progress->next(_t('Processing track %1', $vs_audio));
                 $vs_ext = pathinfo($vs_audio, PATHINFO_EXTENSION);
                 copy($vs_audio, $vs_tmp_filepath = "/tmp/pbc" . md5(time()) . ".{$vs_ext}");
                 $vs_track_idno = pathinfo($vs_audio, PATHINFO_FILENAME);
                 // Does track already exist?
                 $va_track_ids = ca_objects::find(array('idno' => $vs_track_idno, 'deleted' => 0), array('returnAs' => 'ids'));
                 if (!is_array($va_track_ids) || !sizeof($va_track_ids)) {
                     $o_progress->setMessage(_t("Creating %2 track for %1", $vs_track_idno, $vs_category));
                     // Create track record
                     $t_track = new ca_objects();
                     $t_track->setMode(ACCESS_WRITE);
                     $va_tmp = explode("/", $vs_audio);
                     $vs_category = strtolower(str_replace(' ', '_', $vs_category));
                     $t_track->set(array('type_id' => $vs_category, 'idno' => $vs_track_idno, 'parent_id' => $vn_object_id));
                     $vn_track_id = $t_track->insert();
                     if ($t_track->numErrors()) {
                         if ($o_log) {
                             $o_log->logError(_t("Could not add track %1: %2", $vs_track_idno, join("; ", $t_track->getErrors())));
                         }
                     }
                     $t_track->addLabel(array('name' => "{$vs_track_idno}"), $pn_locale_id, null, true);
                     if ($t_track->numErrors()) {
                         if ($o_log) {
                             $o_log->logError(_t("Could not add label to track %1: %2", $vs_track_idno, join("; ", $t_track->getErrors())));
                         }
                     }
                 } else {
                     if ($o_log) {
                         $o_log->logDebug(_t("Found existing track record %1 for %2", $va_track_ids[0], $vs_track_idno));
                     }
                     $t_track = new ca_objects($va_track_ids[0]);
                     if (($vn_audio_count = $t_track->numberOfRepresentationsOfClass("audio")) > 0) {
                         // skip tracks that have audio already
                         //if ($o_log) { $o_log->logDebug(_t("Skip existing track record %1 because it already has %2 audio files", $vs_track_idno, $vn_audio_count)); }
                         //continue;
                         $t_track->removeAllRepresentations();
                     }
                 }
                 //
                 // Add track audio
                 //
                 $o_progress->setMessage(_t("Adding track audio for %1", $vs_track_idno));
                 $t_track->addRepresentation($vs_tmp_filepath, 'front', $pn_locale_id, 0, 1, 1);
                 if ($t_track->numErrors()) {
                     if ($o_log) {
                         $o_log->logError($vs_err_msg = _t("Could not import audio file %1 into track %2: %3", pathinfo($vs_audio, PATHINFO_BASENAME), $vs_track_idno, join("; ", $t_track->getErrors())));
                     }
                     if ($o_progress) {
                         $o_progress->setError($vs_err_msg);
                     }
                 }
                 // Remove tmp files
                 @unlink($vs_tmp_filepath);
                 @unlink($vs_xml_tmppath);
             }
         }
         //print "[9] ".$t->getTime(4)."\n";
         //}
         if ((bool) $this->getSetting('delete_after_import')) {
             $o_progress->setMessage(_t("Deleting SIP %1", $vs_file));
             if ($vb_is_dir) {
                 caRemoveDirectory($vs_file);
             } else {
                 @unlink($vs_file);
             }
         }
     }
     //print "[10] ".$t->getTime(4)."\n";
     $o_progress->finish("Completed processing");
     if ($o_log) {
         $o_log->logDebug(_t("Ended SIP import"));
     }
     //print "DONE\n\n";
     return true;
 }
Пример #2
0
 /**
  * @param array $pa_options
  *		progressCallback =
  *		reportCallback = 
  *		sendMail = 
  */
 public static function importMediaFromDirectory($po_request, $pa_options = null)
 {
     global $g_ui_locale_id;
     $t_object = new ca_objects();
     $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();
     }
     $o_log = new Batchlog(array('user_id' => $po_request->getUserID(), 'batch_type' => 'MI', 'table_num' => (int) $t_object->tableNum(), 'notes' => '', 'transaction' => $o_trans));
     if (!is_dir($pa_options['importFromDirectory'])) {
         $o_eventlog->log(array("CODE" => 'ERR', "SOURCE" => "mediaImport", "MESSAGE" => "Specified import directory is invalid"));
         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" => "Specified import directory is invalid"));
         return null;
     }
     if (preg_match("!/\\.\\.!", $vs_directory) || preg_match("!\\.\\./!", $pa_options['importFromDirectory'])) {
         $o_eventlog->log(array("CODE" => 'ERR', "SOURCE" => "mediaImport", "MESSAGE" => "Specified import directory is invalid"));
         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_object_type_id = $pa_options['ca_objects_type_id'];
     $vn_rep_type_id = $pa_options['ca_object_representations_type_id'];
     $vn_object_access = $pa_options['ca_objects_access'];
     $vn_object_representation_access = $pa_options['ca_object_representations_access'];
     $vn_object_status = $pa_options['ca_objects_status'];
     $vn_object_representation_status = $pa_options['ca_object_representations_status'];
     $vs_idno_mode = $pa_options['idnoMode'];
     $vs_idno = $pa_options['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'];
     $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);
     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' => 'ca_objects', '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_object->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' => _t('Failed to create set %1: %2', $vs_set_create_name, join("; ", $t_set->getErrors())), 'status' => 'SET ERROR');
                 } 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' => _t('Failed to add label to set: %1', join("; ", $t_set->getErrors())), 'status' => 'SET ERROR');
                     }
                     $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' => _t('Cannot add to set %1 because you do not have edit access', $vs_set_create_name), 'status' => 'SET ERROR');
         $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 = $po_request->config->getAssoc('mediaFilenameToObjectIdnoRegexes');
     if (!is_array($va_regex_list)) {
         $va_regex_list = array();
     }
     // 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)) {
             continue;
         }
         $vs_relative_directory = preg_replace("!{$vs_batch_media_import_root_directory}[/]*!", "", $vs_directory);
         // does representation already exist?
         if (ca_object_representations::mediaExists($vs_file)) {
             $va_notices[$vs_relative_directory . '/' . $f] = array('idno' => '', 'label' => $f, 'message' => _t('Skipped %1 from %2 because it already exists', $f, $vs_relative_directory), 'status' => 'SKIPPED');
             continue;
         }
         $t_object = new ca_objects();
         $t_object->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) {
                 foreach ($va_regex_info['regexes'] as $vs_regex) {
                     $va_names_to_match = array();
                     switch ($vs_match_mode) {
                         case 'DIRECTORY_NAME':
                             $va_names_to_match = array($d);
                             break;
                         case 'FILE_AND_DIRECTORY_NAMES':
                             $va_names_to_match = array($f, $d);
                             break;
                         default:
                         case 'FILE_NAME':
                             $va_names_to_match = array($f);
                             break;
                     }
                     foreach ($va_names_to_match as $vs_match_name) {
                         if (preg_match('!' . $vs_regex . '!', $vs_match_name, $va_matches)) {
                             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 ($t_object->load(array('idno' => $va_matches[1], 'deleted' => 0))) {
                                     $va_notices[$vs_relative_directory . '/' . $vs_match_name . '_match'] = array('idno' => $t_object->get($t_object->getProperty('ID_NUMBERING_ID_FIELD')), 'label' => $t_object->getLabelForDisplay(), 'message' => _t('Matched media %1 from %2 to object using %2', $f, $vs_relative_directory, $vs_regex_name), 'status' => 'MATCHED');
                                     break 3;
                                 }
                             }
                         }
                     }
                 }
             }
         }
         if (!$t_object->getPrimaryKey()) {
             // Use filename as idno if all else fails
             if ($t_object->load(array('idno' => $f, 'deleted' => 0))) {
                 $va_notices[$vs_relative_directory . '/' . $f . '_match'] = array('idno' => $t_object->get($t_object->getProperty('ID_NUMBERING_ID_FIELD')), 'label' => $t_object->getLabelForDisplay(), 'message' => _t('Matched media %1 from %2 to object using filename', $f, $vs_relative_directory), 'status' => 'MATCHED');
             }
         }
         $t_new_rep = null;
         if ($t_object->getPrimaryKey()) {
             // found existing object
             $t_object->setMode(ACCESS_WRITE);
             $t_new_rep = $t_object->addRepresentation($vs_directory . '/' . $f, $vn_rep_type_id, $vn_locale_id, $vn_object_representation_status, $vn_object_representation_access, false, array(), array('original_filename' => $f, 'returnRepresentation' => true));
             if ($t_object->numErrors()) {
                 $o_eventlog->log(array("CODE" => 'ERR', "SOURCE" => "mediaImport", "MESSAGE" => "Error importing {$f} from {$vs_directory}: " . join('; ', $t_object->getErrors())));
                 $va_errors[$vs_relative_directory . '/' . $f] = array('idno' => $t_object->get($t_object->getProperty('ID_NUMBERING_ID_FIELD')), 'label' => $t_object->getLabelForDisplay(), 'errors' => $t_object->errors(), 'message' => _t("Error importing %1 from %2: %3", $f, $vs_relative_directory, join('; ', $t_object->getErrors())), 'status' => 'ERROR');
                 $o_trans->rollback();
                 continue;
             } else {
                 if ($vb_delete_media_on_import) {
                     @unlink($vs_directory . '/' . $f);
                 }
             }
         } else {
             // should we create new object?
             if (in_array($vs_import_mode, array('TRY_TO_MATCH', 'DONT_MATCH'))) {
                 $t_object->setMode(ACCESS_WRITE);
                 $t_object->set('type_id', $vn_object_type_id);
                 $t_object->set('locale_id', $vn_locale_id);
                 $t_object->set('status', $vn_object_status);
                 $t_object->set('access', $vn_object_access);
                 switch ($vs_idno_mode) {
                     case 'filename':
                         // use the filename as identifier
                         $t_object->set('idno', $f);
                         break;
                     case 'directory_and_filename':
                         // use the directory + filename as identifier
                         $t_object->set('idno', $d . '/' . $f);
                         break;
                     default:
                         // Calculate identifier using numbering plugin
                         $o_numbering_plugin = $t_object->getIDNoPlugInInstance();
                         if (!($vs_sep = $o_numbering_plugin->getSeparator())) {
                             $vs_sep = '';
                         }
                         if (!is_array($va_idno_values = $o_numbering_plugin->htmlFormValuesAsArray('idno', $vs_object_idno, false, false, true))) {
                             $va_idno_values = array();
                         }
                         $t_object->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_object->insert();
                 if ($t_object->numErrors()) {
                     $o_eventlog->log(array("CODE" => 'ERR', "SOURCE" => "mediaImport", "MESSAGE" => "Error creating new object while importing {$f} from {$vs_relative_directory}: " . join('; ', $t_object->getErrors())));
                     $va_errors[$vs_relative_directory . '/' . $f] = array('idno' => $t_object->get($t_object->getProperty('ID_NUMBERING_ID_FIELD')), 'label' => $t_object->getLabelForDisplay(), 'errors' => $t_object->errors(), 'message' => _t("Error creating new object while importing %1 from %2: %3", $f, $vs_relative_directory, join('; ', $t_object->getErrors())), 'status' => 'ERROR');
                     $o_trans->rollback();
                     continue;
                 }
                 $t_object->addLabel(array('name' => $f), $vn_locale_id, null, true);
                 if ($t_object->numErrors()) {
                     $o_eventlog->log(array("CODE" => 'ERR', "SOURCE" => "mediaImport", "MESSAGE" => "Error creating object label while importing {$f} from {$vs_relative_directory}: " . join('; ', $t_object->getErrors())));
                     $va_errors[$vs_relative_directory . '/' . $f] = array('idno' => $t_object->get($t_object->getProperty('ID_NUMBERING_ID_FIELD')), 'label' => $t_object->getLabelForDisplay(), 'errors' => $t_object->errors(), 'message' => _t("Error creating object label while importing %1 from %2: %3", $f, $vs_relative_directory, join('; ', $t_object->getErrors())), 'status' => 'ERROR');
                     $o_trans->rollback();
                     continue;
                 }
                 $t_new_rep = $t_object->addRepresentation($vs_directory . '/' . $f, $vn_rep_type_id, $vn_locale_id, $vn_object_representation_status, $vn_object_representation_access, true, array(), array('original_filename' => $f, 'returnRepresentation' => true));
                 if ($t_object->numErrors()) {
                     $o_eventlog->log(array("CODE" => 'ERR', "SOURCE" => "mediaImport", "MESSAGE" => "Error importing {$f} from {$vs_relative_directory}: " . join('; ', $t_object->getErrors())));
                     $va_errors[$vs_relative_directory . '/' . $f] = array('idno' => $t_object->get($t_object->getProperty('ID_NUMBERING_ID_FIELD')), 'label' => $t_object->getLabelForDisplay(), 'errors' => $t_object->errors(), 'message' => _t("Error importing %1 from %2: %3", $f, $vs_relative_directory, join('; ', $t_object->getErrors())), 'status' => 'ERROR');
                     $o_trans->rollback();
                     continue;
                 } else {
                     if ($vb_delete_media_on_import) {
                         @unlink($vs_directory . '/' . $f);
                     }
                 }
             }
         }
         if ($t_object->getPrimaryKey()) {
             $va_notices[$t_object->getPrimaryKey()] = array('idno' => $t_object->get($t_object->getProperty('ID_NUMBERING_ID_FIELD')), 'label' => $t_object->getLabelForDisplay(), 'message' => _t('Imported %1 as %2', $f, $t_object->get($t_object->getProperty('ID_NUMBERING_ID_FIELD'))), 'status' => 'SUCCESS');
             if ($vn_set_id) {
                 $t_set->addItem($t_object->getPrimaryKey(), null, $po_request->getUserID());
             }
             $o_log->addItem($t_object->getPrimaryKey(), $t_object->getErrors());
             // 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_object->getAppDatamodel()->getInstanceByTableName($vs_rel_table);
                         if ($t_rel->load(array($t_rel->getProperty('ID_NUMBERING_ID_FIELD') => $vs_idno))) {
                             $t_object->addRelationship($vs_rel_table, $t_rel->getPrimaryKey(), $va_relationship_type_id_for[$vs_rel_table]);
                             if (!$t_object->numErrors()) {
                                 $va_notices[$t_object->getPrimaryKey() . '_rel'] = array('idno' => $t_object->get($t_object->getProperty('ID_NUMBERING_ID_FIELD')), 'label' => $vs_label = $t_object->getLabelForDisplay(), 'message' => _t('Added relationship between <em>%1</em> and %2 <em>%3</em>', $vs_label, $t_rel->getProperty('NAME_SINGULAR'), $t_rel->getLabelForDisplay()), 'status' => 'RELATED');
                             } else {
                                 $va_notices[$t_object->getPrimaryKey()] = array('idno' => $t_object->get($t_object->getProperty('ID_NUMBERING_ID_FIELD')), 'label' => $vs_label = $t_object->getLabelForDisplay(), 'message' => _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_object->getErrors())), 'status' => 'ERROR');
                             }
                         }
                     }
                 }
             }
         } else {
             $va_notices[$vs_relative_directory . '/' . $f] = array('idno' => '', 'label' => $f, 'message' => $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');
         }
         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_object->get($t_object->getProperty('ID_NUMBERING_ID_FIELD')), $vn_c, $vn_num_items), $t_new_rep, time() - $vn_start_time, memory_get_usage(true), sizeof($va_notices), 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), sizeof($va_notices), 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' => sizeof($va_notices), 'batchSize' => $vn_num_items, 'table' => 'ca_objects', 'set_id' => $t_set->getPrimaryKey(), 'setName' => $t_set->getLabelForDisplay());
         $ps_callback($po_request, $va_general, $va_notices, $va_errors);
     }
     $o_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' => sizeof($va_notices), '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));
     }
     return array('errors' => $va_errors, 'notices' => $va_notices, 'processing_time' => caFormatInterval($vn_elapsed_time));
 }