public function info($pa_parameters)
 {
     AssetLoadManager::register('panel');
     parent::info($pa_parameters);
     $vn_annotation_id = isset($pa_parameters['annotation_id']) ? $pa_parameters['annotation_id'] : null;
     $t_annotation = new ca_representation_annotations($vn_annotation_id);
     $t_rep = new ca_object_representations($t_annotation->get('representation_id'));
     if ($vn_annotation_id) {
         $this->view->setVar('screen', $this->request->getActionExtra());
         // name of screen
         // find object editor screen with media bundle
         $t_ui = ca_editor_uis::loadDefaultUI('ca_object_representations', $this->request, $t_rep->getTypeID());
         $this->view->setVar('representation_editor_screen', $t_ui->getScreenWithBundle('ca_representation_annotations', $this->request));
     }
     return $this->render('widget_representation_annotation_info_html.php', true);
 }
Esempio n. 2
0
					<div id='setItemContainer<?php 
            print $vn_item_id;
            ?>
' class='imagecontainer'>
						<div class='remove'><a href='#' class='setDeleteButton' id='setItemDelete<?php 
            print $vn_item_id;
            ?>
'>X</a></div>
						<div class='setItemThumbnail'>
<?php 
            $vn_num_reps_selected = is_array($va_item['selected_representations']) ? sizeof($va_item['selected_representations']) : 0;
            if ($vn_num_reps_selected == 0 && $va_item['representation_tag_thumbnail']) {
                print caNavLink($this->request, $va_item['representation_tag_thumbnail'], '', 'Detail', 'Object', 'Show', array('object_id' => $va_item['row_id']));
            } else {
                if ($vn_num_reps_selected > 0) {
                    $t_rep = new ca_object_representations($va_item['selected_representations'][0]);
                    print caNavLink($this->request, $t_rep->getMediaTag('media', 'thumbnail'), '', 'Detail', 'Object', 'Show', array('object_id' => $va_item['row_id']));
                }
            }
            $vs_title = '';
            if ($va_item['name']) {
                if (mb_strlen($va_item['name']) > 70) {
                    $vs_title .= '<em>' . mb_substr($va_item['name'], 0, 67) . '...</em>';
                } else {
                    $vs_title .= '<em>' . $va_item['name'] . '</em>';
                }
            }
            if ($va_item['idno']) {
                $vs_title .= " (" . $va_item['idno'] . ")";
            }
            ?>
Esempio n. 3
0
 /**
  * Get a record summary that is easier to parse when importing to another system
  */
 private function getItemInfoForImport()
 {
     if (!($t_instance = $this->_getTableInstance($this->ops_table, $this->opn_id))) {
         return false;
     }
     $o_dm = Datamodel::load();
     $t_list = new ca_lists();
     $t_locales = new ca_locales();
     //
     // Options
     //
     if (!($vs_delimiter = $this->opo_request->getParameter('delimiter', pString))) {
         $vs_delimiter = "; ";
     }
     if (!($vs_flatten = $this->opo_request->getParameter('flatten', pString))) {
         $vs_flatten = null;
     }
     $va_flatten = preg_split("![ ]*[;]+[ ]*!", $vs_flatten);
     $va_flatten = array_flip($va_flatten);
     $va_locales = $t_locales->getLocaleList(array("available_for_cataloguing_only" => true));
     $va_return = array();
     // allow user-defined template to be passed; allows flexible formatting of returned "display" value
     if (!($vs_template = $this->opo_request->getParameter('template', pString))) {
         $vs_template = '';
     }
     if ($vs_template) {
         $va_return['display'] = caProcessTemplateForIDs($vs_template, $this->ops_table, array($this->opn_id));
     }
     // "intrinsic" fields
     foreach ($t_instance->getFieldsArray() as $vs_field_name => $va_field_info) {
         $vs_list = null;
         if (!is_null($vs_val = $t_instance->get($vs_field_name))) {
             if (preg_match("/^hier\\_/", $vs_field_name)) {
                 continue;
             }
             if (preg_match("/\\_sort\$/", $vs_field_name)) {
                 continue;
             }
             if ($vs_field_name == $t_instance->primaryKey()) {
                 continue;
             }
             if (isset($va_field_info["LIST_CODE"])) {
                 // typical example: type_id
                 $va_item = $t_list->getItemFromListByItemID($va_field_info["LIST_CODE"], $vs_val);
                 if ($t_item = new ca_list_items($va_item["item_id"])) {
                     $vs_val = $t_item->get('idno');
                 }
             }
             $va_return['intrinsic'][$vs_field_name] = $vs_val;
         }
     }
     // preferred labels
     $va_labels = $t_instance->get($this->ops_table . ".preferred_labels", array("returnAllLocales" => true));
     $va_labels = end($va_labels);
     $vs_display_field_name = $t_instance->getLabelDisplayField();
     if (is_array($va_labels)) {
         foreach ($va_labels as $vn_locale_id => $va_labels_by_locale) {
             foreach ($va_labels_by_locale as $va_tmp) {
                 $va_label = array();
                 $va_label['locale'] = $va_locales[$vn_locale_id]["code"];
                 // add only UI fields to return
                 foreach (array_merge($t_instance->getLabelUIFields(), array('type_id')) as $vs_label_fld) {
                     $va_label[$vs_label_fld] = $va_tmp[$vs_label_fld];
                 }
                 $va_label[$vs_label_fld] = $va_tmp[$vs_label_fld];
                 $va_label['label'] = $va_tmp[$vs_display_field_name];
                 $va_return["preferred_labels"][$va_label['locale']] = $va_label;
             }
         }
         if (isset($va_flatten['locales'])) {
             $va_return["preferred_labels"] = array_pop(caExtractValuesByUserLocale(array($va_return["preferred_labels"])));
         }
     }
     // nonpreferred labels
     $va_labels = $t_instance->get($this->ops_table . ".nonpreferred_labels", array("returnAllLocales" => true));
     $va_labels = end($va_labels);
     if (is_array($va_labels)) {
         foreach ($va_labels as $vn_locale_id => $va_labels_by_locale) {
             foreach ($va_labels_by_locale as $va_tmp) {
                 $va_label = array();
                 $va_label['locale'] = $va_locales[$vn_locale_id]["code"];
                 // add only UI fields to return
                 foreach (array_merge($t_instance->getLabelUIFields(), array('type_id')) as $vs_label_fld) {
                     $va_label[$vs_label_fld] = $va_tmp[$vs_label_fld];
                 }
                 $va_return["nonpreferred_labels"][$va_label['locale']] = $va_label;
             }
         }
         if (isset($va_flatten['locales'])) {
             $va_return["nonpreferred_labels"] = array_pop(caExtractValuesByUserLocale(array($va_return["nonpreferred_labels"])));
         }
     }
     // attributes
     $va_codes = $t_instance->getApplicableElementCodes();
     foreach ($va_codes as $vs_code) {
         if ($va_vals = $t_instance->get($this->ops_table . "." . $vs_code, array("convertCodesToDisplayText" => false, "returnAllLocales" => true))) {
             $va_vals_as_text = end($t_instance->get($this->ops_table . "." . $vs_code, array("convertCodesToDisplayText" => true, "returnAllLocales" => true)));
             $va_vals_by_locale = end($va_vals);
             foreach ($va_vals_by_locale as $vn_locale_id => $va_locale_vals) {
                 foreach ($va_locale_vals as $vs_val_id => $va_actual_data) {
                     if (!is_array($va_actual_data)) {
                         continue;
                     }
                     $vs_locale_code = isset($va_locales[$vn_locale_id]["code"]) ? $va_locales[$vn_locale_id]["code"] : "none";
                     foreach ($va_actual_data as $vs_f => $vs_v) {
                         if (isset($va_vals_as_text[$vn_locale_id][$vs_val_id][$vs_f]) && $vs_v != $va_vals_as_text[$vn_locale_id][$vs_val_id][$vs_f]) {
                             $va_actual_data[$vs_f . '_display'] = $va_vals_as_text[$vn_locale_id][$vs_val_id][$vs_f];
                             if ($vs_item_idno = caGetListItemIdno($va_actual_data[$vs_f])) {
                                 $va_actual_data[$vs_f] = $vs_item_idno;
                             }
                         }
                     }
                     $va_return['attributes'][$vs_code][$vs_locale_code][] = array_merge(array('locale' => $vs_locale_code), $va_actual_data);
                 }
             }
         }
     }
     if (isset($va_flatten['locales'])) {
         $va_return['attributes'] = caExtractValuesByUserLocale($va_return['attributes']);
     }
     // relationships
     // yes, not all combinations between these tables have
     // relationships but it also doesn't hurt to query
     foreach ($this->opa_valid_tables as $vs_rel_table) {
         $t_rel = $o_dm->getInstanceByTableName($vs_rel_table, true);
         //
         // set-related hacks
         if ($this->ops_table == "ca_sets" && $vs_rel_table == "ca_tours") {
             // throw SQL error in getRelatedItems
             continue;
         }
         $va_related_items = $t_instance->get($vs_rel_table, array("returnAsArray" => true, 'returnLocaleCodes' => true, 'groupFields' => true));
         if ($this->ops_table == "ca_objects" && $vs_rel_table == "ca_object_representations") {
             $va_versions = $t_instance->getMediaVersions('media');
             if (isset($va_flatten['all'])) {
                 $va_reps = $t_instance->getRepresentations(array('original'));
                 $va_urls = array();
                 foreach ($va_reps as $vn_i => $va_rep) {
                     $va_urls[] = $va_rep['urls']['original'];
                 }
                 $va_return['representations'] = join($vs_delimiter, $va_urls);
             } else {
                 $va_return['representations'] = $t_instance->getRepresentations($va_versions);
             }
             foreach ($va_return['representations'] as $vn_i => $va_rep) {
                 unset($va_return['representations'][$vn_i]['media']);
                 unset($va_return['representations'][$vn_i]['media_metadata']);
             }
         }
         if (is_array($va_related_items) && sizeof($va_related_items) > 0) {
             foreach ($va_related_items as $va_rel_item) {
                 $va_item_add = array();
                 foreach ($va_rel_item as $vs_fld => $vs_val) {
                     if (!is_array($vs_val) && strlen(trim($vs_val)) > 0) {
                         // rewrite and ignore certain field names
                         switch ($vs_fld) {
                             case 'item_type_id':
                                 $va_item_add[$vs_fld] = $vs_val;
                                 $va_item_add['type_id'] = $vs_val;
                                 break;
                             default:
                                 $va_item_add[$vs_fld] = $vs_val;
                                 break;
                         }
                     } else {
                         if (in_array($vs_fld, array('preferred_labels', 'intrinsic'))) {
                             $va_item_add[$vs_fld] = $vs_val;
                         }
                     }
                 }
                 if ($vs_rel_table == "ca_object_representations") {
                     $t_rep = new ca_object_representations($va_rel_item['representation_id']);
                     $va_item_add['media'] = $t_rep->getMediaUrl('media', 'original');
                 }
                 $va_return["related"][$vs_rel_table][] = $va_item_add;
             }
         }
     }
     return $va_return;
 }
 /**
  * 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;
 }
 /** 
  * Check it a file already exists in the database as a representation
  *
  * @param string $ps_filepath The full path to the file
  * @return mixed ca_object_representations instance representing the first representation that contains the file, if representation exists with this file, false if the file does not yet exist
  */
 static function mediaExists($ps_filepath)
 {
     if (!file_exists($ps_filepath)) {
         return null;
     }
     $vs_md5 = md5_file($ps_filepath);
     $t_rep = new ca_object_representations();
     if ($t_rep->load(array('md5' => $vs_md5, 'deleted' => 0))) {
         return $t_rep;
     }
     return false;
 }
 /**
  * Returns list of valid template placeholders for the specified bundle. These placeholders always begin
  * with a caret ("^") and will be replaced with content values when a bundle display is rendered by xxx()
  * 
  * @param $ps_bundle_name - name of bundle
  * @return array - list of placeholders as keys; values are text description of value; will return null if bundle name is invalid
  */
 public function getTemplatePlaceholderListForBundle($ps_bundle_name)
 {
     $o_dm = $this->getAppDatamodel();
     $t_instance = null;
     $va_tmp = explode('.', $ps_bundle_name);
     switch (sizeof($va_tmp)) {
         case 2:
             $vs_table = $va_tmp[0];
             $vs_bundle = $va_tmp[1];
             if ($vs_bundle == 'rel') {
                 $vs_bundle = 'preferred_labels';
             }
             break;
         case 1:
             if (!($t_instance = $o_dm->getInstanceByTableName($va_tmp[0], true))) {
                 $vs_table = $o_dm->getTableName($this->get('table_num'));
                 $vs_bundle = $va_tmp[0];
             } else {
                 $vs_table = $va_tmp[0];
                 $vs_bundle = 'preferred_labels';
             }
             break;
         default:
             return null;
             break;
     }
     if (!$t_instance) {
         if (!($t_instance = $o_dm->getInstanceByTableName($vs_table, true))) {
             return null;
         }
     }
     $va_key = array('^label' => array('label' => _t('Placement label'), 'description' => _t('The label for this placement as defined in the placements settings. The value used will be adjusted to reflect the current user&apos;s locale.')));
     if ($t_instance->hasField($vs_bundle)) {
         // is intrinsic field
         $va_key["^{$vs_bundle}"] = array('label' => $t_instance->getFieldInfo($vs_bundle, 'LABEL'), 'description' => $t_instance->getFieldInfo($vs_bundle, 'DESCRIPTION'));
         return $va_key;
     }
     $va_element_codes = array_flip($t_instance->getApplicableElementCodes(null, false, false));
     if ($va_element_codes[$vs_bundle]) {
         $t_element = new ca_metadata_elements();
         if ($this->inTransaction()) {
             $t_element->setTransaction($this->getTransaction());
         }
         if ($t_element->load(array('element_code' => $vs_bundle))) {
             // is attribute
             $va_hier = $t_element->getElementsInSet();
             if (is_array($va_hier) && sizeof($va_hier) > 0) {
                 // is container with children
                 foreach ($va_hier as $va_node) {
                     if ($va_node['datatype'] == 0) {
                         continue;
                     }
                     // skip containers
                     $va_key['^' . $va_node['element_code']] = array('label' => $t_instance->getAttributeLabel($va_node['element_code']), 'description' => $t_instance->getAttributeDescription($va_node['element_code']));
                 }
                 return $va_key;
             }
             // is simple single-element attribute
             $va_key["^{$vs_bundle}"] = array('label' => $t_instance->getAttributeLabel($vs_bundle), 'description' => $t_instance->getAttributeDescription($vs_bundle));
             return $va_key;
         }
     }
     if ($vs_bundle == 'preferred_labels') {
         if ($t_label = $t_instance->getLabelTableInstance()) {
             foreach ($t_label->getFormFields() as $vs_field => $va_field_info) {
                 $va_key['^' . $vs_field] = array('label' => $va_field_info['LABEL'], 'description' => $va_field_info['DESCRIPTION']);
             }
             return $va_key;
         }
     }
     if ($vs_bundle == 'nonpreferred_labels') {
         if ($t_label = $t_instance->getLabelTableInstance()) {
             foreach ($t_label->getFormFields() as $vs_field => $va_field_info) {
                 $va_key['^' . $vs_field] = array('label' => $va_field_info['LABEL'], 'description' => $va_field_info['DESCRIPTION']);
             }
             return $va_key;
         }
     }
     if ($vs_bundle == 'ca_object_representations') {
         if ($vs_table == 'ca_objects') {
             $t_rep = new ca_object_representations();
             foreach ($t_rep->getFormFields() as $vs_field => $va_field_info) {
                 $va_key['^' . $vs_field] = array('label' => $va_field_info['LABEL'], 'description' => $va_field_info['DESCRIPTION']);
             }
             $va_key['^media:{version name}'] = array('label' => _t('Specified version of media'), 'description' => _t('The version of the media representation specified by {version name} for display.'));
             return $va_key;
         }
     }
     return null;
 }
Esempio n. 7
0
 private function fetchAndImport($pa_item_queue, $po_client, $pa_config, $pa_tables, $ps_code)
 {
     if (!is_array($pa_tables)) {
         $pa_tables = array();
     }
     $t_rel_type = new ca_relationship_types();
     $vs_base_url = $pa_config['baseUrl'];
     $o_dm = Datamodel::load();
     $t_locale = new ca_locales();
     $t_list = new ca_lists();
     $vn_source_id = $t_list->getItemIDFromList('object_sources', $pa_config['code']);
     $pn_rep_type_id = $t_list->getItemIDFromList('object_representation_types', 'front');
     foreach ($pa_item_queue as $vn_i => $va_item) {
         $vs_table = $va_item['table'];
         $va_import_relationships_from = $pa_config['importRelatedFor'][$va_item['table']];
         print "oo";
         print_r($va_import_relationships_from);
         $vn_id = $va_item['id'];
         if (!$vn_id) {
             print "[Notice] SKIP CAUSE NO ID ({$ps_code})\n";
             continue;
         }
         if (isset($this->opa_processed_records[$vs_table . '/' . $vn_id])) {
             continue;
         }
         $vs_idno = trim((string) $va_item['idno']);
         try {
             $o_xml = $po_client->getItem($vs_table, $vn_id)->get();
         } catch (exception $e) {
             print "[ERROR] While trying to get item information: " . $e->getMessage() . "\n";
             continue;
         }
         $o_item = $o_xml->getItem;
         $t_instance = $o_dm->getInstanceByTableName($vs_table, false);
         $t_instance_label = $t_instance->getLabelTableInstance();
         // Look for existing record
         $vb_skip = false;
         $vb_update = false;
         $vs_label_fld = $t_instance->getLabelDisplayField();
         $vs_label = (string) $o_item->preferred_labels->en_US->{$vs_label_fld};
         print "[Notice] Processing [{$vs_table}] {$vs_label} [{$vs_idno}] ({$ps_code})\n";
         $t_instance_label->clear();
         if ($vs_idno && ($vs_table == 'ca_objects' && $t_instance->load(array('idno' => $vs_idno)) || $vs_table != 'ca_objects' && $t_instance->load(array('idno' => $vs_idno)))) {
             if ($t_instance->hasField('deleted') && $t_instance->get('deleted') == 1) {
                 $t_instance->set('deleted', 0);
             }
             //print "[Notice] Update [{$vs_idno}] for {$vs_table} 'cause it already exists ({$ps_code})\n";
             if (!$t_instance->getPrimaryKey()) {
                 $vb_skip = true;
                 print "[ERROR] Could not load instance for [{$vs_idno}]\n";
             }
             $vb_update = true;
             $t_instance->setMode(ACCESS_WRITE);
             // Clear labels
             $t_instance->removeAllLabels();
             if ($t_instance->numErrors()) {
                 print "[ERROR] Could not remove labels for updating: " . join("; ", $t_instance->getErrors()) . "\n";
             }
             // Clear attributes
             $t_instance->removeAttributes(null, array('dontCheckMinMax' => true));
             if ($t_instance->numErrors()) {
                 print "[ERROR] Could not remove attributes for updating: " . join("; ", $t_instance->getErrors()) . "\n";
             }
             // Clear relationships
             if (is_array($va_import_relationships_from)) {
                 foreach ($va_import_relationships_from as $vs_rel_table => $va_table_info) {
                     $t_instance->removeRelationships($vs_rel_table);
                     if ($t_instance->numErrors()) {
                         print "[ERROR] Could not remove {$vs_rel_table} relationships for updating: " . join("; ", $t_instance->getErrors()) . "\n";
                     }
                 }
             }
             if ($t_instance->tableName() == 'ca_objects') {
                 //$t_instance->set('source_id', $vn_source_id);
             }
             $t_instance->update();
             if ($t_instance->numErrors()) {
                 print "[ERROR] Could not clear record for updating: " . join("; ", $t_instance->getErrors()) . "\n";
             }
         }
         // create new one
         if (!$vb_update) {
             $t_instance->clear();
             if ($t_instance->tableName() == 'ca_objects') {
                 //$t_instance->set('source_id', $vn_source_id);
             }
         }
         $t_instance->setMode(ACCESS_WRITE);
         // add intrinsics
         switch ($vs_table) {
             case 'ca_collections':
                 $va_intrinsics = array('status', 'access', 'idno');
                 break;
             case 'ca_occurrences':
                 $va_intrinsics = array('status', 'access', 'idno');
                 break;
             case 'ca_objects':
                 $va_intrinsics = array('status', 'access', 'idno');
                 break;
             case 'ca_entities':
                 $va_intrinsics = array('status', 'access', 'lifespan', 'source_id', 'idno');
                 break;
             case 'ca_object_lots':
                 $va_intrinsics = array('status', 'access', 'idno_stub');
                 break;
             default:
                 $va_intrinsics = array('status', 'access', 'idno');
                 break;
         }
         // TODO: Need to properly handle foreign-key intrinsics when the item they point to doesn't exist
         // eg. source_id fields, various ca_objects and ca_object_lots intrinsics, etc.
         if ($vs_table == 'ca_list_items') {
             // does list exist?
             $vs_list_code = (string) $o_item->{'list_code'};
             $t_list = new ca_lists();
             if (!$t_list->load(array('list_code' => $vs_list_code))) {
                 // create list
                 $t_list->setMode(ACCESS_WRITE);
                 // TODO: should we bother to replicate the is_hierarchical, use_as_vocabulary and default_sort settings via a service?
                 // For now just set reasonable values
                 $t_list->set('list_code', $vs_list_code);
                 $t_list->set('is_hierarchical', 1);
                 $t_list->set('use_as_vocabulary', 1);
                 $t_list->set('default_sort', 0);
                 $t_list->insert();
                 if ($t_list->numErrors()) {
                     print "[ERROR] Could not insert new list '{$vs_list_code}': " . join('; ', $t_list->getErrors()) . "\n";
                 } else {
                     $t_list->addLabel(array('name' => $vs_list_code), $pn_locale_id, null, true);
                     if ($t_list->numErrors()) {
                         print "[ERROR] Could not add label to new list '{$vs_list_code}': " . join('; ', $t_list->getErrors()) . "\n";
                     }
                 }
             }
             $t_instance->set('list_id', $t_list->getPrimaryKey());
         }
         foreach ($va_intrinsics as $vs_f) {
             $t_instance->set($vs_f, $o_item->{$vs_f});
         }
         if (!$vb_update) {
             $vn_type_id = $t_instance->getTypeIDForCode((string) $o_item->type_id);
             if (!$vn_type_id) {
                 print "NO TYPE FOR {$vs_table}/" . $o_item->type_id . "\n";
             }
             $t_instance->set('type_id', $vn_type_id);
             if ($t_instance->tableName() == 'ca_objects') {
                 //$t_instance->set('source_id', $vn_source_id);
             }
             // TODO: add hook onBeforeInsert()
             $t_instance->insert();
             // TODO: add hook onInsert()
             if ($t_instance->numErrors()) {
                 print "[ERROR] Could not insert record: " . join('; ', $t_instance->getErrors()) . "\n";
             }
         }
         // add attributes
         // TODO: make this configurable
         $va_codes = $t_instance->getApplicableElementCodes();
         // $va_codes = array(
         // 				'description',
         // 				'georeference', 'geonames', 'internal_notes',
         // 				'oclc_number', 'file_name',
         // 				'digitized_by', 'digitized_date', 'call_number',
         // 				'other_call_number', 'collection_title', 'collection_number',
         // 				'box_number', 'folder_number', 'volume_number', 'page_number', 'shelf',
         // 				'pulled_digitization', 'pulled_name', 'pulled_date', 'returned_digitization',
         // 				'returned_name', 'returned_date', 'needs_redigitization', 'donor', 'copyright_holder',
         // 				'reproduction_restrictions', 'administrative_notes', 'date_view', 'date_item',
         // 				'view_format', 'item_format', 'dimensions', 'map_scale', 'image_description', 'address',
         // 				'lcsh_terms',  'inscription'
         //
         // 			);
         foreach ($va_codes as $vs_code) {
             $t_element = $t_instance->_getElementInstance($vs_code);
             switch ($t_element->get('datatype')) {
                 case 0:
                     // container
                     $va_elements = $t_element->getElementsInSet();
                     $o_attr = $o_item->{'ca_attribute_' . $vs_code};
                     foreach ($o_attr as $va_tag => $o_tags) {
                         foreach ($o_tags as $vs_locale => $o_values) {
                             if (!($vn_locale_id = $t_locale->localeCodeToID($vs_locale))) {
                                 $vn_locale_id = null;
                             }
                             $va_container_data = array('locale_id' => $vn_locale_id);
                             foreach ($o_values as $o_value) {
                                 foreach ($va_elements as $vn_i => $va_element_info) {
                                     if ($va_element_info['datatype'] == 0) {
                                         continue;
                                     }
                                     if ($vs_value = trim((string) $o_value->{$va_element_info['element_code']})) {
                                         switch ($va_element_info['datatype']) {
                                             case 3:
                                                 //list
                                                 $va_tmp = explode(":", $vs_value);
                                                 //<item_id>:<item_idno>
                                                 //print "CONTAINER LIST CODE=".$va_tmp[1]."/$vs_value/".$va_element_info['list_id']."\n";
                                                 $va_container_data[$va_element_info['element_code']] = $t_list->getItemIDFromList($va_element_info['list_id'], $va_tmp[1]);
                                                 break;
                                             default:
                                                 $va_container_data[$va_element_info['element_code']] = $vs_value;
                                                 break;
                                         }
                                     }
                                 }
                                 $t_instance->replaceAttribute($va_container_data, $vs_code);
                             }
                         }
                     }
                     break;
                 case 3:
                     // list
                     $o_attr = $o_item->{'ca_attribute_' . $vs_code};
                     foreach ($o_attr as $va_tag => $o_tags) {
                         foreach ($o_tags as $vs_locale => $o_values) {
                             if (!($vn_locale_id = $t_locale->localeCodeToID($vs_locale))) {
                                 $vn_locale_id = null;
                             }
                             foreach ($o_values as $o_value) {
                                 if ($vs_value = trim((string) $o_value->{$vs_code})) {
                                     $va_tmp = explode(":", $vs_value);
                                     //<item_id>:<item_idno>
                                     // TODO: create lists and list items if they don't already exist
                                     if ($vn_item_id = $t_list->getItemIDFromList($t_element->get('list_id'), $va_tmp[1])) {
                                         $t_instance->replaceAttribute(array($vs_code => $vn_item_id, 'locale_id' => $vn_locale_id), $vs_code);
                                     }
                                 }
                             }
                         }
                     }
                     break;
                 case 15:
                     // File
                 // File
                 case 16:
                     // Media
                     $t_instance->update();
                     if ($t_instance->numErrors()) {
                         print "[ERROR] Could not update record before media: " . join('; ', $t_instance->getErrors()) . "\n";
                     }
                     // TODO: detect if media has changes and only pull if it has
                     $o_attr = $o_item->{'ca_attribute_' . $vs_code};
                     foreach ($o_attr as $va_tag => $o_tags) {
                         foreach ($o_tags as $vs_locale => $o_values) {
                             if (!($vn_locale_id = $t_locale->localeCodeToID($vs_locale))) {
                                 $vn_locale_id = null;
                             }
                             foreach ($o_values as $o_value) {
                                 if ($vs_value = trim((string) $o_value->{$vs_code})) {
                                     $t_instance->replaceAttribute(array($vs_code => $vs_value, 'locale_id' => $vn_locale_id), $vs_code);
                                 }
                             }
                         }
                     }
                     $t_instance->update();
                     if ($t_instance->numErrors()) {
                         print "[ERROR] Could not update record after media: " . join('; ', $t_instance->getErrors()) . "\n";
                     }
                     break;
                 default:
                     $o_attr = $o_item->{'ca_attribute_' . $vs_code};
                     foreach ($o_attr as $va_tag => $o_tags) {
                         foreach ($o_tags as $vs_locale => $o_values) {
                             if (!($vn_locale_id = $t_locale->localeCodeToID($vs_locale))) {
                                 $vn_locale_id = null;
                             }
                             foreach ($o_values as $o_value) {
                                 if ($vs_value = trim((string) $o_value->{$vs_code})) {
                                     $t_instance->replaceAttribute(array($vs_code => $vs_value, 'locale_id' => $vn_locale_id), $vs_code);
                                 }
                             }
                         }
                     }
                     break;
             }
         }
         $t_instance->update();
         if ($t_instance->numErrors()) {
             print "[ERROR] Could not update [1] record: " . join('; ', $t_instance->getErrors()) . "\n";
         }
         // TODO: add hook onBeforeUpdate()
         $t_instance->update();
         // TODO: add hook onUpdate()
         if ($t_instance->numErrors()) {
             print "[ERROR] Could not update [2] record: " . join('; ', $t_instance->getErrors()) . "\n";
         }
         // get label fields
         $va_label_data = array();
         foreach ($t_instance->getLabelUIFields() as $vs_field) {
             if (!($va_label_data[$vs_field] = $o_item->preferred_labels->en_US->{$vs_field})) {
                 $va_label_data[$vs_field] = $o_item->preferred_labels->en_US->{$vs_field};
             }
         }
         // TODO: add hook onBeforeAddLabel()
         $t_instance->addLabel($va_label_data, 1, null, true);
         // TODO: add hook onAddLabel()
         if ($t_instance->numErrors()) {
             print "ERROR adding label: " . join('; ', $t_instance->getErrors()) . "\n";
         }
         $this->opa_processed_records[$va_item['table'] . '/' . (int) $va_item['id']] = $t_instance->getPrimaryKey();
         if ($vb_skip) {
             continue;
         }
         if (!is_array($va_import_relationships_from)) {
             continue;
         }
         $pa_tables[$va_item['table']] = true;
         // Are there relationships?
         $pb_imported_self_relations = false;
         print_r($va_import_relationships_from);
         foreach ($va_import_relationships_from as $vs_rel_table => $va_table_info) {
             $vb_is_self_relation = $vs_rel_table == $t_instance->tableName() && !$pb_imported_self_relations ? true : false;
             if (!$pa_tables[$vs_rel_table] || $vb_is_self_relation) {
                 // load related records recursively
                 if ($vs_rel_table == $t_instance->tableName()) {
                     $pb_imported_self_relations = true;
                 }
                 if ($o_item->{'related_' . $vs_rel_table}) {
                     $t_rel = $o_dm->getInstanceByTableName($vs_rel_table, false);
                     // TODO: add hook onBeforeAddRelationships()
                     foreach ($o_item->{'related_' . $vs_rel_table} as $vs_tag => $o_related_items) {
                         foreach ($o_related_items as $vs_i => $o_related_item) {
                             if (is_array($pa_config['importRelatedFor'][$va_item['table']][$vs_rel_table])) {
                                 $va_rel_types = array_keys($pa_config['importRelatedFor'][$va_item['table']][$vs_rel_table]);
                                 if (is_array($va_rel_types) && sizeof($va_rel_types) && !in_array((string) $o_related_item->relationship_type_code, $va_rel_types)) {
                                     print "[INFO] Skipped relationship for {$vs_display_name} because type='" . (string) $o_related_item->relationship_type_code . "' is excluded\n";
                                     continue;
                                 }
                             }
                             $vs_pk = $t_rel->primaryKey();
                             $vn_id = (int) $o_related_item->{$vs_pk};
                             $va_queue = array($vs_rel_table . "/" . $vn_id => array('table' => $vs_rel_table, 'id' => $vn_id, 'idno' => (string) $o_related_item->idno));
                             // TODO: Add from/until support
                             $this->fetchAndImport($va_queue, $po_client, $pa_config, $pa_tables, $ps_code);
                             $vn_rel_record_id = $this->opa_processed_records[$vs_rel_table . '/' . (int) $vn_id];
                             $vb_skip = false;
                             if ($vb_is_self_relation) {
                                 if ($this->opa_processed_self_relations[$vs_rel_table][$vn_rel_record_id][$t_instance->getPrimaryKey()][(string) $o_related_item->relationship_type_code] || $this->opa_processed_self_relations[$vs_rel_table][$t_instance->getPrimaryKey()][$vn_rel_record_id][(string) $o_related_item->relationship_type_code]) {
                                     $vb_skip = true;
                                 } else {
                                     $this->opa_processed_self_relations[$vs_rel_table][$t_instance->getPrimaryKey()][$vn_rel_record_id][(string) $o_related_item->relationship_type_code] = $this->opa_processed_self_relations[$vs_rel_table][$vn_rel_record_id][$t_instance->getPrimaryKey()][(string) $o_related_item->relationship_type_code] = true;
                                 }
                             }
                             if (!$vb_skip) {
                                 $t_instance->addRelationship($vs_rel_table, $vn_rel_record_id, (string) $o_related_item->relationship_type_code);
                                 if ($t_instance->numErrors()) {
                                     print "[ERROR] Could not add relationship to {$vs_rel_table} for row_id={$vn_rel_record_id}: " . join('; ', $t_instance->getErrors()) . "\n";
                                 }
                             }
                         }
                     }
                     // TODO: add hook onAddRelationships()
                 }
             }
         }
         // Is there media?
         if ($t_instance->tableName() == 'ca_objects') {
             try {
                 $o_rep_xml = $po_client->getObjectRepresentations((int) $va_item['id'], array('large', 'original'))->get();
             } catch (exception $e) {
                 print "[ERROR] While getting object representations: " . $e->getMessage() . "\n";
             }
             $va_existing_reps = $t_instance->getRepresentations(array('large', 'original'));
             $va_existing_md5s = array();
             $va_rep_ids = array();
             $va_dupe_reps = array();
             foreach ($va_existing_reps as $va_rep) {
                 if ($va_existing_md5s[$va_rep['info']['original']['MD5']] && $va_existing_md5s[$va_rep['info']['large']['MD5']]) {
                     // dupe
                     $va_dupe_reps[] = $va_rep['representation_id'];
                     continue;
                 }
                 $va_existing_md5s[$va_rep['info']['original']['MD5']] = $va_rep['representation_id'];
                 $va_existing_md5s[$va_rep['info']['large']['MD5']] = $va_rep['representation_id'];
                 $va_rep_ids[] = $va_rep['representation_id'];
             }
             if ($o_rep_xml->getObjectRepresentations) {
                 foreach ($o_rep_xml->getObjectRepresentations as $vs_x => $o_reps) {
                     foreach ($o_reps as $vs_key => $o_rep) {
                         if ($vs_url = trim((string) $o_rep->urls->large)) {
                             $vs_remote_original_md5 = (string) $o_rep->info->original->MD5;
                             $vs_remote_large_md5 = (string) $o_rep->info->large->MD5;
                             if (isset($va_existing_md5s[$vs_remote_original_md5]) && $va_existing_md5s[$vs_remote_original_md5] || isset($va_existing_md5s[$vs_remote_large_md5]) && $va_existing_md5s[$vs_remote_large_md5]) {
                                 print "[NOTICE] Skipping representation at {$vs_url} because it already exists (MD5={$vs_remote_original_md5}/{$vs_remote_large_md5}) ({$ps_code})\n";
                                 if (!($vn_kill_rep_id = $va_existing_md5s[$vs_remote_large_md5])) {
                                     $vn_kill_rep_id = $va_existing_md5s[$vs_remote_original_md5];
                                 }
                                 foreach ($va_existing_md5s as $vs_md5 => $vn_rep_id) {
                                     if ($vn_kill_rep_id == $vn_rep_id) {
                                         $t_existing_rep_link = new ca_objects_x_object_representations();
                                         if ($t_existing_rep_link->load(array('object_id' => $t_instance->getPrimaryKey(), 'representation_id' => $vn_rep_id))) {
                                             $t_existing_rep_link->setMode(ACCESS_WRITE);
                                             //	print "update object_id ".$t_instance->getPrimaryKey()."/rep=$vn_rep_id to rank=".$o_rep->rank."/primary=".$o_rep->is_primary."\n";
                                             $t_existing_rep_link->set('is_primary', (int) $o_rep->is_primary);
                                             $t_existing_rep_link->set('rank', (int) $o_rep->rank);
                                             $t_existing_rep_link->update();
                                             if ($t_existing_rep_link->numErrors()) {
                                                 print_r($t_existing_rep_link->getErrors());
                                             }
                                         }
                                         unset($va_existing_md5s[$vs_md5]);
                                     }
                                 }
                                 continue;
                             }
                             print "[Notice] Importing for [{$vs_idno}] media from {$vs_url}: primary=" . (string) $o_rep->is_primary . " ({$ps_code})\n";
                             print "instance has id=" . $t_instance->getPrimaryKey() . "\n";
                             // TODO: add hook onBeforeAddMedia()
                             $vn_link_id = $t_instance->addRepresentation($vs_url, $pn_rep_type_id, 1, (int) $o_rep->status, (int) $o_rep->access, (int) $o_rep->is_primary);
                             // TODO: add hook onAddMedia()
                             if ($t_instance->numErrors()) {
                                 print "[ERROR] Could not load object representation: " . join("; ", $t_instance->getErrors()) . " ({$ps_code})\n";
                             } else {
                                 $t_link = new ca_objects_x_object_representations($vn_link_id);
                                 $t_new_rep = new ca_object_representations($t_link->get('representation_id'));
                                 //unlink($x=$t_new_rep->getMediaPath('media', 'original'));
                             }
                         }
                     }
                 }
             }
             $va_rep_ids = array();
             foreach ($va_existing_md5s as $vs_md5 => $vn_rep_id) {
                 if ($va_rep_ids[$vn_rep_id]) {
                     continue;
                 }
                 $t_obj_x_rep = new ca_objects_x_object_representations();
                 while ($t_obj_x_rep->load(array('object_id' => $t_instance->getPrimaryKey(), 'representation_id' => $vn_rep_id))) {
                     $t_obj_x_rep->setMode(ACCESS_WRITE);
                     $t_obj_x_rep->delete(true);
                     if ($t_obj_x_rep->numErrors()) {
                         print "[ERROR] Could not load remove object-to-representation link: " . join("; ", $t_obj_x_rep->getErrors()) . " ({$ps_code})\n";
                         break;
                     }
                     if (!$t_obj_x_rep->load(array('representation_id' => $vn_rep_id))) {
                         $t_rep = new ca_object_representations();
                         if ($t_rep->load($vn_rep_id)) {
                             $t_rep->setMode(ACCESS_WRITE);
                             $t_rep->delete(true, array('hard' => true));
                             if ($t_rep->numErrors()) {
                                 print "[ERROR] Could not remove representation: " . join("; ", $t_rep->getErrors()) . "\n";
                                 break;
                             }
                         }
                     }
                 }
                 $va_rep_ids[$vn_rep_id] = true;
             }
             foreach ($va_dupe_reps as $vn_dupe_rep_id) {
                 $t_rep = new ca_object_representations();
                 if ($t_rep->load($vn_dupe_rep_id)) {
                     print "[Notice] DELETE DUPE {$vn_dupe_rep_id}\n";
                     $t_rep->setMode(ACCESS_WRITE);
                     $t_rep->delete(true, array('hard' => true));
                     if ($t_rep->numErrors()) {
                         print "[ERROR] Could not remove dupe representation: " . join("; ", $t_rep->getErrors()) . "\n";
                         break;
                     }
                 }
             }
         }
         unset($pa_tables[$va_item['table']]);
     }
 }
Esempio n. 8
0
 /**
  * 
  */
 public function GetPageListAsJSON()
 {
     $pn_object_id = $this->request->getParameter('object_id', pInteger);
     $pn_representation_id = $this->request->getParameter('representation_id', pInteger);
     $ps_content_mode = $this->request->getParameter('content_mode', pString);
     $this->view->setVar('object_id', $pn_object_id);
     $this->view->setVar('representation_id', $pn_representation_id);
     $this->view->setVar('content_mode', $ps_content_mode);
     $t_rep = new ca_object_representations($pn_representation_id);
     $va_download_display_info = caGetMediaDisplayInfo('download', $t_rep->getMediaInfo('media', 'INPUT', 'MIMETYPE'));
     $vs_download_version = $va_download_display_info['display_version'];
     $this->view->setVar('download_version', $vs_download_version);
     $va_page_list_cache = $this->request->session->getVar('caDocumentViewerPageListCache');
     $va_pages = $va_page_list_cache[$pn_object_id . '/' . $pn_representation_id];
     if (!isset($va_pages)) {
         // Page cache not set?
         $this->postError(1100, _t('Invalid object/representation'), 'DetailController->GetPage');
         return;
     }
     $va_section_cache = $this->request->session->getVar('caDocumentViewerSectionCache');
     $this->view->setVar('pages', $va_pages);
     $this->view->setVar('sections', $va_section_cache[$pn_object_id . '/' . $pn_representation_id]);
     $this->view->setVar('is_searchable', MediaContentLocationIndexer::hasIndexing('ca_object_representations', $pn_representation_id));
     $this->render('Details/object_representation_page_list_json.php');
 }
Esempio n. 9
0
 /**
  * Remove representation from database
  *
  * @param int $representation_id
  * @return boolean
  * @throws SoapFault
  */
 public function removeObjectRepresentation($representation_id)
 {
     require_once __CA_MODELS_DIR__ . "/ca_object_representations.php";
     $t_rep = new ca_object_representations();
     if (!$t_rep->load($representation_id)) {
         throw new SoapFault("Server", "Invalid representation ID");
     }
     $t_rep->delete();
     if ($t_rep->numErrors() == 0) {
         return true;
     } else {
         throw new SoapFault("Server", "There were errors while removing the representation: " . join(";", $t_rep->getErrors()));
     }
 }
Esempio n. 10
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));
 }
 /** 
  * Link existing media represention to currently loaded item
  *
  * @param $pn_representation_id - 
  * @param $pb_is_primary - if set to true, representation is designated "primary." Primary representation are used in cases where only one representation is required (such as search results). If a primary representation is already attached to this item, then it will be changed to non-primary as only one representation can be primary at any given time. If no primary representations exist, then the new representation will always be marked primary no matter what the setting of this parameter (there must always be a primary representation, if representations are defined).
  * @param $pa_options - an array of options passed through to BaseModel::set() when creating the new representation. Currently supported options:
  *		rank - a numeric rank used to order the representations when listed
  *
  * @return mixed Returns primary key (link_id) of the relatipnship row linking the  representation to the item; boolean false is returned on error
  */
 public function linkRepresentation($pn_representation_id, $pb_is_primary, $pa_options = null)
 {
     if (!($vn_id = $this->getPrimaryKey())) {
         return null;
     }
     if (!$pn_locale_id) {
         $pn_locale_id = ca_locales::getDefaultCataloguingLocaleID();
     }
     if (!ca_object_representations::find(array('representation_id' => $pn_representation_id), array('transaction' => $this->getTransaction()))) {
         return null;
     }
     if (!($t_oxor = $this->_getRepresentationRelationshipTableInstance())) {
         return null;
     }
     $vs_pk = $this->primaryKey();
     if ($this->inTransaction()) {
         $t_oxor->setTransaction($this->getTransaction());
     }
     $t_oxor->setMode(ACCESS_WRITE);
     $t_oxor->set($vs_pk, $vn_id);
     $t_oxor->set('representation_id', $pn_representation_id);
     $t_oxor->set('is_primary', $pb_is_primary ? 1 : 0);
     $t_oxor->set('rank', isset($pa_options['rank']) ? (int) $pa_options['rank'] : $pn_representation_id);
     if ($t_oxor->hasField('type_id')) {
         $t_oxor->set('type_id', isset($pa_options['type_id']) ? (int) $pa_options['type_id'] : null);
     }
     $t_oxor->insert();
     if ($t_oxor->numErrors()) {
         $this->errors = array_merge($this->errors, $t_oxor->errors());
         return false;
     }
     return $t_oxor->getPrimaryKey();
 }
Esempio n. 12
0
 /**
  * Returns content for overlay containing details for media attribute
  *
  * Expects the following request parameters: 
  *		value_id = the id of the attribute value (ca_attribute_values) record to display
  *
  *	Optional request parameters:
  *		version = The version of the representation to display. If omitted the display version configured in media_display.conf is used
  *
  */
 public function GetMediaInfo()
 {
     $pn_representation_id = $this->request->getParameter('representation_id', pInteger);
     $pn_value_id = $this->request->getParameter('value_id', pInteger);
     if ($pn_value_id) {
         $t_rep = new ca_object_representations();
         $t_attr_val = new ca_attribute_values($pn_value_id);
         $t_attr = new ca_attributes($t_attr_val->get('attribute_id'));
         $t_subject = $this->opo_datamodel->getInstanceByTableNum($t_attr->get('table_num'), true);
         $t_subject->load($t_attr->get('row_id'));
         $va_rep_display_info = caGetMediaDisplayInfo('media_overlay', $t_attr_val->getMediaInfo('value_blob', 'INPUT', 'MIMETYPE'));
         // check subject_id here
         $va_opts = array('t_attribute_value' => $t_attr_val, 'display' => 'media_overlay', 't_subject' => $t_subject, 'containerID' => 'caMediaPanelContentArea');
         if (strlen($vs_use_book_viewer = $this->request->getParameter('use_book_viewer', pInteger))) {
             $va_opts['use_book_viewer'] = (bool) $vs_use_book_viewer;
         }
         $this->response->addContent(caGetMediaViewerHTMLBundle($this->request, $va_opts));
     } elseif ($pn_representation_id) {
         $t_rep = new ca_object_representations($pn_representation_id);
         $t_subject = new ca_objects($vn_subject_id = $this->request->getParameter('object_id', pInteger));
         if (!$vn_subject_id) {
             if (is_array($va_subject_ids = $t_rep->get($t_subject->tableName() . '.' . $t_subject->primaryKey(), array('returnAsArray' => true))) && sizeof($va_subject_ids)) {
                 $vn_subject_id = array_shift($va_subject_ids);
             } else {
                 $this->postError(1100, _t('Invalid object/representation'), 'ObjectEditorController->GetRepresentationInfo');
                 return;
             }
         }
         $va_opts = array('display' => 'media_overlay', 't_subject' => $t_subject, 't_representation' => $t_rep, 'containerID' => 'caMediaPanelContentArea');
         if (strlen($vs_use_book_viewer = $this->request->getParameter('use_book_viewer', pInteger))) {
             $va_opts['use_book_viewer'] = (bool) $vs_use_book_viewer;
         }
         $this->response->addContent(caGetMediaViewerHTMLBundle($this->request, $va_opts));
     } else {
         //
     }
     //$pn_value_id 	= $this->request->getParameter('value_id', pInteger);
     //$this->response->addContent(caGetMediaViewerHTMLBundle($this->request, array('display' => 'media_overlay', 't_attribute_value' => $pn_value_id, 'containerID' => 'caMediaPanelContentArea')));
 }
Esempio n. 13
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));
 }
 /**
  * Remove a single representation from the currently loaded object. Note that the representation will be removed from the database completely, so if it is also linked to other items it will be removed from them as well.
  *
  * @param int $pn_representation_id The representation_id of the representation to remove
  * @param array $pa_options Options are passed through to BaseMode::delete()
  * @return bool True if delete succeeded, false if there was an error. You can get the error messages by calling getErrors() on the instance.
  */
 public function removeRepresentation($pn_representation_id, $pa_options = null)
 {
     if (!$this->getPrimaryKey()) {
         return null;
     }
     $va_path = array_keys($this->getAppDatamodel()->getPath($this->tableName(), 'ca_object_representations'));
     if (is_array($va_path) && sizeof($va_path) == 3) {
         $vs_rel_table = $va_path[1];
         if ($t_rel = $this->getAppDatamodel()->getInstanceByTableName($vs_rel_table)) {
             if ($t_rel->load(array($this->primaryKey() => $this->getPrimaryKey(), 'representation_id' => $pn_representation_id))) {
                 $t_rel->setMode(ACCESS_WRITE);
                 $t_rel->delete();
                 if ($t_rel->numErrors()) {
                     $this->errors = array_merge($this->errors, $t_rel->errors());
                     return false;
                 }
             }
         }
     }
     $t_rep = new ca_object_representations();
     if (!$t_rep->load($pn_representation_id)) {
         $this->postError(750, _t("Representation id=%1 does not exist", $pn_representation_id), "RepresentableBaseModel->removeRepresentation()");
         return false;
     } else {
         //
         // Only delete the related representation if nothing else is related to it
         //
         $va_rels = $t_rep->hasRelationships();
         if (is_array($va_rels) && isset($va_rels['ca_object_representation_labels'])) {
             // labels don't count as relationships in this case
             unset($va_rels['ca_object_representation_labels']);
         }
         if (!is_array($va_rels) || sizeof($va_rels) == 0) {
             $t_rep->setMode(ACCESS_WRITE);
             $t_rep->delete(true, $pa_options);
             if ($t_rep->numErrors()) {
                 $this->errors = array_merge($this->errors, $t_rep->errors());
                 return false;
             }
         }
         // remove any replicated media
         if (is_array($va_replication_targets = $t_rep->getUsedMediaReplicationTargets('media'))) {
             foreach ($va_replication_targets as $vs_target => $va_target_info) {
                 $t_rep->removeMediaReplication('media', $vs_target, $t_rep->getMediaReplicationKey('media', $vs_target));
             }
         }
         return true;
     }
     return false;
 }
                 print "</div><!-- end unit -->";
             }
         }
     }
 }
 # --- related objects
 $va_related_objects_links = $t_occurrence->get("ca_objects_x_occurrences.relation_id", array("returnAsArray" => true));
 if (sizeof($va_related_objects_links)) {
     $t_objects_x_occurrences = new ca_objects_x_occurrences();
     $t_object = new ca_objects();
     foreach ($va_related_objects_links as $vn_relation_id) {
         $t_objects_x_occurrences->load($vn_relation_id);
         $va_reps = $t_objects_x_occurrences->get("ca_objects_x_occurrences.representation_list", array("returnAsArray" => true, 'idsOnly' => true));
         if (is_array($va_reps)) {
             foreach ($va_reps as $vn_i => $va_attr) {
                 $t_rep = new ca_object_representations($va_attr['representation_list']);
                 print "<div class='unit'>";
                 if ($ps_mode == "print") {
                     print "<input type='checkbox' checked name='print_fields[]' value='rep" . $t_rep->get("representation_id") . "'> ";
                 }
                 # --- open in media viewer
                 print "<a href='#' onclick='caMediaPanel.showPanel(\"" . caNavUrl($this->request, 'Detail', 'Object', 'GetRepresentationInfo', array('object_id' => $t_objects_x_occurrences->get("ca_objects.object_id"), 'representation_id' => $t_rep->getPrimaryKey())) . "\"); return false;' >" . $t_rep->getMediaTag('media', 'medium') . "</a>";
                 #print $t_rep->getMediaTag('media', 'medium');
                 print "</div><!-- end unit -->";
             }
         }
         print "<div class='unit' style='font-size:11px; font-style:italic;'>" . caNavLink($this->request, $t_objects_x_occurrences->get("ca_objects.preferred_labels.name"), '', 'Detail', 'Object', 'Show', array('object_id' => $t_objects_x_occurrences->get("ca_objects.object_id")));
         if ($va_dates = $t_objects_x_occurrences->get("ca_objects.date", array("returnAsArray" => true))) {
             foreach ($va_dates as $va_date_info) {
                 if ($va_date_info["dc_dates_types"] == $vn_original_date) {
                     print ", " . $va_date_info["dates_value"];
Esempio n. 16
0
 /**
  * 
  */
 public function getItems($pa_options = null)
 {
     if (isset($pa_options['order_id']) && (int) $pa_options['order_id']) {
         $vn_order_id = (int) $pa_options['order_id'];
     } else {
         $vn_order_id = $this->getPrimaryKey();
     }
     if (!$vn_order_id) {
         return null;
     }
     $o_db = $this->getDb();
     $va_additional_fee_codes = $this->opo_client_services_config->getAssoc($this->get('order_type') == 'L' ? 'additional_loan_fees' : 'additional_order_item_fees');
     $qr_res = $o_db->query("\n\t \t\tSELECT i.*, objl.name, objl.name_sort, objl.locale_id, obj.idno, obj.idno_sort\n\t \t\tFROM ca_commerce_order_items i\n\t \t\tINNER JOIN ca_commerce_orders AS o ON o.order_id = i.order_id\n\t \t\tINNER JOIN ca_objects AS obj ON obj.object_id = i.object_id\n\t \t\tINNER JOIN ca_object_labels AS objl ON objl.object_id = obj.object_id\n\t \t\tWHERE\n\t \t\t\t(o.order_id = ?) AND (objl.is_preferred = 1)\n\t \t\tORDER BY i.rank\n\t \t", (int) $vn_order_id);
     $va_object_ids = $qr_res->getAllFieldValues('object_id');
     $va_item_ids = $qr_res->getAllFieldValues('item_id');
     $va_orders = array();
     // Get representation (page) counts
     $va_rep_counts = $va_total_rep_counts = array();
     $va_item_to_rep_ids = array();
     if (sizeof($va_item_ids)) {
         if ($this->get('order_type') == 'O') {
             $qr_rep_count = $o_db->query("\n\t\t\t\t\tSELECT coixor.item_id, coixor.representation_id, count(*) c\n\t\t\t\t\tFROM ca_commerce_order_items_x_object_representations coixor\n\t\t\t\t\tINNER JOIN ca_object_representations AS o_r ON o_r.representation_id = coixor.representation_id\n\t\t\t\t\tWHERE\n\t\t\t\t\t\tcoixor.item_id IN (?) AND o_r.deleted = 0\n\t\t\t\t\tGROUP BY coixor.item_id\n\t\t\t\t", array($va_item_ids));
             while ($qr_rep_count->nextRow()) {
                 $va_rep_counts[(int) $qr_rep_count->get('item_id')] = (int) $qr_rep_count->get('c');
                 $va_item_to_rep_ids[(int) $qr_rep_count->get('item_id')] = (int) $qr_rep_count->get('representation_id');
             }
         } else {
             $qr_rep_count = $o_db->query("\n\t\t\t\t\tSELECT o.item_id, coixor.representation_id, count(*) c\n\t\t\t\t\tFROM ca_commerce_order_items o\n\t\t\t\t\tINNER JOIN ca_objects_x_object_representations AS coixor ON o.object_id = coixor.object_id\n\t\t\t\t\tINNER JOIN ca_object_representations AS o_r ON o_r.representation_id = coixor.representation_id\n\t\t\t\t\tWHERE\n\t\t\t\t\t\to.item_id IN (?) AND o_r.deleted = 0\n\t\t\t\t\tGROUP BY o.item_id\n\t\t\t\t", array($va_item_ids));
             while ($qr_rep_count->nextRow()) {
                 $va_rep_counts[(int) $qr_rep_count->get('item_id')] = (int) $qr_rep_count->get('c');
                 $va_item_to_rep_ids[(int) $qr_rep_count->get('item_id')] = (int) $qr_rep_count->get('representation_id');
             }
             $qr_rep_count = $o_db->query("\n\t\t\t\t\tSELECT o.item_id, coixor.representation_id\n\t\t\t\t\tFROM ca_commerce_order_items o\n\t\t\t\t\tINNER JOIN ca_objects_x_object_representations AS coixor ON o.object_id = coixor.object_id\n\t\t\t\t\tINNER JOIN ca_object_representations AS o_r ON o_r.representation_id = coixor.representation_id\n\t\t\t\t\tWHERE\n\t\t\t\t\t\to.item_id IN (?) AND o_r.deleted = 0 AND coixor.is_primary = 1\n\t\t\t\t", array($va_item_ids));
             while ($qr_rep_count->nextRow()) {
                 $va_item_to_rep_ids[(int) $qr_rep_count->get('item_id')] = (int) $qr_rep_count->get('representation_id');
             }
         }
         $qr_rep_count = $o_db->query("\n\t\t\t\tSELECT coixor.object_id, count(*) c\n\t\t\t\tFROM ca_objects_x_object_representations coixor\n\t\t\t\tINNER JOIN ca_object_representations AS o_r ON o_r.representation_id = coixor.representation_id\n\t\t\t\tWHERE\n\t\t\t\t\tcoixor.object_id IN (?) AND o_r.deleted = 0\n\t\t\t\tGROUP BY coixor.object_id\n\t\t\t", array($va_object_ids));
         while ($qr_rep_count->nextRow()) {
             $va_total_rep_counts[(int) $qr_rep_count->get('object_id')] = (int) $qr_rep_count->get('c');
         }
     }
     $qr_res->seek(0);
     // Get representations
     $t_rep = new ca_object_representations();
     $va_reps = $t_rep->getRepresentationMediaForIDs(array_values($va_item_to_rep_ids), array('thumbnail'));
     while ($qr_res->nextRow()) {
         $va_row = $qr_res->getRow();
         $vn_item_id = (int) $qr_res->get('item_id');
         $va_row['fee'] = sprintf("%4.2f", $va_row['fee']);
         $va_row['tax'] = sprintf("%4.2f", $va_row['tax']);
         $va_row['shipping_cost'] = sprintf("%4.2f", $va_row['shipping_cost']);
         $va_row['handling_cost'] = sprintf("%4.2f", $va_row['handling_cost']);
         $va_row['thumbnail_tag'] = $va_reps[$va_item_to_rep_ids[$va_row['item_id']]]['tags']['thumbnail'];
         $va_row['selected_representation_count'] = (int) $va_rep_counts[$vn_item_id];
         $va_row['representation_count'] = (int) $va_total_rep_counts[(int) $qr_res->get('object_id')];
         if (!is_array($va_fees = caUnserializeForDatabase($va_row['additional_fees']))) {
             $va_fees = array();
         }
         $vn_fee_total = 0;
         foreach ($va_additional_fee_codes as $vs_code => $va_info) {
             if (isset($va_fees[$vs_code])) {
                 $vn_fee = (double) $va_fees[$vs_code];
                 $vn_fee_total += $vn_fee;
             } else {
                 $vn_fee = (double) $va_info['default_cost'];
             }
             $va_row['ADDITIONAL_FEE_' . $vs_code] = sprintf("%4.2f", $vn_fee);
         }
         $va_row['additional_fees_total'] = sprintf("%4.2f", $vn_fee_total);
         $va_orders[$vn_item_id][(int) $qr_res->get('locale_id')] = $va_row;
     }
     $va_orders = caExtractValuesByUserLocale($va_orders);
     return $va_orders;
 }
 public function getAnnotationType($pn_representation_id = null)
 {
     if (!$pn_representation_id) {
         if (!($vn_representation_id = $this->get('representation_id'))) {
             return false;
         }
     } else {
         $vn_representation_id = $pn_representation_id;
     }
     $t_rep = new ca_object_representations();
     return $t_rep->getAnnotationType($vn_representation_id);
 }
 /**
  *
  */
 public function parseValue($ps_value, $pa_element_info, $pa_options = null)
 {
     $vb_require_value = is_null($pa_element_info['settings']['requireValue']) ? true : (bool) $pa_element_info['settings']['requireValue'];
     if (preg_match('![^\\d]+!', $ps_value)) {
         // try to convert idno to representation_id
         if ($vn_id = ca_object_representations::find(array('idno' => $ps_value), array('returnAs' => 'firstId'))) {
             $ps_value = $vn_id;
         }
     }
     if (!$vb_require_value && !(int) $ps_value) {
         return array('value_longtext1' => null, 'value_integer1' => null);
     }
     if (strlen($ps_value) && !is_numeric($ps_value)) {
         $this->postError(1970, _t('Item_id %2 is not valid for element %1', $pa_element_info["element_code"], $ps_value), 'ObjectRepresentationsAttributeValue->parseValue()');
         return false;
     }
     $t_item = new ca_object_representations((int) $ps_value);
     if (!$t_item->getPrimaryKey()) {
         if ($ps_value) {
             $this->postError(1970, _t('%1 is not a valid representation_id for %2 [%3]', $ps_value, $pa_element_info['displayLabel'], $pa_element_info['element_code']), 'ObjectRepresentationsAttributeValue->parseValue()');
         } else {
             return null;
         }
         return false;
     }
     return array('value_longtext1' => $ps_value, 'value_integer1' => (int) $ps_value);
 }
<?php

$t_object = $this->getVar("item");
$va_comments = $this->getVar("comments");
$pn_representation_id = $this->getVar("representation_id");
# --- media
$va_audios = $t_object->representationsWithMimeType(array("audio/mpeg", "audio/x-aiff", "audio/x-wav", "audio/mp4"), array("checkAccess" => $this->getVar("access_values")));
$t_rep = new ca_object_representations();
$vn_audio_rep_id = "";
$va_audio_rep = array();
$va_audio_media_display_info = array();
$va_annotations = array();
if (sizeof($va_audios)) {
    # --- if a rep_id was passed use that instead of the primary rep
    if ($pn_representation_id) {
        $va_audio_rep = $va_audios[$pn_representation_id];
        unset($va_audios[$pn_representation_id]);
    } else {
        $va_audio_rep = array_shift($va_audios);
    }
    $vn_audio_rep_id = $va_audio_rep["representation_id"];
    $va_audio_media_display_info = caGetMediaDisplayInfo('detail', $va_audio_rep["mimetype"]);
}
$va_transcript = $t_object->representationsWithMimeType(array("application/pdf", "application/msword", "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "application/vnd.ms-excel", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "application/vnd.ms-powerpoint", "application/vnd.openxmlformats-officedocument.presentationml.presentation"), array("checkAccess" => $this->getVar("access_values")));
# --- is there a transcript/ doc to show
if (sizeof($va_transcript)) {
    $va_transcript = array_shift($va_transcript);
    $vn_transcript_rep_id = $va_transcript["representation_id"];
    $va_doc_media_display_info = caGetMediaDisplayInfo('detail', $va_transcript["mimetype"]);
    $vs_transcript_link = "<a href='#' onclick='caMediaPanel.showPanel(\"" . caNavUrl($this->request, '', 'Detail', 'GetRepresentationInfo', array('object_id' => $t_object->get("object_id"), 'representation_id' => $vn_transcript_rep_id, 'overlay' => 1)) . "\"); return false;' title='" . _t("Transcript") . "'><i class='fa fa-file-text-o'></i> TRANSCRIPT</a>\n";
}
Esempio n. 20
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;
 }
Esempio n. 21
0
 /**
  * 
  */
 public static function regenerate_annotation_previews($po_opts = null)
 {
     require_once __CA_LIB_DIR__ . "/core/Db.php";
     require_once __CA_MODELS_DIR__ . "/ca_representation_annotations.php";
     $o_db = new Db();
     $t_rep = new ca_object_representations();
     $t_rep->setMode(ACCESS_WRITE);
     if (!($vn_start = (int) $po_opts->getOption('start_id'))) {
         $vn_start = null;
     }
     if (!($vn_end = (int) $po_opts->getOption('end_id'))) {
         $vn_end = null;
     }
     $vs_sql_where = null;
     $va_params = array();
     if ($vn_start > 0 && $vn_end > 0 && $vn_start <= $vn_end || $vn_start > 0 && $vn_end == null) {
         $vs_sql_where = "WHERE annotation_id >= ?";
         $va_params[] = $vn_start;
         if ($vn_end) {
             $vs_sql_where .= " AND annotation_id <= ?";
             $va_params[] = $vn_end;
         }
     }
     $qr_reps = $o_db->query("\n\t\t\t\tSELECT annotation_id \n\t\t\t\tFROM ca_representation_annotations \n\t\t\t\t{$vs_sql_where}\n\t\t\t\tORDER BY annotation_id\n\t\t\t", $va_params);
     $vn_total = $qr_reps->numRows();
     print CLIProgressBar::start($vn_total, _t('Finding annotations'));
     $vn_c = 1;
     while ($qr_reps->nextRow()) {
         $t_instance = new ca_representation_annotations($vn_id = $qr_reps->get('annotation_id'));
         print CLIProgressBar::next(1, _t('Annotation %1', $vn_id));
         $t_instance->setMode(ACCESS_WRITE);
         $t_instance->update(array('forcePreviewGeneration' => true));
         $vn_c++;
     }
     print CLIProgressBar::finish();
 }
Esempio n. 22
0
 /**
  *
  */
 public function SelectRepresentations()
 {
     $pn_item_id = $this->request->getParameter('item_id', pInteger);
     $pn_object_id = $this->request->getParameter('object_id', pInteger);
     $t_item = new ca_set_items($pn_item_id);
     $t_set = new ca_sets($t_item->get('set_id'));
     if (!$t_set->getPrimaryKey() || !$t_set->haveAccessToSet($this->request->getUserID(), __CA_SET_EDIT_ACCESS__)) {
         // TODO: proper error reporting or redirect?
         return;
     }
     $t_object = new ca_objects($pn_object_id);
     if (!$vn_object_id) {
         $vn_object_id = 0;
     }
     $t_rep = new ca_object_representations($t_object->getPrimaryRepresentationID());
     $va_opts = array('use_book_viewer' => true, 'display' => 'media_overlay', 'object_id' => $pn_object_id, 'item_id' => $pn_item_id, 'containerID' => 'caMediaPanelContentArea', 'access' => caGetUserAccessValues($this->request));
     $this->response->addContent($t_rep->getRepresentationViewerHTMLBundle($this->request, $va_opts, array('sectionsAreSelectable' => true, 'use_book_viewer_when_number_of_representations_exceeds' => 0)));
 }
Esempio n. 23
0
 public function getSetItemRep()
 {
     $pn_set_id = $this->request->getParameter('set_id', pInteger);
     $t_set = new ca_sets($pn_set_id);
     $t_set->load($pn_set_id);
     $va_set_items = caExtractValuesByUserLocale($t_set->getItems(array("thumbnailVersions" => array("icon"), "checkAccess" => $this->opa_access_values)));
     $this->view->setVar("set_id", $pn_set_id);
     $pn_item_id = $this->request->getParameter('item_id', pInteger);
     $t_rep = new ca_object_representations($va_set_items[$pn_item_id]["representation_id"]);
     $va_rep_info = $t_rep->getMediaInfo("media", "mediumlarge");
     $this->view->setVar("rep", $t_rep->getMediaTag("media", "mediumlarge"));
     $this->view->setVar("repToolBar", caRepToolbar($this->request, $t_rep, $va_set_items[$pn_item_id]["row_id"]));
     $this->view->setVar("representation_id", $va_set_items[$pn_item_id]["representation_id"]);
     $this->view->setVar("object_id", $va_set_items[$pn_item_id]["row_id"]);
     $pn_previous_id = 0;
     $pn_next_id = 0;
     $va_set_item_ids = array_keys($va_set_items);
     $vn_current_index = array_search($pn_item_id, $va_set_item_ids);
     if ($va_set_item_ids[$vn_current_index - 1]) {
         $pn_previous_id = $va_set_item_ids[$vn_current_index - 1];
     }
     if ($va_set_item_ids[$vn_current_index + 1]) {
         $pn_next_id = $va_set_item_ids[$vn_current_index + 1];
     }
     $this->view->setVar("next_item_id", $pn_next_id);
     $this->view->setVar("previous_item_id", $pn_previous_id);
     $this->render("Gallery/set_item_rep_html.php");
 }
Esempio n. 24
0
 /**
  * 
  */
 public function RemoveMediaReplication()
 {
     $pn_representation_id = $this->request->getParameter('representation_id', pInteger);
     $ps_target = $this->request->getParameter('target', pString);
     $ps_key = urldecode($this->request->getParameter('key', pString));
     $t_rep = new ca_object_representations($pn_representation_id);
     $this->view->setVar('target_list', $t_rep->getAvailableMediaReplicationTargetsAsHTMLFormElement('target', 'media'));
     $this->view->setVar('representation_id', $pn_representation_id);
     $this->view->setVar('t_representation', $t_rep);
     $this->view->setVar('selected_target', $ps_target);
     $t_rep->removeMediaReplication('media', $ps_target, $ps_key);
     $this->MediaReplicationControls($t_rep);
 }
 /**
  * Saves all bundles on the specified screen in the database by extracting 
  * required data from the supplied request
  * $pm_screen can be a screen tag (eg. "Screen5") or a screen_id (eg. 5)
  *
  * Calls processBundlesBeforeBaseModelSave() method in subclass right before invoking insert() or update() on
  * the BaseModel, if the method is defined. Passes the following parameters to processBundlesBeforeBaseModelSave():
  *		array $pa_bundles An array of bundles to be saved
  *		string $ps_form_prefix The form prefix
  *		RequestHTTP $po_request The current request
  *		array $pa_options Optional array of parameters; expected to be the same as that passed to saveBundlesForScreen()
  *
  * The processBundlesBeforeBaseModelSave() is useful for those odd cases where you need to do some processing before the basic
  * database record defined by the model (eg. intrinsic fields and hierarchy coding) is inserted or updated. You usually don't need 
  * to use it.
  *
  * @param mixed $pm_screen
  * @param RequestHTTP $ps_request
  * @param array $pa_options Options are:
  *		dryRun = Go through the motions of saving but don't actually write information to the database
  *		batch = Process save in "batch" mode. Specifically this means honoring batch mode settings (add, replace, remove), skipping bundles that are not supported in batch mode and ignoring updates
  *		existingRepresentationMap = an array of representation_ids key'ed on file path. If set saveBundlesForScreen() use link the specified representation to the row it is saving rather than processing the uploaded file. saveBundlesForScreen() will build the map as it goes, adding newly uploaded files. If you want it to process a file in a batch situation where it should be processed the first time and linked subsequently then pass an empty array here. saveBundlesForScreen() will use the empty array to build the map.
  */
 public function saveBundlesForScreen($pm_screen, $po_request, &$pa_options)
 {
     $vb_we_set_transaction = false;
     $vs_form_prefix = caGetOption('formName', $pa_options, $po_request->getParameter('_formName', pString));
     $vb_dryrun = caGetOption('dryRun', $pa_options, false);
     $vb_batch = caGetOption('batch', $pa_options, false);
     if (!$this->inTransaction()) {
         $this->setTransaction(new Transaction($this->getDb()));
         $vb_we_set_transaction = true;
     } else {
         if ($vb_dryrun) {
             $this->postError(799, _t('Cannot do dry run save when in transaction. Try again without setting a transaction.'), "BundlableLabelableBaseModelWithAttributes->saveBundlesForScreen()");
             return false;
         }
     }
     $vb_read_only_because_deaccessioned = $this->hasField('is_deaccessioned') && (bool) $this->getAppConfig()->get('deaccession_dont_allow_editing') && (bool) $this->get('is_deaccessioned');
     BaseModel::setChangeLogUnitID();
     // get items on screen
     $t_ui = caGetOption('ui_instance', $pa_options, ca_editor_uis::loadDefaultUI($this->tableName(), $po_request, $this->getTypeID()));
     $va_bundle_lists = $this->getBundleListsForScreen($pm_screen, $po_request, $t_ui, $pa_options);
     //
     // Filter bundles to save if deaccessioned - only allow editing of the ca_objects_deaccession bundle
     //
     if ($vb_read_only_because_deaccessioned) {
         foreach ($va_bundle_lists['bundles'] as $vn_i => $va_bundle) {
             if ($va_bundle['bundle_name'] !== 'ca_objects_deaccession') {
                 unset($va_bundle_lists['bundles'][$vn_i]);
             }
         }
         foreach ($va_bundle_lists['fields_by_type'] as $vs_type => $va_bundles) {
             foreach ($va_bundles as $vs_id => $vs_bundle_name) {
                 if ($vs_bundle_name !== 'ca_objects_deaccession') {
                     unset($va_bundle_lists['fields_by_type'][$vs_type][$vs_id]);
                 }
             }
         }
     }
     $va_bundles = $va_bundle_lists['bundles'];
     $va_fields_by_type = $va_bundle_lists['fields_by_type'];
     // save intrinsic fields
     if (is_array($va_fields_by_type['intrinsic'])) {
         $vs_idno_field = $this->getProperty('ID_NUMBERING_ID_FIELD');
         foreach ($va_fields_by_type['intrinsic'] as $vs_placement_code => $vs_f) {
             if ($vb_batch) {
                 $vs_batch_mode = $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}_batch_mode", pString);
                 if ($vs_batch_mode == '_disabled_') {
                     continue;
                 }
             }
             if (isset($_FILES["{$vs_placement_code}{$vs_form_prefix}{$vs_f}"]) && $_FILES["{$vs_placement_code}{$vs_form_prefix}{$vs_f}"]) {
                 // media field
                 $this->set($vs_f, $_FILES["{$vs_placement_code}{$vs_form_prefix}{$vs_f}"]['tmp_name'], array('original_filename' => $_FILES["{$vs_placement_code}{$vs_form_prefix}{$vs_f}"]['name']));
             } else {
                 switch ($vs_f) {
                     case 'access':
                         if ((bool) $this->getAppConfig()->get($this->tableName() . '_allow_access_inheritance') && $this->hasField('access_inherit_from_parent')) {
                             $this->set('access_inherit_from_parent', $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}access_inherit_from_parent", pInteger));
                         }
                         if (!(bool) $this->getAppConfig()->get($this->tableName() . '_allow_access_inheritance') || !$this->hasField('access_inherit_from_parent') || !(bool) $this->get('access_inherit_from_parent')) {
                             $this->set('access', $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}access", pString));
                         }
                         break;
                     case $vs_idno_field:
                         if ($this->opo_idno_plugin_instance) {
                             $this->opo_idno_plugin_instance->setDb($this->getDb());
                             $this->set($vs_f, $vs_tmp = $this->opo_idno_plugin_instance->htmlFormValue($vs_idno_field));
                         } else {
                             $this->set($vs_f, $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}{$vs_f}", pString));
                         }
                         break;
                     default:
                         // Look for fully qualified intrinsic
                         if (!strlen($vs_v = $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}{$vs_f}", pString))) {
                             // fall back to simple field name intrinsic spec - still used for "mandatory" fields such as type_id and parent_id
                             $vs_v = $po_request->getParameter("{$vs_f}", pString);
                         }
                         $this->set($vs_f, $vs_v);
                         break;
                 }
             }
             if ($this->numErrors() > 0) {
                 foreach ($this->errors() as $o_e) {
                     switch ($o_e->getErrorNumber()) {
                         case 795:
                             // field conflicts
                             foreach ($this->getFieldConflicts() as $vs_conflict_field) {
                                 $po_request->addActionError($o_e, $vs_conflict_field);
                             }
                             break;
                         default:
                             $po_request->addActionError($o_e, $vs_f);
                             break;
                     }
                 }
             }
         }
     }
     // save attributes
     $va_inserted_attributes_by_element = array();
     if (isset($va_fields_by_type['attribute']) && is_array($va_fields_by_type['attribute'])) {
         //
         // name of attribute request parameters are:
         // 	For new attributes
         // 		{$vs_form_prefix}_attribute_{element_set_id}_{element_id|'locale_id'}_new_{n}
         //		ex. ObjectBasicForm_attribute_6_locale_id_new_0 or ObjectBasicForm_attribute_6_desc_type_new_0
         //
         // 	For existing attributes:
         // 		{$vs_form_prefix}_attribute_{element_set_id}_{element_id|'locale_id'}_{attribute_id}
         //
         // look for newly created attributes; look for attributes to delete
         $va_inserted_attributes = array();
         $reserved_elements = array();
         foreach ($va_fields_by_type['attribute'] as $vs_placement_code => $vs_f) {
             $vs_element_set_code = preg_replace("/^ca_attribute_/", "", $vs_f);
             //does the attribute's datatype have a saveElement method - if so, use that instead
             $vs_element = $this->_getElementInstance($vs_element_set_code);
             $vn_element_id = $vs_element->getPrimaryKey();
             $vs_element_datatype = $vs_element->get('datatype');
             $vs_datatype = Attribute::getValueInstance($vs_element_datatype);
             if (method_exists($vs_datatype, 'saveElement')) {
                 $reserved_elements[] = $vs_element;
                 continue;
             }
             $va_attributes_to_insert = array();
             $va_attributes_to_delete = array();
             $va_locales = array();
             $vs_batch_mode = $_REQUEST[$vs_placement_code . $vs_form_prefix . '_attribute_' . $vn_element_id . '_batch_mode'];
             if ($vb_batch && $vs_batch_mode == '_delete_') {
                 // Remove all attributes and continue
                 $this->removeAttributes($vn_element_id, array('force' => true));
                 continue;
             }
             foreach ($_REQUEST as $vs_key => $vs_val) {
                 // is it a newly created attribute?
                 if (preg_match('/' . $vs_placement_code . $vs_form_prefix . '_attribute_' . $vn_element_id . '_([\\w\\d\\-_]+)_new_([\\d]+)/', $vs_key, $va_matches)) {
                     if ($vb_batch) {
                         switch ($vs_batch_mode) {
                             case '_disabled_':
                                 // skip
                                 continue 2;
                                 break;
                             case '_add_':
                                 // just try to add attribute as in normal non-batch save
                                 // noop
                                 break;
                             case '_replace_':
                                 // remove all existing attributes before trying to save
                                 $this->removeAttributes($vn_element_id, array('force' => true));
                                 continue;
                                 break;
                         }
                     }
                     $vn_c = intval($va_matches[2]);
                     // yep - grab the locale and value
                     $vn_locale_id = isset($_REQUEST[$vs_placement_code . $vs_form_prefix . '_attribute_' . $vn_element_id . '_locale_id_new_' . $vn_c]) ? $_REQUEST[$vs_placement_code . $vs_form_prefix . '_attribute_' . $vn_element_id . '_locale_id_new_' . $vn_c] : null;
                     $va_inserted_attributes_by_element[$vn_element_id][$vn_c]['locale_id'] = $va_attributes_to_insert[$vn_c]['locale_id'] = $vn_locale_id;
                     $va_inserted_attributes_by_element[$vn_element_id][$vn_c][$va_matches[1]] = $va_attributes_to_insert[$vn_c][$va_matches[1]] = $vs_val;
                 } else {
                     // is it a delete key?
                     if (preg_match('/' . $vs_placement_code . $vs_form_prefix . '_attribute_' . $vn_element_id . '_([\\d]+)_delete/', $vs_key, $va_matches)) {
                         $vn_attribute_id = intval($va_matches[1]);
                         $va_attributes_to_delete[$vn_attribute_id] = true;
                     }
                 }
             }
             // look for uploaded files as attributes
             foreach ($_FILES as $vs_key => $va_val) {
                 if (preg_match('/' . $vs_placement_code . $vs_form_prefix . '_attribute_' . $vn_element_id . '_locale_id_new_([\\d]+)/', $vs_key, $va_locale_matches)) {
                     $vn_locale_c = intval($va_locale_matches[1]);
                     $va_locales[$vn_locale_c] = $vs_val;
                     continue;
                 }
                 // is it a newly created attribute?
                 if (preg_match('/' . $vs_placement_code . $vs_form_prefix . '_attribute_' . $vn_element_id . '_([\\w\\d\\-_]+)_new_([\\d]+)/', $vs_key, $va_matches)) {
                     if (!$va_val['size']) {
                         continue;
                     }
                     // skip empty files
                     // yep - grab the value
                     $vn_c = intval($va_matches[2]);
                     $va_inserted_attributes_by_element[$vn_element_id][$vn_c]['locale_id'] = $va_attributes_to_insert[$vn_c]['locale_id'] = $va_locales[$vn_c];
                     $va_val['_uploaded_file'] = true;
                     $va_inserted_attributes_by_element[$vn_element_id][$vn_c][$va_matches[1]] = $va_attributes_to_insert[$vn_c][$va_matches[1]] = $va_val;
                 }
             }
             if (!$vb_batch) {
                 // do deletes
                 $this->clearErrors();
                 foreach ($va_attributes_to_delete as $vn_attribute_id => $vb_tmp) {
                     $this->removeAttribute($vn_attribute_id, $vs_f, array('pending_adds' => $va_attributes_to_insert));
                 }
             }
             // do inserts
             foreach ($va_attributes_to_insert as $va_attribute_to_insert) {
                 $this->clearErrors();
                 $this->addAttribute($va_attribute_to_insert, $vn_element_id, $vs_f);
             }
             if (!$vb_batch) {
                 // check for attributes to update
                 if (is_array($va_attrs = $this->getAttributesByElement($vn_element_id))) {
                     $t_element = new ca_metadata_elements();
                     $va_attrs_update_list = array();
                     foreach ($va_attrs as $o_attr) {
                         $this->clearErrors();
                         $vn_attribute_id = $o_attr->getAttributeID();
                         if (isset($va_inserted_attributes[$vn_attribute_id]) && $va_inserted_attributes[$vn_attribute_id]) {
                             continue;
                         }
                         if (isset($va_attributes_to_delete[$vn_attribute_id]) && $va_attributes_to_delete[$vn_attribute_id]) {
                             continue;
                         }
                         $vn_element_set_id = $o_attr->getElementID();
                         $va_attr_update = array('locale_id' => $po_request->getParameter($vs_placement_code . $vs_form_prefix . '_attribute_' . $vn_element_set_id . '_locale_id_' . $vn_attribute_id, pString));
                         //
                         // Check to see if there are any values in the element set that are not in the  attribute we're editing
                         // If additional sub-elements were added to the set after the attribute we're updating was created
                         // those sub-elements will not have corresponding values returned by $o_attr->getValues() above.
                         // Because we use the element_ids in those values to pull request parameters, if an element_id is missing
                         // it effectively becomes invisible and cannot be set. This is a fairly unusual case but it happens, and when it does
                         // it's really annoying. It would be nice and efficient to simply create the missing values at configuration time, but we wouldn't
                         // know what to set the values to. So what we do is, after setting all of the values present in the attribute from the request, grab
                         // the configuration for the element set and see if there are any elements in the set that we didn't get values for.
                         //
                         $va_sub_elements = $t_element->getElementsInSet($vn_element_set_id);
                         foreach ($va_sub_elements as $vn_i => $va_element_info) {
                             if ($va_element_info['datatype'] == 0) {
                                 continue;
                             }
                             //$vn_element_id = $o_attr_val->getElementID();
                             $vn_element_id = $va_element_info['element_id'];
                             $vs_k = $vs_placement_code . $vs_form_prefix . '_attribute_' . $vn_element_set_id . '_' . $vn_element_id . '_' . $vn_attribute_id;
                             if (isset($_FILES[$vs_k]) && ($va_val = $_FILES[$vs_k])) {
                                 if ($va_val['size'] > 0) {
                                     // is there actually a file?
                                     $va_val['_uploaded_file'] = true;
                                     $va_attr_update[$vn_element_id] = $va_val;
                                     continue;
                                 }
                             }
                             $vs_attr_val = $po_request->getParameter($vs_k, pString);
                             $va_attr_update[$vn_element_id] = $vs_attr_val;
                         }
                         $this->clearErrors();
                         $this->editAttribute($vn_attribute_id, $vn_element_set_id, $va_attr_update, $vs_f);
                     }
                 }
             }
         }
     }
     if (!$vb_batch) {
         // hierarchy moves are not supported in batch mode
         if (is_array($va_fields_by_type['special'])) {
             foreach ($va_fields_by_type['special'] as $vs_placement_code => $vs_bundle) {
                 if ($vs_bundle !== 'hierarchy_location') {
                     continue;
                 }
                 $va_parent_tmp = explode("-", $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}_new_parent_id", pString));
                 // Hierarchy browser sets new_parent_id param to "X" if user wants to extract item from hierarchy
                 $vn_parent_id = ($vn_parent_id = array_pop($va_parent_tmp)) == 'X' ? -1 : (int) $vn_parent_id;
                 if (sizeof($va_parent_tmp) > 0) {
                     $vs_parent_table = array_pop($va_parent_tmp);
                 } else {
                     $vs_parent_table = $this->tableName();
                 }
                 if ($this->getPrimaryKey() && $this->HIERARCHY_PARENT_ID_FLD && $vn_parent_id > 0) {
                     if ($vs_parent_table == $this->tableName()) {
                         $this->set($this->HIERARCHY_PARENT_ID_FLD, $vn_parent_id);
                     } else {
                         if ((bool) $this->getAppConfig()->get('ca_objects_x_collections_hierarchy_enabled') && $vs_parent_table == 'ca_collections' && $this->tableName() == 'ca_objects' && ($vs_coll_rel_type = $this->getAppConfig()->get('ca_objects_x_collections_hierarchy_relationship_type'))) {
                             // link object to collection
                             $this->removeRelationships('ca_collections', $vs_coll_rel_type);
                             $this->set($this->HIERARCHY_PARENT_ID_FLD, null);
                             $this->set($this->HIERARCHY_ID_FLD, $this->getPrimaryKey());
                             if (!$this->addRelationship('ca_collections', $vn_parent_id, $vs_coll_rel_type)) {
                                 $this->postError(2510, _t('Could not move object under collection: %1', join("; ", $this->getErrors())), "BundlableLabelableBaseModelWithAttributes->saveBundlesForScreen()");
                             }
                         }
                     }
                 } else {
                     if ($this->getPrimaryKey() && $this->HIERARCHY_PARENT_ID_FLD && $this->HIERARCHY_TYPE == __CA_HIER_TYPE_ADHOC_MONO__ && isset($_REQUEST["{$vs_placement_code}{$vs_form_prefix}_new_parent_id"]) && $vn_parent_id <= 0) {
                         $this->set($this->HIERARCHY_PARENT_ID_FLD, null);
                         $this->set($this->HIERARCHY_ID_FLD, $this->getPrimaryKey());
                         // Support for collection-object cross-table hierarchies
                         if ((bool) $this->getAppConfig()->get('ca_objects_x_collections_hierarchy_enabled') && $this->tableName() == 'ca_objects' && ($vs_coll_rel_type = $this->getAppConfig()->get('ca_objects_x_collections_hierarchy_relationship_type')) && $vn_parent_id == -1) {
                             // -1 = extract from hierarchy
                             $this->removeRelationships('ca_collections', $vs_coll_rel_type);
                         }
                     }
                 }
                 break;
             }
         }
     }
     //
     // Call processBundlesBeforeBaseModelSave() method in sub-class, if it is defined. The method is passed
     // a list of bundles, the form prefix, the current request and the options passed to saveBundlesForScreen() –
     // everything needed to perform custom processing using the incoming form content that is being saved.
     //
     // A processBundlesBeforeBaseModelSave() method is rarely needed, but can be handy when you need to do something model-specific
     // right before the basic database record is committed via insert() (for new records) or update() (for existing records).
     // For example, the media in ca_object_representations is set in a "special" bundle, which provides a specialized media upload UI. Unfortunately "special's"
     // are handled after the basic database record is saved via insert() or update(), while the actual media must be set prior to the save.
     // processBundlesBeforeBaseModelSave() allows special logic in the ca_object_representations model to be invoked to set the media before the insert() or update().
     // The "special" takes care of other functions after the insert()/update()
     //
     if (method_exists($this, "processBundlesBeforeBaseModelSave")) {
         $this->processBundlesBeforeBaseModelSave($va_bundles, $vs_form_prefix, $po_request, $pa_options);
     }
     $this->setMode(ACCESS_WRITE);
     $vb_is_insert = false;
     if ($this->getPrimaryKey()) {
         $this->update();
     } else {
         $this->insert();
         $vb_is_insert = true;
     }
     if ($this->numErrors() > 0) {
         $va_errors = array();
         foreach ($this->errors() as $o_e) {
             switch ($o_e->getErrorNumber()) {
                 case 2010:
                     $po_request->addActionErrors(array($o_e), 'hierarchy_location');
                     break;
                 case 795:
                     // field conflict
                     foreach ($this->getFieldConflicts() as $vs_conflict_field) {
                         $po_request->addActionError($o_e, $vs_conflict_field);
                     }
                     break;
                 case 1100:
                     if ($vs_idno_field = $this->getProperty('ID_NUMBERING_ID_FIELD')) {
                         $po_request->addActionError($o_e, $this->getProperty('ID_NUMBERING_ID_FIELD'));
                     }
                     break;
                 default:
                     $va_errors[] = $o_e;
                     break;
             }
         }
         $po_request->addActionErrors($va_errors);
         if ($vb_is_insert) {
             BaseModel::unsetChangeLogUnitID();
             if ($vb_we_set_transaction) {
                 $this->removeTransaction(false);
             }
             return false;
             // bail on insert error
         }
     }
     if (!$this->getPrimaryKey()) {
         BaseModel::unsetChangeLogUnitID();
         if ($vb_we_set_transaction) {
             $this->removeTransaction(false);
         }
         return false;
     }
     // bail if insert failed
     $this->clearErrors();
     //save reserved elements -  those with a saveElement method
     if (isset($reserved_elements) && is_array($reserved_elements)) {
         foreach ($reserved_elements as $res_element) {
             $res_element_id = $res_element->getPrimaryKey();
             $res_element_datatype = $res_element->get('datatype');
             $res_datatype = Attribute::getValueInstance($res_element_datatype);
             $res_datatype->saveElement($this, $res_element, $vs_form_prefix, $po_request);
         }
     }
     // save preferred labels
     if ($this->getProperty('LABEL_TABLE_NAME')) {
         $vb_check_for_dupe_labels = $this->_CONFIG->get('allow_duplicate_labels_for_' . $this->tableName()) ? false : true;
         $vb_error_inserting_pref_label = false;
         if (is_array($va_fields_by_type['preferred_label'])) {
             foreach ($va_fields_by_type['preferred_label'] as $vs_placement_code => $vs_f) {
                 if (!$vb_batch) {
                     // check for existing labels to update (or delete)
                     $va_preferred_labels = $this->getPreferredLabels(null, false);
                     foreach ($va_preferred_labels as $vn_item_id => $va_labels_by_locale) {
                         foreach ($va_labels_by_locale as $vn_locale_id => $va_label_list) {
                             foreach ($va_label_list as $va_label) {
                                 if ($vn_label_locale_id = $po_request->getParameter($vs_placement_code . $vs_form_prefix . '_Pref' . 'locale_id_' . $va_label['label_id'], pString)) {
                                     if (is_array($va_label_values = $this->getLabelUIValuesFromRequest($po_request, $vs_placement_code . $vs_form_prefix, $va_label['label_id'], true))) {
                                         if ($vb_check_for_dupe_labels && $this->checkForDupeLabel($vn_label_locale_id, $va_label_values)) {
                                             $this->postError(1125, _t('Value <em>%1</em> is already used and duplicates are not allowed', join("/", $va_label_values)), "BundlableLabelableBaseModelWithAttributes->saveBundlesForScreen()", $this->tableName() . '.preferred_labels');
                                             $po_request->addActionErrors($this->errors(), 'preferred_labels');
                                             continue;
                                         }
                                         $vn_label_type_id = $po_request->getParameter($vs_placement_code . $vs_form_prefix . '_Pref' . 'type_id_' . $va_label['label_id'], pInteger);
                                         $this->editLabel($va_label['label_id'], $va_label_values, $vn_label_locale_id, $vn_label_type_id, true);
                                         if ($this->numErrors()) {
                                             foreach ($this->errors() as $o_e) {
                                                 switch ($o_e->getErrorNumber()) {
                                                     case 795:
                                                         // field conflicts
                                                         $po_request->addActionError($o_e, 'preferred_labels');
                                                         break;
                                                     default:
                                                         $po_request->addActionError($o_e, $vs_f);
                                                         break;
                                                 }
                                             }
                                         }
                                     }
                                 } else {
                                     if ($po_request->getParameter($vs_placement_code . $vs_form_prefix . '_PrefLabel_' . $va_label['label_id'] . '_delete', pString)) {
                                         // delete
                                         $this->removeLabel($va_label['label_id']);
                                     }
                                 }
                             }
                         }
                     }
                 }
                 // check for new labels to add
                 foreach ($_REQUEST as $vs_key => $vs_value) {
                     if (!preg_match('/' . $vs_placement_code . $vs_form_prefix . '_Pref' . 'locale_id_new_([\\d]+)/', $vs_key, $va_matches)) {
                         continue;
                     }
                     if ($vb_batch) {
                         $vs_batch_mode = $po_request->getParameter($vs_placement_code . $vs_form_prefix . '_Pref_batch_mode', pString);
                         switch ($vs_batch_mode) {
                             case '_disabled_':
                                 // skip
                                 continue 2;
                                 break;
                             case '_replace_':
                                 // remove all existing preferred labels before trying to save
                                 $this->removeAllLabels(__CA_LABEL_TYPE_PREFERRED__);
                                 continue;
                             case '_delete_':
                                 // remove all existing preferred labels
                                 $this->removeAllLabels(__CA_LABEL_TYPE_PREFERRED__);
                                 continue 2;
                             case '_add_':
                                 break;
                         }
                     }
                     $vn_c = intval($va_matches[1]);
                     if ($vn_new_label_locale_id = $po_request->getParameter($vs_placement_code . $vs_form_prefix . '_Pref' . 'locale_id_new_' . $vn_c, pString)) {
                         if (is_array($va_label_values = $this->getLabelUIValuesFromRequest($po_request, $vs_placement_code . $vs_form_prefix, 'new_' . $vn_c, true))) {
                             // make sure we don't add multiple pref labels for one locale in batch mode
                             if ($vb_batch && $vs_batch_mode == '_add_') {
                                 // first remove [BLANK] labels for this locale if there are any, as we are about to add a new one
                                 $va_labels_for_this_locale = $this->getPreferredLabels(array($vn_new_label_locale_id));
                                 if (is_array($va_labels_for_this_locale)) {
                                     foreach ($va_labels_for_this_locale as $vn_id => $va_labels_by_locale) {
                                         foreach ($va_labels_by_locale as $vn_locale_id => $va_labels) {
                                             foreach ($va_labels as $vn_i => $va_label) {
                                                 if (isset($va_label[$this->getLabelDisplayField()]) && $va_label[$this->getLabelDisplayField()] == '[' . _t('BLANK') . ']') {
                                                     $this->removeLabel($va_label['label_id']);
                                                 }
                                             }
                                         }
                                     }
                                 }
                                 // if there are non-[BLANK] labels for this locale, don't add this new one
                                 $va_labels_for_this_locale = $this->getPreferredLabels(array($vn_new_label_locale_id), true, array('forDisplay' => true));
                                 if (is_array($va_labels_for_this_locale) && sizeof($va_labels_for_this_locale) > 0) {
                                     $this->postError(1125, _t('A preferred label for this locale already exists. Only one preferred label per locale is allowed.'), "BundlableLabelableBaseModelWithAttributes->saveBundlesForScreen()", $this->tableName() . '.preferred_labels');
                                     $po_request->addActionErrors($this->errors(), $vs_f);
                                     $vb_error_inserting_pref_label = true;
                                     continue;
                                 }
                             }
                             if ($vb_check_for_dupe_labels && $this->checkForDupeLabel($vn_new_label_locale_id, $va_label_values)) {
                                 $this->postError(1125, _t('Value <em>%1</em> is already used and duplicates are not allowed', join("/", $va_label_values)), "BundlableLabelableBaseModelWithAttributes->saveBundlesForScreen()", $this->tableName() . '.preferred_labels');
                                 $po_request->addActionErrors($this->errors(), 'preferred_labels');
                                 $vb_error_inserting_pref_label = true;
                                 continue;
                             }
                             $vn_label_type_id = $po_request->getParameter($vs_placement_code . $vs_form_prefix . '_Pref' . 'type_id_new_' . $vn_c, pInteger);
                             $this->addLabel($va_label_values, $vn_new_label_locale_id, $vn_label_type_id, true);
                             if ($this->numErrors()) {
                                 $po_request->addActionErrors($this->errors(), $vs_f);
                                 $vb_error_inserting_pref_label = true;
                             }
                         }
                     }
                 }
             }
         }
     }
     // Add default label if needed (ie. if the user has failed to set at least one label or if they have deleted all existing labels)
     // This ensures at least one label is present for the record. If no labels are present then the
     // record may not be found in queries
     if ($this->getProperty('LABEL_TABLE_NAME')) {
         if ($vb_error_inserting_pref_label || !$this->addDefaultLabel($vn_new_label_locale_id)) {
             if (!$vb_error_inserting_pref_label) {
                 $po_request->addActionErrors($this->errors(), 'preferred_labels');
             }
             if ($vb_we_set_transaction) {
                 $this->removeTransaction(false);
             }
             if ($vb_is_insert) {
                 $this->_FIELD_VALUES[$this->primaryKey()] = null;
                 // clear primary key, which doesn't actually exist since we rolled back the transaction
                 foreach ($va_inserted_attributes_by_element as $vn_element_id => $va_failed_inserts) {
                     // set attributes as "failed" (but with no error messages) so they stay set
                     $this->setFailedAttributeInserts($vn_element_id, $va_failed_inserts);
                 }
             }
             return false;
         }
     }
     unset($va_inserted_attributes_by_element);
     // save non-preferred labels
     if ($this->getProperty('LABEL_TABLE_NAME') && isset($va_fields_by_type['nonpreferred_label']) && is_array($va_fields_by_type['nonpreferred_label'])) {
         if (!$vb_batch) {
             foreach ($va_fields_by_type['nonpreferred_label'] as $vs_placement_code => $vs_f) {
                 // check for existing labels to update (or delete)
                 $va_nonpreferred_labels = $this->getNonPreferredLabels(null, false);
                 foreach ($va_nonpreferred_labels as $vn_item_id => $va_labels_by_locale) {
                     foreach ($va_labels_by_locale as $vn_locale_id => $va_label_list) {
                         foreach ($va_label_list as $va_label) {
                             if ($vn_label_locale_id = $po_request->getParameter($vs_placement_code . $vs_form_prefix . '_NPref' . 'locale_id_' . $va_label['label_id'], pString)) {
                                 if (is_array($va_label_values = $this->getLabelUIValuesFromRequest($po_request, $vs_placement_code . $vs_form_prefix, $va_label['label_id'], false))) {
                                     $vn_label_type_id = $po_request->getParameter($vs_placement_code . $vs_form_prefix . '_NPref' . 'type_id_' . $va_label['label_id'], pInteger);
                                     $this->editLabel($va_label['label_id'], $va_label_values, $vn_label_locale_id, $vn_label_type_id, false);
                                     if ($this->numErrors()) {
                                         foreach ($this->errors() as $o_e) {
                                             switch ($o_e->getErrorNumber()) {
                                                 case 795:
                                                     // field conflicts
                                                     $po_request->addActionError($o_e, 'nonpreferred_labels');
                                                     break;
                                                 default:
                                                     $po_request->addActionError($o_e, $vs_f);
                                                     break;
                                             }
                                         }
                                     }
                                 }
                             } else {
                                 if ($po_request->getParameter($vs_placement_code . $vs_form_prefix . '_NPrefLabel_' . $va_label['label_id'] . '_delete', pString)) {
                                     // delete
                                     $this->removeLabel($va_label['label_id']);
                                 }
                             }
                         }
                     }
                 }
             }
         }
         // check for new labels to add
         foreach ($va_fields_by_type['nonpreferred_label'] as $vs_placement_code => $vs_f) {
             if ($vb_batch) {
                 $vs_batch_mode = $po_request->getParameter($vs_placement_code . $vs_form_prefix . '_NPref_batch_mode', pString);
                 switch ($vs_batch_mode) {
                     case '_disabled_':
                         // skip
                         continue 2;
                         break;
                     case '_add_':
                         // just try to add attribute as in normal non-batch save
                         // noop
                         break;
                     case '_replace_':
                         // remove all existing nonpreferred labels before trying to save
                         $this->removeAllLabels(__CA_LABEL_TYPE_NONPREFERRED__);
                         continue;
                     case '_delete_':
                         // remove all existing nonpreferred labels
                         $this->removeAllLabels(__CA_LABEL_TYPE_NONPREFERRED__);
                         continue 2;
                         break;
                 }
             }
             foreach ($_REQUEST as $vs_key => $vs_value) {
                 if (!preg_match('/^' . $vs_placement_code . $vs_form_prefix . '_NPref' . 'locale_id_new_([\\d]+)/', $vs_key, $va_matches)) {
                     continue;
                 }
                 $vn_c = intval($va_matches[1]);
                 if ($vn_new_label_locale_id = $po_request->getParameter($vs_placement_code . $vs_form_prefix . '_NPref' . 'locale_id_new_' . $vn_c, pString)) {
                     if (is_array($va_label_values = $this->getLabelUIValuesFromRequest($po_request, $vs_placement_code . $vs_form_prefix, 'new_' . $vn_c, false))) {
                         $vn_new_label_type_id = $po_request->getParameter($vs_placement_code . $vs_form_prefix . '_NPref' . 'type_id_new_' . $vn_c, pInteger);
                         $this->addLabel($va_label_values, $vn_new_label_locale_id, $vn_new_label_type_id, false);
                         if ($this->numErrors()) {
                             $po_request->addActionErrors($this->errors(), $vs_f);
                         }
                     }
                 }
             }
         }
     }
     // save data in related tables
     if (isset($va_fields_by_type['related_table']) && is_array($va_fields_by_type['related_table'])) {
         foreach ($va_fields_by_type['related_table'] as $vs_placement_code => $vs_f) {
             $vn_table_num = $this->_DATAMODEL->getTableNum($vs_f);
             // get settings
             $va_bundle_settings = array();
             foreach ($va_bundles as $va_bundle_info) {
                 if ($va_bundle_info['placement_code'] == $vs_placement_code) {
                     $va_bundle_settings = $va_bundle_info['settings'];
                     break;
                 }
             }
             switch ($vs_f) {
                 # -------------------------------------
                 case 'ca_object_representations':
                     // check for existing representations to update (or delete)
                     $vs_prefix_stub = $vs_placement_code . $vs_form_prefix . '_';
                     $vb_allow_fetching_of_urls = (bool) $this->_CONFIG->get('allow_fetching_of_media_from_remote_urls');
                     $va_rep_ids_sorted = $va_rep_sort_order = explode(';', $po_request->getParameter($vs_prefix_stub . 'ObjectRepresentationBundleList', pString));
                     sort($va_rep_ids_sorted, SORT_NUMERIC);
                     $va_reps = $this->getRepresentations();
                     if (!$vb_batch && is_array($va_reps)) {
                         foreach ($va_reps as $vn_i => $va_rep) {
                             $this->clearErrors();
                             if (strlen($po_request->getParameter($vs_prefix_stub . 'access_' . $va_rep['representation_id'], pInteger)) > 0) {
                                 if ($vb_allow_fetching_of_urls && ($vs_path = $_REQUEST[$vs_prefix_stub . 'media_url_' . $va_rep['representation_id']])) {
                                     $va_tmp = explode('/', $vs_path);
                                     $vs_original_name = array_pop($va_tmp);
                                 } else {
                                     $vs_path = $_FILES[$vs_prefix_stub . 'media_' . $va_rep['representation_id']]['tmp_name'];
                                     $vs_original_name = $_FILES[$vs_prefix_stub . 'media_' . $va_rep['representation_id']]['name'];
                                 }
                                 $vn_is_primary = $po_request->getParameter($vs_prefix_stub . 'is_primary_' . $va_rep['representation_id'], pString) != '' ? $po_request->getParameter($vs_prefix_stub . 'is_primary_' . $va_rep['representation_id'], pInteger) : null;
                                 $vn_locale_id = $po_request->getParameter($vs_prefix_stub . 'locale_id_' . $va_rep['representation_id'], pInteger);
                                 $vs_idno = $po_request->getParameter($vs_prefix_stub . 'idno_' . $va_rep['representation_id'], pString);
                                 $vn_access = $po_request->getParameter($vs_prefix_stub . 'access_' . $va_rep['representation_id'], pInteger);
                                 $vn_status = $po_request->getParameter($vs_prefix_stub . 'status_' . $va_rep['representation_id'], pInteger);
                                 $vs_rep_label = trim($po_request->getParameter($vs_prefix_stub . 'rep_label_' . $va_rep['representation_id'], pString));
                                 //$vn_rep_type_id = $po_request->getParameter($vs_prefix_stub.'rep_type_id'.$va_rep['representation_id'], pInteger);
                                 // Get user-specified center point (images only)
                                 $vn_center_x = $po_request->getParameter($vs_prefix_stub . 'center_x_' . $va_rep['representation_id'], pString);
                                 $vn_center_y = $po_request->getParameter($vs_prefix_stub . 'center_y_' . $va_rep['representation_id'], pString);
                                 $vn_rank = null;
                                 if (($vn_rank_index = array_search($va_rep['representation_id'], $va_rep_sort_order)) !== false) {
                                     $vn_rank = $va_rep_ids_sorted[$vn_rank_index];
                                 }
                                 $this->editRepresentation($va_rep['representation_id'], $vs_path, $vn_locale_id, $vn_status, $vn_access, $vn_is_primary, array('idno' => $vs_idno), array('original_filename' => $vs_original_name, 'rank' => $vn_rank, 'centerX' => $vn_center_x, 'centerY' => $vn_center_y));
                                 if ($this->numErrors()) {
                                     //$po_request->addActionErrors($this->errors(), $vs_f, $va_rep['representation_id']);
                                     foreach ($this->errors() as $o_e) {
                                         switch ($o_e->getErrorNumber()) {
                                             case 795:
                                                 // field conflicts
                                                 $po_request->addActionError($o_e, $vs_f, $va_rep['representation_id']);
                                                 break;
                                             default:
                                                 $po_request->addActionError($o_e, $vs_f, $va_rep['representation_id']);
                                                 break;
                                         }
                                     }
                                 }
                                 if ($vs_rep_label) {
                                     //
                                     // Set representation label
                                     //
                                     $t_rep = new ca_object_representations();
                                     if ($this->inTransaction()) {
                                         $t_rep->setTransaction($this->getTransaction());
                                     }
                                     global $g_ui_locale_id;
                                     if ($t_rep->load($va_rep['representation_id'])) {
                                         $t_rep->setMode(ACCESS_WRITE);
                                         $t_rep->replaceLabel(array('name' => $vs_rep_label), $g_ui_locale_id, null, true);
                                         if ($t_rep->numErrors()) {
                                             $po_request->addActionErrors($t_rep->errors(), $vs_f, $va_rep['representation_id']);
                                         }
                                     }
                                 }
                             } else {
                                 // is it a delete key?
                                 $this->clearErrors();
                                 if ($po_request->getParameter($vs_prefix_stub . $va_rep['representation_id'] . '_delete', pInteger) > 0) {
                                     // delete!
                                     $this->removeRepresentation($va_rep['representation_id']);
                                     if ($this->numErrors()) {
                                         $po_request->addActionErrors($this->errors(), $vs_f, $va_rep['representation_id']);
                                     }
                                 }
                             }
                         }
                     }
                     if ($vb_batch) {
                         $vs_batch_mode = $_REQUEST[$vs_prefix_stub . 'batch_mode'];
                         if ($vs_batch_mode == '_disabled_') {
                             break;
                         }
                         if ($vs_batch_mode == '_replace_') {
                             $this->removeAllRepresentations();
                         }
                         if ($vs_batch_mode == '_delete_') {
                             $this->removeAllRepresentations();
                             break;
                         }
                     }
                     // check for new representations to add
                     $va_file_list = $_FILES;
                     foreach ($_REQUEST as $vs_key => $vs_value) {
                         if (!preg_match('/^' . $vs_prefix_stub . 'media_url_new_([\\d]+)$/', $vs_key, $va_matches)) {
                             continue;
                         }
                         $va_file_list[$vs_key] = array('url' => $vs_value);
                     }
                     foreach ($va_file_list as $vs_key => $va_values) {
                         $this->clearErrors();
                         if (!preg_match('/^' . $vs_prefix_stub . 'media_new_([\\d]+)$/', $vs_key, $va_matches) && ($vb_allow_fetching_of_urls && !preg_match('/^' . $vs_prefix_stub . 'media_url_new_([\\d]+)$/', $vs_key, $va_matches) || !$vb_allow_fetching_of_urls)) {
                             continue;
                         }
                         if ($vs_upload_type = $po_request->getParameter($vs_prefix_stub . 'upload_typenew_' . $va_matches[1], pString)) {
                             $po_request->user->setVar('defaultRepresentationUploadType', $vs_upload_type);
                         }
                         $vn_type_id = $po_request->getParameter($vs_prefix_stub . 'type_id_new_' . $va_matches[1], pInteger);
                         if ($vn_existing_rep_id = $po_request->getParameter($vs_prefix_stub . 'idnew_' . $va_matches[1], pInteger)) {
                             $this->addRelationship('ca_object_representations', $vn_existing_rep_id, $vn_type_id);
                         } else {
                             if ($vb_allow_fetching_of_urls && ($vs_path = $va_values['url'])) {
                                 $va_tmp = explode('/', $vs_path);
                                 $vs_original_name = array_pop($va_tmp);
                             } else {
                                 $vs_path = $va_values['tmp_name'];
                                 $vs_original_name = $va_values['name'];
                             }
                             if (!$vs_path) {
                                 continue;
                             }
                             $vn_rep_type_id = $po_request->getParameter($vs_prefix_stub . 'rep_type_id_new_' . $va_matches[1], pInteger);
                             if (!$vn_rep_type_id && !($vn_rep_type_id = caGetDefaultItemID('object_representation_types'))) {
                                 require_once __CA_MODELS_DIR__ . '/ca_lists.php';
                                 $t_list = new ca_lists();
                                 if (is_array($va_rep_type_ids = $t_list->getItemsForList('object_representation_types', array('idsOnly' => true, 'enabledOnly' => true)))) {
                                     $vn_rep_type_id = array_shift($va_rep_type_ids);
                                 }
                             }
                             if (is_array($pa_options['existingRepresentationMap']) && isset($pa_options['existingRepresentationMap'][$vs_path]) && $pa_options['existingRepresentationMap'][$vs_path]) {
                                 $this->addRelationship('ca_object_representations', $pa_options['existingRepresentationMap'][$vs_path], $vn_type_id);
                                 break;
                             }
                             $vs_rep_label = trim($po_request->getParameter($vs_prefix_stub . 'rep_label_new_' . $va_matches[1], pString));
                             $vn_locale_id = $po_request->getParameter($vs_prefix_stub . 'locale_id_new_' . $va_matches[1], pInteger);
                             $vs_idno = $po_request->getParameter($vs_prefix_stub . 'idno_new_' . $va_matches[1], pString);
                             $vn_status = $po_request->getParameter($vs_prefix_stub . 'status_new_' . $va_matches[1], pInteger);
                             $vn_access = $po_request->getParameter($vs_prefix_stub . 'access_new_' . $va_matches[1], pInteger);
                             $vn_is_primary = $po_request->getParameter($vs_prefix_stub . 'is_primary_new_' . $va_matches[1], pInteger);
                             // Get user-specified center point (images only)
                             $vn_center_x = $po_request->getParameter($vs_prefix_stub . 'center_x_new_' . $va_matches[1], pString);
                             $vn_center_y = $po_request->getParameter($vs_prefix_stub . 'center_y_new_' . $va_matches[1], pString);
                             $t_rep = $this->addRepresentation($vs_path, $vn_rep_type_id, $vn_locale_id, $vn_status, $vn_access, $vn_is_primary, array('name' => $vs_rep_label, 'idno' => $vs_idno), array('original_filename' => $vs_original_name, 'returnRepresentation' => true, 'centerX' => $vn_center_x, 'centerY' => $vn_center_y, 'type_id' => $vn_type_id));
                             // $vn_type_id = *relationship* type_id (as opposed to representation type)
                             if ($this->numErrors()) {
                                 $po_request->addActionErrors($this->errors(), $vs_f, 'new_' . $va_matches[1]);
                             } else {
                                 if ($t_rep && is_array($pa_options['existingRepresentationMap'])) {
                                     $pa_options['existingRepresentationMap'][$vs_path] = $t_rep->getPrimaryKey();
                                 }
                             }
                         }
                     }
                     break;
                     # -------------------------------------
                 # -------------------------------------
                 case 'ca_entities':
                 case 'ca_places':
                 case 'ca_objects':
                 case 'ca_collections':
                 case 'ca_occurrences':
                 case 'ca_list_items':
                 case 'ca_object_lots':
                 case 'ca_storage_locations':
                 case 'ca_loans':
                 case 'ca_movements':
                 case 'ca_tour_stops':
                     $this->_processRelated($po_request, $vs_f, $vs_form_prefix, $vs_placement_code, array('batch' => $vb_batch, 'settings' => $va_bundle_settings));
                     break;
                     # -------------------------------------
                 # -------------------------------------
                 case 'ca_representation_annotations':
                     if ($vb_batch) {
                         break;
                     }
                     // not supported in batch mode
                     $this->_processRepresentationAnnotations($po_request, $vs_form_prefix, $vs_placement_code);
                     break;
                     # -------------------------------------
             }
         }
     }
     // save data for "specials"
     if (isset($va_fields_by_type['special']) && is_array($va_fields_by_type['special'])) {
         foreach ($va_fields_by_type['special'] as $vs_placement_code => $vs_f) {
             // get settings
             $va_bundle_settings = array();
             foreach ($va_bundles as $va_bundle_info) {
                 if ('P' . $va_bundle_info['placement_id'] == $vs_placement_code) {
                     $va_bundle_settings = $va_bundle_info['settings'];
                     break;
                 }
             }
             switch ($vs_f) {
                 # -------------------------------------
                 // This bundle is only available when editing objects of type ca_representation_annotations
                 case 'ca_representation_annotation_properties':
                     if ($vb_batch) {
                         break;
                     }
                     // not supported in batch mode
                     if (!$this->useInEditor()) {
                         break;
                     }
                     foreach ($this->getPropertyList() as $vs_property) {
                         $this->setPropertyValue($vs_property, $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}{$vs_property}", pString));
                     }
                     if (!$this->validatePropertyValues()) {
                         $po_request->addActionErrors($this->errors(), 'ca_representation_annotation_properties', 'general');
                     }
                     $this->update();
                     break;
                     # -------------------------------------
                     // This bundle is only available for types which support set membership
                 # -------------------------------------
                 // This bundle is only available for types which support set membership
                 case 'ca_sets':
                     // check for existing labels to delete (no updating supported)
                     require_once __CA_MODELS_DIR__ . '/ca_sets.php';
                     require_once __CA_MODELS_DIR__ . '/ca_set_items.php';
                     $t_set = new ca_sets();
                     if (!$vb_batch) {
                         $va_sets = caExtractValuesByUserLocale($t_set->getSetsForItem($this->tableNum(), $this->getPrimaryKey(), array('user_id' => $po_request->getUserID())));
                         foreach ($va_sets as $vn_set_id => $va_set_info) {
                             $vn_item_id = $va_set_info['item_id'];
                             if ($po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}_set_id_{$vn_item_id}_delete", pString)) {
                                 // delete
                                 $t_set->load($va_set_info['set_id']);
                                 $t_set->removeItem($this->getPrimaryKey(), $po_request->getUserID());
                                 // remove *all* instances of the item in the set, not just the specified id
                                 if ($t_set->numErrors()) {
                                     $po_request->addActionErrors($t_set->errors(), $vs_f);
                                 }
                             }
                         }
                     }
                     if ($vb_batch) {
                         $vs_batch_mode = $_REQUEST["{$vs_placement_code}{$vs_form_prefix}_batch_mode"];
                         if ($vs_batch_mode == '_disabled_') {
                             break;
                         }
                         if ($vs_batch_mode == '_replace_') {
                             $t_set->removeItemFromAllSets($this->tableNum(), $this->getPrimaryKey());
                         }
                         if ($vs_batch_mode == '_delete_') {
                             $t_set->removeItemFromAllSets($this->tableNum(), $this->getPrimaryKey());
                             break;
                         }
                     }
                     foreach ($_REQUEST as $vs_key => $vs_value) {
                         if (!preg_match("/{$vs_placement_code}{$vs_form_prefix}_set_id_new_([\\d]+)/", $vs_key, $va_matches)) {
                             continue;
                         }
                         $vn_c = intval($va_matches[1]);
                         if ($vn_new_set_id = $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}_set_id_new_{$vn_c}", pString)) {
                             $t_set->load($vn_new_set_id);
                             $t_set->addItem($this->getPrimaryKey(), null, $po_request->getUserID());
                             if ($t_set->numErrors()) {
                                 $po_request->addActionErrors($t_set->errors(), $vs_f);
                             }
                         }
                     }
                     break;
                     # -------------------------------------
                     // This bundle is only available for types which support set membership
                 # -------------------------------------
                 // This bundle is only available for types which support set membership
                 case 'ca_set_items':
                     if ($vb_batch) {
                         break;
                     }
                     // not supported in batch mode
                     // check for existing labels to delete (no updating supported)
                     require_once __CA_MODELS_DIR__ . '/ca_sets.php';
                     require_once __CA_MODELS_DIR__ . '/ca_set_items.php';
                     $va_rids = explode(';', $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}setRowIDList", pString));
                     $this->reorderItems($va_rids, array('user_id' => $po_request->getUserID(), 'treatRowIDsAsRIDs' => true, 'deleteExcludedItems' => true));
                     break;
                     # -------------------------------------
                     // This bundle is only available for ca_search_forms
                 # -------------------------------------
                 // This bundle is only available for ca_search_forms
                 case 'ca_search_form_elements':
                     if ($vb_batch) {
                         break;
                     }
                     // not supported in batch mode
                     // save settings
                     $va_settings = $this->getAvailableSettings();
                     foreach ($va_settings as $vs_setting => $va_setting_info) {
                         if (isset($_REQUEST['setting_' . $vs_setting])) {
                             $vs_setting_val = $po_request->getParameter('setting_' . $vs_setting, pString);
                             $this->setSetting($vs_setting, $vs_setting_val);
                             $this->update();
                         }
                     }
                     break;
                     # -------------------------------------
                     // This bundle is only available for ca_bundle_displays
                 # -------------------------------------
                 // This bundle is only available for ca_bundle_displays
                 case 'ca_bundle_display_placements':
                     if ($vb_batch) {
                         break;
                     }
                     // not supported in batch mode
                     $this->savePlacementsFromHTMLForm($po_request, $vs_form_prefix, $vs_placement_code);
                     break;
                     # -------------------------------------
                     // This bundle is only available for ca_bundle_displays
                 # -------------------------------------
                 // This bundle is only available for ca_bundle_displays
                 case 'ca_bundle_display_type_restrictions':
                     if ($vb_batch) {
                         break;
                     }
                     // not supported in batch mode
                     $this->saveTypeRestrictionsFromHTMLForm($po_request, $vs_form_prefix, $vs_placement_code);
                     break;
                     # -------------------------------------
                     // This bundle is only available for ca_search_forms
                 # -------------------------------------
                 // This bundle is only available for ca_search_forms
                 case 'ca_search_form_placements':
                     if ($vb_batch) {
                         break;
                     }
                     // not supported in batch mode
                     $this->savePlacementsFromHTMLForm($po_request, $vs_form_prefix, $vs_placement_code);
                     break;
                     # -------------------------------------
                     // This bundle is only available for ca_editor_ui
                 # -------------------------------------
                 // This bundle is only available for ca_editor_ui
                 case 'ca_editor_ui_screens':
                     if ($vb_batch) {
                         break;
                     }
                     // not supported in batch mode
                     global $g_ui_locale_id;
                     require_once __CA_MODELS_DIR__ . '/ca_editor_ui_screens.php';
                     $va_screen_ids = explode(';', $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}_ScreenBundleList", pString));
                     foreach ($_REQUEST as $vs_key => $vs_val) {
                         if (is_array($vs_val)) {
                             continue;
                         }
                         if (!($vs_val = trim($vs_val))) {
                             continue;
                         }
                         if (preg_match("!^{$vs_placement_code}{$vs_form_prefix}_name_new_([\\d]+)\$!", $vs_key, $va_matches)) {
                             if (!($t_screen = $this->addScreen($vs_val, $g_ui_locale_id, 'screen_' . $this->getPrimaryKey() . '_' . $va_matches[1]))) {
                                 break;
                             }
                             if ($vn_fkey = array_search("new_" . $va_matches[1], $va_screen_ids)) {
                                 $va_screen_ids[$vn_fkey] = $t_screen->getPrimaryKey();
                             } else {
                                 $va_screen_ids[] = $t_screen->getPrimaryKey();
                             }
                             continue;
                         }
                         if (preg_match("!^{$vs_placement_code}{$vs_form_prefix}_([\\d]+)_delete\$!", $vs_key, $va_matches)) {
                             $this->removeScreen($va_matches[1]);
                             if ($vn_fkey = array_search($va_matches[1], $va_screen_ids)) {
                                 unset($va_screen_ids[$vn_fkey]);
                             }
                         }
                     }
                     $this->reorderScreens($va_screen_ids);
                     break;
                     # -------------------------------------
                     // This bundle is only available for ca_editor_ui_screens
                 # -------------------------------------
                 // This bundle is only available for ca_editor_ui_screens
                 case 'ca_editor_ui_bundle_placements':
                     if ($vb_batch) {
                         break;
                     }
                     // not supported in batch mode
                     $this->savePlacementsFromHTMLForm($po_request, $vs_form_prefix, $vs_placement_code);
                     break;
                     # -------------------------------------
                     // This bundle is only available for ca_editor_uis
                 # -------------------------------------
                 // This bundle is only available for ca_editor_uis
                 case 'ca_editor_ui_type_restrictions':
                     if ($vb_batch) {
                         break;
                     }
                     // not supported in batch mode
                     $this->saveTypeRestrictionsFromHTMLForm($po_request, $vs_form_prefix, $vs_placement_code);
                     break;
                     # -------------------------------------
                     // This bundle is only available for ca_editor_ui_screens
                 # -------------------------------------
                 // This bundle is only available for ca_editor_ui_screens
                 case 'ca_editor_ui_screen_type_restrictions':
                     if ($vb_batch) {
                         break;
                     }
                     // not supported in batch mode
                     $this->saveTypeRestrictionsFromHTMLForm($po_request, $vs_form_prefix, $vs_placement_code);
                     break;
                     # -------------------------------------
                     // This bundle is only available for ca_tours
                 # -------------------------------------
                 // This bundle is only available for ca_tours
                 case 'ca_tour_stops_list':
                     if ($vb_batch) {
                         break;
                     }
                     // not supported in batch mode
                     global $g_ui_locale_id;
                     require_once __CA_MODELS_DIR__ . '/ca_tour_stops.php';
                     $va_stop_ids = explode(';', $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}_StopBundleList", pString));
                     foreach ($_REQUEST as $vs_key => $vs_val) {
                         if (!($vs_val = trim($vs_val))) {
                             continue;
                         }
                         if (preg_match("!^{$vs_placement_code}{$vs_form_prefix}_name_new_([\\d]+)\$!", $vs_key, $va_matches)) {
                             $vn_type_id = $_REQUEST["{$vs_placement_code}{$vs_form_prefix}_type_id_new_" . $va_matches[1]];
                             if (!($t_stop = $this->addStop($vs_val, $vn_type_id, $g_ui_locale_id, mb_substr(preg_replace('![^A-Za-z0-9_]+!', '_', $vs_val), 0, 255)))) {
                                 break;
                             }
                             if ($vn_fkey = array_search("new_" . $va_matches[1], $va_stop_ids)) {
                                 $va_stop_ids[$vn_fkey] = $t_stop->getPrimaryKey();
                             } else {
                                 $va_stop_ids[] = $t_stop->getPrimaryKey();
                             }
                             continue;
                         }
                         if (preg_match("!^{$vs_placement_code}{$vs_form_prefix}_([\\d]+)_delete\$!", $vs_key, $va_matches)) {
                             $this->removeStop($va_matches[1]);
                             if ($vn_fkey = array_search($va_matches[1], $va_stop_ids)) {
                                 unset($va_stop_ids[$vn_fkey]);
                             }
                         }
                     }
                     $this->reorderStops($va_stop_ids);
                     break;
                     # -------------------------------------
                 # -------------------------------------
                 case 'ca_user_groups':
                     if ($vb_batch) {
                         break;
                     }
                     // not supported in batch mode
                     if (!$po_request->user->canDoAction('is_administrator') && $po_request->getUserID() != $this->get('user_id')) {
                         break;
                     }
                     // don't save if user is not owner
                     require_once __CA_MODELS_DIR__ . '/ca_user_groups.php';
                     $va_groups_to_set = $va_group_effective_dates = array();
                     foreach ($_REQUEST as $vs_key => $vs_val) {
                         if (preg_match("!^{$vs_placement_code}{$vs_form_prefix}_id(.*)\$!", $vs_key, $va_matches)) {
                             $vs_effective_date = $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}_effective_date_" . $va_matches[1], pString);
                             $vn_group_id = (int) $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}_id" . $va_matches[1], pInteger);
                             $vn_access = $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}_access_" . $va_matches[1], pInteger);
                             if ($vn_access > 0) {
                                 $va_groups_to_set[$vn_group_id] = $vn_access;
                                 $va_group_effective_dates[$vn_group_id] = $vs_effective_date;
                             }
                         }
                     }
                     $this->setUserGroups($va_groups_to_set, $va_group_effective_dates, array('user_id' => $po_request->getUserID()));
                     break;
                     # -------------------------------------
                 # -------------------------------------
                 case 'ca_users':
                     if ($vb_batch) {
                         break;
                     }
                     // not supported in batch mode
                     if (!$po_request->user->canDoAction('is_administrator') && $po_request->getUserID() != $this->get('user_id')) {
                         break;
                     }
                     // don't save if user is not owner
                     require_once __CA_MODELS_DIR__ . '/ca_users.php';
                     $va_users_to_set = $va_user_effective_dates = array();
                     foreach ($_REQUEST as $vs_key => $vs_val) {
                         if (preg_match("!^{$vs_placement_code}{$vs_form_prefix}_id(.*)\$!", $vs_key, $va_matches)) {
                             $vs_effective_date = $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}_effective_date_" . $va_matches[1], pString);
                             $vn_user_id = (int) $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}_id" . $va_matches[1], pInteger);
                             $vn_access = $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}_access_" . $va_matches[1], pInteger);
                             if ($vn_access > 0) {
                                 $va_users_to_set[$vn_user_id] = $vn_access;
                                 $va_user_effective_dates[$vn_user_id] = $vs_effective_date;
                             }
                         }
                     }
                     $this->setUsers($va_users_to_set, $va_user_effective_dates);
                     break;
                     # -------------------------------------
                 # -------------------------------------
                 case 'settings':
                     if ($vb_batch) {
                         break;
                     }
                     // not supported in batch mode
                     $this->setSettingsFromHTMLForm($po_request, array('id' => $vs_form_prefix . '_', 'placement_code' => $vs_placement_code));
                     break;
                     # -------------------------------
                     // This bundle is only available when editing objects of type ca_object_representations
                 # -------------------------------
                 // This bundle is only available when editing objects of type ca_object_representations
                 case 'ca_object_representations_media_display':
                     if ($vb_batch) {
                         break;
                     }
                     // not supported in batch mode
                     $va_versions_to_process = null;
                     if ($vb_use_options = (bool) $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}_derivative_options_selector", pInteger)) {
                         // update only specified versions
                         $va_versions_to_process = $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}_set_versions", pArray);
                     }
                     if (!is_array($va_versions_to_process) || !sizeof($va_versions_to_process)) {
                         $va_versions_to_process = array('_all');
                     }
                     if ($vb_use_options && $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}_derivative_options_mode", pString) == 'timecode') {
                         // timecode
                         if (!(string) ($vs_timecode = $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}_derivative_options_mode_timecode_value", pString))) {
                             $vs_timecode = "1s";
                         }
                         //
                         $o_media = new Media();
                         if ($o_media->read($this->getMediaPath('media', 'original'))) {
                             $va_files = $o_media->writePreviews(array('force' => true, 'outputDirectory' => $this->_CONFIG->get("taskqueue_tmp_directory"), 'minNumberOfFrames' => 1, 'maxNumberOfFrames' => 1, 'startAtTime' => $vs_timecode, 'endAtTime' => $vs_timecode, 'width' => 720, 'height' => 540));
                             if (sizeof($va_files)) {
                                 $this->set('media', array_shift($va_files));
                             }
                         }
                     } else {
                         if ($vb_use_options && $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}_derivative_options_mode", pString) == 'page') {
                             if (!(int) ($vn_page = $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}_derivative_options_mode_page_value", pInteger))) {
                                 $vn_page = 1;
                             }
                             //
                             $o_media = new Media();
                             if ($o_media->read($this->getMediaPath('media', 'original'))) {
                                 $va_files = $o_media->writePreviews(array('force' => true, 'outputDirectory' => $this->_CONFIG->get("taskqueue_tmp_directory"), 'numberOfPages' => 1, 'startAtPage' => $vn_page, 'width' => 2048, 'height' => 2048));
                                 if (sizeof($va_files)) {
                                     $this->set('media', array_shift($va_files));
                                 }
                             }
                         } else {
                             // process file as new upload
                             $vs_key = "{$vs_placement_code}{$vs_form_prefix}_url";
                             if (($vs_media_url = trim($po_request->getParameter($vs_key, pString))) && isURL($vs_media_url)) {
                                 $this->set('media', $vs_media_url);
                             } else {
                                 $vs_key = "{$vs_placement_code}{$vs_form_prefix}_media";
                                 if (isset($_FILES[$vs_key])) {
                                     $this->set('media', $_FILES[$vs_key]['tmp_name'], array('original_filename' => $_FILES[$vs_key]['name']));
                                 }
                             }
                         }
                     }
                     if ($this->changed('media')) {
                         $this->update($vs_version != '_all' ? array('updateOnlyMediaVersions' => $va_versions_to_process) : array());
                         if ($this->numErrors()) {
                             $po_request->addActionErrors($this->errors(), 'ca_object_representations_media_display', 'general');
                         }
                     }
                     break;
                     # -------------------------------
                     // This bundle is only available when editing objects of type ca_object_representations
                 # -------------------------------
                 // This bundle is only available when editing objects of type ca_object_representations
                 case 'ca_object_representation_captions':
                     if ($vb_batch) {
                         return null;
                     }
                     // not supported in batch mode
                     $va_users_to_set = array();
                     foreach ($_REQUEST as $vs_key => $vs_val) {
                         if (preg_match("!^{$vs_placement_code}{$vs_form_prefix}_locale_id(.*)\$!", $vs_key, $va_matches)) {
                             $vn_locale_id = (int) $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}_locale_id" . $va_matches[1], pInteger);
                             $this->addCaptionFile($_FILES["{$vs_placement_code}{$vs_form_prefix}_caption_file" . $va_matches[1]]['tmp_name'], $vn_locale_id, array('originalFilename' => $_FILES["{$vs_placement_code}{$vs_form_prefix}_captions_caption_file" . $va_matches[1]]['name']));
                         } else {
                             // any to delete?
                             if (preg_match("!^{$vs_placement_code}{$vs_form_prefix}_([\\d]+)_delete\$!", $vs_key, $va_matches)) {
                                 $this->removeCaptionFile((int) $va_matches[1]);
                             }
                         }
                     }
                     break;
                     # -------------------------------
                     // This bundle is only available for relationships that include an object on one end
                 # -------------------------------
                 // This bundle is only available for relationships that include an object on one end
                 case 'ca_object_representation_chooser':
                     if ($vb_batch) {
                         return null;
                     }
                     // not supported in batch mode
                     if (!is_array($va_rep_ids = $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}", pArray))) {
                         $va_rep_ids = array();
                     }
                     if ($vs_element_code = caGetOption(array('elementCode', 'element_code'), $va_bundle_settings, null)) {
                         if (!is_array($va_current_rep_ids = $this->get($this->tableName() . "." . $vs_element_code, array('returnAsArray' => true, 'idsOnly' => true)))) {
                             $va_current_rep_ids = $va_current_rep_id_with_structure = array();
                         } else {
                             $va_current_rep_id_with_structure = $this->get($this->tableName() . "." . $vs_element_code, array('returnWithStructure' => true, 'idsOnly' => true));
                         }
                         $va_rep_to_attr_id = array();
                         foreach ($va_rep_ids as $vn_rep_id) {
                             if (in_array($vn_rep_id, $va_current_rep_ids)) {
                                 continue;
                             }
                             $this->addAttribute(array($vs_element_code => $vn_rep_id), $vs_element_code);
                         }
                         foreach ($va_current_rep_id_with_structure as $vn_id => $va_vals_by_attr_id) {
                             foreach ($va_vals_by_attr_id as $vn_attribute_id => $va_val) {
                                 if (!in_array($va_val[$vs_element_code], $va_rep_ids)) {
                                     $this->removeAttribute($vn_attribute_id);
                                 }
                             }
                         }
                         $this->update();
                     }
                     break;
                     # -------------------------------
                     // This bundle is only available for objects
                 # -------------------------------
                 // This bundle is only available for objects
                 case 'ca_objects_location':
                     if ($vb_batch) {
                         return null;
                     }
                     // not supported in batch mode
                     if (!$po_request->user->canDoAction('can_edit_ca_objects')) {
                         break;
                     }
                     if ($vn_location_id = $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}_location_idnew_0", pInteger)) {
                         if (is_array($va_relationship_types = caGetOption('ca_storage_locations_relationshipType', $va_bundle_settings, null)) && ($vn_relationship_type_id = array_shift($va_relationship_types))) {
                             $this->addRelationship('ca_storage_locations', $vn_location_id, $vn_relationship_type_id, null, null, null, null, array('allowDuplicates' => true));
                             if ($this->numErrors()) {
                                 $po_request->addActionErrors($this->errors(), 'ca_objects_location', 'general');
                             }
                         }
                     }
                     break;
                     # -------------------------------
                     // This bundle is only available for objects
                 # -------------------------------
                 // This bundle is only available for objects
                 case 'ca_objects_history':
                     if ($vb_batch) {
                         return null;
                     }
                     // not supported in batch mode
                     if (!$po_request->user->canDoAction('can_edit_ca_objects')) {
                         break;
                     }
                     // set storage location
                     if ($vn_location_id = $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}_location_idnew_0", pInteger)) {
                         if (is_array($va_relationship_types = caGetOption('ca_storage_locations_showRelationshipTypes', $va_bundle_settings, null)) && ($vn_relationship_type_id = array_shift($va_relationship_types))) {
                             $this->addRelationship('ca_storage_locations', $vn_location_id, $vn_relationship_type_id, null, null, null, null, array('allowDuplicates' => true));
                             if ($this->numErrors()) {
                                 $po_request->addActionErrors($this->errors(), 'ca_objects_history', 'general');
                             }
                         }
                     }
                     // set loan
                     if ($vn_loan_id = $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}_loan_idnew_0", pInteger)) {
                         if ($vn_loan_type_id = $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}_loan_type_idnew_0", pInteger)) {
                             $this->addRelationship('ca_loans', $vn_loan_id, $vn_loan_type_id);
                             if ($this->numErrors()) {
                                 $po_request->addActionErrors($this->errors(), 'ca_objects_history', 'general');
                             }
                         }
                     }
                     break;
                     # -------------------------------
                     // This bundle is only available for objects
                 # -------------------------------
                 // This bundle is only available for objects
                 case 'ca_objects_deaccession':
                     // object deaccession information
                     if (!$vb_batch && !$this->getPrimaryKey()) {
                         return null;
                     }
                     // not supported for new records
                     if (!$po_request->user->canDoAction('can_edit_ca_objects')) {
                         break;
                     }
                     $this->set('is_deaccessioned', $vb_is_deaccessioned = $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}is_deaccessioned", pInteger));
                     $this->set('deaccession_notes', $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}deaccession_notes", pString));
                     $this->set('deaccession_type_id', $x = $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}deaccession_type_id", pString));
                     $this->set('deaccession_date', $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}deaccession_date", pString));
                     if ($vb_is_deaccessioned && (bool) $this->getAppConfig()->get('deaccession_force_access_private')) {
                         $this->get('access', 0);
                     }
                     // set access to private for accessioned items
                     $this->update();
                     break;
                     # -------------------------------
                     // This bundle is only available for objects
                 # -------------------------------
                 // This bundle is only available for objects
                 case 'ca_object_checkouts':
                     // object checkout information
                     if ($vb_batch) {
                         return null;
                     }
                     // not supported in batch mode
                     if (!$vb_batch && !$this->getPrimaryKey()) {
                         return null;
                     }
                     // not supported for new records
                     if (!$po_request->user->canDoAction('can_edit_ca_objects')) {
                         break;
                     }
                     // NOOP (for now)
                     break;
                     # -------------------------------
             }
         }
     }
     BaseModel::unsetChangeLogUnitID();
     $va_bundle_names = array();
     foreach ($va_bundles as $va_bundle) {
         $vs_bundle_name = str_replace('ca_attribute_', '', $va_bundle['bundle_name']);
         if (!$this->getAppDatamodel()->getInstanceByTableName($vs_bundle_name, true)) {
             $vs_bundle_name = $this->tableName() . '.' . $vs_bundle_name;
         }
         $va_bundle_names[] = $vs_bundle_name;
     }
     // validate metadata dictionary rules
     $va_violations = $this->validateUsingMetadataDictionaryRules(array('bundles' => $va_bundle_names));
     if (sizeof($va_violations)) {
         if ($vb_we_set_transaction && isset($va_violations['ERR']) && is_array($va_violations['ERR']) && sizeof($va_violations['ERR']) > 0) {
             BaseModel::unsetChangeLogUnitID();
             $this->removeTransaction(false);
             $this->_FIELD_VALUES[$this->primaryKey()] = null;
             // clear primary key since transaction has been rolled back
             foreach ($va_violations['ERR'] as $vs_bundle => $va_errs_by_bundle) {
                 foreach ($va_errs_by_bundle as $vn_i => $va_rule) {
                     $vs_bundle = str_replace($this->tableName() . ".", "", $vs_bundle);
                     $po_request->addActionErrors(array(new Error(1100, $va_rule['rule_settings']['violationMessage'], "BundlableLabelableBaseModelWithAttributes->saveBundlesForScreen()", 'MetadataDictionary', false, false)), $vs_bundle, 'general');
                 }
             }
             return false;
         }
     }
     // prepopulate fields
     $vs_prepopulate_cfg = $this->getAppConfig()->get('prepopulate_config');
     $o_prepopulate_conf = Configuration::load($vs_prepopulate_cfg);
     if ($o_prepopulate_conf->get('prepopulate_fields_on_save')) {
         $this->prepopulateFields(array('prepopulateConfig' => $vs_prepopulate_cfg));
     }
     if ($vb_dryrun) {
         $this->removeTransaction(false);
     }
     if ($vb_we_set_transaction) {
         $this->removeTransaction(true);
     }
     return true;
 }
Esempio n. 26
0
 /**
  *
  */
 public static function check_media_fixity($po_opts = null)
 {
     require_once __CA_LIB_DIR__ . "/core/Db.php";
     require_once __CA_MODELS_DIR__ . "/ca_object_representations.php";
     $ps_file_path = strtolower((string) $po_opts->getOption('file'));
     $ps_format = strtolower((string) $po_opts->getOption('format'));
     if (!in_array($ps_format, array('text', 'tab', 'csv'))) {
         $ps_format = 'text';
     }
     $o_db = new Db();
     $o_dm = Datamodel::load();
     $t_rep = new ca_object_representations();
     $vs_report_output = join($ps_format == 'tab' ? "\t" : ",", array(_t('Type'), _t('Error'), _t('Name'), _t('ID'), _t('Version'), _t('File path'), _t('Expected MD5'), _t('Actual MD5'))) . "\n";
     // Verify object representations
     $qr_reps = $o_db->query("SELECT representation_id, idno, media FROM ca_object_representations WHERE deleted = 0");
     print CLIProgressBar::start($vn_rep_count = $qr_reps->numRows(), _t('Checking object representations')) . "\n";
     $vn_errors = 0;
     while ($qr_reps->nextRow()) {
         $vn_representation_id = $qr_reps->get('representation_id');
         print CLIProgressBar::next(1, _t("Checking representation media %1", $vn_representation_id));
         $va_media_versions = $qr_reps->getMediaVersions('media');
         foreach ($va_media_versions as $vs_version) {
             $vs_path = $qr_reps->getMediaPath('media', $vs_version);
             $vs_database_md5 = $qr_reps->getMediaInfo('media', $vs_version, 'MD5');
             $vs_file_md5 = md5_file($vs_path);
             if ($vs_database_md5 !== $vs_file_md5) {
                 $t_rep->load($vn_representation_id);
                 $vs_message = _t("[Object representation][MD5 mismatch] %1; version %2 [%3]", $t_rep->get("ca_objects.preferred_labels.name") . " (" . $t_rep->get("ca_objects.idno") . "); representation_id={$vn_representation_id}", $vs_version, $vs_path);
                 switch ($ps_format) {
                     case 'text':
                     default:
                         $vs_report_output .= "{$vs_message}\n";
                         break;
                     case 'tab':
                     case 'csv':
                         $va_log = array(_t('Object representation'), "MD5 mismatch", caEscapeForDelimitedOutput($t_rep->get("ca_objects.preferred_labels.name") . " (" . $t_rep->get("ca_objects.idno") . ")"), $vn_representation_id, $vs_version, $vs_path, $vs_database_md5, $vs_file_md5);
                         $vs_report_output .= join($ps_format == 'tab' ? "\t" : ",", $va_log) . "\n";
                         break;
                 }
                 CLIUtils::addError($vs_message);
                 $vn_errors++;
             }
         }
     }
     print CLIProgressBar::finish();
     CLIUtils::addMessage(_t('%1 errors for %2 representations', $vn_errors, $vn_rep_count));
     // get all Media elements
     $va_elements = ca_metadata_elements::getElementsAsList(false, null, null, true, false, true, array(16));
     // 16=media
     if (is_array($va_elements) && sizeof($va_elements)) {
         if (is_array($va_element_ids = caExtractValuesFromArrayList($va_elements, 'element_id', array('preserveKeys' => false))) && sizeof($va_element_ids)) {
             $qr_c = $o_db->query("\n\t\t\t\t\t\tSELECT count(*) c\n\t\t\t\t\t\tFROM ca_attribute_values\n\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\telement_id in (?)\n\t\t\t\t\t", array($va_element_ids));
             if ($qr_c->nextRow()) {
                 $vn_count = $qr_c->get('c');
             } else {
                 $vn_count = 0;
             }
             print CLIProgressBar::start($vn_count, _t('Checking attribute media'));
             $vn_errors = 0;
             foreach ($va_elements as $vs_element_code => $va_element_info) {
                 $qr_vals = $o_db->query("SELECT value_id FROM ca_attribute_values WHERE element_id = ?", (int) $va_element_info['element_id']);
                 $va_vals = $qr_vals->getAllFieldValues('value_id');
                 foreach ($va_vals as $vn_value_id) {
                     $t_attr_val = new ca_attribute_values($vn_value_id);
                     if ($t_attr_val->getPrimaryKey()) {
                         $t_attr_val->setMode(ACCESS_WRITE);
                         $t_attr_val->useBlobAsMediaField(true);
                         print CLIProgressBar::next(1, _t("Checking attribute media %1", $vn_value_id));
                         $va_media_versions = $t_attr_val->getMediaVersions('value_blob');
                         foreach ($va_media_versions as $vs_version) {
                             $vs_path = $t_attr_val->getMediaPath('value_blob', $vs_version);
                             $vs_database_md5 = $t_attr_val->getMediaInfo('value_blob', $vs_version, 'MD5');
                             $vs_file_md5 = md5_file($vs_path);
                             if ($vs_database_md5 !== $vs_file_md5) {
                                 $t_attr = new ca_attributes($vn_attribute_id = $t_attr_val->get('attribute_id'));
                                 $vs_label = "attribute_id={$vn_attribute_id}; value_id={$vn_value_id}";
                                 if ($t_instance = $o_dm->getInstanceByTableNum($t_attr->get('table_num'), true)) {
                                     if ($t_instance->load($t_attr->get('row_id'))) {
                                         $vs_label = $t_instance->get($t_instance->tableName() . '.preferred_labels');
                                         if ($vs_idno = $t_instance->get($t_instance->getProperty('ID_NUMBERING_ID_FIELD'))) {
                                             $vs_label .= " ({$vs_label})";
                                         }
                                     }
                                 }
                                 $vs_message = _t("[Media attribute][MD5 mismatch] %1; value_id=%2; version %3 [%4]", $vs_label, $vn_value_id, $vs_version, $vs_path);
                                 switch ($ps_format) {
                                     case 'text':
                                     default:
                                         $vs_report_output .= "{$vs_message}\n";
                                         break;
                                     case 'tab':
                                     case 'csv':
                                         $va_log = array(_t('Media attribute'), _t("MD5 mismatch"), caEscapeForDelimitedOutput($vs_label), $vn_value_id, $vs_version, $vs_path, $vs_database_md5, $vs_file_md5);
                                         $vs_report_output .= join($ps_format == 'tab' ? "\t" : ",", $va_log);
                                         break;
                                 }
                                 CLIUtils::addError($vs_message);
                                 $vn_errors++;
                             }
                         }
                     }
                 }
             }
             print CLIProgressBar::finish();
             CLIUtils::addMessage(_t('%1 errors for %2 attributes', $vn_errors, $vn_rep_count));
         }
     }
     // get all File elements
     $va_elements = ca_metadata_elements::getElementsAsList(false, null, null, true, false, true, array(15));
     // 15=file
     if (is_array($va_elements) && sizeof($va_elements)) {
         if (is_array($va_element_ids = caExtractValuesFromArrayList($va_elements, 'element_id', array('preserveKeys' => false))) && sizeof($va_element_ids)) {
             $qr_c = $o_db->query("\n\t\t\t\t\t\tSELECT count(*) c\n\t\t\t\t\t\tFROM ca_attribute_values\n\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\telement_id in (?)\n\t\t\t\t\t", array($va_element_ids));
             if ($qr_c->nextRow()) {
                 $vn_count = $qr_c->get('c');
             } else {
                 $vn_count = 0;
             }
             print CLIProgressBar::start($vn_count, _t('Checking attribute files'));
             $vn_errors = 0;
             foreach ($va_elements as $vs_element_code => $va_element_info) {
                 $qr_vals = $o_db->query("SELECT value_id FROM ca_attribute_values WHERE element_id = ?", (int) $va_element_info['element_id']);
                 $va_vals = $qr_vals->getAllFieldValues('value_id');
                 foreach ($va_vals as $vn_value_id) {
                     $t_attr_val = new ca_attribute_values($vn_value_id);
                     if ($t_attr_val->getPrimaryKey()) {
                         $t_attr_val->setMode(ACCESS_WRITE);
                         $t_attr_val->useBlobAsFileField(true);
                         print CLIProgressBar::next(1, _t("Checking attribute file %1", $vn_value_id));
                         $vs_path = $t_attr_val->getFilePath('value_blob');
                         $vs_database_md5 = $t_attr_val->getFileInfo('value_blob', 'MD5');
                         $vs_file_md5 = md5_file($vs_path);
                         if ($vs_database_md5 !== $vs_file_md5) {
                             $t_attr = new ca_attributes($vn_attribute_id = $t_attr_val->get('attribute_id'));
                             $vs_label = "attribute_id={$vn_attribute_id}; value_id={$vn_value_id}";
                             if ($t_instance = $o_dm->getInstanceByTableNum($t_attr->get('table_num'), true)) {
                                 if ($t_instance->load($t_attr->get('row_id'))) {
                                     $vs_label = $t_instance->get($t_instance->tableName() . '.preferred_labels');
                                     if ($vs_idno = $t_instance->get($t_instance->getProperty('ID_NUMBERING_ID_FIELD'))) {
                                         $vs_label .= " ({$vs_label})";
                                     }
                                 }
                             }
                             $vs_message = _t("[File attribute][MD5 mismatch] %1; value_id=%2; version %3 [%4]", $vs_label, $vn_value_id, $vs_version, $vs_path);
                             switch ($ps_format) {
                                 case 'text':
                                 default:
                                     $vs_report_output .= "{$vs_message}\n";
                                     break;
                                 case 'tab':
                                 case 'csv':
                                     $va_log = array(_t('File attribute'), _t("MD5 mismatch"), caEscapeForDelimitedOutput($vs_label), $vn_value_id, $vs_version, $vs_path, $vs_database_md5, $vs_file_md5);
                                     $vs_report_output .= join($ps_format == 'tab' ? "\t" : ",", $va_log);
                                     break;
                             }
                             CLIUtils::addError($vs_message);
                             $vn_errors++;
                         }
                     }
                 }
             }
             print CLIProgressBar::finish();
             CLIUtils::addMessage(_t('%1 errors for %2 attributes', $vn_errors, $vn_rep_count));
         }
     }
     if ($ps_file_path) {
         file_put_contents($ps_file_path, $vs_report_output);
     }
     return true;
 }
Esempio n. 27
0
 public function setItemInfo()
 {
     $va_access_values = caGetUserAccessValues($this->request);
     $pn_set_id = $this->request->getParameter('set_id', pInteger);
     $t_set = new ca_sets($pn_set_id);
     $this->view->setVar('set_id', $pn_set_id);
     $pn_set_item_id = $this->request->getParameter('set_item_id', pInteger);
     $t_set_item = new ca_set_items($pn_set_item_id);
     $va_set_item_info = array();
     $va_items = $t_set->getItemIDs(array("checkAccess" => $va_access_values));
     $pn_previous_id = "";
     foreach ($va_items as $vn_item_id => $va_item_info) {
         if ($va_set_item_info["item_id"]) {
             $va_set_item_info["next_id"] = $vn_item_id;
             break;
         }
         if ($pn_set_item_id == $vn_item_id) {
             $va_set_item_info["previous_id"] = $pn_previous_id;
             $va_set_item_info["item_id"] = $vn_item_id;
         }
         $pn_previous_id = $vn_item_id;
     }
     $va_set_item_info["item_id"] = $t_set_item->get("item_id");
     $va_reps = $t_set_item->getRepresentations(array("mediumlarge", "small"), null, array("return_with_access" => $va_access_values));
     $va_rep = array_shift($va_rep);
     $this->view->setVar('t_object_representation', $t_rep = new ca_object_representations($va_rep['representation_id']));
     $va_rep_display_info = caGetMediaDisplayInfo('cropped_gallery_media_overlay', $t_rep->getMediaInfo('media', 'INPUT', 'MIMETYPE'));
     $this->view->setVar('rep_display_version', $va_rep_display_info['display_version']);
     unset($va_display_info['display_version']);
     $va_rep_display_info['poster_frame_url'] = $t_rep->getMediaUrl('media', $va_rep_display_info['poster_frame_version']);
     unset($va_display_info['poster_frame_version']);
     $this->view->setVar('rep_display_options', $va_rep_display_info);
     $va_set_item_info["info"] = $va_rep['info'];
     $va_set_item_info["label"] = $t_set_item->getLabelForDisplay();
     $va_set_item_info["description"] = $t_set_item->get($this->opo_plugin_config->get('set_description_element_code'), array('convertLineBreaks' => true));
     $va_set_item_info["item_description"] = $t_set_item->get($this->opo_plugin_config->get('set_item_description_element_code'), array('convertLineBreaks' => true));
     $va_set_item_info["row_id"] = $t_set_item->get("row_id");
     $va_set_item_info["lesson"] = $t_set_item->get('set_item_description');
     $t_object = new ca_objects($t_set_item->get("row_id"));
     $va_set_item_info["object_label"] = $t_object->getLabelForDisplay();
     $this->view->setVar('item_info', $va_set_item_info);
     $this->render($this->ops_theme . '/ajax_item_info_html.php');
 }
 /**
  * Remove a single representation from the currently loaded object. Note that the representation will be removed from the database completely, so if it is also linked to other items it will be removed from them as well.
  *
  * @param int $pn_representation_id The representation_id of the representation to remove
  * @param array $pa_options Options are passed through to BaseMode::delete()
  * @return bool True if delete succeeded, false if there was an error. You can get the error messages by calling getErrors() on the instance.
  */
 public function removeRepresentation($pn_representation_id, $pa_options = null)
 {
     if (!$this->getPrimaryKey()) {
         return null;
     }
     $va_path = array_keys($this->getAppDatamodel()->getPath($this->tableName(), 'ca_object_representations'));
     if (is_array($va_path) && sizeof($va_path) == 3) {
         $vs_rel_table = $va_path[1];
         if ($t_rel = $this->getAppDatamodel()->getInstanceByTableName($vs_rel_table)) {
             if ($t_rel->load(array($this->primaryKey() => $this->getPrimaryKey(), 'representation_id' => $pn_representation_id))) {
                 $t_rel->setMode(ACCESS_WRITE);
                 $t_rel->delete();
                 if ($t_rel->numErrors()) {
                     $this->errors = array_merge($this->errors, $t_rel->errors());
                     return false;
                 }
             }
         }
     }
     $t_rep = new ca_object_representations();
     if (!$t_rep->load($pn_representation_id)) {
         $this->postError(750, _t("Representation id=%1 does not exist", $pn_representation_id), "RepresentableBaseModel->removeRepresentation()");
         return false;
     } else {
         if (!($va_rels = $t_rep->hasRelationships()) || !is_array($va_rels) || !sizeof($va_rels)) {
             //
             // Only delete the related representation if nothing else is related to it
             //
             $t_rep->setMode(ACCESS_WRITE);
             $t_rep->delete(false, $pa_options);
             if ($t_rep->numErrors()) {
                 $this->errors = array_merge($this->errors, $t_rep->errors());
                 return false;
             }
         }
         return true;
     }
     return false;
 }
Esempio n. 29
0
/**
 * Generates standard-format inspector panels for editors
 *
 * @param View $po_view Inspector view object
 * @param array $pa_options Optional array of options. Supported options are:
 *		backText = a string to use as the "back" button text; default is "Results"
 *
 * @return string HTML implementing the inspector
 */
function caEditorInspector($po_view, $pa_options = null)
{
    require_once __CA_MODELS_DIR__ . '/ca_sets.php';
    require_once __CA_MODELS_DIR__ . '/ca_data_exporters.php';
    $t_item = $po_view->getVar('t_item');
    $vs_table_name = $t_item->tableName();
    if (($vs_priv_table_name = $vs_table_name) == 'ca_list_items') {
        $vs_priv_table_name = 'ca_lists';
    }
    $vn_item_id = $t_item->getPrimaryKey();
    $o_result_context = $po_view->getVar('result_context');
    $t_ui = $po_view->getVar('t_ui');
    $t_type = method_exists($t_item, "getTypeInstance") ? $t_item->getTypeInstance() : null;
    $vs_type_name = method_exists($t_item, "getTypeName") ? $t_item->getTypeName() : '';
    if (!$vs_type_name) {
        $vs_type_name = $t_item->getProperty('NAME_SINGULAR');
    }
    $va_reps = $po_view->getVar('representations');
    $o_dm = Datamodel::load();
    if ($t_item->isHierarchical()) {
        $va_ancestors = $po_view->getVar('ancestors');
        $vn_parent_id = $t_item->get($t_item->getProperty('HIERARCHY_PARENT_ID_FLD'));
    } else {
        $va_ancestors = array();
        $vn_parent_id = null;
    }
    // action extra to preserve currently open screen across next/previous links
    $vs_screen_extra = $po_view->getVar('screen') ? '/' . $po_view->getVar('screen') : '';
    if ($vs_type_name == "list item") {
        $vs_style = "style='height:auto;'";
    }
    if ($vn_item_id | $po_view->request->getAction() === 'Delete') {
        $vs_buf = '<h3 class="nextPrevious" ' . $vs_style . '>' . caEditorFindResultNavigation($po_view->request, $t_item, $o_result_context, $pa_options) . "</h3>\n";
    }
    $vs_color = null;
    if ($t_type) {
        $vs_color = trim($t_type->get('color'));
    }
    if (!$vs_color && $t_ui) {
        $vs_color = trim($t_ui->get('color'));
    }
    if (!$vs_color) {
        $vs_color = "FFFFFF";
    }
    $vs_buf .= "<h4><div id='caColorbox' style='border: 6px solid #{$vs_color};'>\n";
    $vs_icon = null;
    if ($t_type) {
        $vs_icon = $t_type->getMediaTag('icon', 'icon');
    }
    if (!$vs_icon && $t_ui) {
        $vs_icon = $t_ui->getMediaTag('icon', 'icon');
    }
    if ($vs_icon) {
        $vs_buf .= "<div id='inspectoricon' style='border-right: 6px solid #{$vs_color}; border-bottom: 6px solid #{$vs_color}; -moz-border-radius-bottomright: 8px; -webkit-border-bottom-right-radius: 8px;'>\n{$vs_icon}</div>\n";
    }
    if ($po_view->request->getAction() === 'Delete' && $po_view->request->getParameter('confirm', pInteger)) {
        $vs_buf .= "<strong>" . _t("Deleted %1", $vs_type_name) . "</strong>\n";
        $vs_buf .= "<br style='clear: both;'/></div></h4>\n";
    } else {
        if ($vn_item_id) {
            if (!$po_view->request->config->get("{$vs_priv_table_name}_inspector_disable_headline")) {
                if ($po_view->request->user->canDoAction("can_edit_" . $vs_priv_table_name) && sizeof($t_item->getTypeList()) > 1) {
                    $vs_buf .= "<strong>" . _t("Editing %1", $vs_type_name) . ": </strong>\n";
                } else {
                    $vs_buf .= "<strong>" . _t("Viewing %1", $vs_type_name) . ": </strong>\n";
                }
            }
            if ($t_item->hasField('is_deaccessioned') && $t_item->get('is_deaccessioned') && $t_item->get('deaccession_date', array('getDirectDate' => true)) <= caDateToHistoricTimestamp(_t('now'))) {
                // If currently deaccessioned then display deaccession message
                $vs_buf .= "<br/><div class='inspectorDeaccessioned'>" . _t('Deaccessioned %1', $t_item->get('deaccession_date')) . "</div>\n";
                if ($vs_deaccession_notes = $t_item->get('deaccession_notes')) {
                    TooltipManager::add(".inspectorDeaccessioned", $vs_deaccession_notes);
                }
            } else {
                if ($po_view->request->user->canDoAction('can_see_current_location_in_inspector_ca_objects')) {
                    if ($t_ui && method_exists($t_item, "getObjectHistory") && (is_array($va_placements = $t_ui->getPlacementsForBundle('ca_objects_history')) && sizeof($va_placements) > 0)) {
                        //
                        // Output current "location" of object in life cycle. Configuration is taken from a ca_objects_history bundle configured for the current editor
                        //
                        $va_placement = array_shift($va_placements);
                        $va_bundle_settings = $va_placement['settings'];
                        if (is_array($va_history = $t_item->getObjectHistory($va_bundle_settings, array('limit' => 1, 'currentOnly' => true))) && sizeof($va_history) > 0) {
                            $va_current_location = array_shift(array_shift($va_history));
                            if (!($vs_inspector_current_location_label = $po_view->request->config->get("ca_objects_inspector_current_location_label"))) {
                                $vs_inspector_current_location_label = _t('Current');
                            }
                            if ($va_current_location['display']) {
                                $vs_buf .= "<div class='inspectorCurrentLocation'><strong>" . $vs_inspector_current_location_label . ':</strong><br/>' . $va_current_location['display'] . "</div>";
                            }
                        }
                    } elseif (method_exists($t_item, "getLastLocationForDisplay")) {
                        // If no ca_objects_history bundle is configured then display the last storage location
                        if ($vs_current_location = $t_item->getLastLocationForDisplay("<ifdef code='ca_storage_locations.parent.preferred_labels'>^ca_storage_locations.parent.preferred_labels ➜ </ifdef>^ca_storage_locations.preferred_labels.name")) {
                            $vs_buf .= "<br/><div class='inspectorCurrentLocation'>" . _t('Location: %1', $vs_current_location) . "</div>\n";
                            $vs_full_location_hierarchy = $t_item->getLastLocationForDisplay("^ca_storage_locations.hierarchy.preferred_labels.name%delimiter=_➜_");
                            if ($vs_full_location_hierarchy !== $vs_current_location) {
                                TooltipManager::add(".inspectorCurrentLocation", $vs_full_location_hierarchy);
                            }
                        }
                    }
                }
            }
            //
            // Display flags; expressions for these are defined in app.conf in the <table_name>_inspector_display_flags directive
            //
            if (is_array($va_display_flags = $po_view->request->config->getAssoc("{$vs_table_name}_inspector_display_flags"))) {
                $va_display_flag_buf = array();
                foreach ($va_display_flags as $vs_exp => $vs_display_flag) {
                    $va_exp_vars = array();
                    foreach (ExpressionParser::getVariableList($vs_exp) as $vs_var_name) {
                        $va_exp_vars[$vs_var_name] = $t_item->get($vs_var_name, array('returnIdno' => true));
                    }
                    if (ExpressionParser::evaluate($vs_exp, $va_exp_vars)) {
                        $va_display_flag_buf[] = $t_item->getWithTemplate("{$vs_display_flag}");
                    }
                }
                if (sizeof($va_display_flag_buf) > 0) {
                    $vs_buf .= join("; ", $va_display_flag_buf);
                }
            }
            $vs_label = '';
            $vb_dont_use_labels_for_ca_objects = (bool) $t_item->getAppConfig()->get('ca_objects_dont_use_labels');
            if (!($vs_table_name === 'ca_objects' && $vb_dont_use_labels_for_ca_objects)) {
                if ($vs_get_spec = $po_view->request->config->get("{$vs_table_name}_inspector_display_title")) {
                    $vs_label = caProcessTemplateForIDs($vs_get_spec, $vs_table_name, array($t_item->getPrimaryKey()));
                } else {
                    $va_object_collection_collection_ancestors = $po_view->getVar('object_collection_collection_ancestors');
                    if ($t_item->tableName() == 'ca_objects' && $t_item->getAppConfig()->get('ca_objects_x_collections_hierarchy_enabled') && is_array($va_object_collection_collection_ancestors) && sizeof($va_object_collection_collection_ancestors)) {
                        $va_collection_links = array();
                        foreach ($va_object_collection_collection_ancestors as $va_collection_ancestor) {
                            $va_collection_links[] = caEditorLink($po_view->request, $va_collection_ancestor['label'], '', 'ca_collections', $va_collection_ancestor['collection_id']);
                        }
                        $vs_label .= join(" / ", $va_collection_links) . ' &gt; ';
                    }
                    if (method_exists($t_item, 'getLabelForDisplay')) {
                        $vn_parent_index = sizeof($va_ancestors) - 1;
                        if ($vn_parent_id && ($vs_table_name != 'ca_places' || $vn_parent_index > 0)) {
                            $va_parent = $va_ancestors[$vn_parent_index];
                            $vs_disp_fld = $t_item->getLabelDisplayField();
                            if ($va_parent['NODE'][$vs_disp_fld] && ($vs_editor_link = caEditorLink($po_view->request, $va_parent['NODE'][$vs_disp_fld], '', $vs_table_name, $va_parent['NODE'][$t_item->primaryKey()]))) {
                                $vs_label .= $vs_editor_link . ' &gt; ' . $t_item->getLabelForDisplay();
                            } else {
                                $vs_label .= ($va_parent['NODE'][$vs_disp_fld] ? $va_parent['NODE'][$vs_disp_fld] . ' &gt; ' : '') . $t_item->getLabelForDisplay();
                            }
                        } else {
                            $vs_label .= $t_item->getLabelForDisplay();
                            if ($vs_table_name === 'ca_editor_uis' && in_array($po_view->request->getAction(), array('EditScreen', 'DeleteScreen', 'SaveScreen'))) {
                                $t_screen = new ca_editor_ui_screens($po_view->request->getParameter('screen_id', pInteger));
                                if (!($vs_screen_name = $t_screen->getLabelForDisplay())) {
                                    $vs_screen_name = _t('new screen');
                                }
                                $vs_label .= " &gt; " . $vs_screen_name;
                            }
                        }
                    } else {
                        $vs_label .= $t_item->get('name');
                    }
                }
            }
            $vb_show_idno = (bool) ($vs_idno = $t_item->get($t_item->getProperty('ID_NUMBERING_ID_FIELD')));
            if (!$vs_label) {
                switch ($vs_table_name) {
                    case 'ca_commerce_orders':
                        if ($t_item->get('order_type') == 'L') {
                            if ($vs_org = $t_item->get('billing_organization')) {
                                $vs_label = _t('%5 #%4 on %1 to %2 (%3)', caGetLocalizedDate($t_item->get('created_on', array('getDirectDate' => true)), array('dateFormat' => 'delimited', 'timeOmit' => true)), $t_item->get('billing_fname') . ' ' . $t_item->get('billing_lname'), $vs_org, $t_item->getOrderNumber(), caUcFirstUTF8Safe($t_item->getProperty('NAME_SINGULAR')));
                            } else {
                                $vs_label = _t('%4 #%3 on %1 to %2', caGetLocalizedDate($t_item->get('created_on', array('getDirectDate' => true)), array('dateFormat' => 'delimited', 'timeOmit' => true)), $t_item->get('billing_fname') . ' ' . $t_item->get('billing_lname'), $t_item->getOrderNumber(), caUcFirstUTF8Safe($t_item->getProperty('NAME_SINGULAR')));
                            }
                        } else {
                            if ($vs_org = $t_item->get('billing_organization')) {
                                $vs_label = _t('%5 #%4 on %1 from %2 (%3)', caGetLocalizedDate($t_item->get('created_on', array('getDirectDate' => true)), array('dateFormat' => 'delimited', 'timeOmit' => true)), $t_item->get('billing_fname') . ' ' . $t_item->get('billing_lname'), $vs_org, $t_item->getOrderNumber(), caUcFirstUTF8Safe($t_item->getProperty('NAME_SINGULAR')));
                            } else {
                                $vs_label = _t('%4 #%3 on %1 from %2', caGetLocalizedDate($t_item->get('created_on', array('getDirectDate' => true)), array('dateFormat' => 'delimited', 'timeOmit' => true)), $t_item->get('billing_fname') . ' ' . $t_item->get('billing_lname'), $t_item->getOrderNumber(), caUcFirstUTF8Safe($t_item->getProperty('NAME_SINGULAR')));
                            }
                        }
                        break;
                    default:
                        if ($vs_table_name === 'ca_objects' && $vb_dont_use_labels_for_ca_objects) {
                            $vs_label = $vs_idno;
                            $vb_show_idno = false;
                        } else {
                            $vs_label = '[' . _t('BLANK') . ']';
                        }
                        break;
                }
            }
            $vs_buf .= "<div class='recordTitle {$vs_table_name}' style='width:190px; overflow:hidden;'>{$vs_label}" . ($vb_show_idno ? "<a title='{$vs_idno}'>" . ($vs_idno ? " ({$vs_idno})" : '') : "") . "</a></div>";
            if ($vs_table_name === 'ca_object_lots' && $t_item->getPrimaryKey()) {
                $vs_buf .= "<div id='inspectorLotMediaDownload'><strong>" . (($vn_num_objects = $t_item->numObjects()) == 1 ? _t('Lot contains %1 object', $vn_num_objects) : _t('Lot contains %1 objects', $vn_num_objects)) . "</strong>\n";
            }
            if ($po_view->request->config->get("include_custom_inspector")) {
                if (file_exists($po_view->request->getViewsDirectoryPath() . "/bundles/inspector_info.php")) {
                    $vo_inspector_view = new View($po_view->request, $po_view->request->getViewsDirectoryPath() . "/bundles/");
                    $vo_inspector_view->setVar('t_item', $t_item);
                    $vs_buf .= $vo_inspector_view->render('inspector_info.php');
                }
            }
        } else {
            $vs_parent_name = '';
            if ($vn_parent_id = $po_view->request->getParameter('parent_id', pInteger)) {
                $t_parent = clone $t_item;
                $t_parent->load($vn_parent_id);
                $vs_parent_name = $t_parent->getLabelForDisplay();
            }
            $vs_buf .= "<div class='creatingNew'>" . _t("Creating new %1", $vs_type_name) . " " . ($vs_parent_name ? _t("%1 &gt; New %2", $vs_parent_name, $vs_type_name) : '') . "</div>\n";
            $vs_buf .= "<br/>\n";
        }
        // -------------------------------------------------------------------------------------
        if ($t_item->getPrimaryKey()) {
            if (sizeof($va_reps) > 0) {
                $va_imgs = array();
                $vs_buf .= "<div id='inspectorMedia'>";
                $vn_r = $vn_primary_index = 0;
                foreach ($va_reps as $va_rep) {
                    if (!($va_rep['info']['preview170']['WIDTH'] && $va_rep['info']['preview170']['HEIGHT'])) {
                        continue;
                    }
                    if ($vb_is_primary = isset($va_rep['is_primary']) && (bool) $va_rep['is_primary']) {
                        $vn_primary_index = $vn_r;
                    }
                    $va_imgs[] = "{url:'" . $va_rep['urls']['preview170'] . "', width: " . $va_rep['info']['preview170']['WIDTH'] . ", height: " . $va_rep['info']['preview170']['HEIGHT'] . ", link: '#', onclick:  'caMediaPanel.showPanel(\\'" . caNavUrl($po_view->request, '*', '*', 'GetMediaOverlay', array($t_item->primaryKey() => $vn_item_id, 'representation_id' => $va_rep['representation_id'])) . "\\')'}";
                    $vn_r++;
                }
                if (sizeof($va_reps) > 1) {
                    $vs_buf .= "\n\t\t\t\t\t<div class='leftScroll'>\n\t\t\t\t\t\t<a href='#' onclick='inspectorInfoRepScroller.scrollToPreviousImage(); return false;'>" . caNavIcon($po_view->request, __CA_NAV_BUTTON_SCROLL_LT__) . "</a>\n\t\t\t\t\t</div>\n\t\t";
                }
                if (sizeof($va_imgs) > 0) {
                    $vs_buf .= "\n\t\t\t\t<div id='inspectorInfoRepScrollingViewer' style='position: relative;'>\n\t\t\t\t\t<div id='inspectorInfoRepScrollingViewerContainer'>\n\t\t\t\t\t\t<div id='inspectorInfoRepScrollingViewerImageContainer'></div>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t";
                    if (sizeof($va_reps) > 1) {
                        $vs_buf .= "\n\t\t\t\t\t<div class='rightScroll'>\n\t\t\t\t\t\t<a href='#' onclick='inspectorInfoRepScroller.scrollToNextImage(); return false;'>" . caNavIcon($po_view->request, __CA_NAV_BUTTON_SCROLL_RT__) . "</a>\n\t\t\t\t\t</div>\n\t\t";
                    }
                    TooltipManager::add(".leftScroll", _t('Previous'));
                    TooltipManager::add(".rightScroll", _t('Next'));
                    $vs_buf .= "<script type='text/javascript'>";
                    $vs_buf .= "\n\t\t\t\t\tvar inspectorInfoRepScroller = caUI.initImageScroller([" . join(",", $va_imgs) . "], 'inspectorInfoRepScrollingViewerImageContainer', {\n\t\t\t\t\t\t\tcontainerWidth: 170, containerHeight: 170,\n\t\t\t\t\t\t\timageCounterID: 'inspectorInfoRepScrollingViewerCounter',\n\t\t\t\t\t\t\tscrollingImageClass: 'inspectorInfoRepScrollerImage',\n\t\t\t\t\t\t\tscrollingImagePrefixID: 'inspectorInfoRep',\n\t\t\t\t\t\t\tinitialIndex: {$vn_primary_index}\n\t\t\t\t\t\t\t\n\t\t\t\t\t});\n\t\t\t\t</script>";
                }
                $vs_buf .= "</div>\n";
                if ($vs_get_spec = $po_view->request->config->get("{$vs_table_name}_inspector_display_below_media")) {
                    $vs_buf .= caProcessTemplateForIDs($vs_get_spec, $vs_table_name, array($t_item->getPrimaryKey()));
                }
            }
            $vs_buf .= "<div id='toolIcons'>";
            if ($vn_item_id) {
                # --- watch this link
                $vs_watch = "";
                if (in_array($vs_table_name, array('ca_objects', 'ca_object_lots', 'ca_entities', 'ca_places', 'ca_occurrences', 'ca_collections', 'ca_storage_locations'))) {
                    require_once __CA_MODELS_DIR__ . '/ca_watch_list.php';
                    $t_watch_list = new ca_watch_list();
                    $vs_watch = "<div class='watchThis'><a href='#' title='" . _t('Add/remove item to/from watch list.') . "' onclick='caToggleItemWatch(); return false;' id='caWatchItemButton'>" . caNavIcon($po_view->request, $t_watch_list->isItemWatched($vn_item_id, $t_item->tableNum(), $po_view->request->user->get("user_id")) ? __CA_NAV_BUTTON_UNWATCH__ : __CA_NAV_BUTTON_WATCH__) . "</a></div>";
                    $vs_buf .= "\n<script type='text/javascript'>\n\t\tfunction caToggleItemWatch() {\n\t\t\tvar url = '" . caNavUrl($po_view->request, $po_view->request->getModulePath(), $po_view->request->getController(), 'toggleWatch', array($t_item->primaryKey() => $vn_item_id)) . "';\n\t\t\t\n\t\t\tjQuery.getJSON(url, {}, function(data, status) {\n\t\t\t\tif (data['status'] == 'ok') {\n\t\t\t\t\tjQuery('#caWatchItemButton').html((data['state'] == 'watched') ? '" . addslashes(caNavIcon($po_view->request, __CA_NAV_BUTTON_UNWATCH__)) . "' : '" . addslashes(caNavIcon($po_view->request, __CA_NAV_BUTTON_WATCH__)) . "');\n\t\t\t\t} else {\n\t\t\t\t\tconsole.log('Error toggling watch status for item: ' + data['errors']);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\t</script>\n";
                }
                $vs_buf .= "{$vs_watch}\n";
                TooltipManager::add("#caWatchItemButton", _t('Watch/Unwatch this record'));
                if ($po_view->request->user->canDoAction("can_change_type_{$vs_table_name}")) {
                    $vs_buf .= "<div id='inspectorChangeType'><div id='inspectorChangeTypeButton'><a href='#' onclick='caTypeChangePanel.showPanel(); return false;'>" . caNavIcon($po_view->request, __CA_NAV_BUTTON_CHANGE__ . " Change Type", array('title' => _t('Change type'))) . "</a></div></div>\n";
                    $vo_change_type_view = new View($po_view->request, $po_view->request->getViewsDirectoryPath() . "/bundles/");
                    $vo_change_type_view->setVar('t_item', $t_item);
                    FooterManager::add($vo_change_type_view->render("change_type_html.php"));
                    TooltipManager::add("#inspectorChangeType", _t('Change Record Type'));
                }
                if ($t_item->getPrimaryKey() && $po_view->request->config->get($vs_table_name . '_show_add_child_control_in_inspector')) {
                    $vb_show_add_child_control = true;
                    if (is_array($va_restrict_add_child_control_to_types = $po_view->request->config->getList($vs_table_name . '_restrict_child_control_in_inspector_to_types')) && sizeof($va_restrict_add_child_control_to_types)) {
                        $t_type_instance = $t_item->getTypeInstance();
                        if (!in_array($t_type_instance->get('idno'), $va_restrict_add_child_control_to_types) && !in_array($t_type_instance->getPrimaryKey(), $va_restrict_add_child_control_to_types)) {
                            $vb_show_add_child_control = false;
                        }
                    }
                    if ($vb_show_add_child_control) {
                        if ((bool) $po_view->request->config->get($vs_table_name . '_enforce_strict_type_hierarchy')) {
                            // strict menu
                            $vs_type_list = $t_item->getTypeListAsHTMLFormElement('type_id', array('style' => 'width: 90px; font-size: 9px;'), array('childrenOfCurrentTypeOnly' => true, 'directChildrenOnly' => $po_view->request->config->get($vs_table_name . '_enforce_strict_type_hierarchy') == '~' ? false : true, 'returnHierarchyLevels' => true, 'access' => __CA_BUNDLE_ACCESS_EDIT__));
                        } else {
                            // all types
                            $vs_type_list = $t_item->getTypeListAsHTMLFormElement('type_id', array('style' => 'width: 90px; font-size: 9px;'), array('access' => __CA_BUNDLE_ACCESS_EDIT__));
                        }
                        if ($vs_type_list) {
                            $vs_buf .= "<div id='inspectorCreateChild'><div id='inspectorCreateChildButton'><a href='#' onclick='caCreateChildPanel.showPanel(); return false;'>" . caNavIcon($po_view->request, __CA_NAV_BUTTON_CHILD__, array('title' => _t('Create Child Record'))) . "</a></div></div>\n";
                            $vo_create_child_view = new View($po_view->request, $po_view->request->getViewsDirectoryPath() . "/bundles/");
                            $vo_create_child_view->setVar('t_item', $t_item);
                            $vo_create_child_view->setVar('type_list', $vs_type_list);
                            FooterManager::add($vo_create_child_view->render("create_child_html.php"));
                            TooltipManager::add("#inspectorCreateChildButton", _t('Create a child record under this one'));
                        }
                    }
                }
            }
            if ($po_view->request->user->canDoAction('can_duplicate_' . $vs_table_name) && $t_item->getPrimaryKey()) {
                $vs_buf .= '<div id="caDuplicateItemButton">';
                $vs_buf .= caFormTag($po_view->request, 'Edit', 'DuplicateItemForm', $po_view->request->getModulePath() . '/' . $po_view->request->getController(), 'post', 'multipart/form-data', '_top', array('disableUnsavedChangesWarning' => true, 'noTimestamp' => true));
                $vs_buf .= caFormSubmitLink($po_view->request, caNavIcon($po_view->request, __CA_NAV_BUTTON_DUPLICATE__), '', 'DuplicateItemForm');
                $vs_buf .= caHTMLHiddenInput($t_item->primaryKey(), array('value' => $t_item->getPrimaryKey()));
                $vs_buf .= caHTMLHiddenInput('mode', array('value' => 'dupe'));
                $vs_buf .= "</form>";
                $vs_buf .= "</div>";
                TooltipManager::add("#caDuplicateItemButton", _t('Duplicate this %1', mb_strtolower($vs_type_name, 'UTF-8')));
            }
            //
            // Download media in lot ($vn_num_objects is only set for object lots)
            if ($vn_num_objects > 0) {
                $vs_buf .= "<div id='inspectorLotMediaDownloadButton'>" . caNavLink($po_view->request, caNavIcon($po_view->request, __CA_NAV_BUTTON_DOWNLOAD__), "button", $po_view->request->getModulePath(), $po_view->request->getController(), 'getLotMedia', array('lot_id' => $t_item->getPrimaryKey(), 'download' => 1), array()) . "</div>\n";
                TooltipManager::add('#inspectorLotMediaDownloadButton', _t("Download all media associated with objects in this lot"));
            }
            //
            // Download media in set
            if ($vs_table_name == 'ca_sets' && sizeof($t_item->getItemRowIDs()) > 0) {
                $vs_buf .= "<div id='inspectorSetMediaDownloadButton'>" . caNavLink($po_view->request, caNavIcon($po_view->request, __CA_NAV_BUTTON_DOWNLOAD__), "button", $po_view->request->getModulePath(), $po_view->request->getController(), 'getSetMedia', array('set_id' => $t_item->getPrimaryKey(), 'download' => 1), array()) . "</div>\n";
                TooltipManager::add('#inspectorSetMediaDownloadButton', _t("Download all media associated with records in this set"));
            }
            $vs_more_info = '';
            // list of sets in which item is a member
            $t_set = new ca_sets();
            if (is_array($va_sets = caExtractValuesByUserLocale($t_set->getSetsForItem($t_item->tableNum(), $t_item->getPrimaryKey(), array('user_id' => $po_view->request->getUserID(), 'access' => __CA_SET_READ_ACCESS__)))) && sizeof($va_sets)) {
                $va_links = array();
                foreach ($va_sets as $vn_set_id => $va_set) {
                    $va_links[] = "<a href='" . caEditorUrl($po_view->request, 'ca_sets', $vn_set_id) . "'>" . $va_set['name'] . "</a>";
                }
                $vs_more_info .= "<div><strong>" . (sizeof($va_links) == 1 ? _t("In set") : _t("In sets")) . "</strong> " . join(", ", $va_links) . "</div>\n";
            }
            // export options
            if ($vn_item_id && ($vs_select = $po_view->getVar('available_mappings_as_html_select'))) {
                $vs_more_info .= "<div class='inspectorExportControls'>" . caFormTag($po_view->request, 'exportItem', 'caExportForm', null, 'post', 'multipart/form-data', '_top', array('disableUnsavedChangesWarning' => true));
                $vs_more_info .= $vs_select;
                $vs_more_info .= caHTMLHiddenInput($t_item->primaryKey(), array('value' => $t_item->getPrimaryKey()));
                $vs_more_info .= caHTMLHiddenInput('download', array('value' => 1));
                $vs_more_info .= caFormSubmitLink($po_view->request, 'Export &rsaquo;', 'button', 'caExportForm');
                $vs_more_info .= "</form></div>";
            }
            $va_creation = $t_item->getCreationTimestamp();
            $va_last_change = $t_item->getLastChangeTimestamp();
            if ($va_creation['timestamp'] || $va_last_change['timestamp']) {
                $vs_more_info .= "<div class='inspectorChangeDateList'>";
                if ($va_creation['timestamp']) {
                    if (!trim($vs_name = $va_creation['fname'] . ' ' . $va_creation['lname'])) {
                        $vs_name = null;
                    }
                    $vs_interval = ($vn_t = time() - $va_creation['timestamp']) == 0 ? _t('Just now') : _t('%1 ago', caFormatInterval($vn_t, 2));
                    $vs_more_info .= "<div class='inspectorChangeDateListLine'  id='caInspectorCreationDate'>" . ($vs_name ? _t('<strong>Created</strong><br/>%1 by %2', $vs_interval, $vs_name) : _t('<strong>Created</strong><br/>%1', $vs_interval)) . "</div>";
                    TooltipManager::add("#caInspectorCreationDate", "<h2>" . _t('Created on') . "</h2>" . _t('Created on %1', caGetLocalizedDate($va_creation['timestamp'], array('dateFormat' => 'delimited'))));
                }
                if ($va_last_change['timestamp'] && $va_creation['timestamp'] != $va_last_change['timestamp']) {
                    if (!trim($vs_name = $va_last_change['fname'] . ' ' . $va_last_change['lname'])) {
                        $vs_name = null;
                    }
                    $vs_interval = ($vn_t = time() - $va_last_change['timestamp']) == 0 ? _t('Just now') : _t('%1 ago', caFormatInterval($vn_t, 2));
                    $vs_more_info .= "<div class='inspectorChangeDateListLine' id='caInspectorChangeDate'>" . ($vs_name ? _t('<strong>Last changed</strong><br/>%1 by %2', $vs_interval, $vs_name) : _t('<strong>Last changed</strong><br/>%1', $vs_interval)) . "</div>";
                    TooltipManager::add("#caInspectorChangeDate", "<h2>" . _t('Last changed on') . "</h2>" . _t('Last changed on %1', caGetLocalizedDate($va_last_change['timestamp'], array('dateFormat' => 'delimited'))));
                }
                if (method_exists($t_item, 'getMetadataDictionaryRuleViolations') && is_array($va_violations = $t_item->getMetadataDictionaryRuleViolations()) && ($vn_num_violations = sizeof($va_violations)) > 0) {
                    $va_violation_messages = array();
                    foreach ($va_violations as $vn_violation_id => $va_violation) {
                        $vs_label = $t_item->getDisplayLabel($va_violation['bundle_name']);
                        $va_violation_messages[] = "<li><em><u>{$vs_label}</u></em> " . $va_violation['violationMessage'] . "</li>";
                    }
                    $vs_more_info .= "<div id='caInspectorViolationsList'>" . ($vs_num_violations_display = "<img src='" . $po_view->request->getThemeUrlPath() . "/graphics/icons/warning_small.gif' border='0'/> " . ($vn_num_violations > 1 ? _t('%1 problems require attention', $vn_num_violations) : _t('%1 problem requires attention', $vn_num_violations))) . "</div>\n";
                    TooltipManager::add("#caInspectorViolationsList", "<h2>{$vs_num_violations_display}</h2><ol>" . join("\n", $va_violation_messages)) . "</ol>\n";
                }
                $vs_more_info .= "</div>\n";
            }
            if ($vs_get_spec = $po_view->request->config->get("{$vs_table_name}_inspector_display_more_info")) {
                $vs_more_info .= caProcessTemplateForIDs($vs_get_spec, $vs_table_name, array($t_item->getPrimaryKey()));
            }
            if ($vs_more_info) {
                $vs_buf .= "<div class='button info'><a href='#' id='inspectorMoreInfo'>" . caNavIcon($po_view->request, __CA_NAV_BUTTON_INFO2__) . "</a></div>\n\t\t\t<div id='inspectorInfo' >";
                $vs_buf .= $vs_more_info . "</div>\n";
                TooltipManager::add("#inspectorMoreInfo", _t('See more information about this record'));
            }
            $vs_buf .= "</div><!--End tooIcons-->";
        }
        // -------------------------------------------------------------------------------------
        //
        // Item-specific information
        //
        //
        // Output info for related items
        //
        if (!$t_item->getPrimaryKey()) {
            // only applies to new records
            $vs_rel_table = $po_view->request->getParameter('rel_table', pString);
            $vn_rel_type_id = $po_view->request->getParameter('rel_type_id', pString);
            $vn_rel_id = $po_view->request->getParameter('rel_id', pInteger);
            if ($vs_rel_table && $po_view->request->datamodel->tableExists($vs_rel_table) && $vn_rel_type_id && $vn_rel_id) {
                $t_rel = $po_view->request->datamodel->getTableInstance($vs_rel_table);
                if ($t_rel && $t_rel->load($vn_rel_id)) {
                    $vs_buf .= '<strong>' . _t("Will be related to %1", $t_rel->getTypeName()) . '</strong>: ' . $t_rel->getLabelForDisplay();
                }
            }
        }
        //
        // Output lot info for ca_objects
        //
        $vb_is_currently_part_of_lot = true;
        if (!($vn_lot_id = $t_item->get('lot_id'))) {
            $vn_lot_id = $po_view->request->getParameter('lot_id', pInteger);
            $vb_is_currently_part_of_lot = false;
        }
        if ($vs_table_name === 'ca_objects' && $vn_lot_id) {
            require_once __CA_MODELS_DIR__ . '/ca_object_lots.php';
            $va_lot_lots = caGetTypeListForUser('ca_object_lots', array('access' => __CA_BUNDLE_ACCESS_READONLY__));
            $t_lot = new ca_object_lots($vn_lot_id);
            if ($t_lot->get('deleted') == 0 && in_array($t_lot->get('type_id'), $va_lot_lots)) {
                if (!($vs_lot_displayname = $t_lot->get('idno_stub'))) {
                    if (!($vs_lot_displayname = $t_lot->getLabelForDisplay())) {
                        $vs_lot_displayname = "Lot {$vn_lot_id}";
                    }
                }
                if ($vs_lot_displayname) {
                    if (!($vs_part_of_lot_msg = $po_view->request->config->get("ca_objects_inspector_part_of_lot_msg"))) {
                        $vs_part_of_lot_msg = _t('Part of lot');
                    }
                    if (!($vs_will_be_part_of_lot_msg = $po_view->request->config->get("ca_objects_inspector_will_be_part_of_lot_msg"))) {
                        $vs_will_be_part_of_lot_msg = _t('Will be part of lot');
                    }
                    $vs_buf .= "<strong>" . ($vb_is_currently_part_of_lot ? $vs_part_of_lot_msg : $vs_will_be_part_of_lot_msg) . "</strong>: " . caNavLink($po_view->request, $vs_lot_displayname, '', 'editor/object_lots', 'ObjectLotEditor', 'Edit', array('lot_id' => $vn_lot_id));
                }
            }
        }
        $va_object_container_types = $po_view->request->config->getList('ca_objects_container_types');
        $va_object_component_types = $po_view->request->config->getList('ca_objects_component_types');
        $vb_can_add_component = $vs_table_name === 'ca_objects' && $t_item->getPrimaryKey() && $po_view->request->user->canDoAction('can_create_ca_objects') && $t_item->canTakeComponents();
        if (method_exists($t_item, 'getComponentCount')) {
            if ($vn_component_count = $t_item->getComponentCount()) {
                if ($t_ui && ($vs_component_list_screen = $t_ui->getScreenWithBundle("ca_objects_components_list", $po_view->request)) && $vs_component_list_screen !== $po_view->request->getActionExtra()) {
                    $vs_component_count_link = caNavLink($po_view->request, $vn_component_count == 1 ? _t('%1 component', $vn_component_count) : _t('%1 components', $vn_component_count), '', '*', '*', $po_view->request->getAction() . '/' . $vs_component_list_screen, array($t_item->primaryKey() => $t_item->getPrimaryKey()));
                } else {
                    $vs_component_count_link = $vn_component_count == 1 ? _t('%1 component', $vn_component_count) : _t('%1 components', $vn_component_count);
                }
                $vs_buf .= "<br/><strong>" . _t('Has') . ":</strong> {$vs_component_count_link}";
            }
        }
        if ($vb_can_add_component) {
            $vs_buf .= ' <a href="#" onclick=\'caObjectComponentPanel.showPanel("' . caNavUrl($po_view->request, '*', 'ObjectComponent', 'Form', array('parent_id' => $t_item->getPrimaryKey())) . '"); return false;\')>' . caNavIcon($po_view->request, __CA_NAV_BUTTON_ADD__) . '</a>';
            $vo_change_type_view = new View($po_view->request, $po_view->request->getViewsDirectoryPath() . "/bundles/");
            $vo_change_type_view->setVar('t_item', $t_item);
            FooterManager::add($vo_change_type_view->render("create_component_html.php"));
        }
        //
        // Output lot info for ca_object_lots
        //
        if ($vs_table_name === 'ca_object_lots' && $t_item->getPrimaryKey()) {
            $va_component_types = $po_view->request->config->getList('ca_objects_component_types');
            if (is_array($va_component_types) && sizeof($va_component_types)) {
                $vs_buf .= "<strong>" . (($vn_num_objects = $t_item->numObjects(null, array('return' => 'objects'))) == 1 ? _t('Lot contains %1 object', $vn_num_objects) : _t('Lot contains %1 objects', $vn_num_objects)) . "</strong>\n";
                $vs_buf .= "<strong>" . (($vn_num_components = $t_item->numObjects(null, array('return' => 'components'))) == 1 ? _t('Lot contains %1 component', $vn_num_components) : _t('Lot contains %1 components', $vn_num_components)) . "</strong>\n";
            } else {
                $vs_buf .= "<strong>" . (($vn_num_objects = $t_item->numObjects()) == 1 ? _t('Lot contains %1 object', $vn_num_objects) : _t('Lot contains %1 objects', $vn_num_objects)) . "</strong>\n";
            }
            if ((bool) $po_view->request->config->get('allow_automated_renumbering_of_objects_in_a_lot') && ($va_nonconforming_objects = $t_item->getObjectsWithNonConformingIdnos())) {
                $vs_buf .= '<br/><br/><em>' . (($vn_c = sizeof($va_nonconforming_objects)) == 1 ? _t('There is %1 object with non-conforming numbering', $vn_c) : _t('There are %1 objects with non-conforming numbering', $vn_c)) . "</em>\n";
                $vs_buf .= "<a href='#' onclick='jQuery(\"#inspectorNonConformingNumberList\").toggle(250); return false;'>" . caNavIcon($po_view->request, __CA_NAV_BUTTON_ADD__);
                $vs_buf .= "<div id='inspectorNonConformingNumberList' class='inspectorNonConformingNumberList'><div class='inspectorNonConformingNumberListScroll'><ol>\n";
                foreach ($va_nonconforming_objects as $vn_object_id => $va_object_info) {
                    $vs_buf .= '<li>' . caEditorLink($po_view->request, $va_object_info['idno'], '', 'ca_objects', $vn_object_id) . "</li>\n";
                }
                $vs_buf .= "</ol></div>";
                $vs_buf .= caNavLink($po_view->request, _t('Re-number objects') . ' &rsaquo;', 'button', $po_view->request->getModulePath(), $po_view->request->getController(), 'renumberObjects', array('lot_id' => $t_item->getPrimaryKey()));
                $vs_buf .= "</div>\n";
            }
            require_once __CA_MODELS_DIR__ . '/ca_objects.php';
            $t_object = new ca_objects();
            $vs_buf .= "<div class='inspectorLotObjectTypeControls'><form action='#' id='caAddObjectToLotForm'>";
            if ((bool) $po_view->request->config->get('ca_objects_enforce_strict_type_hierarchy')) {
                // strict menu
                $vs_buf .= _t('Add new %1 to lot', $t_object->getTypeListAsHTMLFormElement('type_id', array('id' => 'caAddObjectToLotForm_type_id'), array('childrenOfCurrentTypeOnly' => true, 'directChildrenOnly' => $po_view->request->config->get('ca_objects_enforce_strict_type_hierarchy') == '~' ? false : true, 'returnHierarchyLevels' => true, 'access' => __CA_BUNDLE_ACCESS_EDIT__)));
            } else {
                // all types
                $vs_buf .= _t('Add new %1 to lot', $t_object->getTypeListAsHTMLFormElement('type_id', array('id' => 'caAddObjectToLotForm_type_id'), array('access' => __CA_BUNDLE_ACCESS_EDIT__)));
            }
            $vs_buf .= " <a href='#' onclick='caAddObjectToLotForm()'>" . caNavIcon($po_view->request, __CA_NAV_BUTTON_ADD__) . '</a>';
            $vs_buf .= "</form></div>\n";
            $vs_buf .= "<script type='text/javascript'>\n\tfunction caAddObjectToLotForm() { \n\t\twindow.location='" . caEditorUrl($po_view->request, 'ca_objects', 0, false, array('lot_id' => $t_item->getPrimaryKey(), 'rel' => 1, 'type_id' => '')) . "' + jQuery('#caAddObjectToLotForm_type_id').val();\n\t}\n\tjQuery(document).ready(function() {\n\t\tjQuery('#objectLotsNonConformingNumberList').hide();\n\t});\n</script>\n";
        }
        if ($vs_table_name === 'ca_objects') {
            //
            // Output loan info for ca_objects
            //
            if ($po_view->request->user->canDoAction('can_manage_clients') && ($va_loan_details = $t_item->isOnLoan())) {
                $vs_buf .= "<div>" . caNavLink($po_view->request, _t('On loan to %1', $va_loan_details['billing_fname'] . ' ' . $va_loan_details['billing_lname']), 'inspectorOnLoan', 'client/library', 'OrderEditor', 'Edit', array('order_id' => $va_loan_details['order_id'])) . "</div>";
            }
            //
            // Output checkout info for ca_objects
            //
            if ((bool) $po_view->request->config->get('enable_client_services') && ((bool) $po_view->request->config->get('enable_client_services_sales') || (bool) $po_view->request->config->get('enable_client_services_library')) && $t_item->canBeCheckedOut() && ($va_checkout_status = $t_item->getCheckoutStatus(array('returnAsArray' => true)))) {
                $vs_buf .= "<div class='inspectorCheckedOut'>" . $va_checkout_status['status_display'];
                if ($va_checkout_status['user_name']) {
                    $vs_buf .= _t("; checked out by %1", $va_checkout_status['user_name']);
                }
                $vs_buf .= "</div>";
            }
        }
        //
        // Output related objects for ca_object_representations
        //
        if ($vs_table_name === 'ca_object_representations') {
            foreach (array('ca_objects', 'ca_object_lots', 'ca_entities', 'ca_places', 'ca_occurrences', 'ca_collections', 'ca_storage_locations', 'ca_loans', 'ca_movements') as $vs_rel_table) {
                if (sizeof($va_objects = $t_item->getRelatedItems($vs_rel_table))) {
                    $vs_buf .= "<div><strong>" . _t("Related %1", $o_dm->getTableProperty($vs_rel_table, 'NAME_PLURAL')) . "</strong>: <br/>\n";
                    $vs_screen = '';
                    if ($t_ui = ca_editor_uis::loadDefaultUI($vs_rel_table, $po_view->request, null)) {
                        $vs_screen = $t_ui->getScreenWithBundle('ca_object_representations', $po_view->request);
                    }
                    foreach ($va_objects as $vn_rel_id => $va_rel_info) {
                        if ($vs_label = array_shift($va_rel_info['labels'])) {
                            $vs_buf .= caEditorLink($po_view->request, '&larr; ' . $vs_label . ' (' . $va_rel_info['idno'] . ')', '', $vs_rel_table, $va_rel_info[$o_dm->getTablePrimaryKeyName($vs_rel_table)], array(), array(), array('action' => 'Edit' . ($vs_screen ? "/{$vs_screen}" : ""))) . "<br/>\n";
                        }
                    }
                    $vs_buf .= "</div>\n";
                }
            }
        }
        //
        // Output related object reprsentation for ca_representation_annotation
        //
        if ($vs_table_name === 'ca_representation_annotations') {
            if ($vn_representation_id = $t_item->get('representation_id')) {
                $vs_buf .= "<div><strong>" . _t("Applied to representation") . "</strong>: <br/>\n";
                $t_rep = new ca_object_representations($vn_representation_id);
                $vs_buf .= caNavLink($po_view->request, '&larr; ' . $t_rep->getLabelForDisplay(), '', 'editor/object_representations', 'ObjectRepresentationEditor', 'Edit/' . $po_view->getVar('representation_editor_screen'), array('representation_id' => $vn_representation_id)) . '<br/>';
                $vs_buf .= "</div>\n";
            }
        }
        //
        // Output extra useful info for sets
        //
        if ($vs_table_name === 'ca_sets') {
            $vn_set_item_count = $t_item->getItemCount(array('user_id' => $po_view->request->getUserID()));
            if ($vn_set_item_count > 0 && $po_view->request->user->canDoAction('can_batch_edit_' . $o_dm->getTableName($t_item->get('table_num')))) {
                $vs_buf .= caNavButton($po_view->request, __CA_NAV_BUTTON_BATCH_EDIT__, _t('Batch edit'), 'editorBatchSetEditorLink', 'batch', 'Editor', 'Edit', array('set_id' => $t_item->getPrimaryKey()), array(), array('icon_position' => __CA_NAV_BUTTON_ICON_POS_LEFT__, 'no_background' => true, 'dont_show_content' => true));
            }
            $vs_buf .= "<div><strong>" . _t("Number of items") . "</strong>: {$vn_set_item_count}<br/>\n";
            if ($t_item->getPrimaryKey()) {
                $vn_set_table_num = $t_item->get('table_num');
                $vs_set_table_name = $o_dm->getTableName($vn_set_table_num);
                $vs_buf .= "<strong>" . _t("Type of content") . "</strong>: " . caGetTableDisplayName($vn_set_table_num) . "<br/>\n";
                $vs_buf .= "</div>\n";
            } else {
                if ($vn_set_table_num = $po_view->request->getParameter('table_num', pInteger)) {
                    $vs_buf .= "<div><strong>" . _t("Type of content") . "</strong>: " . caGetTableDisplayName($vn_set_table_num) . "<br/>\n";
                    $vs_buf .= "</div>\n";
                }
            }
            $t_user = new ca_users(($vn_user_id = $t_item->get('user_id')) ? $vn_user_id : $po_view->request->getUserID());
            if ($t_user->getPrimaryKey()) {
                $vs_buf .= "<div><strong>" . _t('Owner') . "</strong>: " . $t_user->get('fname') . ' ' . $t_user->get('lname') . "</div>\n";
            }
            if ($po_view->request->user->canDoAction('can_export_' . $vs_set_table_name) && $t_item->getPrimaryKey() && sizeof(ca_data_exporters::getExporters($vn_set_table_num)) > 0) {
                $vs_buf .= '<div style="border-top: 1px solid #aaaaaa; margin-top: 5px; font-size: 10px; text-align: right;" id="caExportItemButton">';
                $vs_buf .= _t('Export this set of records') . "&nbsp; ";
                $vs_buf .= "<a class='button' onclick='jQuery(\"#exporterFormList\").show();' style='text-align:right;' href='#'>" . caNavIcon($po_view->request, __CA_NAV_BUTTON_ADD__) . "</a>";
                $vs_buf .= caFormTag($po_view->request, 'ExportData', 'caExportForm', 'manage/MetadataExport', 'post', 'multipart/form-data', '_top', array('disableUnsavedChangesWarning' => true));
                $vs_buf .= "<div id='exporterFormList'>";
                $vs_buf .= ca_data_exporters::getExporterListAsHTMLFormElement('exporter_id', $vn_set_table_num, array('id' => 'caExporterList'), array('width' => '135px'));
                $vs_buf .= caHTMLHiddenInput('set_id', array('value' => $t_item->getPrimaryKey()));
                $vs_buf .= caFormSubmitLink($po_view->request, _t('Export') . " &rsaquo;", "button", "caExportForm");
                $vs_buf .= "</div>\n";
                $vs_buf .= "</form>";
                $vs_buf .= "</div>";
                $vs_buf .= "<script type='text/javascript'>";
                $vs_buf .= "jQuery(document).ready(function() {";
                $vs_buf .= "jQuery(\"#exporterFormList\").hide();";
                $vs_buf .= "});";
                $vs_buf .= "</script>";
            }
        }
        //
        // Output extra useful info for set items
        //
        if ($vs_table_name === 'ca_set_items') {
            AssetLoadManager::register("panel");
            $t_set = new ca_sets();
            if ($t_set->load($vn_set_id = $t_item->get('set_id'))) {
                $vs_buf .= "<div><strong>" . _t("Part of set") . "</strong>: " . caEditorLink($po_view->request, $t_set->getLabelForDisplay(), '', 'ca_sets', $vn_set_id) . "<br/>\n";
                $t_content_instance = $t_item->getAppDatamodel()->getInstanceByTableNum($vn_item_table_num = $t_item->get('table_num'));
                if ($t_content_instance->load($vn_row_id = $t_item->get('row_id'))) {
                    $vs_label = $t_content_instance->getLabelForDisplay();
                    if ($vs_id_fld = $t_content_instance->getProperty('ID_NUMBERING_ID_FIELD')) {
                        $vs_label .= " (" . $t_content_instance->get($vs_id_fld) . ")";
                    }
                    $vs_buf .= "<strong>" . _t("Is %1", caGetTableDisplayName($vn_item_table_num, false) . "</strong>: " . caEditorLink($po_view->request, $vs_label, '', $vn_item_table_num, $vn_row_id)) . "<br/>\n";
                }
                $vs_buf .= "</div>\n";
            }
        }
        //
        // Output extra useful info for lists
        //
        if ($vs_table_name === 'ca_lists' && $t_item->getPrimaryKey()) {
            $vs_buf .= "<strong>" . _t("Number of items") . "</strong>: " . $t_item->numItemsInList() . "<br/>\n";
            $t_list_item = new ca_list_items();
            $t_list_item->load(array('list_id' => $t_item->getPrimaryKey(), 'parent_id' => null));
            $vs_type_list = $t_list_item->getTypeListAsHTMLFormElement('type_id', array('style' => 'width: 90px; font-size: 9px;'), array('access' => __CA_BUNDLE_ACCESS_EDIT__));
            if ($vs_type_list) {
                $vs_buf .= '<div style="border-top: 1px solid #aaaaaa; margin-top: 5px; font-size: 10px;">';
                $vs_buf .= caFormTag($po_view->request, 'Edit', 'NewChildForm', 'administrate/setup/list_item_editor/ListItemEditor', 'post', 'multipart/form-data', '_top', array('disableUnsavedChangesWarning' => true));
                $vs_buf .= _t('Add a %1 to this list', $vs_type_list) . caHTMLHiddenInput($t_list_item->primaryKey(), array('value' => '0')) . caHTMLHiddenInput('parent_id', array('value' => $t_list_item->getPrimaryKey()));
                $vs_buf .= caFormSubmitLink($po_view->request, caNavIcon($po_view->request, __CA_NAV_BUTTON_ADD__), '', 'NewChildForm');
                $vs_buf .= "</form></div>\n";
            }
        }
        //
        // Output containing list for list items
        //
        if ($vs_table_name === 'ca_list_items') {
            if ($t_list = $po_view->getVar('t_list')) {
                $vn_list_id = $t_list->getPrimaryKey();
                $vs_buf .= "<strong>" . _t("Part of") . "</strong>: " . caEditorLink($po_view->request, $t_list->getLabelForDisplay(), '', 'ca_lists', $vn_list_id) . "<br/>\n";
                if ($t_item->get('is_default')) {
                    $vs_buf .= "<strong>" . _t("Is default for list") . "</strong><br/>\n";
                }
            }
        }
        //
        // Output containing relationship type name for relationship types
        //
        if ($vs_table_name === 'ca_relationship_types') {
            if (!($t_rel_instance = $t_item->getAppDatamodel()->getInstanceByTableNum($t_item->get('table_num'), true))) {
                if ($vn_parent_id = $po_view->request->getParameter('parent_id', pInteger)) {
                    $t_rel_type = new ca_relationship_types($vn_parent_id);
                    $t_rel_instance = $t_item->getAppDatamodel()->getInstanceByTableNum($t_rel_type->get('table_num'), true);
                }
            }
            if ($t_rel_instance) {
                $vs_buf .= "<div><strong>" . _t("Is a") . "</strong>: " . $t_rel_instance->getProperty('NAME_SINGULAR') . "<br/></div>\n";
            }
        }
        //
        // Output extra useful info for metadata elements
        //
        if ($vs_table_name === 'ca_metadata_elements' && $t_item->getPrimaryKey()) {
            $vs_buf .= "<div><strong>" . _t("Element code") . "</strong>: " . $t_item->get('element_code') . "<br/></div>\n";
            if (sizeof($va_uis = $t_item->getUIs()) > 0) {
                $vs_buf .= "<div><strong>" . _t("Referenced by user interfaces") . "</strong>:<br/>\n";
                foreach ($va_uis as $vn_ui_id => $va_ui_info) {
                    $vs_buf .= caNavLink($po_view->request, $va_ui_info['name'], '', 'administrate/setup/interface_screen_editor', 'InterfaceScreenEditor', 'Edit', array('ui_id' => $vn_ui_id, 'screen_id' => $va_ui_info['screen_id']));
                    $vs_buf .= " (" . $o_dm->getTableProperty($va_ui_info['editor_type'], 'NAME_PLURAL') . ")<br/>\n";
                }
                $vs_buf .= "</div>\n";
            }
        }
        //
        // Output related objects for ca_editor_uis and ca_editor_ui_screens
        //
        if ($vs_table_name === 'ca_editor_uis') {
            $vs_buf .= "<div><strong>" . _t("Number of screens") . "</strong>: " . (int) $t_item->getScreenCount() . "\n";
            if ($t_item->getPrimaryKey()) {
                $vs_buf .= "<div><strong>" . _t("Edits") . "</strong>: " . caGetTableDisplayName($t_item->get('editor_type')) . "<br/>\n";
            } else {
                $vs_buf .= "<div><strong>" . _t("Edits") . "</strong>: " . caGetTableDisplayName($po_view->request->getParameter('editor_type', pInteger)) . "<br/>\n";
            }
            $vs_buf .= "</div>\n";
        }
        //
        // Output related objects for ca_editor_uis and ca_editor_ui_screens
        //
        if ($vs_table_name === 'ca_editor_ui_screens') {
            $t_ui = new ca_editor_uis($vn_ui_id = $t_item->get('ui_id'));
            $vs_buf .= "<div><strong>" . _t("Part of") . "</strong>: " . caNavLink($po_view->request, $t_ui->getLabelForDisplay(), '', 'administrate/setup/interface_editor', 'InterfaceEditor', 'Edit', array('ui_id' => $vn_ui_id)) . "\n";
            $vs_buf .= "</div>\n";
        }
        //
        // Output extra useful info for bundle displays
        //
        if ($vs_table_name === 'ca_bundle_displays') {
            $vs_buf .= "<div><strong>" . _t("Number of placements") . "</strong>: " . $t_item->getPlacementCount(array('user_id' => $po_view->request->getUserID())) . "<br/>\n";
            if ($t_item->getPrimaryKey()) {
                $vn_content_table_num = $t_item->get('table_num');
                $vs_buf .= "<strong>" . _t("Type of content") . "</strong>: " . caGetTableDisplayName($vn_content_table_num) . "\n";
                $vs_buf .= "</div>\n";
            } else {
                if ($vn_content_table_num = $po_view->request->getParameter('table_num', pInteger)) {
                    $vs_buf .= "<div><strong>" . _t("Type of content") . "</strong>: " . caGetTableDisplayName($vn_content_table_num) . "\n";
                    $vs_buf .= "</div>\n";
                }
            }
            $t_user = new ca_users(($vn_user_id = $t_item->get('user_id')) ? $vn_user_id : $po_view->request->getUserID());
            if ($t_user->getPrimaryKey()) {
                $vs_buf .= "<div><strong>" . _t('Owner') . "</strong>: " . $t_user->get('fname') . ' ' . $t_user->get('lname') . "</div>\n";
            }
        }
        //
        // Output extra useful info for search forms
        //
        if ($vs_table_name === 'ca_search_forms') {
            $vs_buf .= "<div><strong>" . _t("Number of placements") . "</strong>: " . $t_item->getPlacementCount(array('user_id' => $po_view->request->getUserID())) . "<br/>\n";
            if ($t_item->getPrimaryKey()) {
                $vn_content_table_num = $t_item->get('table_num');
                $vs_buf .= "<strong>" . _t("Searches for") . "</strong>: " . caGetTableDisplayName($vn_content_table_num) . "\n";
                $vs_buf .= "</div>\n";
            } else {
                if ($vn_content_table_num = $po_view->request->getParameter('table_num', pInteger)) {
                    $vs_buf .= "<strong>" . _t("Searches for") . "</strong>: " . caGetTableDisplayName($vn_content_table_num) . "\n";
                    $vs_buf .= "</div>\n";
                }
            }
            $t_user = new ca_users(($vn_user_id = $t_item->get('user_id')) ? $vn_user_id : $po_view->request->getUserID());
            if ($t_user->getPrimaryKey()) {
                $vs_buf .= "<div><strong>" . _t('Owner') . "</strong>: " . $t_user->get('fname') . ' ' . $t_user->get('lname') . "</div>\n";
            }
        }
        //
        // Output extra useful info for tours
        //
        if ($vs_table_name === 'ca_tours' && $t_item->getPrimaryKey()) {
            $vs_buf .= "<br/><strong>" . _t("Number of stops") . "</strong>: " . $t_item->getStopCount() . "<br/>\n";
        }
        //
        // Output containing tour for tour stops
        //
        if ($vs_table_name === 'ca_tour_stops') {
            $t_tour = new ca_tours($vn_tour_id = $t_item->get('tour_id'));
            $vs_buf .= "<strong>" . _t("Part of") . "</strong>: " . caEditorLink($po_view->request, $t_tour->getLabelForDisplay(), '', 'ca_tours', $vn_tour_id) . "<br/>\n";
        }
        //
        // Output extra useful info for bundle mappings
        //
        if ($vs_table_name === 'ca_bundle_mappings') {
            if ($t_item->getPrimaryKey()) {
                $vn_content_table_num = $t_item->get('table_num');
                $vs_buf .= "<br/><strong>" . _t("Type of content") . "</strong>: " . caGetTableDisplayName($vn_content_table_num) . "<br/>\n";
                $vs_buf .= "<strong>" . _t("Type") . "</strong>: " . $t_item->getChoiceListValue('direction', $t_item->get('direction')) . "<br/>\n";
                $vs_buf .= "<strong>" . _t("Target format") . "</strong>: " . $t_item->get('target') . "<br/>\n";
                $va_stats = $t_item->getMappingStatistics();
                $vs_buf .= "<div><strong>" . _t("Number of groups") . "</strong>: " . $va_stats['groupCount'] . "<br/>\n";
                $vs_buf .= "<strong>" . _t("Number of rules") . "</strong>: " . $va_stats['ruleCount'] . "<br/>\n";
                $vs_buf .= "</div>\n";
            } else {
                if ($vn_content_table_num = $po_view->request->getParameter('table_num', pInteger)) {
                    $vs_buf .= "<div><strong>" . _t("Type of content") . "</strong>: " . caGetTableDisplayName($vn_content_table_num) . "<br/>\n";
                    $vs_buf .= "<strong>" . _t("Type") . "</strong>: " . $t_item->getChoiceListValue('direction', $po_view->request->getParameter('direction', pString)) . "<br/>\n";
                    $vs_buf .= "<strong>" . _t("Target format") . "</strong>: " . $po_view->request->getParameter('target', pString) . "<br/>\n";
                    $vs_buf .= "<div><strong>" . _t("Number of groups") . "</strong>: 0<br/>\n";
                    $vs_buf .= "<strong>" . _t("Number of rules") . "</strong>: 0</div>\n";
                    $vs_buf .= "</div>\n";
                }
            }
        }
        //
        // Output extra useful info for client services/commerce orders
        //
        if ($vs_table_name === 'ca_commerce_orders') {
            $o_client_services_config = Configuration::load($po_view->request->config->get('client_services_config'));
            $va_order_totals = $t_item->getOrderTotals();
            if ($va_order_totals['fee'] + $va_order_totals['tax'] + $va_order_totals['shipping'] + $va_order_totals['handling'] + $va_order_totals['additional_order_fees'] + $va_order_totals['additional_item_fees'] != 0) {
                $vs_currency_symbol = $o_client_services_config->get('currency_symbol');
                $vs_buf .= "<table style='margin-left: 10px;'>";
                $vs_buf .= "<tr><td><strong>" . _t("Items") . '</strong></td><td>' . $vs_currency_symbol . sprintf("%4.2f", $va_order_totals['fee']) . " (" . (int) $va_order_totals['items'] . ")</td></tr>\n";
                $vs_buf .= "<tr><td><strong>" . _t("S+H") . '</strong></td><td>' . $vs_currency_symbol . sprintf("%4.2f", $va_order_totals['shipping'] + $va_order_totals['handling']) . "</td></tr>\n";
                $vs_buf .= "<tr><td><strong>" . _t("Tax") . '</strong></td><td>' . $vs_currency_symbol . sprintf("%4.2f", $va_order_totals['tax']) . "</td></tr>\n";
                $vs_buf .= "<tr><td><strong>" . _t("Addtl fees") . '</strong></td><td>' . $vs_currency_symbol . sprintf("%4.2f", $va_order_totals['additional_order_fees'] + $va_order_totals['additional_item_fees']) . "</td></tr>\n";
                $vs_buf .= "<tr><td><strong>" . _t("Total") . '</strong></td><td>' . $vs_currency_symbol . sprintf("%4.2f", $va_order_totals['fee'] + $va_order_totals['tax'] + $va_order_totals['shipping'] + $va_order_totals['handling'] + $va_order_totals['additional_order_fees'] + $va_order_totals['additional_item_fees']) . "</td></tr>\n";
                $vs_buf .= "</table>";
                $vs_buf .= "<strong>" . $t_item->getFieldInfo('payment_status', 'LABEL') . "</strong>: " . $t_item->getChoiceListValue('payment_status', $t_item->get('payment_status')) . "<br/>\n";
            }
            $vs_buf .= "<br/><strong>" . $t_item->getFieldInfo('order_status', 'LABEL') . "</strong>: " . $t_item->getChoiceListValue('order_status', $t_item->get('order_status')) . "<br/>\n";
            if ($vs_shipping_date = $t_item->get('shipping_date', array('dateFormat' => 'delimited', 'timeOmit' => true))) {
                $vs_buf .= "<strong>" . $t_item->getFieldInfo('shipping_date', 'LABEL') . "</strong>: " . $vs_shipping_date;
                if ($vs_shipped_on_date = $t_item->get('shipped_on_date', array('dateFormat' => 'delimited'))) {
                    $vs_buf .= " (" . _t('shipped %1', $vs_shipped_on_date) . ")";
                } else {
                    $vs_buf .= " (" . _t('not shipped') . ")";
                }
                $vs_buf .= "<br/>\n";
            }
            if (($vn_shipping_method = $t_item->get('shipping_method')) && $t_item->getChoiceListValue('shipping_method', $vn_shipping_method) != 'None') {
                $vs_buf .= "<strong>" . $t_item->getFieldInfo('shipping_method', 'LABEL') . "</strong>: " . $t_item->getChoiceListValue('shipping_method', $vn_shipping_method) . "<br/>\n";
            }
        }
        //
        // Output configurable additional info from config, if set
        //
        if ($vs_additional_info = $po_view->request->config->get("{$vs_table_name}_inspector_additional_info")) {
            if (is_array($vs_additional_info)) {
                $vs_buf .= "<br/>";
                foreach ($vs_additional_info as $vs_info) {
                    $vs_buf .= caProcessTemplateForIDs($vs_info, $vs_table_name, array($t_item->getPrimaryKey()), array('requireLinkTags' => true)) . "<br/>\n";
                }
            } else {
                $vs_buf .= "<br/>" . caProcessTemplateForIDs($vs_additional_info, $vs_table_name, array($t_item->getPrimaryKey()), array('requireLinkTags' => true)) . "<br/>\n";
            }
        }
        // -------------------------------------------------------------------------------------
        // Export
        if ($t_item->getPrimaryKey() && $po_view->request->config->get($vs_table_name . '_show_add_child_control_in_inspector')) {
            $vb_show_add_child_control = true;
            if (is_array($va_restrict_add_child_control_to_types = $po_view->request->config->getList($vs_table_name . '_restrict_child_control_in_inspector_to_types')) && sizeof($va_restrict_add_child_control_to_types)) {
                $t_type_instance = $t_item->getTypeInstance();
                if (!in_array($t_type_instance->get('idno'), $va_restrict_add_child_control_to_types) && !in_array($t_type_instance->getPrimaryKey(), $va_restrict_add_child_control_to_types)) {
                    $vb_show_add_child_control = false;
                }
            }
        }
        if ($po_view->request->user->canDoAction('can_export_' . $vs_table_name) && $t_item->getPrimaryKey() && sizeof(ca_data_exporters::getExporters($t_item->tableNum())) > 0) {
            $vs_buf .= '<div style="border-top: 1px solid #aaaaaa; margin-top: 5px; font-size: 10px; text-align: right;" id="caExportItemButton">';
            $vs_buf .= _t('Export this %1', mb_strtolower($vs_type_name, 'UTF-8')) . " ";
            $vs_buf .= "<a class='button' onclick='jQuery(\"#exporterFormList\").show();' style='text-align:right;' href='#'>" . caNavIcon($po_view->request, __CA_NAV_BUTTON_ADD__) . "</a>";
            $vs_buf .= caFormTag($po_view->request, 'ExportSingleData', 'caExportForm', 'manage/MetadataExport', 'post', 'multipart/form-data', '_top', array('disableUnsavedChangesWarning' => true));
            $vs_buf .= "<div id='exporterFormList'>";
            $vs_buf .= ca_data_exporters::getExporterListAsHTMLFormElement('exporter_id', $t_item->tableNum(), array('id' => 'caExporterList'), array('width' => '120px'));
            $vs_buf .= caHTMLHiddenInput('item_id', array('value' => $t_item->getPrimaryKey()));
            $vs_buf .= caFormSubmitLink($po_view->request, _t('Export') . " &rsaquo;", "button", "caExportForm");
            $vs_buf .= "</div>\n";
            $vs_buf .= "</form>";
            $vs_buf .= "</div>";
            $vs_buf .= "<script type='text/javascript'>";
            $vs_buf .= "jQuery(document).ready(function() {";
            $vs_buf .= "jQuery(\"#exporterFormList\").hide();";
            $vs_buf .= "});";
            $vs_buf .= "</script>";
        }
        $vs_buf .= "</div></h4>\n";
        $vs_buf .= "<script type='text/javascript'>\n\t\t\tvar inspectorCookieJar = jQuery.cookieJar('caCookieJar');";
        if ($t_item->getPrimaryKey()) {
            if ($vs_more_info) {
                $vs_buf .= "\t\t\t\n\t\t\tif (inspectorCookieJar.get('inspectorMoreInfoIsOpen') == undefined) {\t\t// default is to have info open\n\t\t\t\tinspectorCookieJar.set('inspectorMoreInfoIsOpen', 1);\n\t\t\t}\n\t\t\tif (inspectorCookieJar.get('inspectorMoreInfoIsOpen') == 1) {\n\t\t\t\tjQuery('#inspectorInfo').toggle(0);\n\t\t\t\tjQuery('#inspectorMoreInfo').html('" . addslashes(caNavIcon($po_view->request, __CA_NAV_BUTTON_COLLAPSE__)) . "');\n\t\t\t}\n\t\t\n\t\t\tjQuery('#inspectorMoreInfo').click(function() {\n\t\t\t\tjQuery('#inspectorInfo').slideToggle(350, function() { \n\t\t\t\t\tinspectorCookieJar.set('inspectorMoreInfoIsOpen', (this.style.display == 'block') ? 1 : 0); \n\t\t\t\t\tjQuery('#inspectorMoreInfo').html((this.style.display == 'block') ? '" . addslashes(caNavIcon($po_view->request, __CA_NAV_BUTTON_COLLAPSE__)) . "' : '" . addslashes(caNavIcon($po_view->request, __CA_NAV_BUTTON_INFO2__)) . "');\n\t\t\t\t\tcaResizeSideNav();\n\t\t\t\t}); \n\t\t\t\treturn false;\n\t\t\t});\n\t\t";
            }
            if (sizeof($va_reps)) {
                $vs_buf .= "\n\t\tif (inspectorCookieJar.get('inspectorShowMediaIsOpen') == undefined) {\t\t// default is to have media open\n\t\t\tinspectorCookieJar.set('inspectorShowMediaIsOpen', 1);\n\t\t}\n\t\t\n\t\tif (inspectorCookieJar.get('inspectorShowMediaIsOpen') == 1) {\n\t\t\tjQuery('#inspectorMedia').toggle();\n\t\t}\n\t\n\t\tjQuery('#caColorbox').on('click', function(e) {\n\t\t\tif (e.altKey) {\n\t\t\t\tjQuery('#inspectorMedia').slideToggle(200, function() { \n\t\t\t\t\tinspectorCookieJar.set('inspectorShowMediaIsOpen', (this.style.display == 'block') ? 1 : 0); \n\t\t\t\t\t\tcaResizeSideNav();\n\t\t\t\t}); \n\t\t\t\treturn false;\n\t\t\t}\n\t\t});\n\t\t\t\t\t";
            }
        }
        $vs_buf .= "</script>\n";
    }
    $o_app_plugin_manager = new ApplicationPluginManager();
    $va_hookAppend = $o_app_plugin_manager->hookAppendToEditorInspector(array("t_item" => $t_item));
    if (is_string($va_hookAppend["caEditorInspectorAppend"])) {
        $vs_buf .= $va_hookAppend["caEditorInspectorAppend"];
    }
    return $vs_buf;
}
 /**
  * Perform client services-related periodic tasks
  */
 public function hookPeriodicTask(&$pa_params)
 {
     $t_log = new Eventlog();
     $o_db = new Db();
     if (!(bool) $this->opo_config->get('enable_client_services')) {
         return true;
     }
     // Find any orders with status PROCESSED_AWAITING_MEDIA_ACCESS and fetch media
     $qr_orders = $o_db->query("\n\t\t\t\tSELECT order_id\n\t\t\t\tFROM ca_commerce_orders\n\t\t\t\tWHERE\n\t\t\t\t\torder_status = 'PROCESSED_AWAITING_MEDIA_ACCESS'\n\t\t\t");
     //
     // Set up HTTP client for REST calls
     //
     if ($this->opo_client_services_config->get('remote_media_base_url')) {
         $vs_base_url = $this->opo_client_services_config->get('remote_media_base_url');
         $o_client = new RestClient($vs_base_url . "/service.php/iteminfo/ItemInfo/rest");
         try {
             $o_res = $o_client->auth($this->opo_client_services_config->get('remote_media_username'), $this->opo_client_services_config->get('remote_media_password'))->get();
             if (!$o_res->isSuccess()) {
                 $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('Could not authenticate to remote system %1', $vs_base_url), 'SOURCE' => 'clientServicesPlugin->hookPeriodicTask'));
             }
             while ($qr_orders->nextRow()) {
                 $t_order = new ca_commerce_orders($qr_orders->get('order_id'));
                 $vb_download_errors = false;
                 if ($t_order->getPrimaryKey() && sizeof($va_missing_media = $t_order->itemsMissingDownloadableMedia())) {
                     $va_missing_media_representation_ids = $t_order->itemsMissingDownloadableMedia('original', array('returnRepresentationIDs' => true));
                     foreach ($va_missing_media as $vn_object_id => $va_representation_md5s) {
                         foreach ($va_representation_md5s as $vn_i => $vs_representation_md5) {
                             $o_xml = $o_client->getObjectRepresentationURLByMD5($vs_representation_md5, 'original')->get();
                             $vs_url = (string) $o_xml->getObjectRepresentationURLByMD5->original;
                             if (!$vs_url) {
                                 continue;
                             }
                             // media no longer exists
                             // fetch the file
                             $t_rep = new ca_object_representations($va_missing_media_representation_ids[$vn_object_id][$vn_i]);
                             if ($t_rep->getPrimaryKey() && ($vs_target_path = $t_rep->getMediaPath('media', 'original'))) {
                                 if ($r_source = fopen($vs_url, "rb")) {
                                     if ($r_target = fopen($vs_target_path, "wb")) {
                                         while (feof($r_source) === false) {
                                             fwrite($r_target, fread($r_source, 1024 * 8), 1024 * 8);
                                         }
                                         fclose($r_target);
                                     } else {
                                         $vb_download_errors = true;
                                         $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('Could not open target path %1', $vs_target_path), 'SOURCE' => 'clientServicesPlugin->hookPeriodicTask'));
                                     }
                                     fclose($r_source);
                                 } else {
                                     $vb_download_errors = true;
                                     $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('Could not open download URL "%1"', $vs_url), 'SOURCE' => 'clientServicesPlugin->hookPeriodicTask'));
                                 }
                                 // verify the file was downloaded correctly
                                 if (($vs_target_md5 = md5_file($vs_target_path)) !== $vs_representation_md5) {
                                     unlink($vs_target_path);
                                     $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('Media file %1 failed to be downloaded from url "%2"; checksums differ: %3/%4', $vs_target_path, $vs_url, $vs_representation_md5, $vs_target_md5), 'SOURCE' => 'clientServicesPlugin->hookPeriodicTask'));
                                     $vb_download_errors = true;
                                 }
                             } else {
                                 $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('Invalid representation_id "%1" or target path "%2"', $vn_representation_id, $vs_representation_md5, $vs_target_path), 'SOURCE' => 'clientServicesPlugin->hookPeriodicTask'));
                                 $vb_download_errors = true;
                             }
                         }
                     }
                 }
                 if (!$vb_download_errors) {
                     $t_order->setMode(ACCESS_WRITE);
                     $t_order->set('order_status', 'PROCESSED');
                     $t_order->update();
                     if ($t_order->numErrors()) {
                         $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('Change of order status to PROCESSED from PROCESSED_AWAITING_MEDIA_ACCESS failed for order_id %1: %2', $t_order->getPrimaryKey(), join('; ', $t_order->getErrors())), 'SOURCE' => 'clientServicesPlugin->hookPeriodicTask'));
                     }
                 }
             }
         } catch (Exception $e) {
             // noop
         }
     }
     // Find any orders with status PROCESSED_AWAITING_DIGITIZATION where all media are now present
     $qr_orders = $o_db->query("\n\t\t\t\tSELECT order_id\n\t\t\t\tFROM ca_commerce_orders\n\t\t\t\tWHERE\n\t\t\t\t\torder_status = 'PROCESSED_AWAITING_DIGITIZATION'\n\t\t\t");
     while ($qr_orders->nextRow()) {
         $t_order = new ca_commerce_orders($qr_orders->get('order_id'));
         if ($t_order->getPrimaryKey() && !sizeof($t_order->itemsWithNoDownloadableMedia())) {
             $t_order->setMode(ACCESS_WRITE);
             $t_order->set('order_status', 'PROCESSED');
             $t_order->update();
             if ($t_order->numErrors()) {
                 $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('Change of order status to PROCESSED from PROCESSED_AWAITING_DIGITIZATION failed for order_id %1: %2', $t_order->getPrimaryKey(), join('; ', $t_order->getErrors())), 'SOURCE' => 'clientServicesPlugin->hookPeriodicTask'));
             }
         }
     }
     // Find orders paid/shipped more than X days ago and mark them as "COMPLETED"
     $vn_days = (int) $this->opo_client_services_config->get('completed_order_age_threshold');
     if ($vn_days > 1) {
         $vn_threshold = (int) (time() - $vn_days * 24 * 60 * 60);
         $qr_orders = $o_db->query("\n\t\t\t\t\tSELECT order_id\n\t\t\t\t\tFROM ca_commerce_orders\n\t\t\t\t\tWHERE\n\t\t\t\t\t\t(order_status = 'PROCESSED') \n\t\t\t\t\t\tAND \n\t\t\t\t\t\t((payment_received_on > 0) AND (payment_received_on < ?))\n\t\t\t\t\t\tAND \n\t\t\t\t\t\t(\n\t\t\t\t\t\t\t(shipping_date IS NULL AND shipped_on_date IS NULL)\n\t\t\t\t\t\t\tOR\n\t\t\t\t\t\t\t(\n\t\t\t\t\t\t\t\t(shipped_on_date > 0) AND (shipped_on_date < ?)\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t)\n\t\t\t\t", $vn_threshold, $vn_threshold);
         while ($qr_orders->nextRow()) {
             $t_order = new ca_commerce_orders($qr_orders->get('order_id'));
             if ($t_order->getPrimaryKey()) {
                 $t_order->setMode(ACCESS_WRITE);
                 $t_order->set('order_status', 'COMPLETED');
                 $t_order->update();
                 if ($t_order->numErrors()) {
                     $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('Change of order status to COMPLETED from PROCESSED failed for order_id %1: %2', $t_order->getPrimaryKey(), join('; ', $t_order->getErrors())), 'SOURCE' => 'clientServicesPlugin->hookPeriodicTask'));
                 }
             }
         }
     }
     return true;
 }