示例#1
0
 public function testGetElementIDsForTable()
 {
     $o_mapping = new ElasticSearch\Mapping();
     $va_element_ids = $o_mapping->getElementIDsForTable('ca_objects');
     foreach (array_keys(ca_metadata_elements::getElementsAsList(true, 'ca_objects')) as $vn_element_id) {
         $this->assertTrue(in_array($vn_element_id, $va_element_ids), "Expected element id {$vn_element_id} to be part of " . print_r($va_element_ids, true));
     }
 }
 /**
  * Returns all available bundle display placements - those data bundles that can be displayed for the given content type, in other words.
  * The returned value is a list of arrays; each array contains a 'bundle' specifier than can be passed got Model::get() or SearchResult::get() and a display name
  *
  * @param mixed $pm_table_name_or_num The table name or number specifying the content type to fetch bundles for. If omitted the content table of the currently loaded display will be used.
  * @param array $pa_options Support options are
  *		no_cache = if set caching of underlying data required to generate list is disabled. This is required in certain situations such as during installation. Only set this if you suspect stale data is being used to generate the list. Eg. if you've been changing metadata attributes in the same request in which you call this method. Default is false.
  *		no_tooltips = if set no tooltips for available bundles will be emitted. Default is false - tooltips will be emitted.
  *		format = specifies label format for bundles. Valid values are "simple" (just the name of the element) or "full" (name of element, name of type of item element pertains to and alternate label, if defined). Default is "full"
  * @return array And array of bundles keyed on display label. Each value is an array with these keys:
  *		bundle = The bundle name (eg. ca_objects.idno)
  *		display = Display label for each available bundle
  *		description = Description of bundle
  * 
  * Will return null if table name or number is invalid.
  */
 public function getAvailableBundles($pm_table_name_or_num = null, $pa_options = null)
 {
     if (!$pm_table_name_or_num) {
         $pm_table_name_or_num = $this->get('table_num');
     }
     $pm_table_name_or_num = $this->getAppDatamodel()->getTableNum($pm_table_name_or_num);
     if (!$pm_table_name_or_num) {
         return null;
     }
     $vb_show_tooltips = isset($pa_options['no_tooltips']) && (bool) $pa_options['no_tooltips'] ? false : true;
     $vs_format = isset($pa_options['format']) && in_array($pa_options['format'], array('simple', 'full')) ? $pa_options['format'] : 'full';
     $t_instance = $this->getAppDatamodel()->getInstanceByTableNum($pm_table_name_or_num, false);
     $vs_table = $t_instance->tableName();
     $vs_table_display_name = $t_instance->getProperty('NAME_PLURAL');
     $va_available_bundles = array();
     $t_placement = new ca_bundle_display_placements(null, array());
     if ($this->inTransaction()) {
         $t_placement->setTransaction($this->getTransaction());
     }
     // get intrinsic fields
     $va_additional_settings = array('maximum_length' => array('formatType' => FT_NUMBER, 'displayType' => DT_FIELD, 'width' => 6, 'height' => 1, 'takesLocale' => false, 'default' => 100, 'label' => _t('Maximum length'), 'description' => _t('Maximum length, in characters, of displayed information.')));
     foreach ($t_instance->getFormFields() as $vs_f => $va_info) {
         if (isset($va_info['DONT_USE_AS_BUNDLE']) && $va_info['DONT_USE_AS_BUNDLE']) {
             continue;
         }
         if ($t_instance->getFieldInfo($vs_f, 'ALLOW_BUNDLE_ACCESS_CHECK')) {
             if (caGetBundleAccessLevel($vs_table, $vs_f) == __CA_BUNDLE_ACCESS_NONE__) {
                 continue;
             }
         }
         $vs_bundle = $vs_table . '.' . $vs_f;
         $vs_display = "<div id='bundleDisplayEditorBundle_{$vs_table}_{$vs_f}'><span class='bundleDisplayEditorPlacementListItemTitle'>" . caUcFirstUTF8Safe($t_instance->getProperty('NAME_SINGULAR')) . "</span> " . ($vs_label = $t_instance->getDisplayLabel($vs_bundle)) . "</div>";
         $va_available_bundles[strip_tags($vs_display)][$vs_bundle] = array('bundle' => $vs_bundle, 'display' => $vs_format == 'simple' ? $vs_label : $vs_display, 'description' => $vs_description = $t_instance->getDisplayDescription($vs_bundle), 'settingsForm' => $t_placement->getHTMLSettingForm(array('id' => $vs_bundle . '_0')), 'settings' => $va_additional_settings);
         if ($vb_show_tooltips) {
             TooltipManager::add("#bundleDisplayEditorBundle_{$vs_table}_{$vs_f}", $this->_formatBundleTooltip($vs_label, $vs_bundle, $vs_description));
         }
     }
     // get attributes
     $va_element_codes = $t_instance->getApplicableElementCodes(null, false, $pa_options['no_cache']);
     $t_md = new ca_metadata_elements();
     if ($this->inTransaction()) {
         $t_md->setTransaction($this->getTransaction());
     }
     $va_all_elements = $t_md->getElementsAsList();
     $va_additional_settings = array('format' => array('formatType' => FT_TEXT, 'displayType' => DT_FIELD, 'width' => 35, 'height' => 5, 'takesLocale' => false, 'default' => '', 'label' => _t('Display format'), 'description' => _t('Template used to format output.'), 'helpText' => ''), 'delimiter' => array('formatType' => FT_TEXT, 'displayType' => DT_FIELD, 'width' => 35, 'height' => 1, 'takesLocale' => false, 'default' => '', 'label' => _t('Delimiter'), 'description' => _t('Text to place in-between repeating values.')), 'maximum_length' => array('formatType' => FT_NUMBER, 'displayType' => DT_FIELD, 'width' => 6, 'height' => 1, 'takesLocale' => false, 'default' => 2048, 'label' => _t('Maximum length'), 'description' => _t('Maximum length, in characters, of displayed information.')), 'filter' => array('formatType' => FT_TEXT, 'displayType' => DT_FIELD, 'width' => 35, 'height' => 5, 'takesLocale' => false, 'default' => '', 'label' => _t('Filter using expression'), 'description' => _t('Expression to filter values with. Leave blank if you do not wish to filter values.')));
     foreach ($va_element_codes as $vn_element_id => $vs_element_code) {
         if (!is_null($va_all_elements[$vn_element_id]['settings']['canBeUsedInDisplay']) && !$va_all_elements[$vn_element_id]['settings']['canBeUsedInDisplay']) {
             continue;
         }
         $t_placement = new ca_bundle_display_placements(null, $va_additional_settings);
         if ($this->inTransaction()) {
             $t_placement->setTransaction($this->getTransaction());
         }
         if (caGetBundleAccessLevel($vs_table, $vs_element_code) == __CA_BUNDLE_ACCESS_NONE__) {
             continue;
         }
         switch ($va_all_elements[$vn_element_id]['datatype']) {
             case 3:
                 // list
                 $va_even_more_settings = array('sense' => array('formatType' => FT_TEXT, 'displayType' => DT_SELECT, 'width' => 20, 'height' => 1, 'takesLocale' => false, 'default' => 'singular', 'options' => array(_t('Singular') => 'singular', _t('Plural') => 'plural'), 'label' => _t('Sense'), 'description' => _t('Determines if value used is singular or plural version.')));
                 break;
             case 0:
                 // container (allows sub-elements to be summarized)
             // container (allows sub-elements to be summarized)
             case 6:
                 // Currency
             // Currency
             case 8:
                 // Length
             // Length
             case 9:
                 // Weight
             // Weight
             case 10:
                 // Timecode
             // Timecode
             case 11:
                 // Integer
             // Integer
             case 12:
                 // Numeric (decimal)
                 $va_even_more_settings = array('bottom_line' => array('formatType' => FT_TEXT, 'displayType' => DT_FIELD, 'width' => 35, 'height' => 5, 'takesLocale' => false, 'default' => '', 'label' => _t('Bottom line format'), 'description' => _t('Template to format aggregate data for display under this column. The template can include these aggregate data tags: ^PAGEAVG, ^AVG, ^PAGESUM, ^SUM, ^PAGEMin, ^MIN, ^PAGEMAX, ^MAX. For containers follow the tag with the element code of the subelement to aggregate. Ex. ^SUM:dimensions_width')));
                 if ($va_all_elements[$vn_element_id]['datatype'] == 6) {
                     $va_even_more_settings['display_currency_conversion'] = array('formatType' => FT_NUMBER, 'displayType' => DT_CHECKBOXES, 'width' => 10, 'height' => 1, 'takesLocale' => false, 'default' => '0', 'label' => _t('Display currency conversion?'), 'description' => _t('Check this option if you want your currency values to be displayed in both the specified and local currency.'));
                 }
                 break;
             default:
                 $va_even_more_settings = array();
                 break;
         }
         $vs_bundle = $vs_table . '.' . $vs_element_code;
         $va_even_more_settings['format'] = $va_additional_settings['format'];
         //$va_even_more_settings['format']['helpText'] = $this->getTemplatePlaceholderDisplayListForBundle($vs_bundle);
         $t_placement = new ca_bundle_display_placements(null, array_merge($va_additional_settings, $va_even_more_settings));
         if ($this->inTransaction()) {
             $t_placement->setTransaction($this->getTransaction());
         }
         $vs_display = "<div id='bundleDisplayEditorBundle_{$vs_table}_{$vs_element_code}'><span class='bundleDisplayEditorPlacementListItemTitle'>" . caUcFirstUTF8Safe($t_instance->getProperty('NAME_SINGULAR')) . "</span> " . ($vs_label = $t_instance->getDisplayLabel($vs_bundle)) . "</div>";
         $va_available_bundles[strip_tags($vs_display)][$vs_bundle] = array('bundle' => $vs_bundle, 'display' => $vs_format == 'simple' ? $vs_label : $vs_display, 'description' => $vs_description = $t_instance->getDisplayDescription($vs_bundle), 'settingsForm' => $t_placement->getHTMLSettingForm(array('id' => $vs_bundle . '_0')), 'settings' => array_merge($va_additional_settings, $va_even_more_settings));
         if ($vb_show_tooltips) {
             TooltipManager::add("#bundleDisplayEditorBundle_{$vs_table}_{$vs_element_code}", $this->_formatBundleTooltip($vs_label, $vs_bundle, $vs_description));
         }
     }
     if (caGetBundleAccessLevel($vs_table, "preferred_labels") != __CA_BUNDLE_ACCESS_NONE__) {
         // get preferred labels for this table
         $va_additional_settings = array('format' => array('formatType' => FT_TEXT, 'displayType' => DT_FIELD, 'width' => 35, 'height' => 5, 'takesLocale' => false, 'default' => '', 'label' => _t('Display format'), 'description' => _t('Template used to format output.')), 'delimiter' => array('formatType' => FT_TEXT, 'displayType' => DT_FIELD, 'width' => 35, 'height' => 1, 'takesLocale' => false, 'default' => '', 'label' => _t('Delimiter'), 'description' => _t('Text to place in-between repeating values.')), 'maximum_length' => array('formatType' => FT_NUMBER, 'displayType' => DT_FIELD, 'width' => 6, 'height' => 1, 'takesLocale' => false, 'default' => 100, 'label' => _t('Maximum length'), 'description' => _t('Maximum length, in characters, of displayed information.')));
         $t_placement = new ca_bundle_display_placements(null, $va_additional_settings);
         if ($this->inTransaction()) {
             $t_placement->setTransaction($this->getTransaction());
         }
         $vs_bundle = $vs_table . '.preferred_labels';
         $vs_display = "<div id='bundleDisplayEditorBundle_{$vs_table}_preferred_labels'><span class='bundleDisplayEditorPlacementListItemTitle'>" . caUcFirstUTF8Safe($t_instance->getProperty('NAME_SINGULAR')) . "</span> " . ($vs_label = $t_instance->getDisplayLabel($vs_bundle)) . "</div>";
         $va_available_bundles[strip_tags($vs_display)][$vs_bundle] = array('bundle' => $vs_bundle, 'display' => $vs_format == 'simple' ? $vs_label : $vs_display, 'description' => $vs_description = $t_instance->getDisplayDescription($vs_bundle), 'settingsForm' => $t_placement->getHTMLSettingForm(array('id' => $vs_bundle . '_0')), 'settings' => $va_additional_settings);
         if ($vb_show_tooltips) {
             TooltipManager::add("#bundleDisplayEditorBundle_{$vs_table}_preferred_labels", $this->_formatBundleTooltip($vs_label, $vs_bundle, $vs_description));
         }
     }
     if (caGetBundleAccessLevel($vs_table, "nonpreferred_labels") != __CA_BUNDLE_ACCESS_NONE__) {
         // get non-preferred labels for this table
         $t_placement = new ca_bundle_display_placements(null, $va_additional_settings);
         if ($this->inTransaction()) {
             $t_placement->setTransaction($this->getTransaction());
         }
         $vs_bundle = $vs_table . '.nonpreferred_labels';
         $vs_display = "<div id='bundleDisplayEditorBundle_{$vs_table}_nonpreferred_labels'><span class='bundleDisplayEditorPlacementListItemTitle'>" . caUcFirstUTF8Safe($t_instance->getProperty('NAME_SINGULAR')) . "</span> " . ($vs_label = $t_instance->getDisplayLabel($vs_bundle)) . "</div>";
         $va_available_bundles[strip_tags($vs_display)][$vs_bundle] = array('bundle' => $vs_bundle, 'display' => $vs_format == 'simple' ? $vs_label : $vs_display, 'description' => $vs_description = $t_instance->getDisplayDescription($vs_bundle), 'settingsForm' => $t_placement->getHTMLSettingForm(array('id' => $vs_bundle . '_0')), 'settings' => $va_additional_settings);
         if ($vb_show_tooltips) {
             TooltipManager::add("#bundleDisplayEditorBundle_{$vs_table}_nonpreferred_labels", $this->_formatBundleTooltip($vs_label, $vs_bundle, $vs_description));
         }
     }
     // get library checkout and commerce order history bundle (objects only, of course)
     if ($vs_table == 'ca_objects') {
         $va_additional_settings = array('order_type' => array('formatType' => FT_TEXT, 'displayType' => DT_SELECT, 'width' => 35, 'height' => 1, 'takesLocale' => false, 'default' => '', 'options' => array(_t('Sales order') => 'O', _t('Loan') => 'L'), 'label' => _t('Type of order'), 'description' => _t('Determines which type of order is displayed.')));
         $t_placement = new ca_bundle_display_placements(null, $va_additional_settings);
         if ($this->inTransaction()) {
             $t_placement->setTransaction($this->getTransaction());
         }
         $vs_bundle = 'ca_commerce_order_history';
         $vs_label = _t('Order history');
         $vs_display = _t('Order history');
         $vs_description = _t('List of orders (loans or sales) that include this object');
         $va_available_bundles[strip_tags($vs_display)][$vs_bundle] = array('bundle' => $vs_bundle, 'display' => $vs_format == 'simple' ? $vs_label : $vs_display, 'description' => $vs_description, 'settingsForm' => $t_placement->getHTMLSettingForm(array('id' => $vs_bundle . '_0')), 'settings' => $va_additional_settings);
         if ($vb_show_tooltips) {
             TooltipManager::add("#bundleDisplayEditorBundle_ca_commerce_order_history", $this->_formatBundleTooltip($vs_label, $vs_bundle, $vs_description));
         }
         $va_additional_settings = array('format' => array('formatType' => FT_TEXT, 'displayType' => DT_FIELD, 'width' => 35, 'height' => 5, 'takesLocale' => false, 'default' => '', 'label' => _t('Display format'), 'description' => _t('Template used to format output.')));
         $t_placement = new ca_bundle_display_placements(null, $va_additional_settings);
         if ($this->inTransaction()) {
             $t_placement->setTransaction($this->getTransaction());
         }
         $vs_bundle = 'ca_object_checkouts';
         $vs_label = _t('Library checkouts');
         $vs_display = "<div id='bundleDisplayEditorBundle_{$vs_table}_preferred_labels'><span class='bundleDisplayEditorPlacementListItemTitle'>" . caUcFirstUTF8Safe($t_instance->getProperty('NAME_SINGULAR')) . "</span> " . _t('Library checkouts') . "</div>";
         $vs_description = _t('List of library checkouts that include this object');
         $va_available_bundles[strip_tags($vs_display)][$vs_bundle] = array('bundle' => $vs_bundle, 'display' => $vs_format == 'simple' ? $vs_label : $vs_display, 'description' => $vs_description, 'settingsForm' => $t_placement->getHTMLSettingForm(array('id' => $vs_bundle . '_0')), 'settings' => $va_additional_settings);
         if ($vb_show_tooltips) {
             TooltipManager::add("#bundleDisplayEditorBundle_ca_object_checkouts", $this->_formatBundleTooltip($vs_label, $vs_bundle, $vs_description));
         }
         $va_additional_settings = array();
         $t_placement = new ca_bundle_display_placements(null, $va_additional_settings);
         if ($this->inTransaction()) {
             $t_placement->setTransaction($this->getTransaction());
         }
         $vs_bundle = $vs_table . '.ca_objects_location';
         $vs_label = _t('Current location');
         $vs_display = "<div id='bundleDisplayEditorBundle_{$vs_table}_ca_objects_location'><span class='bundleDisplayEditorPlacementListItemTitle'>" . caUcFirstUTF8Safe($t_instance->getProperty('NAME_SINGULAR')) . "</span> " . _t('Current location') . "</div>";
         $vs_description = _t('Current location of object');
         $va_available_bundles[strip_tags($vs_display)][$vs_bundle] = array('bundle' => $vs_bundle, 'display' => $vs_format == 'simple' ? $vs_label : $vs_display, 'description' => $vs_description, 'settingsForm' => $t_placement->getHTMLSettingForm(array('id' => $vs_bundle . '_0')), 'settings' => $va_additional_settings);
         if ($vb_show_tooltips) {
             TooltipManager::add("#bundleDisplayEditorBundle_ca_objects_location", $this->_formatBundleTooltip($vs_label, $vs_bundle, $vs_description));
         }
     }
     if (caGetBundleAccessLevel($vs_table, "ca_object_representations") != __CA_BUNDLE_ACCESS_NONE__) {
         // get object representations (objects only, of course)
         if ($vs_table == 'ca_objects') {
             $va_additional_settings = array('display_mode' => array('formatType' => FT_TEXT, 'displayType' => DT_SELECT, 'width' => 35, 'height' => 1, 'takesLocale' => false, 'default' => '', 'options' => array(_t('Media') => 'media', _t('URL') => 'url'), 'label' => _t('Output mode'), 'description' => _t('Determines if value used is URL of media or the media itself.')));
             $o_media_settings = new MediaProcessingSettings('ca_object_representations', 'media');
             $va_versions = $o_media_settings->getMediaTypeVersions('*');
             foreach ($va_versions as $vs_version => $va_version_info) {
                 $t_placement = new ca_bundle_display_placements(null, $va_additional_settings);
                 if ($this->inTransaction()) {
                     $t_placement->setTransaction($this->getTransaction());
                 }
                 $vs_bundle = 'ca_object_representations.media.' . $vs_version;
                 $vs_display = "<div id='bundleDisplayEditorBundle_ca_object_representations_media_{$vs_version}'><span class='bundleDisplayEditorPlacementListItemTitle'>" . caUcFirstUTF8Safe($t_instance->getProperty('NAME_SINGULAR')) . "</span> " . ($vs_label = $t_instance->getDisplayLabel($vs_bundle)) . "</div>";
                 $va_available_bundles[strip_tags($vs_display)][$vs_bundle] = array('bundle' => $vs_bundle, 'display' => $vs_format == 'simple' ? $vs_label : $vs_display, 'description' => $vs_description = $t_instance->getDisplayDescription($vs_bundle), 'settingsForm' => $t_placement->getHTMLSettingForm(array('id' => $vs_bundle . '_0')), 'settings' => $va_additional_settings);
                 if ($vb_show_tooltips) {
                     TooltipManager::add("#bundleDisplayEditorBundle_ca_object_representations_media_{$vs_version}", $this->_formatBundleTooltip($vs_label, $vs_bundle, $vs_description));
                 }
             }
             $t_rep = new ca_object_representations();
             if ($this->inTransaction()) {
                 $t_rep->setTransaction($this->getTransaction());
             }
             foreach (array('mimetype', 'md5', 'original_filename') as $vs_rep_field) {
                 $vs_bundle = 'ca_object_representations.' . $vs_rep_field;
                 $vs_display = "<div id='bundleDisplayEditorBundle_ca_object_representations_{$vs_rep_field}'><span class='bundleDisplayEditorPlacementListItemTitle'>" . caUcFirstUTF8Safe($t_rep->getProperty('NAME_SINGULAR')) . "</span> " . ($vs_label = $t_rep->getDisplayLabel($vs_bundle)) . "</div>";
                 $va_available_bundles[strip_tags($vs_display)][$vs_bundle] = array('bundle' => $vs_bundle, 'display' => $vs_format == 'simple' ? $vs_label : $vs_display, 'description' => $vs_description = $t_rep->getDisplayDescription($vs_bundle), 'settingsForm' => $t_placement->getHTMLSettingForm(array('id' => $vs_bundle . '_0')), 'settings' => array());
             }
         }
     }
     // get related items
     $o_dm = $this->getAppDatamodel();
     foreach (array('ca_objects', 'ca_object_lots', 'ca_entities', 'ca_places', 'ca_occurrences', 'ca_collections', 'ca_storage_locations', 'ca_loans', 'ca_movements', 'ca_list_items', 'ca_object_representations') as $vs_related_table) {
         if ($this->getAppConfig()->get($vs_related_table . '_disable') && !($vs_related_table == 'ca_object_representations' && !$this->getAppConfig()->get('ca_objects_disable'))) {
             continue;
         }
         if (caGetBundleAccessLevel($vs_table, $vs_related_table) == __CA_BUNDLE_ACCESS_NONE__) {
             continue;
         }
         if ($vs_related_table === $vs_table) {
             $vs_bundle = $vs_related_table . '.related';
         } else {
             $vs_bundle = $vs_related_table;
         }
         $t_rel_instance = $o_dm->getInstanceByTableName($vs_related_table, true);
         $vs_table_name = $o_dm->getTableName($this->get('table_num'));
         $va_path = array_keys($o_dm->getPath($vs_table_name, $vs_related_table));
         if (sizeof($va_path) < 2 || sizeof($va_path) > 3) {
             continue;
         }
         // only use direct relationships (one-many or many-many)
         $va_additional_settings = array('format' => array('formatType' => FT_TEXT, 'displayType' => DT_FIELD, 'width' => 35, 'height' => 5, 'takesLocale' => false, 'default' => '', 'label' => _t('Display format'), 'description' => _t('Template used to format output.')), 'restrict_to_relationship_types' => array('formatType' => FT_TEXT, 'displayType' => DT_SELECT, 'useRelationshipTypeList' => $va_path[1], 'width' => 35, 'height' => 5, 'takesLocale' => false, 'default' => '', 'label' => _t('Restrict to relationship types'), 'description' => _t('Restricts display to items related using the specified relationship type(s). Leave all unchecked for no restriction.')), 'restrict_to_types' => array('formatType' => FT_TEXT, 'displayType' => DT_SELECT, 'useList' => $t_rel_instance->getTypeListCode(), 'width' => 35, 'height' => 5, 'takesLocale' => false, 'default' => '', 'label' => _t('Restrict to types'), 'description' => _t('Restricts display to items of the specified type(s). Leave all unchecked for no restriction.')), 'delimiter' => array('formatType' => FT_TEXT, 'displayType' => DT_FIELD, 'width' => 35, 'height' => 1, 'takesLocale' => false, 'default' => '', 'label' => _t('Delimiter'), 'description' => _t('Text to place in-between repeating values.')));
         if ($t_rel_instance->isHierarchical()) {
             $va_additional_settings += array('show_hierarchy' => array('formatType' => FT_NUMBER, 'displayType' => DT_CHECKBOXES, 'width' => 10, 'height' => 1, 'hideOnSelect' => array('format'), 'takesLocale' => false, 'default' => '0', 'label' => _t('Show hierarchy?'), 'description' => _t('If checked the full hierarchical path will be shown.')), 'remove_first_items' => array('formatType' => FT_NUMBER, 'displayType' => DT_FIELD, 'width' => 10, 'height' => 1, 'takesLocale' => false, 'default' => '0', 'label' => _t('Remove first items from hierarchy?'), 'description' => _t('If set to a non-zero value, the specified number of items at the top of the hierarchy will be omitted. For example, if set to 2, the root and first child of the hierarchy will be omitted.')), 'hierarchy_order' => array('formatType' => FT_TEXT, 'displayType' => DT_SELECT, 'options' => array(_t('top first') => 'ASC', _t('bottom first') => 'DESC'), 'width' => 35, 'height' => 1, 'takesLocale' => false, 'default' => '', 'label' => _t('Order hierarchy'), 'description' => _t('Determines order in which hierarchy is displayed.')), 'hierarchy_limit' => array('formatType' => FT_NUMBER, 'displayType' => DT_FIELD, 'width' => 10, 'height' => 1, 'takesLocale' => false, 'default' => '', 'label' => _t('Maximum length of hierarchy'), 'description' => _t('Maximum number of items to show in the hierarchy. Leave blank to show the unabridged hierarchy.')), 'hierarchical_delimiter' => array('formatType' => FT_TEXT, 'displayType' => DT_FIELD, 'width' => 35, 'height' => 1, 'takesLocale' => false, 'default' => ' ➔ ', 'label' => _t('Hierarchical delimiter'), 'description' => _t('Text to place in-between elements of a hierarchical value.')));
         }
         if ($vs_table === 'ca_objects' && $vs_related_table === 'ca_storage_locations' || $vs_table === 'ca_storage_locations' && $vs_related_table === 'ca_objects' || $vs_table === 'ca_objects' && $vs_related_table === 'ca_movements' || $vs_table === 'ca_movements' && $vs_related_table === 'ca_objects' || $vs_table === 'ca_storage_locations' && $vs_related_table === 'ca_movements' || $vs_table === 'ca_movements' && $vs_related_table === 'ca_storage_locations') {
             $va_additional_settings['showCurrentOnly'] = array('formatType' => FT_TEXT, 'displayType' => DT_CHECKBOXES, 'width' => "10", 'height' => "1", 'takesLocale' => false, 'default' => '0', 'label' => _t('Show current only?'), 'description' => _t('If checked only current objects are displayed.'));
         }
         //$va_additional_settings['format']['helpText'] = $this->getTemplatePlaceholderDisplayListForBundle($vs_bundle);
         $t_placement = new ca_bundle_display_placements(null, $va_additional_settings);
         if ($this->inTransaction()) {
             $t_placement->setTransaction($this->getTransaction());
         }
         $vs_id_suffix = "bundleDisplayEditorBundle_" . str_replace(".", "_", $vs_bundle);
         $vs_display = "<div id='bundleDisplayEditorBundle_{$vs_id_suffix}'><span class='bundleDisplayEditorPlacementListItemTitle'>" . caUcFirstUTF8Safe($t_rel_instance->getProperty('NAME_SINGULAR')) . "</span> " . ($vs_label = $t_rel_instance->getDisplayLabel($vs_bundle)) . "</div>";
         $va_available_bundles[strip_tags($vs_display)][$vs_bundle] = array('bundle' => $vs_bundle, 'display' => $vs_format == 'simple' ? $vs_label : $vs_display, 'description' => $vs_description = $t_rel_instance->getDisplayDescription($vs_bundle), 'settingsForm' => $t_placement->getHTMLSettingForm(array('id' => $vs_bundle . '_0')), 'settings' => $va_additional_settings);
         if ($vb_show_tooltips) {
             TooltipManager::add("#bundleDisplayEditorBundle_{$vs_id_suffix}", $this->_formatBundleTooltip($vs_label, $vs_bundle, $vs_description));
         }
     }
     // created and modified
     $va_additional_settings = array('dateFormat' => array('formatType' => FT_TEXT, 'displayType' => DT_SELECT, 'width' => 40, 'height' => 1, 'takesLocale' => false, 'default' => 'iso8601', 'options' => array('ISO-8601' => 'iso8601', 'Text' => 'text'), 'label' => _t('Date format'), 'description' => _t('Sets format for output of date when exporting.')));
     $t_placement = new ca_bundle_display_placements(null, $va_additional_settings);
     if ($this->inTransaction()) {
         $t_placement->setTransaction($this->getTransaction());
     }
     $vs_bundle = "{$vs_table}.created";
     $vs_display = "<div id='bundleDisplayEditorBundle_{$vs_table}_created'><span class='bundleDisplayEditorPlacementListItemTitle'>" . _t('General') . "</span> " . ($vs_label = $t_instance->getDisplayLabel($vs_bundle)) . "</div>";
     $va_available_bundles[strip_tags($vs_display)][$vs_bundle] = array('bundle' => $vs_bundle, 'display' => $vs_format == 'simple' ? $vs_label : $vs_display, 'description' => $vs_description = _t('Date and time item was created'), 'settingsForm' => $t_placement->getHTMLSettingForm(array('id' => $vs_bundle . '_0')), 'settings' => $va_additional_settings);
     if ($vb_show_tooltips) {
         TooltipManager::add("#bundleDisplayEditorBundle_{$vs_table}_created", $this->_formatBundleTooltip($vs_label, $vs_bundle, $vs_description));
     }
     $vs_bundle = "{$vs_table}.lastModified";
     $vs_display = "<div id='bundleDisplayEditorBundle_{$vs_table}_lastModified'><span class='bundleDisplayEditorPlacementListItemTitle'>" . _t('General') . "</span> " . ($vs_label = $t_instance->getDisplayLabel($vs_bundle)) . "</div>";
     $va_available_bundles[strip_tags($vs_display)][$vs_bundle] = array('bundle' => $vs_bundle, 'display' => $vs_display, 'description' => $vs_description = _t('Date and time item was last modified'), 'settingsForm' => $t_placement->getHTMLSettingForm(array('id' => $vs_bundle . '_0')), 'settings' => $va_additional_settings);
     if ($vb_show_tooltips) {
         TooltipManager::add("#bundleDisplayEditorBundle_{$vs_table}_lastModified", $this->_formatBundleTooltip($vs_label, $vs_bundle, $vs_description));
     }
     ksort($va_available_bundles);
     $va_sorted_bundles = array();
     foreach ($va_available_bundles as $vs_k => $va_val) {
         foreach ($va_val as $vs_real_key => $va_info) {
             $va_sorted_bundles[$vs_real_key] = $va_info;
         }
     }
     return $va_sorted_bundles;
 }
示例#3
0
 /**
  * Reindex PDF media by content for in-PDF search
  */
 public static function reindex_pdfs($po_opts = null)
 {
     require_once __CA_LIB_DIR__ . "/core/Db.php";
     require_once __CA_MODELS_DIR__ . "/ca_object_representations.php";
     if (!caPDFMinerInstalled()) {
         CLIUtils::addError(_t("Can't reindex PDFs: PDFMiner is not installed."));
         return false;
     }
     $o_db = new Db();
     $t_rep = new ca_object_representations();
     $t_rep->setMode(ACCESS_WRITE);
     $va_versions = array("original");
     $va_kinds = ($vs_kinds = $po_opts->getOption("kinds")) ? explode(",", $vs_kinds) : array();
     if (!is_array($va_kinds) || !sizeof($va_kinds)) {
         $va_kinds = array('all');
     }
     $va_kinds = array_map('strtolower', $va_kinds);
     if (in_array('all', $va_kinds) || in_array('ca_object_representations', $va_kinds)) {
         if (!($vn_start = (int) $po_opts->getOption('start_id'))) {
             $vn_start = null;
         }
         if (!($vn_end = (int) $po_opts->getOption('end_id'))) {
             $vn_end = null;
         }
         if ($vn_id = (int) $po_opts->getOption('id')) {
             $vn_start = $vn_id;
             $vn_end = $vn_id;
         }
         $va_ids = array();
         if ($vs_ids = (string) $po_opts->getOption('ids')) {
             if (sizeof($va_tmp = explode(",", $vs_ids))) {
                 foreach ($va_tmp as $vn_id) {
                     if ((int) $vn_id > 0) {
                         $va_ids[] = (int) $vn_id;
                     }
                 }
             }
         }
         $vs_sql_where = null;
         $va_params = array();
         if (sizeof($va_ids)) {
             $vs_sql_where = "WHERE representation_id IN (?)";
             $va_params[] = $va_ids;
         } else {
             if ($vn_start > 0 && $vn_end > 0 && $vn_start <= $vn_end || $vn_start > 0 && $vn_end == null) {
                 $vs_sql_where = "WHERE representation_id >= ?";
                 $va_params[] = $vn_start;
                 if ($vn_end) {
                     $vs_sql_where .= " AND representation_id <= ?";
                     $va_params[] = $vn_end;
                 }
             }
         }
         if ($vs_sql_where) {
             $vs_sql_where .= " AND mimetype = 'application/pdf'";
         } else {
             $vs_sql_where = " WHERE mimetype = 'application/pdf'";
         }
         $qr_reps = $o_db->query("\n\t\t\t\t\tSELECT * \n\t\t\t\t\tFROM ca_object_representations \n\t\t\t\t\t{$vs_sql_where}\n\t\t\t\t\tORDER BY representation_id\n\t\t\t\t", $va_params);
         print CLIProgressBar::start($qr_reps->numRows(), _t('Reindexing PDF representations'));
         $vn_rep_table_num = $t_rep->tableNum();
         while ($qr_reps->nextRow()) {
             $va_media_info = $qr_reps->getMediaInfo('media');
             $vs_original_filename = $va_media_info['ORIGINAL_FILENAME'];
             print CLIProgressBar::next(1, _t("Reindexing PDF %1", $vs_original_filename ? $vs_original_filename . " (" . $qr_reps->get('representation_id') . ")" : $qr_reps->get('representation_id')));
             $t_rep->load($qr_reps->get('representation_id'));
             $vn_rep_id = $t_rep->getPrimaryKey();
             $m = new Media();
             if ($m->read($vs_path = $t_rep->getMediaPath('media', 'original')) && is_array($va_locs = $m->getExtractedTextLocations())) {
                 MediaContentLocationIndexer::clear($vn_rep_table_num, $vn_rep_id);
                 foreach ($va_locs as $vs_content => $va_loc_list) {
                     foreach ($va_loc_list as $va_loc) {
                         MediaContentLocationIndexer::index($vn_rep_table_num, $vn_rep_id, $vs_content, $va_loc['p'], $va_loc['x1'], $va_loc['y1'], $va_loc['x2'], $va_loc['y2']);
                     }
                 }
                 MediaContentLocationIndexer::write();
             } else {
                 //CLIUtils::addError(_t("[Warning] No content to reindex for PDF representation: %1", $vs_path));
             }
         }
         print CLIProgressBar::finish();
     }
     if (in_array('all', $va_kinds) || in_array('ca_attributes', $va_kinds)) {
         // get all Media elements
         $va_elements = ca_metadata_elements::getElementsAsList(false, null, null, true, false, true, array(16));
         // 16=media
         $qr_c = $o_db->query("\n\t\t\t\t\tSELECT count(*) c \n\t\t\t\t\tFROM ca_attribute_values\n\t\t\t\t\tWHERE\n\t\t\t\t\t\telement_id in (?)\n\t\t\t\t", caExtractValuesFromArrayList($va_elements, 'element_id', array('preserveKeys' => false)));
         if ($qr_c->nextRow()) {
             $vn_count = $qr_c->get('c');
         } else {
             $vn_count = 0;
         }
         $t_attr_val = new ca_attribute_values();
         $vn_attr_table_num = $t_attr_val->tableNum();
         print CLIProgressBar::start($vn_count, _t('Reindexing metadata attribute media'));
         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);
                     $va_media_info = $t_attr_val->getMediaInfo('value_blob');
                     $vs_original_filename = $va_media_info['ORIGINAL_FILENAME'];
                     if (!is_array($va_media_info) || $va_media_info['MIMETYPE'] !== 'application/pdf') {
                         continue;
                     }
                     print CLIProgressBar::next(1, _t("Reindexing %1", $vs_original_filename ? $vs_original_filename . " ({$vn_value_id})" : $vn_value_id));
                     $m = new Media();
                     if ($m->read($vs_path = $t_attr_val->getMediaPath('value_blob', 'original')) && is_array($va_locs = $m->getExtractedTextLocations())) {
                         MediaContentLocationIndexer::clear($vn_attr_table_num, $vn_attr_table_num);
                         foreach ($va_locs as $vs_content => $va_loc_list) {
                             foreach ($va_loc_list as $va_loc) {
                                 MediaContentLocationIndexer::index($vn_attr_table_num, $vn_value_id, $vs_content, $va_loc['p'], $va_loc['x1'], $va_loc['y1'], $va_loc['x2'], $va_loc['y2']);
                             }
                         }
                         MediaContentLocationIndexer::write();
                     } else {
                         //CLIUtils::addError(_t("[Warning] No content to reindex for PDF in metadata attribute: %1", $vs_path));
                     }
                 }
             }
         }
         print CLIProgressBar::finish();
     }
     return true;
 }
示例#4
0
 /**
  * Returns HTML form element for editing of setting
  *
  * Options:
  *
  * 	'name' => sets the name of the HTML form element explicitly, otherwise 'setting_<name_of_setting>' is used
  * 	'id' => sets the id of the HTML form element explicitly, otherwise 'setting_<name_of_setting>' is used
  *  'value' => sets the value of the HTML form element explicitly, otherwise the current value for the setting in the loaded row is used
  *  'label_id' => sets the id of the label for the setting form element (used to link tools tips to the label); if not set then the default is to set it to  'setting_<name_of_setting>_label'
  */
 public function settingHTMLFormElement($ps_setting, $pa_options = null)
 {
     if (!$this->isValidSetting($ps_setting)) {
         return false;
     }
     $va_available_settings = $this->getAvailableSettings();
     $va_properties = $va_available_settings[$ps_setting];
     if (isset($pa_options['name'])) {
         $vs_input_name = $pa_options['name'];
     } else {
         $vs_input_name = "setting_{$ps_setting}";
     }
     if (isset($pa_options['id'])) {
         $vs_input_id = $pa_options['id'];
     } else {
         $vs_input_id = "setting_{$ps_setting}";
     }
     if (isset($pa_options['value'])) {
         $vs_value = $pa_options['value'];
     } else {
         $vs_value = $this->getSetting(trim($ps_setting));
     }
     if (isset($pa_options['label_id'])) {
         $vs_label_id = $pa_options['label_id'];
     } else {
         $vs_label_id = "setting_{$ps_setting}_label";
     }
     $vs_return = "\n" . '<div class="formLabel" id="' . $vs_input_id . '_container">' . "\n";
     $vs_return .= '<span id="' . $vs_label_id . '"  class="' . $vs_label_id . '">' . $va_properties['label'] . '</span>';
     if ($vs_help_text = $pa_options['helpText']) {
         $vs_return .= "<a href='#' onclick='jQuery(\"#" . str_replace(".", "_", $vs_label_id) . "_help_text\").slideToggle(250); return false;' class='settingsKeyButton'>" . _t('Key') . "</a>";
     }
     $vs_return .= '<br />' . "\n";
     if ($vs_help_text) {
         $vs_return .= "\n<div id='" . str_replace(".", "_", $vs_label_id) . "_help_text' class='settingsKey'>{$vs_help_text}</div>\n";
     }
     switch ($va_properties['displayType']) {
         # --------------------------------------------
         case DT_FIELD:
             $vb_takes_locale = false;
             if (isset($va_properties['takesLocale']) && $va_properties['takesLocale']) {
                 $vb_takes_locale = true;
                 $va_locales = ca_locales::getLocaleList(array('sort_field' => '', 'sort_order' => 'asc', 'index_by_code' => true, 'available_for_cataloguing_only' => true));
             } else {
                 $va_locales = array('_generic' => array());
             }
             foreach ($va_locales as $vs_locale => $va_locale_info) {
                 if ($vb_takes_locale && sizeof($va_locales) > 1) {
                     $vs_locale_label = " (" . $va_locale_info['name'] . ")";
                     $vs_input_name_suffix = '_' . $vs_locale;
                 } else {
                     if ($vb_takes_locale) {
                         $vs_input_name_suffix = '_' . $vs_locale;
                     } else {
                         $vs_input_name_suffix = $vs_locale_label = '';
                     }
                 }
                 if ($vs_locale != '_generic' && is_array($vs_value)) {
                     // _generic means this setting doesn't take a locale
                     if (!($vs_text_value = $vs_value[$va_locale_info['locale_id']])) {
                         $vs_text_value = is_array($vs_value) && isset($vs_value[$va_locale_info['code']]) ? $vs_value[$va_locale_info['code']] : '';
                     }
                 } else {
                     $vs_text_value = $vs_value;
                 }
                 $vs_return .= caHTMLTextInput($vs_input_name . $vs_input_name_suffix, array('size' => $va_properties["width"], 'height' => $va_properties["height"], 'value' => $vs_text_value, 'id' => $vs_input_id)) . "{$vs_locale_label}<br/>\n";
             }
             break;
             # --------------------------------------------
         # --------------------------------------------
         case DT_CHECKBOXES:
             $va_attributes = array('value' => '1', 'id' => $vs_input_id);
             if ((int) $vs_value === 1) {
                 $va_attributes['checked'] = '1';
             }
             if (isset($va_properties['hideOnSelect'])) {
                 if (!is_array($va_properties['hideOnSelect'])) {
                     $va_properties['hideOnSelect'] = array($va_properties['hideOnSelect']);
                 }
                 $va_ids = array();
                 foreach ($va_properties['hideOnSelect'] as $vs_n) {
                     $va_ids[] = "#" . $pa_options['id_prefix'] . "_{$vs_n}_container";
                 }
                 $va_attributes['onchange'] = 'jQuery(this).prop("checked") ? jQuery("' . join(",", $va_ids) . '").slideUp(250).find("input, textarea").val("") : jQuery("' . join(",", $va_ids) . '").slideDown(250);';
             }
             $vs_return .= caHTMLCheckboxInput($vs_input_name, $va_attributes, array());
             break;
             # --------------------------------------------
         # --------------------------------------------
         case DT_COLORPICKER:
             $va_attributes = array('value' => $vs_value, 'id' => $vs_input_id);
             $vs_return .= caHTMLHiddenInput($vs_input_name, $va_attributes, array());
             $vs_return .= "<div id='{$vs_input_id}_colorchip' class='colorpicker_chip' style='background-color: #{$vs_value}'><!-- empty --></div>";
             $vs_return .= "<script type='text/javascript'>jQuery(document).ready(function() { jQuery('#{$vs_input_name}_colorchip').ColorPicker({\n\t\t\t\t\t\t\t\tonShow: function (colpkr) {\n\t\t\t\t\t\t\t\t\tjQuery(colpkr).fadeIn(500);\n\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tonHide: function (colpkr) {\n\t\t\t\t\t\t\t\t\tjQuery(colpkr).fadeOut(500);\n\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tonChange: function (hsb, hex, rgb) {\n\t\t\t\t\t\t\t\t\tjQuery('#{$vs_input_name}').val(hex);\n\t\t\t\t\t\t\t\t\tjQuery('#{$vs_input_name}_colorchip').css('backgroundColor', '#' + hex);\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tcolor: jQuery('#" . $pa_options["name"] . "').val()\n\t\t\t\t\t\t\t})}); </script>\n";
             JavascriptLoadManager::register('jquery', 'colorpicker');
             break;
             # --------------------------------------------
         # --------------------------------------------
         case DT_SELECT:
             include_once __CA_MODELS_DIR__ . '/ca_relationship_types.php';
             $vn_width = isset($va_properties['width']) && strlen($va_properties['width']) > 0 ? $va_properties['width'] : "100px";
             $vn_height = isset($va_properties['height']) && strlen($va_properties['height']) > 0 ? $va_properties['height'] : "50px";
             $vs_select_element = '';
             if (($vs_rel_table = $va_properties['useRelationshipTypeList']) || ($vb_locale_list = (bool) $va_properties['useLocaleList']) || ($vs_list_code = $va_properties['useList']) || ($vb_show_lists = (bool) $va_properties['showLists'] || (bool) $va_properties['showVocabularies'])) {
                 if ($vs_rel_table) {
                     $t_rel = new ca_relationship_types();
                     $va_rels = $t_rel->getRelationshipInfo($vs_rel_table);
                     $va_rel_opts = array();
                     if (isset($va_properties['allowNull']) && $va_properties['allowNull']) {
                         $va_rel_opts['-'] = null;
                     }
                     foreach ($va_rels as $vn_type_id => $va_rel_type_info) {
                         if (!$va_rel_type_info['parent_id']) {
                             continue;
                         }
                         $va_rel_opts[$va_rel_type_info['typename'] . '/' . $va_rel_type_info['typename_reverse']] = $va_rel_type_info['type_id'];
                     }
                 } else {
                     if ($vb_locale_list) {
                         include_once __CA_MODELS_DIR__ . '/ca_locales.php';
                         $va_rel_opts = array_flip(ca_locales::getLocaleList(array('return_display_values' => true)));
                     } else {
                         if ($vb_show_lists) {
                             include_once __CA_MODELS_DIR__ . '/ca_lists.php';
                             $t_list = new ca_lists();
                             $va_lists = caExtractValuesByUserLocale($t_list->getListOfLists());
                             $va_rel_opts = array();
                             foreach ($va_lists as $vn_list_id => $va_list_info) {
                                 if ($va_properties['showVocabularies'] && !$va_list_info['use_as_vocabulary']) {
                                     continue;
                                 }
                                 $va_rel_opts[$va_list_info['name'] . ' (' . $va_list_info['list_code'] . ')'] = $vn_list_id;
                             }
                         }
                     }
                 }
                 $va_attr = array();
                 if ($vn_height > 1) {
                     $va_attr['multiple'] = 1;
                     $vs_input_name .= '[]';
                 }
                 $va_opts = array('id' => $vs_input_id, 'width' => $vn_width, 'height' => $vn_height);
                 if ($vn_height > 1) {
                     if ($vs_value && !is_array($vs_value)) {
                         $vs_value = array($vs_value);
                     }
                     $va_opts['values'] = $vs_value;
                 } else {
                     if (is_array($vs_value)) {
                         $va_opts['value'] = array_pop($vs_value);
                     } else {
                         if ($vs_value) {
                             $va_opts['value'] = $vs_value;
                         } else {
                             $va_opts['value'] = null;
                         }
                     }
                 }
                 if ($vs_list_code) {
                     $t_list = new ca_lists();
                     if (!isset($va_opts['value'])) {
                         $va_opts['value'] = -1;
                     }
                     // make sure default list item is never selected
                     $vs_select_element = $t_list->getListAsHTMLFormElement($vs_list_code, $vs_input_name, $va_attr, $va_opts);
                 } else {
                     if (!isset($va_opts['value'])) {
                         $va_opts['value'] = -1;
                     }
                     // make sure default list item is never selected
                     $vs_select_element = caHTMLSelect($vs_input_name, $va_rel_opts, $va_attr, $va_opts);
                 }
             } else {
                 if (strlen($va_properties['showSortableBundlesFor']) > 0) {
                     require_once __CA_MODELS_DIR__ . '/ca_metadata_elements.php';
                     $o_dm = Datamodel::load();
                     if (!($t_rel = $o_dm->getInstanceByTableName($va_properties['showSortableBundlesFor'], true))) {
                         break;
                     }
                     $va_elements = ca_metadata_elements::getSortableElements($va_properties['showSortableBundlesFor']);
                     $va_select_opts = array(_t('User defined sort order') => '', _t('Order created') => 'relation_id', _t('Preferred label') => $va_properties['showSortableBundlesFor'] . ".preferred_labels." . $t_rel->getLabelDisplayField());
                     foreach ($va_elements as $vn_element_id => $va_element) {
                         if (!$va_element['display_label']) {
                             continue;
                         }
                         $va_select_opts[_t('Element: %1', $va_element['display_label'])] = $va_properties['showSortableBundlesFor'] . "." . $va_element['element_code'];
                     }
                     $va_opts = array('id' => $vs_input_id, 'width' => $vn_width, 'height' => $vn_height, 'value' => is_array($vs_value) ? $vs_value[0] : $vs_value, 'values' => is_array($vs_value) ? $vs_value : array($vs_value));
                     $vs_select_element = caHTMLSelect($vs_input_name, $va_select_opts, array(), $va_opts);
                 } elseif ((int) $va_properties['showSortableElementsFor'] > 0) {
                     require_once __CA_MODELS_DIR__ . '/ca_metadata_elements.php';
                     $t_element = new ca_metadata_elements($va_properties['showSortableElementsFor']);
                     if (!$t_element->getPrimaryKey()) {
                         return '';
                     }
                     $va_elements = $t_element->getElementsInSet();
                     $va_select_opts = array(_t('Order created') => '');
                     foreach ($va_elements as $vn_i => $va_element) {
                         if ((int) $va_element['element_id'] == (int) $va_properties['showSortableElementsFor']) {
                             continue;
                         }
                         if (!$va_element['display_label']) {
                             continue;
                         }
                         $va_select_opts[_t('Element: %1', $va_element['display_label'])] = $va_element['element_code'];
                     }
                     $va_opts = array('id' => $vs_input_id, 'width' => $vn_width, 'height' => $vn_height, 'value' => is_array($vs_value) ? $vs_value[0] : $vs_value, 'values' => is_array($vs_value) ? $vs_value : array($vs_value));
                     $vs_select_element = caHTMLSelect($vs_input_name, $va_select_opts, array(), $va_opts);
                 } elseif ((int) $va_properties['showMetadataElementsWithDataType'] > 0) {
                     require_once __CA_MODELS_DIR__ . '/ca_metadata_elements.php';
                     $va_rep_elements = ca_metadata_elements::getElementsAsList(true, $va_properties['table'], null, true, false, true, array($va_properties['showMetadataElementsWithDataType']));
                     if (is_array($va_rep_elements)) {
                         $va_select_opts = array();
                         foreach ($va_rep_elements as $vs_element_code => $va_element_info) {
                             $va_select_opts[$va_element_info['display_label']] = $vs_element_code;
                         }
                         $va_opts = array('id' => $vs_input_id, 'width' => $vn_width, 'height' => $vn_height, 'value' => is_array($vs_value) ? $vs_value[0] : $vs_value, 'values' => is_array($vs_value) ? $vs_value : array($vs_value));
                         $vs_select_element = caHTMLSelect($vs_input_name, $va_select_opts, array(), $va_opts);
                     }
                 } else {
                     // Regular drop-down with configured options
                     if ($vn_height > 1) {
                         $va_attr['multiple'] = 1;
                         $vs_input_name .= '[]';
                     }
                     $va_opts = array('id' => $vs_input_id, 'width' => $vn_width, 'height' => $vn_height, 'value' => is_array($vs_value) ? $vs_value[0] : $vs_value, 'values' => is_array($vs_value) ? $vs_value : array($vs_value));
                     if (!isset($va_opts['value'])) {
                         $va_opts['value'] = -1;
                     }
                     // make sure default list item is never selected
                     $vs_select_element = caHTMLSelect($vs_input_name, $va_properties['options'], array(), $va_opts);
                 }
             }
             if ($vs_select_element) {
                 $vs_return .= $vs_select_element;
             } else {
                 return '';
             }
             break;
             # --------------------------------------------
         # --------------------------------------------
         default:
             break;
             # --------------------------------------------
     }
     $vs_return .= '</div>' . "\n";
     TooltipManager::add('.' . $vs_label_id, "<h3>" . $va_properties["label"] . "</h3>" . $va_properties["description"]);
     return $vs_return;
 }
 /**
  * Returns all available bundle display placements - those data bundles that can be displayed for the given content type, in other words.
  * The returned value is a list of arrays; each array contains a 'bundle' specifier than can be passed got Model::get() or SearchResult::get() and a display name
  *
  * @param mixed $pm_table_name_or_num The table name or number specifying the content type to fetch bundles for. If omitted the content table of the currently loaded display will be used.
  * @param array $pa_options Supported options are:
  *		dontCache = disable caching when fetching model properties
  * @return array And array of bundles keyed on display label. Each value is an array with these keys:
  *		bundle = The bundle name (eg. ca_objects.idno)
  *		display = Display label for each available bundle
  *		description = Description of bundle
  * 
  * Will return null if table name or number is invalid.
  */
 public function getAvailableBundles($pm_table_name_or_num = null, $pa_options = null)
 {
     $pb_dont_cache = caGetOption('dontCache', $pa_options, false);
     if (!$pm_table_name_or_num) {
         $pm_table_name_or_num = $this->getTableNum();
     }
     if (!is_numeric($pm_table_name_or_num)) {
         $pm_table_name_or_num = $this->_DATAMODEL->getTableNum($pm_table_name_or_num);
     }
     if (!($t_instance = $this->_DATAMODEL->getInstanceByTableNum($pm_table_name_or_num, false))) {
         return null;
     }
     $vs_table = $t_instance->tableName();
     // if cache is disabled, make sure bundle definitions are up-to-date for this instance. they are usually cached.
     if ($pb_dont_cache) {
         $t_instance->reloadLabelDefinitions();
     }
     $vs_table_display_name = $t_instance->getProperty('NAME_PLURAL');
     $t_placement = new ca_editor_ui_bundle_placements(null, array());
     $va_defined_bundles = $t_instance->getBundleList(array('includeBundleInfo' => true));
     // these are the bundles defined for this type of editor
     $va_available_bundles = array();
     $va_elements = ca_metadata_elements::getElementsAsList(true, $pm_table_name_or_num, null, !$pb_dont_cache, false, true);
     foreach ($va_defined_bundles as $vs_bundle => $va_info) {
         $vs_bundle_proc = preg_replace('!^ca_attribute_!', '', $vs_bundle);
         $va_additional_settings = array();
         switch ($va_info['type']) {
             case 'intrinsic':
                 $va_field_info = $t_instance->getFieldInfo($vs_bundle);
                 if (isset($va_field_info['DONT_ALLOW_IN_UI']) && $va_field_info['DONT_ALLOW_IN_UI']) {
                     continue 2;
                 }
                 if (is_subclass_of($t_instance, 'BaseRelationshipModel')) {
                     if (isset($va_field_info['IDENTITY']) && $va_field_info['IDENTITY']) {
                         continue 2;
                     }
                     if ($t_instance->getTypeFieldName() == $vs_bundle) {
                         continue 2;
                     }
                     if ($t_instance->getLeftTableFieldName() == $vs_bundle) {
                         continue 2;
                     }
                     if ($t_instance->getRightTableFieldName() == $vs_bundle) {
                         continue 2;
                     }
                 }
                 $va_additional_settings = array('documentation_url' => array('formatType' => FT_TEXT, 'displayType' => DT_FIELD, 'default' => '', 'width' => "275px", 'height' => 1, 'label' => _t('Documentation URL'), 'description' => _t('URL pointing to documentation for this field. Leave blank if no documentation URL exists.')));
                 break;
             case 'preferred_label':
             case 'nonpreferred_label':
                 $va_additional_settings = array('usewysiwygeditor' => array('formatType' => FT_NUMBER, 'displayType' => DT_SELECT, 'options' => array(_t('yes') => 1, _t('no') => 0), 'default' => '', 'width' => "100px", 'height' => 1, 'label' => _t('Use rich text editor'), 'description' => _t('Check this option if you want to use a word-processor like editor with this text field. If you expect users to enter rich text (italic, bold, underline) then you might want to enable this.')), 'documentation_url' => array('formatType' => FT_TEXT, 'displayType' => DT_FIELD, 'default' => '', 'width' => "275px", 'height' => 1, 'label' => _t('Documentation URL'), 'description' => _t('URL pointing to documentation for this field. Leave blank if no documentation URL exists.')));
                 break;
             case 'attribute':
                 $va_additional_settings = array('sort' => array('formatType' => FT_TEXT, 'displayType' => DT_SELECT, 'width' => "200px", 'height' => "1", 'takesLocale' => false, 'default' => '1', 'label' => _t('Sort using'), 'showSortableElementsFor' => $va_elements[preg_replace('!ca_attribute_!', '', $vs_bundle)]['element_id'], 'description' => _t('Method used to sort repeating values.')), 'sortDirection' => array('formatType' => FT_TEXT, 'displayType' => DT_SELECT, 'width' => "200px", 'height' => "1", 'takesLocale' => false, 'default' => 'ASC', 'options' => array(_t('Ascending') => 'ASC', _t('Descending') => 'DESC'), 'label' => _t('Sort direction'), 'description' => _t('Direction of sort.')), 'documentation_url' => array('formatType' => FT_TEXT, 'displayType' => DT_FIELD, 'default' => '', 'width' => "275px", 'height' => 1, 'label' => _t('Documentation URL'), 'description' => _t('URL pointing to documentation for this field. Leave blank if you wish to use the default URL for this metadata element.')));
                 if ($va_elements[preg_replace('!ca_attribute_!', '', $vs_bundle)]['datatype'] == 1) {
                     // 1=text
                     $va_additional_settings['usewysiwygeditor'] = array('formatType' => FT_TEXT, 'displayType' => DT_SELECT, 'options' => array(_t('yes') => 1, _t('no') => 0, _t('use default') => null), 'default' => '', 'width' => "100px", 'height' => 1, 'label' => _t('Use rich text editor'), 'description' => _t('Check this option if you want to use a word-processor like editor with this text field. If you expect users to enter rich text (italic, bold, underline) then you might want to enable this.'));
                 }
                 break;
             case 'related_table':
                 if (!($t_rel = $this->_DATAMODEL->getInstanceByTableName($vs_bundle, true))) {
                     continue;
                 }
                 $va_path = array_keys($this->_DATAMODEL->getPath($t_instance->tableName(), $vs_bundle));
                 $va_additional_settings = array('restrict_to_relationship_types' => array('formatType' => FT_TEXT, 'displayType' => DT_SELECT, 'useRelationshipTypeList' => $va_path[1], 'width' => "275px", 'height' => "75px", 'takesLocale' => false, 'default' => '', 'label' => _t('Restrict to relationship types'), 'description' => _t('Restricts display to items related using the specified relationship type(s). Leave all unselected for no restriction.')), 'restrict_to_types' => array('formatType' => FT_TEXT, 'displayType' => DT_SELECT, 'useList' => $t_rel->getTypeListCode(), 'width' => "275px", 'height' => "75px", 'takesLocale' => false, 'default' => '', 'label' => _t('Restrict to types'), 'description' => _t('Restricts display to items of the specified type(s). Leave all unselected for no restriction.')), 'dont_include_subtypes_in_type_restriction' => array('formatType' => FT_TEXT, 'displayType' => DT_CHECKBOXES, 'width' => "10", 'height' => "1", 'takesLocale' => false, 'default' => '0', 'label' => _t('Do not include sub-types in type restriction'), 'description' => _t('Normally restricting to type(s) automatically includes all sub-(child) types. If this option is checked then the lookup results will include items with the selected type(s) <b>only</b>.')), 'list_format' => array('formatType' => FT_TEXT, 'displayType' => DT_SELECT, 'options' => array(_t('bubbles (draggable)') => 'bubbles', _t('list (not draggable)') => 'list'), 'default' => 'bubbles', 'width' => "200px", 'height' => 1, 'label' => _t('Format of relationship list'), 'description' => _t('.')), 'sort' => array('formatType' => FT_TEXT, 'displayType' => DT_SELECT, 'width' => "200px", 'height' => "1", 'takesLocale' => false, 'default' => '1', 'label' => _t('Sort using'), 'showSortableBundlesFor' => $t_rel->tableName(), 'description' => _t('Method used to sort related items.')), 'sortDirection' => array('formatType' => FT_TEXT, 'displayType' => DT_SELECT, 'width' => "200px", 'height' => "1", 'takesLocale' => false, 'default' => 'ASC', 'options' => array(_t('Ascending') => 'ASC', _t('Descending') => 'DESC'), 'label' => _t('Sort direction'), 'description' => _t('Direction of sort, when not in a user-specified order.')), 'colorFirstItem' => array('formatType' => FT_TEXT, 'displayType' => DT_COLORPICKER, 'width' => "10", 'height' => "1", 'takesLocale' => false, 'default' => '', 'label' => _t('First item color'), 'description' => _t('If set first item in list will use this color.')), 'colorLastItem' => array('formatType' => FT_TEXT, 'displayType' => DT_COLORPICKER, 'width' => "10", 'height' => "1", 'takesLocale' => false, 'default' => '', 'label' => _t('Last item color'), 'description' => _t('If set last item in list will use this color.')), 'dontShowDeleteButton' => array('formatType' => FT_TEXT, 'displayType' => DT_CHECKBOXES, 'width' => "10", 'height' => "1", 'takesLocale' => false, 'default' => '0', 'label' => _t('Do not show delete button'), 'description' => _t('If checked the delete relationship control will not be provided.')), 'display_template' => array('formatType' => FT_TEXT, 'displayType' => DT_FIELD, 'default' => '^' . $t_rel->tableName() . '.preferred_labels', 'width' => "275px", 'height' => 4, 'label' => _t('Relationship display template'), 'description' => _t('Layout for relationship when displayed in list (can include HTML). Element code tags prefixed with the ^ character can be used to represent the value in the template. For example: <i>^my_element_code</i>.')), 'documentation_url' => array('formatType' => FT_TEXT, 'displayType' => DT_FIELD, 'default' => '', 'width' => "275px", 'height' => 1, 'label' => _t('Documentation URL'), 'description' => _t('URL pointing to documentation for this relationship bundle. Leave blank if no documentation URL exists.')), 'minRelationshipsPerRow' => array('formatType' => FT_NUMBER, 'displayType' => DT_FIELD, 'width' => 5, 'height' => 1, 'default' => '', 'label' => _t('Minimum number of relationships of this kind to be associated with an item. '), 'description' => _t('If set to 0 a delete button will allow a cataloguer to clear all relationships.  If set to 1 or more, it will not be possible to delete all relationships once the minimum is established. Note that this is only a user interface limitations rather than constraints on the underlying data model.')), 'maxRelationshipsPerRow' => array('formatType' => FT_NUMBER, 'displayType' => DT_FIELD, 'width' => 5, 'height' => 1, 'default' => '', 'label' => _t('Maximum number of relationships of this kind that can be associated with an item'), 'description' => _t('The extent of repeatability for the relationship will match the number entered here. Note that this is only a user interface limitations rather than constraints on the underlying data model.')));
                 if ($vs_bundle == 'ca_list_items') {
                     $va_additional_settings['restrict_to_lists'] = array('formatType' => FT_TEXT, 'displayType' => DT_SELECT, 'showVocabularies' => true, 'width' => "275px", 'height' => "125px", 'takesLocale' => false, 'default' => '', 'label' => _t('Restrict to list'), 'description' => _t('Restricts display to items from the specified list(s). Leave all unselected for no restriction.'));
                 }
                 if (in_array($vs_bundle, array('ca_places', 'ca_list_items', 'ca_storage_locations'))) {
                     $va_additional_settings['useHierarchicalBrowser'] = array('formatType' => FT_TEXT, 'displayType' => DT_CHECKBOXES, 'width' => "10", 'height' => "1", 'takesLocale' => false, 'default' => '1', 'label' => _t('Use hierarchy browser?'), 'description' => _t('If checked a hierarchical browser will be used to select related items instead of an auto-complete lookup.'));
                     $va_additional_settings['hierarchicalBrowserHeight'] = array('formatType' => FT_TEXT, 'displayType' => DT_FIELD, 'width' => "10", 'height' => "1", 'takesLocale' => false, 'default' => '200px', 'label' => _t('Height of hierarchical browser'), 'description' => _t('Height of hierarchical browser.'));
                 }
                 if ($vs_bundle == 'ca_movements' && $t_instance->tableName() == 'ca_objects') {
                     $va_additional_settings['showCurrentOnly'] = array('formatType' => FT_TEXT, 'displayType' => DT_CHECKBOXES, 'width' => "10", 'height' => "1", 'takesLocale' => false, 'default' => '1', 'label' => _t('Show current only?'), 'description' => _t('If checked only current movements are displayed.'));
                 }
                 if ($vs_bundle == 'ca_objects' && $t_instance->tableName() == 'ca_movements') {
                     $va_additional_settings['showCurrentOnly'] = array('formatType' => FT_TEXT, 'displayType' => DT_CHECKBOXES, 'width' => "10", 'height' => "1", 'takesLocale' => false, 'default' => '1', 'label' => _t('Show current only?'), 'description' => _t('If checked only current objects are displayed.'));
                 }
                 if ($vs_bundle == 'ca_movements' && $t_instance->tableName() == 'ca_storage_locations') {
                     $va_additional_settings['showCurrentOnly'] = array('formatType' => FT_TEXT, 'displayType' => DT_CHECKBOXES, 'width' => "10", 'height' => "1", 'takesLocale' => false, 'default' => '1', 'label' => _t('Show current only?'), 'description' => _t('If checked only current movements are displayed.'));
                 }
                 if ($vs_bundle == 'ca_storage_locations' && $t_instance->tableName() == 'ca_movements') {
                     $va_additional_settings['showCurrentOnly'] = array('formatType' => FT_TEXT, 'displayType' => DT_CHECKBOXES, 'width' => "10", 'height' => "1", 'takesLocale' => false, 'default' => '1', 'label' => _t('Show current only?'), 'description' => _t('If checked only current objects are displayed.'));
                 }
                 if ($vs_bundle == 'ca_storage_locations' && $t_instance->tableName() == 'ca_objects') {
                     $va_additional_settings['showCurrentOnly'] = array('formatType' => FT_TEXT, 'displayType' => DT_CHECKBOXES, 'width' => "10", 'height' => "1", 'takesLocale' => false, 'default' => '1', 'label' => _t('Show current only?'), 'description' => _t('If checked only current storage locations are displayed.'));
                 }
                 if ($vs_bundle == 'ca_objects' && $t_instance->tableName() == 'ca_storage_locations') {
                     $va_additional_settings['showCurrentOnly'] = array('formatType' => FT_TEXT, 'displayType' => DT_CHECKBOXES, 'width' => "10", 'height' => "1", 'takesLocale' => false, 'default' => '1', 'label' => _t('Show current only?'), 'description' => _t('If checked only current objects are displayed.'));
                 }
                 if ($t_instance->tableName() == 'ca_objects' && in_array($vs_bundle, array('ca_list_items'))) {
                     $va_additional_settings['restrictToTermsRelatedToCollection'] = array('formatType' => FT_TEXT, 'displayType' => DT_CHECKBOXES, 'width' => "10", 'height' => "1", 'takesLocale' => false, 'default' => '0', 'label' => _t('Restrict to checklist of terms from related collections?'), 'description' => _t('Will restrict checklist to those terms applied to related collections.'));
                     $va_additional_settings['restrictToTermsOnCollectionWithRelationshipType'] = array('formatType' => FT_TEXT, 'displayType' => DT_SELECT, 'useRelationshipTypeList' => 'ca_objects_x_collections', 'width' => "275px", 'height' => "75px", 'takesLocale' => false, 'default' => '', 'label' => _t('Restrict checklist to terms related to collection as'), 'description' => _t('Will restrict checklist to terms related to collections with the specified relationship type. Leave all unselected for no restriction.'));
                     $va_additional_settings['restrictToTermsOnCollectionUseRelationshipType'] = array('formatType' => FT_TEXT, 'displayType' => DT_SELECT, 'useRelationshipTypeList' => 'ca_objects_x_vocabulary_terms', 'width' => "275px", 'height' => "1", 'takesLocale' => false, 'default' => '', 'label' => _t('Checked collection term relationship type'), 'description' => _t('Specified the relationship used to relate collection-restricted terms to this object.'));
                 }
                 if (!$t_rel->hasField('type_id')) {
                     unset($va_additional_settings['restrict_to_types']);
                 }
                 if (sizeof($va_path) == 3) {
                     if ($t_link = $this->_DATAMODEL->getInstanceByTableName($va_path[1], true)) {
                         if (!$t_link->hasField('type_id')) {
                             unset($va_additional_settings['restrict_to_relationship_types']);
                             unset($va_additional_settings['useFixedRelationshipType']);
                         }
                     }
                 }
                 break;
             case 'special':
                 if (in_array($vs_bundle, array('hierarchy_location', 'hierarchy_navigation'))) {
                     $va_additional_settings = array('open_hierarchy' => array('formatType' => FT_NUMBER, 'displayType' => DT_CHECKBOXES, 'width' => "4", 'height' => "1", 'takesLocale' => false, 'default' => '1', 'label' => _t('Open hierarchy browser by default'), 'description' => _t('If checked hierarchy browser will be open when form loads.')), 'documentation_url' => array('formatType' => FT_TEXT, 'displayType' => DT_FIELD, 'default' => '', 'width' => "275px", 'height' => 1, 'label' => _t('Documentation URL'), 'description' => _t('URL pointing to documentation for this hierarchy browser. Leave blank if no documentation URL exists.')));
                 } else {
                     switch ($vs_bundle) {
                         case 'ca_commerce_order_history':
                             $va_additional_settings = array('orderType' => array('formatType' => FT_TEXT, 'displayType' => DT_SELECT, 'takesLocale' => false, 'default' => '', 'options' => array(_t('Sales order') => 'O', _t('Loan') => 'L'), 'label' => _t('Type of order'), 'description' => _t('Determines which type of order is displayed.')));
                             break;
                         case 'ca_object_representation_chooser':
                             $va_additional_settings = array('elementCode' => array('formatType' => FT_TEXT, 'displayType' => DT_SELECT, 'takesLocale' => false, 'default' => '', 'showMetadataElementsWithDataType' => 21, 'table' => $pm_table_name_or_num, 'label' => _t('Metadata element'), 'description' => _t('Metadata element to store representation selection in. Must be of type ObjectRepresentation.')));
                             break;
                         case 'ca_objects_components_list':
                             $va_additional_settings = array('displayTemplate' => array('formatType' => FT_TEXT, 'displayType' => DT_FIELD, 'default' => '<l>^ca_objects.preferred_labels.name</l> (^ca_objects.idno)', 'width' => "275px", 'height' => 4, 'label' => _t('Component display template'), 'description' => _t('Layout for component when displayed in list (can include HTML). Element code tags prefixed with the ^ character can be used to represent the value in the template. For example: <i>^ca_objects.idno</i>.')));
                             break;
                         case 'ca_objects_location':
                             $va_additional_settings = array('locationTrackingMode' => array('formatType' => FT_TEXT, 'displayType' => DT_SELECT, 'options' => array(_t('movements') => 'ca_movements', _t('storage location relationships') => 'ca_storage_locations'), 'default' => 'ca_movements', 'width' => "275px", 'height' => 1, 'label' => _t('Track location using'), 'description' => _t('')), 'ca_movements_dateElement' => array('formatType' => FT_TEXT, 'displayType' => DT_SELECT, 'table' => 'ca_movements', 'showMetadataElementsWithDataType' => 2, 'takesLocale' => false, 'default' => '', 'width' => "275px", 'height' => "75px", 'label' => _t('Movement date'), 'description' => _t('')), 'ca_movements_relationshipType' => array('formatType' => FT_TEXT, 'displayType' => DT_SELECT, 'useRelationshipTypeList' => 'ca_movements_x_objects', 'takesLocale' => false, 'default' => '', 'width' => "275px", 'height' => "75px", 'label' => _t('Limit movement tracking to relationship types'), 'description' => _t('')), 'ca_storage_locations_relationshipType' => array('formatType' => FT_TEXT, 'displayType' => DT_SELECT, 'useRelationshipTypeList' => 'ca_objects_x_storage_locations', 'takesLocale' => false, 'default' => '', 'width' => "275px", 'height' => "75px", 'label' => _t('Limit storage location tracking to relationship types'), 'description' => _t('')), 'displayTemplate' => array('formatType' => FT_TEXT, 'displayType' => DT_FIELD, 'default' => '', 'width' => "275px", 'height' => 4, 'label' => _t('Object location display template'), 'description' => _t('Layout for current location of object when displayed in list (can include HTML). The template is evaluated relative to the object-movement or object-storage location relationship that is current. Element code tags prefixed with the ^ character can be used to represent the value in the template. For example: <i>^ca_movements.idno</i>.')), 'historyTemplate' => array('formatType' => FT_TEXT, 'displayType' => DT_FIELD, 'default' => '', 'width' => "275px", 'height' => 4, 'label' => _t('Object location history template'), 'description' => _t('Layout for each previous location of object when displayed in history list (can include HTML). The template is evaluated relative to the object-movement or object-storage location relationship. Element code tags prefixed with the ^ character can be used to represent the value in the template. For example: <i>^ca_movements.idno</i>.')), 'currentLocationColor' => array('formatType' => FT_TEXT, 'displayType' => DT_COLORPICKER, 'takesLocale' => false, 'default' => '#EEEEEE', 'width' => "275px", 'height' => "75px", 'label' => _t('Color for current location'), 'description' => _t('Color to use as highlight for the current location in the location history.')), 'futureLocationColor' => array('formatType' => FT_TEXT, 'displayType' => DT_COLORPICKER, 'takesLocale' => false, 'default' => '#EEEEEE', 'width' => "275px", 'height' => "75px", 'label' => _t('Color for future locations'), 'description' => _t('Color to use as highlight for future locations in the location history.')), 'pastLocationColor' => array('formatType' => FT_TEXT, 'displayType' => DT_COLORPICKER, 'takesLocale' => false, 'default' => '#EEEEEE', 'width' => "275px", 'height' => "75px", 'label' => _t('Color for past locations'), 'description' => _t('Color to use as highlight for the previous locations in the location history.')), 'useHierarchicalBrowser' => array('formatType' => FT_TEXT, 'displayType' => DT_CHECKBOXES, 'width' => "10", 'height' => "1", 'takesLocale' => false, 'default' => '1', 'label' => _t('Use hierarchy browser for storage locations?'), 'description' => _t('If checked a hierarchical browser will be used to select stroage location items instead of an auto-complete lookup.')));
                             break;
                         case 'ca_objects_history':
                             $va_additional_settings = array('ca_object_lots_showTypes' => array('formatType' => FT_TEXT, 'displayType' => DT_SELECT, 'useList' => 'object_lot_types', 'takesLocale' => false, 'default' => '', 'width' => "275px", 'height' => "75px", 'label' => _t('Show lots'), 'description' => _t('')));
                             $va_types = caGetTypeList("ca_object_lots");
                             foreach ($va_types as $vn_type_id => $va_type) {
                                 $va_additional_settings["ca_object_lots_{$va_type['idno']}_dateElement"] = array('formatType' => FT_TEXT, 'displayType' => DT_SELECT, 'table' => 'ca_object_lots', 'showMetadataElementsWithDataType' => 2, 'takesLocale' => false, 'default' => '', 'width' => "275px", 'height' => "75px", 'label' => _t('Lot (%1) date', $va_type['name_singular']), 'description' => _t(''));
                                 $va_additional_settings["ca_object_lots_{$va_type['idno']}_color"] = array('formatType' => FT_TEXT, 'displayType' => DT_COLORPICKER, 'takesLocale' => false, 'default' => '#EEEEEE', 'width' => "275px", 'height' => "75px", 'label' => _t('Color for %1', $va_type['name_singular']), 'description' => _t('Color to use as highlight %1.', $va_type['name_plural']));
                                 $va_additional_settings["ca_object_lots_{$va_type['idno']}_displayTemplate"] = array('formatType' => FT_TEXT, 'displayType' => DT_FIELD, 'default' => '', 'width' => "275px", 'height' => 4, 'label' => _t('Lot (%1) display template', $va_type['name_singular']), 'description' => _t('Layout for lot when displayed in history list (can include HTML). The template is evaluated relative to the lot. Element code tags prefixed with the ^ character can be used to represent the value in the template. For example: <i>^ca_object_lots.idno_stub</i>.'));
                             }
                             $va_additional_settings['ca_occurrences_showTypes'] = array('formatType' => FT_TEXT, 'displayType' => DT_SELECT, 'useList' => 'occurrence_types', 'takesLocale' => false, 'default' => '', 'width' => "275px", 'height' => "75px", 'label' => _t('Show occurrences'), 'description' => _t(''));
                             $va_types = caGetTypeList("ca_occurrences");
                             foreach ($va_types as $vn_type_id => $va_type) {
                                 $va_additional_settings["ca_occurrences_{$va_type['idno']}_dateElement"] = array('formatType' => FT_TEXT, 'displayType' => DT_SELECT, 'table' => 'ca_occurrences', 'showMetadataElementsWithDataType' => 2, 'takesLocale' => false, 'default' => '', 'width' => "275px", 'height' => "75px", 'label' => _t('%1 date', $va_type['name_singular']), 'description' => _t(''));
                                 $va_additional_settings["ca_occurrences_{$va_type['idno']}_color"] = array('formatType' => FT_TEXT, 'displayType' => DT_COLORPICKER, 'takesLocale' => false, 'default' => '#EEEEEE', 'width' => "275px", 'height' => "75px", 'label' => _t('Color for %1', $va_type['name_singular']), 'description' => _t('Color to use as highlight %1.', $va_type['name_plural']));
                                 $va_additional_settings["ca_occurrences_{$va_type['idno']}_displayTemplate"] = array('formatType' => FT_TEXT, 'displayType' => DT_FIELD, 'default' => '', 'width' => "275px", 'height' => 4, 'label' => _t('%1 display template', $va_type['name_singular']), 'description' => _t('Layout for %1 when displayed in history list (can include HTML). The template is evaluated relative to the %1. Element code tags prefixed with the ^ character can be used to represent the value in the template. For example: <i>^ca_occurrences.idno</i>.', $va_type['name_singular']));
                             }
                             $va_additional_settings['ca_movements_showTypes'] = array('formatType' => FT_TEXT, 'displayType' => DT_SELECT, 'useList' => 'movement_types', 'takesLocale' => false, 'default' => '', 'width' => "275px", 'height' => "75px", 'label' => _t('Show movements'), 'description' => _t(''));
                             $va_types = caGetTypeList("ca_movements");
                             foreach ($va_types as $vn_type_id => $va_type) {
                                 $va_additional_settings["ca_movements_{$va_type['idno']}_dateElement"] = array('formatType' => FT_TEXT, 'displayType' => DT_SELECT, 'table' => 'ca_movements', 'showMetadataElementsWithDataType' => 2, 'takesLocale' => false, 'default' => '', 'width' => "275px", 'height' => "75px", 'label' => _t('%1 date', $va_type['name_singular']), 'description' => _t(''));
                                 $va_additional_settings["ca_movements_{$va_type['idno']}_color"] = array('formatType' => FT_TEXT, 'displayType' => DT_COLORPICKER, 'takesLocale' => false, 'default' => '#EEEEEE', 'width' => "275px", 'height' => "75px", 'label' => _t('Color for %1', $va_type['name_singular']), 'description' => _t('Color to use as highlight %1.', $va_type['name_plural']));
                                 $va_additional_settings["ca_movements_{$va_type['idno']}_displayTemplate"] = array('formatType' => FT_TEXT, 'displayType' => DT_FIELD, 'default' => '', 'width' => "275px", 'height' => 4, 'label' => _t('%1 display template', $va_type['name_singular']), 'description' => _t('Layout for %1 when displayed in history list (can include HTML). The template is evaluated relative to the %1. Element code tags prefixed with the ^ character can be used to represent the value in the template. For example: <i>^ca_movements.idno</i>.', $va_type['name_singular']));
                             }
                             $va_additional_settings['ca_loans_showTypes'] = array('formatType' => FT_TEXT, 'displayType' => DT_SELECT, 'useList' => 'loan_types', 'takesLocale' => false, 'default' => '', 'width' => "275px", 'height' => "75px", 'label' => _t('Show loans'), 'description' => _t(''));
                             $va_types = caGetTypeList("ca_loans");
                             foreach ($va_types as $vn_type_id => $va_type) {
                                 $va_additional_settings["ca_loans_{$va_type['idno']}_dateElement"] = array('formatType' => FT_TEXT, 'displayType' => DT_SELECT, 'table' => 'ca_loans', 'showMetadataElementsWithDataType' => 2, 'takesLocale' => false, 'default' => '', 'width' => "275px", 'height' => "75px", 'label' => _t('%1 date', $va_type['name_singular']), 'description' => _t(''));
                                 $va_additional_settings["ca_loans_{$va_type['idno']}_color"] = array('formatType' => FT_TEXT, 'displayType' => DT_COLORPICKER, 'takesLocale' => false, 'default' => '#EEEEEE', 'width' => "275px", 'height' => "75px", 'label' => _t('Color for %1', $va_type['name_singular']), 'description' => _t('Color to use as highlight %1.', $va_type['name_plural']));
                                 $va_additional_settings["ca_loans_{$va_type['idno']}_displayTemplate"] = array('formatType' => FT_TEXT, 'displayType' => DT_FIELD, 'default' => '', 'width' => "275px", 'height' => 4, 'label' => _t('%1 display template', $va_type['name_singular']), 'description' => _t('Layout for %1 when displayed in history list (can include HTML). The template is evaluated relative to the %1. Element code tags prefixed with the ^ character can be used to represent the value in the template. For example: <i>^ca_loans.idno</i>.', $va_type['name_singular']));
                             }
                             $va_additional_settings += array('ca_storage_locations_showRelationshipTypes' => array('formatType' => FT_TEXT, 'displayType' => DT_SELECT, 'useRelationshipTypeList' => 'ca_objects_x_storage_locations', 'takesLocale' => false, 'default' => '', 'width' => "275px", 'height' => "75px", 'label' => _t('Show storage locations'), 'description' => _t('Show storage locations with selected relationship types.')), 'ca_storage_locations_color' => array('formatType' => FT_TEXT, 'displayType' => DT_COLORPICKER, 'takesLocale' => false, 'default' => '#EEEEEE', 'width' => "275px", 'height' => "75px", 'label' => _t('Color for storage location'), 'description' => _t('Color to use as highlight storage location.')), 'ca_storage_locations_displayTemplate' => array('formatType' => FT_TEXT, 'displayType' => DT_FIELD, 'default' => '', 'width' => "275px", 'height' => 4, 'label' => _t('Storage location display template'), 'description' => _t('Layout for storage location when displayed in history list (can include HTML). The template is evaluated relative to the object-storage location relationship. Element code tags prefixed with the ^ character can be used to represent the value in the template. For example: <i>^ca_object_lots.idno_stub</i>.')), 'showDeaccessionInformation' => array('formatType' => FT_NUMBER, 'displayType' => DT_CHECKBOXES, 'width' => "4", 'height' => "1", 'takesLocale' => false, 'default' => '1', 'label' => _t('Show deaccession information'), 'description' => _t('If clicked deaccession information will be shown in the history.')), 'deaccession_color' => array('formatType' => FT_TEXT, 'displayType' => DT_COLORPICKER, 'takesLocale' => false, 'default' => '#EEEEEE', 'width' => "275px", 'height' => "75px", 'label' => _t('Color for deaccession'), 'description' => _t('Color to use as highlight deaccession.')), 'deaccession_displayTemplate' => array('formatType' => FT_TEXT, 'displayType' => DT_FIELD, 'default' => '', 'width' => "275px", 'height' => 4, 'label' => _t('Deaccession display template'), 'description' => _t('Layout for deaccession information when displayed in history list (can include HTML). The template is evaluated relative to the object. Element code tags prefixed with the ^ character can be used to represent the value in the template. For example: <i>^ca_objects.deaccession_notes</i>.')));
                             break;
                     }
                     $va_additional_settings['documentation_url'] = array('formatType' => FT_TEXT, 'displayType' => DT_FIELD, 'default' => '', 'width' => "275px", 'height' => 1, 'label' => _t('Documentation URL'), 'description' => _t('URL pointing to documentation. Leave blank if no documentation URL exists.'));
                 }
                 break;
             default:
                 $va_additional_settings = array();
                 break;
         }
         $t_placement->setSettingDefinitionsForPlacement($va_additional_settings);
         $vs_display = "<div id='uiEditorBundle_{$vs_table}_{$vs_bundle_proc}'><span class='bundleDisplayEditorPlacementListItemTitle'>" . caUcFirstUTF8Safe($t_instance->getProperty('NAME_SINGULAR')) . "</span> " . ($vs_label = $t_instance->getDisplayLabel($vs_table . '.' . $vs_bundle_proc)) . "</div>";
         $va_available_bundles[$vs_display][$vs_bundle] = array('bundle' => $vs_bundle, 'display' => $vs_display, 'description' => $vs_description = $t_instance->getDisplayDescription($vs_table . '.' . $vs_bundle), 'settingsForm' => $t_placement->getHTMLSettingForm(array('id' => $vs_bundle . '_0_')), 'settings' => $va_additional_settings);
         TooltipManager::add("#uiEditorBundle_{$vs_table}_{$vs_bundle_proc}", "<h2>{$vs_label}</h2>" . _t("Bundle name") . ": {$vs_bundle_proc}<br />" . (strlen($vs_description) > 0 ? _t("Description") . ": {$vs_description}<br />" : ""));
     }
     ksort($va_available_bundles);
     $va_sorted_bundles = array();
     foreach ($va_available_bundles as $vs_k => $va_val) {
         foreach ($va_val as $vs_real_key => $va_info) {
             $va_sorted_bundles[$vs_real_key] = $va_info;
         }
     }
     return $va_sorted_bundles;
 }
示例#6
0
 public static function reload_service_values($po_opts = null)
 {
     $va_infoservice_elements = ca_metadata_elements::getElementsAsList(false, null, null, true, false, false, array(__CA_ATTRIBUTE_VALUE_INFORMATIONSERVICE__));
     $o_db = new Db();
     foreach ($va_infoservice_elements as $va_element) {
         $qr_values = $o_db->query("\n\t\t\t\t\tSELECT * FROM ca_attribute_values\n\t\t\t\t\tWHERE element_id = ?\n\t\t\t\t", $va_element['element_id']);
         print CLIProgressBar::start($qr_values->numRows(), "Reloading values for element code " . $va_element['element_code']);
         $t_value = new ca_attribute_values();
         while ($qr_values->nextRow()) {
             $o_val = new InformationServiceAttributeValue($qr_values->getRow());
             $vs_uri = $o_val->getUri();
             print CLIProgressBar::next();
             // inc before first continuation point
             if (!$vs_uri || !strlen($vs_uri)) {
                 continue;
             }
             if (!$t_value->load($qr_values->get('value_id'))) {
                 continue;
             }
             $t_value->editValue($vs_uri);
             if ($t_value->numErrors() > 0) {
                 print _t('There were errors updating an attribute row: ') . join(' ', $t_value->getErrors());
             }
         }
         print CLIProgressBar::finish();
     }
     return true;
 }
示例#7
0
 /**
  * Reprocess media
  */
 public static function reprocess_media($po_opts = null)
 {
     require_once __CA_LIB_DIR__ . "/core/Db.php";
     require_once __CA_MODELS_DIR__ . "/ca_object_representations.php";
     $o_db = new Db();
     $t_rep = new ca_object_representations();
     $t_rep->setMode(ACCESS_WRITE);
     $va_mimetypes = ($vs_mimetypes = $po_opts->getOption("mimetypes")) ? explode(",", $vs_mimetypes) : array();
     $va_versions = ($vs_versions = $po_opts->getOption("versions")) ? explode(",", $vs_versions) : array();
     $va_kinds = ($vs_kinds = $po_opts->getOption("kinds")) ? explode(",", $vs_kinds) : array();
     if (!is_array($va_kinds) || !sizeof($va_kinds)) {
         $va_kinds = array('all');
     }
     $va_kinds = array_map('strtolower', $va_kinds);
     if (in_array('all', $va_kinds) || in_array('ca_object_representations', $va_kinds)) {
         if (!($vn_start = (int) $po_opts->getOption('start_id'))) {
             $vn_start = null;
         }
         if (!($vn_end = (int) $po_opts->getOption('end_id'))) {
             $vn_end = null;
         }
         if ($vn_id = (int) $po_opts->getOption('id')) {
             $vn_start = $vn_id;
             $vn_end = $vn_id;
         }
         $va_ids = array();
         if ($vs_ids = (string) $po_opts->getOption('ids')) {
             if (sizeof($va_tmp = explode(",", $vs_ids))) {
                 foreach ($va_tmp as $vn_id) {
                     if ((int) $vn_id > 0) {
                         $va_ids[] = (int) $vn_id;
                     }
                 }
             }
         }
         $vs_sql_where = null;
         $va_params = array();
         if (sizeof($va_ids)) {
             $vs_sql_where = "WHERE representation_id IN (?)";
             $va_params[] = $va_ids;
         } else {
             if ($vn_start > 0 && $vn_end > 0 && $vn_start <= $vn_end || $vn_start > 0 && $vn_end == null) {
                 $vs_sql_where = "WHERE representation_id >= ?";
                 $va_params[] = $vn_start;
                 if ($vn_end) {
                     $vs_sql_where .= " AND representation_id <= ?";
                     $va_params[] = $vn_end;
                 }
             }
         }
         $qr_reps = $o_db->query("\n\t\t\t\t\tSELECT * \n\t\t\t\t\tFROM ca_object_representations \n\t\t\t\t\t{$vs_sql_where}\n\t\t\t\t\tORDER BY representation_id\n\t\t\t\t", $va_params);
         print CLIProgressBar::start($qr_reps->numRows(), _t('Re-processing representation media'));
         while ($qr_reps->nextRow()) {
             $va_media_info = $qr_reps->getMediaInfo('media');
             $vs_original_filename = $va_media_info['ORIGINAL_FILENAME'];
             print CLIProgressBar::next(1, _t("Re-processing %1", $vs_original_filename ? $vs_original_filename . " (" . $qr_reps->get('representation_id') . ")" : $qr_reps->get('representation_id')));
             $vs_mimetype = $qr_reps->getMediaInfo('media', 'original', 'MIMETYPE');
             if (sizeof($va_mimetypes)) {
                 foreach ($va_mimetypes as $vs_mimetype_pattern) {
                     if (!preg_match("!^{$vs_mimetype_pattern}!", $vs_mimetype)) {
                         continue 2;
                     }
                 }
             }
             $t_rep->load($qr_reps->get('representation_id'));
             $t_rep->set('media', $qr_reps->getMediaPath('media', 'original'), array('original_filename' => $vs_original_filename));
             if (sizeof($va_versions)) {
                 $t_rep->update(array('updateOnlyMediaVersions' => $va_versions));
             } else {
                 $t_rep->update();
             }
             if ($t_rep->numErrors()) {
                 CLIUtils::addError(_t("Error processing representation media: %1", join('; ', $t_rep->getErrors())));
             }
         }
         print CLIProgressBar::finish();
     }
     if (in_array('all', $va_kinds) || in_array('ca_attributes', $va_kinds)) {
         // get all Media elements
         $va_elements = ca_metadata_elements::getElementsAsList(false, null, null, true, false, true, array(16));
         // 16=media
         $qr_c = $o_db->query("\n\t\t\t\t\tSELECT count(*) c \n\t\t\t\t\tFROM ca_attribute_values\n\t\t\t\t\tWHERE\n\t\t\t\t\t\telement_id in (?)\n\t\t\t\t", caExtractValuesFromArrayList($va_elements, 'element_id', array('preserveKeys' => false)));
         if ($qr_c->nextRow()) {
             $vn_count = $qr_c->get('c');
         } else {
             $vn_count = 0;
         }
         print CLIProgressBar::start($vn_count, _t('Re-processing attribute media'));
         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);
                     $va_media_info = $t_attr_val->getMediaInfo('value_blob');
                     $vs_original_filename = is_array($va_media_info) ? $va_media_info['ORIGINAL_FILENAME'] : '';
                     print CLIProgressBar::next(1, _t("Re-processing %1", $vs_original_filename ? $vs_original_filename . " ({$vn_value_id})" : $vn_value_id));
                     $t_attr_val->set('value_blob', $t_attr_val->getMediaPath('value_blob', 'original'), array('original_filename' => $vs_original_filename));
                     $t_attr_val->update();
                     if ($t_attr_val->numErrors()) {
                         CLIUtils::addError(_t("Error processing attribute media: %1", join('; ', $t_attr_val->getErrors())));
                     }
                 }
             }
         }
         print CLIProgressBar::finish();
     }
     return true;
 }
示例#8
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;
 }
 public static function getSortableElements($pm_table_name_or_num, $pm_type_name_or_id = null, $pa_options = null)
 {
     $va_elements = ca_metadata_elements::getElementsAsList(false, $pm_table_name_or_num, $pm_type_name_or_id);
     if (!is_array($va_elements) || !sizeof($va_elements)) {
         return array();
     }
     $va_sortable_elements = array();
     $vs_key = caGetOption('indexByElementCode', $pa_options, false) ? 'element_code' : 'element_id';
     foreach ($va_elements as $vn_id => $va_element) {
         if ((int) $va_element['datatype'] === 0) {
             continue;
         }
         if (!isset($va_element['settings']['canBeUsedInSort'])) {
             $va_element['settings']['canBeUsedInSort'] = true;
         }
         if ($va_element['settings']['canBeUsedInSort']) {
             $va_sortable_elements[$va_element[$vs_key]] = $va_element;
         }
     }
     return $va_sortable_elements;
 }