Пример #1
0
 /**
  * "My Account" screen
  */
 function Index()
 {
     if (!$this->request->isLoggedIn()) {
         return;
     }
     $t_order = new ca_commerce_orders();
     $this->view->setVar('t_order', $t_order);
     # -- open orders
     $va_open_orders = $t_order->getOrders(array('user_id' => $this->request->getUserID(), 'order_status' => array('OPEN', 'SUBMITTED', 'AWAITING_PAYMENT', 'IN_PROCESSING', 'PROCESSED', 'PROCESSED_AWAITING_DIGITIZATION', 'FULFILLED', 'REOPENED')));
     $this->view->setVar('open_order_list', $va_open_orders);
     # --- recent orders
     $this->view->setVar('recent_orders_age_threshold', $vn_recent_orders_age_threshold = (int) $this->opo_client_services_config->get('recent_orders_age_threshold'));
     $vn_c = time() - 60 * 60 * 24 * $vn_recent_orders_age_threshold;
     $o_tep = new TimeExpressionParser();
     $o_tep->setUnixTimestamps($vn_c, time());
     $va_recent_orders = $t_order->getOrders(array('user_id' => $this->request->getUserID(), 'created_on' => $o_tep->getText()));
     $this->view->setVar('recent_order_list', $va_recent_orders);
     # -- all orders
     $va_all_orders = $t_order->getOrders(array('user_id' => $this->request->getUserID()));
     $this->view->setVar('all_order_list', $va_all_orders);
     $va_closed_orders = $t_order->getOrders(array('user_id' => $this->request->getUserID(), 'order_status' => array('COMPLETED')));
     $this->view->setVar('closed_order_list', $va_closed_orders);
     $this->render("Account/my_account_html.php");
 }
Пример #2
0
/**
 * Returns date range as a localized string for display, subject to the settings in the app/conf/datetime.conf configuration 
 *
 * @param int $pn_start_timestamp Start of date range, as Unix timestamp
 * @param int $pn_end_timestamp End of date range, as Unix timestamp
 * @param array $pa_options All options supported by TimeExpressionParser::getText() are supported
 *
 * @return string Localized date range expression
 */
function caGetLocalizedDateRange($pn_start_timestamp, $pn_end_timestamp, $pa_options = null)
{
    $o_tep = new TimeExpressionParser();
    $o_tep->setUnixTimestamps($pn_start_timestamp, $pn_end_timestamp);
    return $o_tep->getText($pa_options);
}
Пример #3
0
 /**
  * Get a field value of the table row that is represented by this object.
  *
  * @param string $ps_field field name
  * @param array $pa_options options array; can be omitted.
  * It should be an associative array of boolean (except one of the options) flags. In case that some of the options are not set, they are treated as 'false'.
  * Possible options (keys) are:
  * 		BINARY: return field value as is
  * 		FILTER_HTML_SPECIAL_CHARS: convert all applicable chars to their html entities
  * 		DONT_PROCESS_GLOSSARY_TAGS: ?
  * 		CONVERT_HTML_BREAKS: similar to nl2br()
  * 		convertLineBreaks: same as CONVERT_HTML_BREAKS
  * 		getDirectDate: return raw date value from database if $ps_field adresses a date field, otherwise the value will be parsed using the TimeExpressionParser::getText() method
  * 		getDirectTime: return raw time value from database if $ps_field adresses a time field, otherwise the value will be parsed using the TimeExpressionParser::getText() method
  * 		TIMECODE_FORMAT: set return format for fields representing time ranges possible (string) values: COLON_DELIMITED, HOURS_MINUTES_SECONDS, RAW; data will be passed through floatval() by default
  * 		QUOTE: set return value into quotes
  * 		URL_ENCODE: value will be passed through urlencode()
  * 		ESCAPE_FOR_XML: convert <, >, &, ' and " characters for XML use
  * 		DONT_STRIP_SLASHES: if set to true, return value will not be passed through stripslashes()
  * 		template: formatting string to use for returned value; ^<fieldname> placeholder is used to represent field value in template
  * 		returnAsArray: if true, fields that can return multiple values [currently only <table_name>.children.<field>] will return values in an indexed array; default is false
  * 		returnAllLocales:
  * 		delimiter: if set, value is used as delimiter when fields that can return multiple fields are returned as strings; default is a single space
  * 		convertCodesToDisplayText: if set, id values refering to foreign keys are returned as preferred label text in the current locale
  * 		returnURL: if set then url is returned for media, otherwise an HTML tag for display is returned
  * 		dateFormat: format to return created or lastModified dates in. Valid values are iso8601 or text
  *		checkAccess = array of access values to filter results by; if defined only items with the specified access code(s) are returned. Only supported for table that have an "access" field.
  *		sort = optional field to sort returned values on. The field specifiers are fields with or without table name specified.	 
  *		sort_direction = direction to sort results by, either 'asc' for ascending order or 'desc' for descending order; default is 'asc'	 
  */
 public function get($ps_field, $pa_options = null)
 {
     if (!$ps_field) {
         return null;
     }
     if (!is_array($pa_options)) {
         $pa_options = array();
     }
     $vb_return_as_array = caGetOption('returnAsArray', $pa_options, false);
     $vb_return_with_structure = caGetOption('returnWithStructure', $pa_options, false);
     $vb_return_all_locales = caGetOption('returnAllLocales', $pa_options, false);
     $vs_delimiter = caGetOption('delimiter', $pa_options, ' ');
     if (($vb_return_with_structure || $vb_return_all_locales) && !$vb_return_as_array) {
         $vb_return_as_array = true;
     }
     $vn_row_id = $this->getPrimaryKey();
     if ($vb_return_as_array && $vb_return_as_array) {
         $vn_locale_id = $this->hasField('locale_id') ? $this->get('locale_id') : null;
     }
     $va_tmp = explode('.', $ps_field);
     if (sizeof($va_tmp) > 1) {
         if ($va_tmp[0] === $this->tableName()) {
             //
             // Return created on or last modified
             //
             if (in_array($va_tmp[1], array('created', 'lastModified'))) {
                 if ($vb_return_as_array) {
                     return $va_tmp[1] == 'lastModified' ? $this->getLastChangeTimestamp() : $this->getCreationTimestamp();
                 } else {
                     $va_data = $va_tmp[1] == 'lastModified' ? $this->getLastChangeTimestamp() : $this->getCreationTimestamp();
                     $vs_subfield = isset($va_tmp[2]) && isset($va_data[$va_tmp[2]]) ? $va_tmp[2] : 'timestamp';
                     $vm_val = $va_data[$vs_subfield];
                     if ($vs_subfield == 'timestamp') {
                         $o_tep = new TimeExpressionParser();
                         $o_tep->setUnixTimestamps($vm_val, $vm_val);
                         $vm_val = $o_tep->getText($pa_options);
                     }
                     return $vm_val;
                 }
             }
             //
             // Generalized get
             //
             $va_field_info = $this->getFieldInfo($va_tmp[1]);
             switch (sizeof($va_tmp)) {
                 case 2:
                     // support <table_name>.<field_name> syntax
                     $ps_field = $va_tmp[1];
                     break;
                 default:
                     // > 2 elements
                     // media field?
                     if ($va_field_info['FIELD_TYPE'] === FT_MEDIA && !isset($pa_options['returnAsArray']) && !$pa_options['returnAsArray']) {
                         $o_media_settings = new MediaProcessingSettings($va_tmp[0], $va_tmp[1]);
                         $va_versions = $o_media_settings->getMediaTypeVersions('*');
                         $vs_version = $va_tmp[2];
                         if (!isset($va_versions[$vs_version])) {
                             $va_available_versions = array_keys($va_versions);
                             $vs_version = $va_tmp[2] = array_shift($va_available_versions);
                         }
                         if (isset($va_tmp[3])) {
                             return $this->getMediaInfo($va_tmp[1], $vs_version, 'width');
                         } else {
                             if (isset($pa_options['returnURL']) && $pa_options['returnURL']) {
                                 return $this->getMediaUrl($va_tmp[1], $vs_version, $pa_options);
                             } else {
                                 return $this->getMediaTag($va_tmp[1], $vs_version, $pa_options);
                             }
                         }
                     }
                     if ($va_tmp[1] == 'parent' && $this->isHierarchical() && ($vn_parent_id = $this->get($this->getProperty('HIERARCHY_PARENT_ID_FLD')))) {
                         $t_instance = $this->getAppDatamodel()->getInstanceByTableNum($this->tableNum());
                         if (!$t_instance->load($vn_parent_id)) {
                             return $vb_return_as_array ? array() : null;
                         } else {
                             unset($va_tmp[1]);
                             $va_tmp = array_values($va_tmp);
                             if ($vb_return_as_array) {
                                 if ($vb_return_all_locales) {
                                     return array($vn_row_id => array($vn_locale_id => array($t_instance->get(join('.', $va_tmp)))));
                                 } else {
                                     return array($vn_row_id => $t_instance->get(join('.', $va_tmp)));
                                 }
                             } else {
                                 return $t_instance->get(join('.', $va_tmp));
                             }
                         }
                     } else {
                         if ($va_tmp[1] == 'children' && $this->isHierarchical()) {
                             $vb_check_access = is_array($pa_options['checkAccess']) && $this->hasField('access');
                             $va_sort = isset($pa_options['sort']) ? $pa_options['sort'] : null;
                             if (!is_array($va_sort) && $va_sort) {
                                 $va_sort = array($va_sort);
                             }
                             if (!is_array($va_sort)) {
                                 $va_sort = array();
                             }
                             $vs_sort_direction = isset($pa_options['sort_direction']) && in_array(strtolower($pa_options['sort_direction']), array('asc', 'desc')) ? strtolower($pa_options['sort_direction']) : 'asc';
                             unset($va_tmp[1]);
                             // remove 'children' from field path
                             $va_tmp = array_values($va_tmp);
                             $vs_childless_path = join('.', $va_tmp);
                             $va_data = array();
                             $va_children_ids = $this->getHierarchyChildren(null, array('idsOnly' => true));
                             if (is_array($va_children_ids) && sizeof($va_children_ids)) {
                                 $t_instance = $this->getAppDatamodel()->getInstanceByTableNum($this->tableNum());
                                 if ($va_tmp[1] == $this->primaryKey() && !$vs_sort) {
                                     foreach ($va_children_ids as $vn_child_id) {
                                         $va_data[$vn_child_id] = $vn_child_id;
                                     }
                                 } else {
                                     if (method_exists($this, "makeSearchResult")) {
                                         // Use SearchResult lazy loading when available
                                         $vs_table = $this->tableName();
                                         $vs_pk = $vs_table . '.' . $this->primaryKey();
                                         $qr_children = $this->makeSearchResult($this->tableName(), $va_children_ids);
                                         while ($qr_children->nextHit()) {
                                             if ($vb_check_access && !in_array($qr_children->get("{$vs_table}.access"), $pa_options['checkAccess'])) {
                                                 continue;
                                             }
                                             $vn_child_id = $qr_children->get($vs_pk);
                                             $vs_sort_key = '';
                                             foreach ($va_sort as $vs_sort) {
                                                 $vs_sort_key .= $vs_sort ? $qr_children->get($vs_sort) : 0;
                                             }
                                             if (!is_array($va_data[$vs_sort_key])) {
                                                 $va_data[$vs_sort_key] = array();
                                             }
                                             if ($vb_return_as_array) {
                                                 $va_data[$vs_sort_key][$vn_child_id] = array_shift($qr_children->get($vs_childless_path, array_merge($pa_options, array('returnAsArray' => $vb_return_as_array, 'returnAllLocales' => $vb_return_all_locales))));
                                             } else {
                                                 $va_data[$vs_sort_key][$vn_child_id] = $qr_children->get($vs_childless_path, array_merge($pa_options, array('returnAsArray' => false, 'returnAllLocales' => false)));
                                             }
                                         }
                                         ksort($va_data);
                                         if ($vs_sort_direction && $vs_sort_direction == 'desc') {
                                             $va_data = array_reverse($va_data);
                                         }
                                         $va_sorted_data = array();
                                         foreach ($va_data as $vs_sort_key => $va_items) {
                                             foreach ($va_items as $vs_k => $vs_v) {
                                                 $va_sorted_data[] = $vs_v;
                                             }
                                         }
                                         $va_data = $va_sorted_data;
                                     } else {
                                         // Fall-back to loading records row-by-row (slow)
                                         foreach ($va_children_ids as $vn_child_id) {
                                             if ($t_instance->load($vn_child_id)) {
                                                 if ($vb_check_access && !in_array($t_instance->get("access"), $pa_options['checkAccess'])) {
                                                     continue;
                                                 }
                                                 $vs_sort_key = $vs_sort ? $t_instance->get($vs_sort) : 0;
                                                 if (!is_array($va_data[$vs_sort_key])) {
                                                     $va_data[$vs_sort_key] = array();
                                                 }
                                                 if ($vb_return_as_array) {
                                                     $va_data[$vs_sort_key][$vn_child_id] = array_shift($t_instance->get($vs_childless_path, array_merge($pa_options, array('returnAsArray' => $vb_return_as_array, 'returnAllLocales' => $vb_return_all_locales))));
                                                 } else {
                                                     $va_data[$vs_sort_key][$vn_child_id] = $t_instance->get($vs_childless_path, array_merge($pa_options, array('returnAsArray' => false, 'returnAllLocales' => false)));
                                                 }
                                             }
                                         }
                                         ksort($va_data);
                                         if ($vs_sort_direction && $vs_sort_direction == 'desc') {
                                             $va_data = array_reverse($va_data);
                                         }
                                         $va_sorted_data = array();
                                         foreach ($va_data as $vs_sort_key => $va_items) {
                                             foreach ($va_items as $vs_k => $vs_v) {
                                                 $va_sorted_data[] = $vs_v;
                                             }
                                         }
                                         $va_data = $va_sorted_data;
                                     }
                                 }
                             }
                             if ($vb_return_as_array) {
                                 return $va_data;
                             } else {
                                 return join($vs_delimiter, $va_data);
                             }
                         }
                     }
                     break;
             }
         } else {
             $va_rels = $this->getRelatedItems($va_tmp[0]);
             $va_vals = array();
             if (is_array($va_rels)) {
                 foreach ($va_rels as $va_rel_item) {
                     if (isset($va_rel_item[$va_tmp[1]])) {
                         $va_vals[] = $va_rel_item[$va_tmp[1]];
                     }
                 }
                 return $vb_return_as_array ? $va_vals : join($vs_delimiter, $va_vals);
             }
             // can't pull fields from other tables!
             return $vb_return_as_array ? array() : null;
         }
     }
     if (isset($pa_options["BINARY"]) && $pa_options["BINARY"]) {
         return $this->_FIELD_VALUES[$ps_field];
     }
     if (array_key_exists($ps_field, $this->FIELDS)) {
         $ps_field_type = $this->getFieldInfo($ps_field, "FIELD_TYPE");
         if ($this->getFieldInfo($ps_field, 'IS_LIFESPAN')) {
             $pa_options['isLifespan'] = true;
         }
         switch ($ps_field_type) {
             case FT_BIT:
                 $vs_prop = isset($this->_FIELD_VALUES[$ps_field]) ? $this->_FIELD_VALUES[$ps_field] : "";
                 if (isset($pa_options['convertCodesToDisplayText']) && $pa_options['convertCodesToDisplayText']) {
                     $vs_prop = (bool) $vs_prop ? _t('yes') : _t('no');
                 }
                 return $vs_prop;
                 break;
             case FT_TEXT:
             case FT_NUMBER:
             case FT_PASSWORD:
                 $vs_prop = isset($this->_FIELD_VALUES[$ps_field]) ? $this->_FIELD_VALUES[$ps_field] : null;
                 if (isset($pa_options["FILTER_HTML_SPECIAL_CHARS"]) && $pa_options["FILTER_HTML_SPECIAL_CHARS"]) {
                     $vs_prop = htmlentities(html_entity_decode($vs_prop));
                 }
                 //
                 // Convert foreign keys and choice list values to display text is needed
                 //
                 if (isset($pa_options['convertCodesToDisplayText']) && $pa_options['convertCodesToDisplayText'] && ($vs_list_code = $this->getFieldInfo($ps_field, "LIST_CODE"))) {
                     $t_list = new ca_lists();
                     $vs_prop = $t_list->getItemFromListForDisplayByItemID($vs_list_code, $vs_prop);
                 } else {
                     if (isset($pa_options['convertCodesToDisplayText']) && $pa_options['convertCodesToDisplayText'] && ($vs_list_code = $this->getFieldInfo($ps_field, "LIST"))) {
                         $t_list = new ca_lists();
                         if (!($vs_tmp = $t_list->getItemFromListForDisplayByItemValue($vs_list_code, $vs_prop))) {
                             if ($vs_tmp = $this->getChoiceListValue($ps_field, $vs_prop)) {
                                 $vs_prop = $vs_tmp;
                             }
                         } else {
                             $vs_prop = $vs_tmp;
                         }
                     } else {
                         if (isset($pa_options['convertCodesToDisplayText']) && $pa_options['convertCodesToDisplayText'] && $ps_field === 'locale_id' && (int) $vs_prop > 0) {
                             $t_locale = new ca_locales($vs_prop);
                             $vs_prop = $t_locale->getName();
                         } else {
                             if (isset($pa_options['convertCodesToDisplayText']) && $pa_options['convertCodesToDisplayText'] && is_array($va_list = $this->getFieldInfo($ps_field, "BOUNDS_CHOICE_LIST"))) {
                                 foreach ($va_list as $vs_option => $vs_value) {
                                     if ($vs_value == $vs_prop) {
                                         $vs_prop = $vs_option;
                                         break;
                                     }
                                 }
                             }
                         }
                     }
                 }
                 if (isset($pa_options["CONVERT_HTML_BREAKS"]) && $pa_options["CONVERT_HTML_BREAKS"] || isset($pa_options["convertLineBreaks"]) && $pa_options["convertLineBreaks"]) {
                     $vs_prop = caConvertLineBreaks($vs_prop);
                 }
                 break;
             case FT_DATETIME:
             case FT_TIMESTAMP:
             case FT_HISTORIC_DATETIME:
             case FT_HISTORIC_DATE:
             case FT_DATE:
                 $vn_timestamp = isset($this->_FIELD_VALUES[$ps_field]) ? $this->_FIELD_VALUES[$ps_field] : 0;
                 if ($vb_return_with_structure) {
                     $vs_prop = array('start' => $this->_FIELD_VALUES[$ps_field], 'end' => $this->_FIELD_VALUES[$ps_field]);
                 } elseif (caGetOption('GET_DIRECT_DATE', $pa_options, false) || caGetOption('getDirectDate', $pa_options, false) || caGetOption('rawDate', $pa_options, false)) {
                     $vs_prop = $this->_FIELD_VALUES[$ps_field];
                 } elseif (isset($pa_options['sortable']) && $pa_options['sortable']) {
                     $vs_prop = $vn_timestamp . "/" . $vn_timestamp;
                 } else {
                     $o_tep = new TimeExpressionParser();
                     if ($ps_field_type == FT_HISTORIC_DATETIME || $ps_field_type == FT_HISTORIC_DATE) {
                         $o_tep->setHistoricTimestamps($vn_timestamp, $vn_timestamp);
                     } else {
                         $o_tep->setUnixTimestamps($vn_timestamp, $vn_timestamp);
                     }
                     if ($ps_field_type == FT_DATE || $ps_field_type == FT_HISTORIC_DATE) {
                         $vs_prop = $o_tep->getText(array_merge(array('timeOmit' => true), $pa_options));
                     } else {
                         $vs_prop = $o_tep->getText($pa_options);
                     }
                 }
                 break;
             case FT_TIME:
                 if ($vb_return_with_structure) {
                     $vs_prop = array('start' => $this->_FIELD_VALUES[$ps_field], 'end' => $this->_FIELD_VALUES[$ps_field]);
                 } elseif (caGetOption('GET_DIRECT_TIME', $pa_options, false) || caGetOption('getDirectTime', $pa_options, false) || caGetOption('rawTime', $pa_options, false)) {
                     $vs_prop = $this->_FIELD_VALUES[$ps_field];
                 } else {
                     $o_tep = new TimeExpressionParser();
                     $vn_timestamp = isset($this->_FIELD_VALUES[$ps_field]) ? $this->_FIELD_VALUES[$ps_field] : 0;
                     $o_tep->setTimes($vn_timestamp, $vn_timestamp);
                     $vs_prop = $o_tep->getText($pa_options);
                 }
                 break;
             case FT_DATERANGE:
             case FT_HISTORIC_DATERANGE:
                 $vs_start_field_name = $this->getFieldInfo($ps_field, "START");
                 $vs_end_field_name = $this->getFieldInfo($ps_field, "END");
                 $vn_start_date = isset($this->_FIELD_VALUES[$vs_start_field_name]) ? $this->_FIELD_VALUES[$vs_start_field_name] : null;
                 $vn_end_date = isset($this->_FIELD_VALUES[$vs_end_field_name]) ? $this->_FIELD_VALUES[$vs_end_field_name] : null;
                 if ($vb_return_with_structure) {
                     $vs_prop = array('start' => $vn_start_date, 'end' => $vn_end_date);
                 } elseif (!caGetOption('GET_DIRECT_DATE', $pa_options, false) && !caGetOption('getDirectDate', $pa_options, false) && !caGetOption('rawDate', $pa_options, false)) {
                     $o_tep = new TimeExpressionParser();
                     if ($ps_field_type == FT_HISTORIC_DATERANGE) {
                         $o_tep->setHistoricTimestamps($vn_start_date, $vn_end_date);
                     } else {
                         $o_tep->setUnixTimestamps($vn_start_date, $vn_end_date);
                     }
                     $vs_prop = $o_tep->getText($pa_options);
                 } elseif (isset($pa_options['sortable']) && $pa_options['sortable']) {
                     $vs_prop = $vn_start_date;
                     //."/".$vn_timestamp;
                 } else {
                     $vs_prop = $vn_start_date;
                     //array($vn_start_date, $vn_end_date);
                 }
                 break;
             case FT_TIMERANGE:
                 $vs_start_field_name = $this->getFieldInfo($ps_field, "START");
                 $vs_end_field_name = $this->getFieldInfo($ps_field, "END");
                 $vn_start_date = isset($this->_FIELD_VALUES[$vs_start_field_name]) ? $this->_FIELD_VALUES[$vs_start_field_name] : null;
                 $vn_end_date = isset($this->_FIELD_VALUES[$vs_end_field_name]) ? $this->_FIELD_VALUES[$vs_end_field_name] : null;
                 if ($vb_return_with_structure) {
                     $vs_prop = array('start' => $vn_start_date, 'end' => $vn_end_date);
                 } elseif (!caGetOption('GET_DIRECT_TIME', $pa_options, false) && !caGetOption('getDirectTime', $pa_options, false) && !caGetOption('rawTime', $pa_options, false)) {
                     $o_tep = new TimeExpressionParser();
                     $o_tep->setTimes($vn_start_date, $vn_end_date);
                     $vs_prop = $o_tep->getText($pa_options);
                 } else {
                     $vs_prop = array($vn_start_date, $vn_end_date);
                 }
                 break;
             case FT_TIMECODE:
                 $o_tp = new TimecodeParser();
                 $o_tp->setParsedValueInSeconds($this->_FIELD_VALUES[$ps_field]);
                 $vs_prop = $o_tp->getText(isset($pa_options["TIMECODE_FORMAT"]) ? $pa_options["TIMECODE_FORMAT"] : null);
                 break;
             case FT_MEDIA:
             case FT_FILE:
                 if ($vb_return_with_structure || $pa_options["USE_MEDIA_FIELD_VALUES"]) {
                     if (isset($pa_options["USE_MEDIA_FIELD_VALUES"]) && $pa_options["USE_MEDIA_FIELD_VALUES"]) {
                         $vs_prop = $this->_FIELD_VALUES[$ps_field];
                     } else {
                         $vs_prop = isset($this->_SET_FILES[$ps_field]['tmp_name']) && $this->_SET_FILES[$ps_field]['tmp_name'] ? $this->_SET_FILES[$ps_field]['tmp_name'] : $this->_FIELD_VALUES[$ps_field];
                     }
                 } else {
                     $va_versions = $this->getMediaVersions($ps_field);
                     $vs_tag = $this->getMediaTag($ps_field, array_shift($va_versions));
                     if ($vb_return_as_array) {
                         return array($vs_tag);
                     } else {
                         return $vs_tag;
                     }
                 }
                 break;
             case FT_VARS:
                 $vs_prop = isset($this->_FIELD_VALUES[$ps_field]) && $this->_FIELD_VALUES[$ps_field] ? $this->_FIELD_VALUES[$ps_field] : null;
                 break;
         }
         if (isset($pa_options["QUOTE"]) && $pa_options["QUOTE"]) {
             $vs_prop = $this->quote($ps_field, $vs_prop);
         }
     } else {
         $this->postError(710, _t("'%1' does not exist in this object", $ps_field), "BaseModel->get()");
         return $vb_return_as_array ? array() : null;
     }
     if (isset($pa_options["URL_ENCODE"]) && $pa_options["URL_ENCODE"]) {
         $vs_prop = urlEncode($vs_prop);
     }
     if (isset($pa_options["ESCAPE_FOR_XML"]) && $pa_options["ESCAPE_FOR_XML"]) {
         $vs_prop = caEscapeForXML($vs_prop);
     }
     if (!(isset($pa_options["DONT_STRIP_SLASHES"]) && $pa_options["DONT_STRIP_SLASHES"])) {
         if (is_string($vs_prop)) {
             $vs_prop = stripSlashes($vs_prop);
         }
     }
     if (isset($pa_options["template"]) && $pa_options["template"]) {
         $vs_template_with_substitution = str_replace("^" . $ps_field, $vs_prop, $pa_options["template"]);
         $vs_prop = str_replace("^" . $this->tableName() . "." . $ps_field, $vs_prop, $vs_template_with_substitution);
     }
     if ($vb_return_as_array) {
         if ($vb_return_all_locales) {
             return array($vn_row_id => array($vn_locale_id => array($vs_prop)));
         } else {
             return array($vn_row_id => $vs_prop);
         }
     } else {
         return $vs_prop;
     }
 }
 /**
  * Returns array of users associated with the currently loaded row. The array
  * is key'ed on user user user_id; each value is an  array containing information about the user. Array keys are:
  *			user_id			[user_id for user]
  *			user_name	[name of user]
  *			code				[short alphanumeric code identifying the group]
  *			description	[text description of group]
  *
  * @return array List of groups associated with the currently loaded row
  */
 public function getUsers($pa_options = null)
 {
     if (!($vn_id = (int) $this->getPrimaryKey())) {
         return null;
     }
     if (!($vs_user_rel_table = $this->getProperty('USERS_RELATIONSHIP_TABLE'))) {
         return null;
     }
     $vs_pk = $this->primaryKey();
     if (!is_array($pa_options)) {
         $pa_options = array();
     }
     $vb_return_for_bundle = isset($pa_options['returnAsInitialValuesForBundle']) && $pa_options['returnAsInitialValuesForBundle'] ? true : false;
     $o_dm = Datamodel::load();
     $t_rel = $o_dm->getInstanceByTableName($vs_user_rel_table);
     $vb_supports_date_restrictions = (bool) $t_rel->hasField('effective_date');
     $o_tep = new TimeExpressionParser();
     $o_db = $this->getDb();
     $qr_res = $o_db->query("\n\t\t\t\tSELECT u.*, r.*\n\t\t\t\tFROM {$vs_user_rel_table} r\n\t\t\t\tINNER JOIN ca_users AS u ON u.user_id = r.user_id\n\t\t\t\tWHERE\n\t\t\t\t\tr.{$vs_pk} = ?\n\t\t\t", $vn_id);
     $va_users = array();
     $va_user_ids = $qr_res->getAllFieldValues("user_id");
     if ($qr_users = $this->makeSearchResult('ca_users', $va_user_ids)) {
         $va_initial_values = caProcessRelationshipLookupLabel($qr_users, new ca_users(), array('stripTags' => true));
     } else {
         $va_initial_values = array();
     }
     $qr_res->seek(0);
     while ($qr_res->nextRow()) {
         $va_row = array();
         foreach (array('user_id', 'user_name', 'fname', 'lname', 'email', 'sdatetime', 'edatetime', 'access') as $vs_f) {
             $va_row[$vs_f] = $qr_res->get($vs_f);
         }
         if ($vb_supports_date_restrictions) {
             $o_tep->init();
             $o_tep->setUnixTimestamps($qr_res->get('sdatetime'), $qr_res->get('edatetime'));
             $va_row['effective_date'] = $o_tep->getText();
         }
         if ($vb_return_for_bundle) {
             $va_row['label'] = $va_initial_values[$va_row['user_id']]['label'];
             $va_row['id'] = $va_row['user_id'];
             $va_users[(int) $qr_res->get('relation_id')] = $va_row;
         } else {
             $va_users[(int) $qr_res->get('user_id')] = $va_row;
         }
     }
     return $va_users;
 }
Пример #5
0
 public function DownloadUserReport()
 {
     $vs_download_format = $this->request->getParameter("download_format", pString);
     if (!$vs_download_format) {
         $vs_download_format = "tab";
     }
     $this->view->setVar("download_format", $vs_download_format);
     switch ($vs_download_format) {
         default:
         case "tab":
             $this->view->setVar("file_extension", "txt");
             $this->view->setVar("mimetype", "text/plain");
             $vs_delimiter_col = "\t";
             $vs_delimiter_row = "\n";
             break;
             # -----------------------------------
         # -----------------------------------
         case "csv":
             $this->view->setVar("file_extension", "txt");
             $this->view->setVar("mimetype", "text/plain");
             $vs_delimiter_col = ",";
             $vs_delimiter_row = "\n";
             break;
             # -----------------------------------
     }
     $o_db = new Db();
     $t_user = new ca_users();
     $va_fields = array("lname", "fname", "email", "user_name", "userclass", "active", "last_login");
     $va_profile_prefs = $t_user->getValidPreferences('profile');
     $va_profile_prefs_labels = array();
     foreach ($va_profile_prefs as $vs_pref) {
         $va_pref_info = $t_user->getPreferenceInfo($vs_pref);
         $va_profile_prefs_labels[$vs_pref] = $va_pref_info["label"];
     }
     $qr_users = $o_db->query("SELECT * FROM ca_users ORDER BY user_id DESC");
     if ($qr_users->numRows()) {
         $va_rows = array();
         # --- headings
         $va_row = array();
         # --- headings for field values
         foreach ($va_fields as $vs_field) {
             switch ($vs_field) {
                 case "last_login":
                     $va_row[] = _t("Last login");
                     break;
                     # --------------------
                 # --------------------
                 default:
                     $va_row[] = $t_user->getDisplayLabel("ca_users." . $vs_field);
                     break;
                     # --------------------
             }
         }
         # --- headings for profile prefs
         foreach ($va_profile_prefs_labels as $vs_pref => $vs_pref_label) {
             $va_row[] = $vs_pref_label;
         }
         $va_rows[] = join($vs_delimiter_col, $va_row);
         reset($va_fields);
         reset($va_profile_prefs_labels);
         $o_tep = new TimeExpressionParser();
         while ($qr_users->nextRow()) {
             $va_row = array();
             # --- fields
             foreach ($va_fields as $vs_field) {
                 switch ($vs_field) {
                     case "userclass":
                         $va_row[] = $t_user->getChoiceListValue($vs_field, $qr_users->get("ca_users." . $vs_field));
                         break;
                         # -----------------------
                     # -----------------------
                     case "active":
                         $va_row[] = $qr_users->get("ca_users." . $vs_field) == 1 ? _t("active") : _t("not active");
                         break;
                         # -----------------------
                     # -----------------------
                     case "last_login":
                         //if (!is_array($va_vars = $qr_users->getVars('vars'))) { $va_vars = array(); }
                         if (!is_array($va_vars = $qr_users->getVars('volatile_vars'))) {
                             $va_vars = array();
                         }
                         if ($va_vars['last_login'] > 0) {
                             $o_tep->setUnixTimestamps($va_vars['last_login'], $va_vars['last_login']);
                             $va_row[] = $o_tep->getText();
                         } else {
                             $va_row[] = "-";
                         }
                         break;
                         # -----------------------
                     # -----------------------
                     default:
                         if ($vs_download_format == "csv") {
                             $va_row[] = str_replace(",", "-", $qr_users->get("ca_users." . $vs_field));
                         } else {
                             $va_row[] = $qr_users->get("ca_users." . $vs_field);
                         }
                         break;
                         # -----------------------
                 }
             }
             # --- profile prefs
             foreach ($va_profile_prefs_labels as $vs_pref => $vs_pref_label) {
                 $t_user->load($qr_users->get("ca_users.user_id"));
                 $va_row[] = $t_user->getPreference($vs_pref);
             }
             $va_rows[] = join($vs_delimiter_col, $va_row);
         }
         $vs_file_contents = join($vs_delimiter_row, $va_rows);
         $this->view->setVar("file_contents", $vs_file_contents);
         return $this->render('user_report.php');
     } else {
         $this->notification->addNotification(_t("There are no users"), __NOTIFICATION_TYPE_INFO__);
         $this->ListUsers();
         return;
     }
 }
Пример #6
0
?>
					</th>
					<th class="list-header-unsorted">
						<?php 
print _t('Last login');
?>
					</th>
					<th class="{sorter: false} list-header-nosort">&nbsp;</th>
				</tr>
			</thead>
			<tbody>
<?php 
$o_tep = new TimeExpressionParser();
foreach ($va_user_list as $va_user) {
    if ($va_user['last_login'] > 0) {
        $o_tep->setUnixTimestamps($va_user['last_login'], $va_user['last_login']);
    }
    ?>
			<tr>
				<td>
					<?php 
    print $va_user['user_name'];
    ?>
				</td>
				<td>
					<?php 
    print $va_user['lname'] . ', ' . $va_user['fname'];
    ?>
				</td>
				<td>
					<?php 
 public function renderWidget($ps_widget_id, &$pa_settings)
 {
     parent::renderWidget($ps_widget_id, $pa_settings);
     global $g_ui_locale_id;
     if (!in_array($pa_settings['display_type'], BaseWidget::$s_widget_settings['recentlyCreatedWidget']["display_type"]["options"])) {
         return "";
     }
     if ($t_table = $this->opo_datamodel->getInstanceByTableName($pa_settings['display_type'], true)) {
         $vo_db = new Db();
         $o_tep = new TimeExpressionParser();
         if ($pa_settings["display_limit"] && intval($pa_settings["display_limit"]) > 0 && intval($pa_settings["display_limit"]) < 1000) {
             $vn_limit = intval($pa_settings["display_limit"]);
         } else {
             $vn_limit = 11;
         }
         $vs_deleted_sql = '';
         if ($t_table->hasField('deleted')) {
             $vs_deleted_sql = " AND (t.deleted = 0) ";
         }
         $vs_idno_sql = '';
         if ($t_table->hasField('idno')) {
             $vs_idno_sql = "t.idno,";
         } elseif ($t_table->hasField('idno_stub')) {
             $vs_idno_sql = "t.idno_stub,";
         }
         $vs_sql = "\n\t\t\t\t\tSELECT\n\t\t\t\t\t\tt.{$t_table->primaryKey()},\n\t\t\t\t\t\tlt.{$t_table->getLabelDisplayField()},\n\t\t\t\t\t\t{$vs_idno_sql}\n\t\t\t\t\t\tlt.locale_id\n\t\t\t\t\tFROM\n\t\t\t\t\t\t{$t_table->tableName()} t\n\t\t\t\t\tINNER JOIN\n\t\t\t\t\t\t{$t_table->getLabelTableName()} AS lt ON t.{$t_table->primaryKey()} = lt.{$t_table->primaryKey()}\n\t\t\t\t\tWHERE\n\t\t\t\t\t\t(lt.is_preferred = 1) \n\t\t\t\t\t\t{$vs_deleted_sql}\n\t\t\t\t\tORDER BY\n\t\t\t\t\t\tt.{$t_table->primaryKey()} DESC\n\t\t\t\t\tLIMIT\n\t\t\t\t\t\t{$vn_limit}\n\t\t\t\t";
         $qr_records = $vo_db->query($vs_sql);
         $va_item_list = array();
         while ($qr_records->nextRow() && sizeof($va_item_list) < intval($pa_settings["display_limit"])) {
             if (isset($va_item_list[$qr_records->get($t_table->primaryKey())])) {
                 // we only overwrite if we hit one with UI locale (i.e. the first hit wins if there is no label in UI locale)
                 if (!(intval($qr_records->get($t_table->getLabelTableName() . ".locale_id")) == intval($g_ui_locale_id))) {
                     continue;
                 }
             }
             $vs_sql = "\n\t\t\t\t\t\tSELECT\n\t\t\t\t\t\t\tlog_datetime\n\t\t\t\t\t\tFROM\n\t\t\t\t\t\t\tca_change_log\n\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\tlogged_table_num = " . (int) $t_table->tableNum() . "\n\t\t\t\t\t\tAND\n\t\t\t\t\t\t\tchangetype = 'I'\n\t\t\t\t\t\tAND\n\t\t\t\t\t\t\tlogged_row_id = " . (int) $qr_records->get($t_table->primaryKey()) . "\n\t\t\t\t\t";
             $qr_create_date = $vo_db->query($vs_sql);
             if ($qr_create_date->nextRow()) {
                 $vn_time_created = intval($qr_create_date->get("log_datetime"));
                 $o_tep->setUnixTimestamps($vn_time_created, $vn_time_created);
                 $va_options = $this->opb_dont_show_timestamp ? array('timeOmit' => true) : null;
                 $vs_datetime_text = $o_tep->getText($va_options);
             } else {
                 $vs_datetime_text = '';
             }
             $va_item_list[$qr_records->get($t_table->primaryKey())] = array("display" => $qr_records->get($t_table->getLabelTableName() . "." . $t_table->getLabelDisplayField()), "idno" => $qr_records->get("idno"), "idno_stub" => $qr_records->get("idno_stub"), "locale_id" => $qr_records->get($t_table->getLabelTableName() . ".locale_id"), "datetime" => $vs_datetime_text);
         }
         if (!(intval($pa_settings["height_px"]) > 30 && intval($pa_settings["height_px"]) < 1000)) {
             // if value is not within reasonable boundaries, set it to default
             $this->opo_view->setVar("height_px", 270);
         } else {
             $this->opo_view->setVar("height_px", intval($pa_settings["height_px"]));
         }
         $this->opo_view->setVar('item_list', $va_item_list);
         $this->opo_view->setVar('table_num', $this->opo_datamodel->getTableNum($t_table->tableName()));
         $this->opo_view->setVar('request', $this->getRequest());
         $this->opo_view->setVar('table_display', $this->opa_table_display_names[$t_table->tableName()]);
         $this->opo_view->setVar('idno_display', isset($pa_settings["display_idno"]) ? $pa_settings["display_idno"] : FALSE);
         return $this->opo_view->render('main_html.php');
     }
 }
Пример #8
0
 /**
  * 
  *
  * @param int $pn_user_id user_id of user to check set access for
  * @param int $pn_access type of access required. Use __CA_SET_READ_ACCESS__ for read-only access or __CA_SET_EDIT_ACCESS__ for editing (full) access
  * @param int $pa_set_ids The ids of the sets to check. If omitted then currently loaded set will be checked. Can also be set to a single integer.
  * @return int
  */
 public function getAccessExpirationDates($pn_user_id, $pn_access, $pa_set_ids = null, $pa_options = null)
 {
     if (!is_array($pa_set_ids)) {
         if (!$pa_set_ids) {
             $pa_set_ids = $this->get('set_id');
         }
         if (!$pa_set_ids) {
             return null;
         }
         $pa_set_ids = array($pa_set_ids);
     }
     foreach ($pa_set_ids as $vn_i => $vn_set_id) {
         $pa_set_ids[$vn_i] = (int) $vn_set_id;
     }
     $o_db = $this->getDb();
     $qr_res = $o_db->query("\n\t\t\tSELECT sxg.set_id, sxg.sdatetime, sxg.edatetime, s.user_id\n\t\t\tFROM ca_sets_x_user_groups sxg\n\t\t\tINNER JOIN ca_user_groups AS ug ON sxg.group_id = ug.group_id\n\t\t\tINNER JOIN ca_users_x_groups AS uxg ON uxg.group_id = ug.group_id\n\t\t\tINNER JOIN ca_sets AS s ON s.set_id = sxg.set_id\n\t\t\tWHERE \n\t\t\t\t(sxg.access >= ?) AND (uxg.user_id = ?) AND (sxg.set_id IN (?)) AND (s.deleted = 0)\n\t\t\t\tAND\n\t\t\t\t(\n\t\t\t\t\tsxg.sdatetime <= " . time() . " AND sxg.edatetime >= " . time() . "\n\t\t\t\t)\n\t\t", (int) $pn_access, (int) $pn_user_id, $pa_set_ids);
     $o_tep = new TimeExpressionParser();
     $va_expiration_times = array();
     while ($qr_res->nextRow()) {
         if ($qr_res->get('user_id') == $pn_user_id) {
             $va_expiration_times[$vn_set_id] = -1;
             continue;
         }
         $vn_set_id = $qr_res->get('set_id');
         $vn_exp = $qr_res->get('edatetime');
         if (!isset($va_expiration_times[$vn_set_id]) || $va_expiration_times[$vn_set_id] < $vn_exp) {
             $o_tep->setUnixTimestamps($vn_exp, $vn_exp);
             $vs_text = $o_tep->getText();
             $va_expiration_times[$vn_set_id] = $vs_text;
         }
     }
     $qr_res = $o_db->query("\n\t\t\tSELECT sxu.set_id, sxu.sdatetime, sxu.edatetime, s.user_id\n\t\t\tFROM ca_sets_x_users sxu\n\t\t\tINNER JOIN ca_users AS u ON sxu.user_id = u.user_id\n\t\t\tINNER JOIN ca_sets AS s ON s.set_id = sxu.set_id\n\t\t\tWHERE \n\t\t\t\t(sxu.access >= ?) AND (u.user_id = ?) AND (sxu.set_id IN (?)) AND (s.deleted = 0)\n\t\t\t\tAND\n\t\t\t\t(\n\t\t\t\t\tsxu.sdatetime <= " . time() . " AND sxu.edatetime >= " . time() . "\n\t\t\t\t)\n\t\t", (int) $pn_access, (int) $pn_user_id, $pa_set_ids);
     while ($qr_res->nextRow()) {
         if ($qr_res->get('user_id') == $pn_user_id) {
             $va_expiration_times[$vn_set_id] = -1;
             continue;
         }
         $vn_set_id = $qr_res->get('set_id');
         $vn_exp = $qr_res->get('edatetime');
         if (!isset($va_expiration_times[$vn_set_id]) || $va_expiration_times[$vn_set_id] < $vn_exp) {
             $o_tep->setUnixTimestamps($vn_exp, $vn_exp);
             $vs_text = $o_tep->getText();
             $va_expiration_times[$vn_set_id] = $vs_text;
         }
     }
     return $va_expiration_times;
 }
Пример #9
0
 /**
  *
  */
 public function getComments($ps_mode = null, $pn_limit = null, $pa_options = null)
 {
     $o_db = $this->getDb();
     $vs_where = '';
     switch ($ps_mode) {
         case 'moderated':
             $vs_where = "WHERE cic.moderated_on IS NOT NULL";
             break;
         case 'unmoderated':
             $vs_where = "WHERE cic.moderated_on IS NULL";
             break;
     }
     if (intval($pn_limit) > 0) {
         $vs_limit = " LIMIT " . intval($pn_limit);
     }
     $o_tep = new TimeExpressionParser();
     $qr_res = $o_db->query("\n\t\t\tSELECT cic.*, u.user_id, u.fname, u.lname, u.email user_email\n\t\t\tFROM ca_item_comments cic\n\t\t\tLEFT JOIN ca_users AS u ON u.user_id = cic.user_id\n\t\t\t{$vs_where} ORDER BY cic.created_on DESC {$vs_limit}\n\t\t");
     $o_datamodel = $this->getAppDatamodel();
     $va_comments = array();
     while ($qr_res->nextRow()) {
         $vn_datetime = $qr_res->get('created_on');
         $o_tep->setUnixTimestamps($vn_datetime, $vn_datetime);
         $va_row = $qr_res->getRow();
         $va_row['created_on'] = $o_tep->getText();
         $t_table = $o_datamodel->getInstanceByTableNum($qr_res->get('table_num'), true);
         if ($t_table->load($qr_res->get('row_id'))) {
             $va_row['commented_on'] = $t_table->getLabelForDisplay(false);
             if ($vs_idno = $t_table->get('idno')) {
                 $va_row['commented_on'] .= ' [' . $vs_idno . ']';
             }
         }
         foreach (array("media1", "media2", "media3", "media4") as $vs_media_field) {
             $va_media_versions = array();
             $va_media_versions = $qr_res->getMediaVersions($vs_media_field);
             $va_media = array();
             if (is_array($va_media_versions) && sizeof($va_media_versions) > 0) {
                 foreach ($va_media_versions as $vs_version) {
                     $va_image_info = array();
                     $va_image_info = $qr_res->getMediaInfo($vs_media_field, $vs_version);
                     $va_image_info["TAG"] = $qr_res->getMediaTag($vs_media_field, $vs_version);
                     $va_image_info["URL"] = $qr_res->getMediaUrl($vs_media_field, $vs_version);
                     $va_media[$vs_version] = $va_image_info;
                 }
                 $va_row[$vs_media_field] = $va_media;
             }
         }
         $va_comments[] = $va_row;
     }
     return $va_comments;
 }
Пример #10
0
 /**
  * Returns all tags attached to any kind of row.
  * If the optional $pb_moderation_status parameter is passed then only tags matching the criteria will be returned:
  *		Passing $pb_moderation_status = TRUE will cause only moderated tags to be returned
  *		Passing $pb_moderation_status = FALSE will cause only unmoderated tags to be returned
  *		If you want both moderated and unmoderated tags to be returned then omit the parameter or pass a null value
  *
  * @param bool $pb_moderation_status To return only unmoderated tags set to FALSE; to return only moderated tags set to TRUE; to return all tags set to null or omit
  * @param int $pn_limit Maximum number of tags to return. Default is 0 - no limit.
  * 
  * @return array
  */
 public function getAllTags($pb_moderation_status = null, $pn_limit = 0)
 {
     $o_db = $this->getDb();
     $vs_where = '';
     if ($pb_moderation_status === true) {
         $vs_where = ' WHERE cixt.moderated_on IS NULL';
     } elseif ($pb_moderation_status === false) {
         $vs_where = ' WHERE cixt.moderated_on IS NOT NULL';
     } else {
         $vs_where = '';
     }
     $vs_limit = "";
     if (intval($pn_limit) > 0) {
         $vs_limit = " LIMIT " . intval($pn_limit);
     }
     $o_tep = new TimeExpressionParser();
     $qr_res = $o_db->query("\n\t\t\tSELECT cit.*, cixt.*, u.user_id, u.fname, u.lname, u.email user_email\n\t\t\tFROM ca_items_x_tags cixt\n\t\t\tLEFT JOIN ca_users AS u ON u.user_id = cixt.user_id\n\t\t\tINNER JOIN ca_item_tags AS cit ON cit.tag_id = cixt.tag_id\n\t\t\t{$vs_where} ORDER BY cixt.created_on DESC {$vs_limit}\n\t\t");
     $o_datamodel = $this->getAppDatamodel();
     $va_tags = array();
     while ($qr_res->nextRow()) {
         $vn_datetime = $qr_res->get('created_on');
         $o_tep->setUnixTimestamps($vn_datetime, $vn_datetime);
         $va_row = $qr_res->getRow();
         $va_row['created_on'] = $o_tep->getText();
         $t_table = $o_datamodel->getInstanceByTableNum($qr_res->get('table_num'), true);
         if ($t_table->load($qr_res->get('row_id'))) {
             $va_row['item_tagged'] = $t_table->getLabelForDisplay(false);
             if ($vs_idno = $t_table->get('idno')) {
                 $va_row['item_tagged'] .= ' [' . $vs_idno . ']';
             }
         }
         $va_tags[] = $va_row;
     }
     return $va_tags;
 }
Пример #11
0
 /**
  * Implementation of primary get() functionality
  */
 private function _get($ps_field, $pa_options = null)
 {
     if (!is_array($pa_options)) {
         $pa_options = array();
     }
     if (isset($pa_options['restrictToType']) && (!isset($pa_options['restrict_to_type']) || !$pa_options['restrict_to_type'])) {
         $pa_options['restrict_to_type'] = $pa_options['restrictToType'];
     }
     if (isset($pa_options['restrictToTypes']) && (!isset($pa_options['restrict_to_types']) || !$pa_options['restrict_to_types'])) {
         $pa_options['restrict_to_types'] = $pa_options['restrictToTypes'];
     }
     if (isset($pa_options['restrictToRelationshipTypes']) && (!isset($pa_options['restrict_to_relationship_types']) || !$pa_options['restrict_to_relationship_types'])) {
         $pa_options['restrict_to_relationship_types'] = $pa_options['restrictToRelationshipTypes'];
     }
     if (isset($pa_options['excludeType']) && (!isset($pa_options['exclude_type']) || !$pa_options['exclude_type'])) {
         $pa_options['exclude_type'] = $pa_options['excludeType'];
     }
     if (isset($pa_options['excludeTypes']) && (!isset($pa_options['exclude_types']) || !$pa_options['exclude_types'])) {
         $pa_options['exclude_types'] = $pa_options['excludeTypes'];
     }
     if (isset($pa_options['excludeRelationshipTypes']) && (!isset($pa_options['exclude_relationship_types']) || !$pa_options['exclude_relationship_types'])) {
         $pa_options['exclude_relationship_types'] = $pa_options['excludeRelationshipTypes'];
     }
     $vb_return_as_array = caGetOption('returnAsArray', $pa_options, false, array('castTo' => 'bool'));
     $vb_return_all_locales = caGetOption('returnAllLocales', $pa_options, false, array('castTo' => 'bool'));
     $vb_return_as_link = caGetOption('returnAsLink', $pa_options, false, array('castTo' => 'bool'));
     $vs_return_as_link_text = caGetOption('returnAsLinkText', $pa_options, '');
     $vs_return_as_link_target = caGetOption('returnAsLinkTarget', $pa_options, '');
     $vs_return_as_link_attributes = caGetOption('returnAsLinkAttributes', $pa_options, array(), array('castTo' => 'array'));
     $va_original_path_components = $va_path_components = $this->getFieldPathComponents($ps_field);
     if ($va_path_components['table_name'] != $this->ops_table_name) {
         $vs_access_chk_key = $va_path_components['table_name'] . ($va_path_components['field_name'] ? '.' . $va_path_components['field_name'] : '');
     } else {
         $vs_access_chk_key = $va_path_components['field_name'];
     }
     if (caGetBundleAccessLevel($this->ops_table_name, $vs_access_chk_key) == __CA_BUNDLE_ACCESS_NONE__) {
         return null;
     }
     $vo_request = caGetOption('request', $pa_options, null);
     unset($pa_options['request']);
     // first see if the search engine can provide the field value directly (fastest)
     if (!(($vs_value = $this->opo_engine_result->get($ps_field, $pa_options)) === false)) {
         if ($vb_return_as_array) {
             if ($vb_return_all_locales) {
                 return array(1 => $vs_value);
             } else {
                 return array($vs_value);
             }
         } else {
             return $vs_value;
         }
     }
     $vs_template = caGetOption('template', $pa_options, null);
     $vs_delimiter = caGetOption('delimiter', $pa_options, ' ');
     $vs_hierarchical_delimiter = caGetOption('hierarchicalDelimiter', $pa_options, ' ');
     if ($vb_return_all_locales && !$vb_return_as_array) {
         $vb_return_as_array = true;
     }
     if (isset($pa_options['sort']) && !is_array($pa_options['sort'])) {
         $pa_options['sort'] = array($pa_options['sort']);
     }
     if (is_array($va_sort_fields = isset($pa_options['sort']) && is_array($pa_options['sort']) ? $pa_options['sort'] : null)) {
         foreach ($va_sort_fields as $vn_i => $vs_sort_fld) {
             if (!trim($vs_sort_fld)) {
                 unset($va_sort_fields[$vn_i]);
             }
         }
     }
     $vn_row_id = $this->opo_engine_result->get($this->ops_table_pk);
     // try to lazy load (slower)...
     //
     // Are we getting timestamp (created on or last modified) info?
     //
     if ($va_path_components['table_name'] == $this->ops_table_name && $va_path_components['field_name'] == 'created') {
         if (!isset($this->opa_timestamp_cache['created_on'][$this->ops_table_name][$vn_row_id])) {
             $this->prefetchChangeLogData($this->ops_table_name, $this->opo_engine_result->currentRow(), $this->getOption('prefetch'));
         }
         if ($vb_return_as_array) {
             return $this->opa_timestamp_cache['created_on'][$this->ops_table_name][$vn_row_id];
         } else {
             $vs_subfield = $va_path_components['subfield_name'] ? $va_path_components['subfield_name'] : 'timestamp';
             $vm_val = $this->opa_timestamp_cache['created_on'][$this->ops_table_name][$vn_row_id][$vs_subfield];
             if ($vs_subfield == 'timestamp') {
                 $o_tep = new TimeExpressionParser();
                 $o_tep->setUnixTimestamps($vm_val, $vm_val);
                 $vm_val = $o_tep->getText($pa_options);
             }
             return $vm_val;
         }
     }
     if ($va_path_components['table_name'] == $this->ops_table_name && $va_path_components['field_name'] == 'lastModified') {
         if (!isset($this->opa_timestamp_cache['last_changed'][$this->ops_table_name][$vn_row_id])) {
             $this->prefetchChangeLogData($this->ops_table_name, $this->opo_engine_result->currentRow(), $this->getOption('prefetch'));
         }
         if ($vb_return_as_array) {
             return $this->opa_timestamp_cache['last_changed'][$this->ops_table_name][$vn_row_id];
         } else {
             $vs_subfield = $va_path_components['subfield_name'] ? $va_path_components['subfield_name'] : 'timestamp';
             $vm_val = $this->opa_timestamp_cache['last_changed'][$this->ops_table_name][$vn_row_id][$vs_subfield];
             if ($vs_subfield == 'timestamp') {
                 $o_tep = new TimeExpressionParser();
                 $o_tep->setUnixTimestamps($vm_val, $vm_val);
                 $vm_val = $o_tep->getText($pa_options);
             }
             return $vm_val;
         }
     }
     if (!($t_instance = $this->opo_datamodel->getInstanceByTableName($va_path_components['table_name'], true))) {
         return null;
     }
     // Bad table
     $t_original_instance = $t_instance;
     // $t_original_instance will always be the as-called subject; optimizations may results in $t_instance being transformed into a different model
     //
     // Simple related table get:
     //			<table>
     //			<table>.related
     //			<table>.hierarchy
     //			<table>.related.hierarchy
     //
     if ($va_path_components['num_components'] == 1 && $va_path_components['table_name'] !== $this->ops_table_name || $va_path_components['num_components'] == 2 && $va_path_components['field_name'] == 'related' || $va_path_components['num_components'] == 2 && $va_path_components['field_name'] == 'hierarchy' || $va_path_components['num_components'] == 3 && $va_path_components['field_name'] == 'related' && $va_path_components['subfield_name'] == 'hierarchy') {
         if (!($t_table = $this->opo_datamodel->getInstanceByTableName($this->ops_table_name, true))) {
             return null;
         }
         $vb_show_hierarachy = (bool) ($va_path_components['field_name'] == 'hierarchy' && $t_instance->isHierarchical());
         if ($va_path_components['num_components'] == 2) {
             $va_path_components['num_components'] = 1;
             $va_path_components['field_name'] = null;
         }
         $vs_opt_md5 = caMakeCacheKeyFromOptions($pa_options);
         if (!isset($this->opa_rel_prefetch_cache[$va_path_components['table_name']][$vn_row_id][$vs_opt_md5])) {
             $this->prefetchRelated($va_path_components['table_name'], $this->opo_engine_result->currentRow(), $this->getOption('prefetch'), $pa_options);
         }
         $va_related_items = $this->opa_rel_prefetch_cache[$va_path_components['table_name']][$vn_row_id][$vs_opt_md5];
         if (!is_array($va_related_items)) {
             return null;
         }
         if (is_array($va_sort_fields) && sizeof($va_sort_fields)) {
             $va_related_items = caSortArrayByKeyInValue($va_related_items, $va_sort_fields);
         }
         // Return as array
         if ($vs_template) {
             return caProcessTemplateForIDs($vs_template, $this->opo_subject_instance->tableName(), array($vn_row_id), array_merge($pa_options, array('placeholderPrefix' => $va_path_components['field_name'])));
         }
         if ($vb_return_as_array || $vb_return_all_locales) {
             if ($vb_return_all_locales) {
                 $va_related_tmp = array();
                 foreach ($va_related_items as $vn_i => $va_related_item) {
                     $va_related_tmp[$vn_i][$va_related_item['locale_id']] = $va_related_item;
                 }
                 return $va_related_tmp;
             } else {
                 if (!$vs_template && !$va_path_components['field_name']) {
                     return $va_related_items;
                 }
                 $vs_pk = $t_instance->primaryKey();
                 $va_links = array();
                 foreach ($va_related_items as $vn_relation_id => $va_relation_info) {
                     $va_relation_info['labels'] = caExtractValuesByUserLocale(array(0 => $va_relation_info['labels']));
                     if ($vb_return_as_link) {
                         $va_template_opts = array();
                         $va_template_opts['relationshipValues'][$va_relation_info[$vs_pk]][$va_relation_info['relation_id']]['relationship_typename'] = $va_relation_info['relationship_typename'];
                         $vs_text = $vs_template ? caProcessTemplateForIDs($vs_template, $t_instance->tableName(), array($va_relation_info[$vs_pk]), $va_template_opts) : join("; ", $va_relation_info['labels']);
                         $va_link = caCreateLinksFromText(array($vs_text), $va_original_path_components['table_name'], array($va_relation_info[$vs_pk]), $vs_return_as_link_class, $vs_return_as_link_target);
                         $va_links[$vn_relation_id] = array_pop($va_link);
                     } else {
                         $va_related_items[$vn_relation_id]['labels'] = $va_relation_info['labels'];
                     }
                 }
                 if ($vb_return_as_link) {
                     return $va_links;
                 }
                 return $va_related_items;
             }
         } else {
             // Return scalar
             $va_proc_labels = array();
             $va_row_ids = array();
             $vs_rel_pk = $t_instance->primaryKey();
             $va_relationship_values = array();
             foreach ($va_related_items as $vn_relation_id => $va_relation_info) {
                 $va_row_ids[] = $va_relation_info[$vs_rel_pk];
                 $va_relationship_values[$va_relation_info[$vs_rel_pk]][$vn_relation_id] = array('relationship_typename' => $va_relation_info['relationship_typename'], 'relationship_type_id' => $va_relation_info['relationship_type_id'], 'relationship_type_code' => $va_relation_info['relationship_type_code'], 'relationship_typecode' => $va_relation_info['relationship_type_code'], 'label' => $va_relation_info['label']);
             }
             if (!sizeof($va_row_ids)) {
                 return '';
             }
             if (!$vs_template) {
                 $vs_template = "^label";
             }
             $va_template_opts = $pa_options;
             unset($va_template_opts['request']);
             unset($va_template_opts['template']);
             $va_template_opts['returnAsLink'] = false;
             $va_template_opts['returnAsArray'] = true;
             $va_text = caProcessTemplateForIDs($vs_template, $t_instance->tableNum(), $va_row_ids, array_merge($va_template_opts, array('relationshipValues' => $va_relationship_values, 'showHierarchicalLabels' => $vb_show_hierarachy)));
             if ($vb_return_as_link) {
                 $va_links = caCreateLinksFromText($va_text, $va_original_path_components['table_name'], $va_row_ids, $vs_return_as_link_class, $vs_return_as_link_target);
                 return join($vs_delimiter, $va_links);
             }
             return join($vs_delimiter, $va_text);
         }
     }
     $vb_need_parent = false;
     $vb_need_children = false;
     //
     // Transform "preferred_labels" into tables for pre-fetching
     //
     $vb_is_get_for_labels = $vb_return_all_label_values = $vb_get_preferred_labels_only = $vb_get_nonpreferred_labels_only = false;
     if (in_array($va_path_components['field_name'], array('preferred_labels', 'nonpreferred_labels'))) {
         if ($t_instance->getProperty('LABEL_TABLE_NAME')) {
             $vb_get_preferred_labels_only = $va_path_components['field_name'] == 'preferred_labels' ? true : false;
             $vb_get_nonpreferred_labels_only = $va_path_components['field_name'] == 'nonpreferred_labels' ? true : false;
             if ($va_path_components['num_components'] == 2) {
                 // if it's just <table_name>.preferred_labels then return an array of fields from the label table
                 $vb_return_all_label_values = true;
             }
             $va_path_components['table_name'] = $t_instance->getLabelTableName();
             $t_label_instance = $t_instance->getLabelTableInstance();
             if (!$va_path_components['subfield_name'] || !$t_label_instance->hasField($va_path_components['subfield_name'])) {
                 $va_path_components['field_name'] = $t_instance->getLabelDisplayField();
             } else {
                 $va_path_components['field_name'] = $va_path_components['subfield_name'];
             }
             $va_path_components['subfield_name'] = null;
             $va_path_components = $this->getFieldPathComponents($va_path_components['table_name'] . '.' . $va_path_components['field_name']);
             // Ok, convert the table instance to the label table since that's the table we'll be grabbing data from
             $t_instance = $t_label_instance;
             $vb_is_get_for_labels = true;
         }
     }
     //
     // Handle modifiers (parent, children, related, hierarchy) with and without fields
     //
     if ($va_path_components['num_components'] >= 2) {
         switch ($va_path_components['field_name']) {
             case 'parent':
                 if ($t_instance->isHierarchical() && ($vn_parent_id = $this->get($va_path_components['table_name'] . '.' . $t_instance->getProperty('HIERARCHY_PARENT_ID_FLD')))) {
                     //
                     // TODO: support some kind of prefetching of parents?
                     //
                     unset($va_path_components['components'][1]);
                     if ($t_instance->load($vn_parent_id)) {
                         return $t_instance->get(join('.', array_values($va_path_components['components'])), $pa_options);
                     }
                     return null;
                 }
                 break;
             case 'children':
                 if ($t_instance->isHierarchical()) {
                     //unset($va_path_components['components'][1]);	// remove 'children' from field path
                     $vs_field_spec = join('.', array_values($va_path_components['components']));
                     if ($vn_id = $this->get($va_path_components['table_name'] . '.' . $t_instance->primaryKey(), array('returnAsArray' => false))) {
                         if ($t_instance->load($vn_id)) {
                             return $t_instance->get($vs_field_spec, $pa_options);
                         }
                     }
                     return null;
                 }
                 break;
             case 'related':
                 // Regular related table call
                 if ($va_path_components['table_name'] != $this->ops_table_name) {
                     // just remove "related" from name and be on our way
                     $va_tmp = $va_path_components['components'];
                     array_splice($va_tmp, 1, 1);
                     return $this->get(join('.', $va_tmp), $pa_options);
                 }
                 // Self-relations need special handling
                 $vs_opt_md5 = caMakeCacheKeyFromOptions($pa_options);
                 if (!isset($this->opa_rel_prefetch_cache[$va_path_components['table_name']][$vn_row_id][$vs_opt_md5])) {
                     $this->prefetchRelated($va_path_components['table_name'], $this->opo_engine_result->currentRow(), $this->getOption('prefetch'), $pa_options);
                 }
                 $va_related_items = $this->opa_rel_prefetch_cache[$va_path_components['table_name']][$vn_row_id][$vs_opt_md5];
                 if (!($t_table = $this->opo_datamodel->getInstanceByTableName($va_path_components['table_name'], true))) {
                     return null;
                 }
                 $va_ids = array();
                 foreach ($va_related_items as $vn_relation_id => $va_item) {
                     $va_ids[] = $va_item[$t_table->primaryKey()];
                 }
                 $va_vals = array();
                 if ($qr_res = $t_table->makeSearchResult($va_path_components['table_name'], $va_ids)) {
                     $va_tmp = $va_path_components['components'];
                     unset($va_tmp[1]);
                     $vs_rel_field = join('.', $va_tmp);
                     while ($qr_res->nextHit()) {
                         if ($vb_return_as_array) {
                             $va_vals = array_merge($va_vals, $qr_res->get($vs_rel_field, $pa_options));
                         } else {
                             $va_vals[] = $qr_res->get($vs_rel_field, $pa_options);
                         }
                     }
                 }
                 //if (is_array($va_sort_fields) && sizeof($va_sort_fields)) {
                 //	$va_vals = caSortArrayByKeyInValue($va_vals, $va_sort_fields);
                 //}
                 if ($vb_return_as_link) {
                     if (!$vb_return_all_locales) {
                         $va_vals = caCreateLinksFromText($va_vals, $va_original_path_components['table_name'], $va_ids, $vs_return_as_link_class, $vs_return_as_link_target);
                     }
                 }
                 if ($vb_return_as_array) {
                     return $va_vals;
                 } else {
                     return join($vs_delimiter, $va_vals);
                 }
                 break;
             case 'hierarchy':
                 $vn_max_levels_from_bottom = caGetOption('maxLevelsFromBottom', $pa_options, caGetOption('maxLevels', $pa_options, null));
                 $vn_max_levels_from_top = caGetOption('maxLevelsFromTop', $pa_options, null);
                 if ($t_instance->isHierarchical()) {
                     $vs_field_spec = join('.', array_values($va_path_components['components']));
                     $vs_hier_pk_fld = $t_instance->primaryKey();
                     if ($va_ids = $this->get($va_path_components['table_name'] . '.' . $vs_hier_pk_fld, array_merge($pa_options, array('returnAsArray' => true, 'returnAsLink' => false, 'returnAllLocales' => false)))) {
                         $va_vals = array();
                         if ($va_path_components['subfield_name'] == $vs_hier_pk_fld) {
                             foreach ($va_ids as $vn_id) {
                                 // TODO: This is too slow
                                 if ($t_instance->load($vn_id)) {
                                     $va_vals = array_merge($va_vals, $t_instance->get($va_path_components['table_name'] . ".hierarchy." . $vs_hier_pk_fld, array_merge($pa_options, array('returnAsArray' => true))));
                                 }
                             }
                         } else {
                             foreach ($va_ids as $vn_id) {
                                 // TODO: This is too slow
                                 if ($t_instance->load($vn_id)) {
                                     $va_vals = $t_instance->get($vs_field_spec, array_merge($pa_options, array('returnAsArray' => true)));
                                     if (is_array($va_vals)) {
                                         $va_vals = array_reverse($va_vals);
                                     }
                                     // Add/replace hierarchy name
                                     if ($t_instance->getProperty('HIERARCHY_TYPE') == __CA_HIER_TYPE_MULTI_MONO__ && $t_instance->getHierarchyName()) {
                                         $vn_first_key = array_shift(array_keys($va_vals));
                                         if ($vb_return_all_locales) {
                                             $va_vals[$vn_first_key] = array(0 => array($t_instance->getHierarchyName()));
                                         } else {
                                             $va_vals[$vn_first_key] = $t_instance->getHierarchyName();
                                         }
                                     }
                                     if ($vn_max_levels_from_bottom > 0) {
                                         if (($vn_start = sizeof($va_vals) - $vn_max_levels_from_bottom) < 0) {
                                             $vn_start = 0;
                                         }
                                         $va_vals = array_slice($va_vals, $vn_start, $vn_max_levels_from_bottom, true);
                                     } elseif ($vn_max_levels_from_top > 0) {
                                         $va_vals = array_slice($va_vals, 0, $vn_max_levels_from_top, true);
                                     }
                                 }
                             }
                         }
                         if ($vb_return_as_array) {
                             return $va_vals;
                         } else {
                             return join($vs_hierarchical_delimiter, $va_vals);
                         }
                     }
                     return null;
                 }
                 break;
         }
     }
     // If the requested table was not added to the query via SearchEngine::addTable()
     // then auto-add it here. It's better to explicitly add it with addTables() as that call
     // gives you precise control over which fields are autoloaded and also lets you specify limiting criteria
     // for selection of related field data; and it also lets you explicitly define the tables used to join the
     // related table. Autoloading guesses and usually does what you want, but not always.
     if (!isset($this->opa_tables[$va_path_components['table_name']]) || !$this->opa_tables[$va_path_components['table_name']]) {
         $va_join_tables = $this->opo_datamodel->getPath($this->ops_table_name, $va_path_components['table_name']);
         array_shift($va_join_tables);
         // remove subject table
         array_pop($va_join_tables);
         // remove content table (we only need linking tables here)
         $va_join_criteria = array();
         if (is_array($va_primary_ids)) {
             foreach ($va_primary_ids as $vs_t => $va_t_ids) {
                 if (isset($va_join_tables[$vs_t]) && sizeof($va_t_ids) > 0) {
                     $vs_t_pk = $this->opo_datamodel->getTablePrimaryKeyName($vs_t);
                     $va_join_criteria[] = "{$vs_t}.{$vs_t_pk} NOT IN (" . join(",", $va_t_ids) . ")";
                 }
             }
         }
         $this->opa_tables[$va_path_components['table_name']] = array('fieldList' => array($va_path_components['table_name'] . '.*'), 'joinTables' => array_keys($va_join_tables), 'criteria' => $va_join_criteria);
     }
     if ($va_path_components['table_name'] === $this->ops_table_name && !$t_instance->hasField($va_path_components['field_name']) && method_exists($t_instance, 'getAttributes')) {
         //
         // Return attribute values for primary table
         //
         if ($va_path_components['field_name'] && ($t_element = $t_instance->_getElementInstance($va_path_components['field_name']))) {
             $vn_element_id = $t_element->getPrimaryKey();
         } else {
             $vn_element_id = null;
         }
         if (!isset(ca_attributes::$s_get_attributes_cache[$this->opn_table_num . '/' . $vn_row_id][$vn_element_id])) {
             ca_attributes::prefetchAttributes($this->opo_db, $this->opn_table_num, $this->getRowIDsToPrefetch($va_path_components['table_name'], $this->opo_engine_result->currentRow(), $this->getOption('prefetch')), $vn_element_id ? array($vn_element_id) : null, array('dontFetchAlreadyCachedValues' => true));
         }
         if (!$vb_return_as_array && !$vb_return_all_locales) {
             // return scalar
             //
             // Handle "hierarchy" modifier on list elements
             //
             if ($va_hier = $this->_getElementHierarchy($t_instance, $va_path_components)) {
                 return join($vs_hierarchical_delimiter, $va_hier);
             }
             if (isset($pa_options['convertCodesToDisplayText']) && $pa_options['convertCodesToDisplayText'] && $va_path_components['field_name']) {
                 $vs_template = null;
                 if ($va_path_components['subfield_name']) {
                     $va_values = $t_instance->getAttributeDisplayValues($va_path_components['field_name'], $vn_row_id, $pa_options);
                     $va_value_list = array();
                     foreach ($va_values as $vn_id => $va_attr_val_list) {
                         foreach ($va_attr_val_list as $vn_value_id => $va_value_array) {
                             $va_value_list[] = $va_value_array[$va_path_components['subfield_name']];
                         }
                     }
                     return join(" ", $va_value_list);
                 } else {
                     if (isset($pa_options['template'])) {
                         $vs_template = $pa_options['template'];
                     }
                 }
                 unset($pa_options['template']);
                 if (!$vs_template) {
                     $vs_template = "^" . $va_path_components['subfield_name'] ? $va_path_components['subfield_name'] : $va_path_components['field_name'];
                 }
                 return $t_instance->getAttributesForDisplay($va_path_components['field_name'], $vs_template, array_merge(array('row_id' => $vn_row_id), $pa_options));
             }
             if ($t_element && !$va_path_components['subfield_name'] && $t_element->get('datatype') == 0) {
                 return $t_instance->getAttributesForDisplay($va_path_components['field_name'], $vs_template, array_merge($pa_options, array('row_id' => $vn_row_id)));
             } else {
                 if (!$vs_template) {
                     return $t_instance->getRawValue($vn_row_id, $va_path_components['field_name'], $va_path_components['subfield_name'], ',', $pa_options);
                 } else {
                     return caProcessTemplateForIDs($vs_template, $va_path_components['table_name'], array($vn_row_id), array());
                 }
             }
         } else {
             // return array
             //
             // Handle "hierarchy" modifier on list elements
             //
             if ($va_hier = $this->_getElementHierarchy($t_instance, $va_path_components)) {
                 return $va_hier;
             }
             $va_values = $t_instance->getAttributeDisplayValues($va_path_components['field_name'], $vn_row_id, $pa_options);
             if ($vs_template && !$vb_return_all_locales) {
                 $va_values_tmp = array();
                 foreach ($va_values as $vn_i => $va_value_list) {
                     foreach ($va_value_list as $vn_attr_id => $va_attr_data) {
                         $va_values_tmp[] = caProcessTemplateForIDs($vs_template, $va_path_components['table_name'], array($vn_row_id), array_merge($pa_options, array('placeholderPrefix' => $va_path_components['field_name'])));
                     }
                 }
                 $va_values = $va_values_tmp;
             } else {
                 if ($va_path_components['subfield_name']) {
                     if ($vb_return_all_locales) {
                         foreach ($va_values as $vn_row_id => $va_values_by_locale) {
                             foreach ($va_values_by_locale as $vn_locale_id => $va_value_list) {
                                 foreach ($va_value_list as $vn_attr_id => $va_attr_data) {
                                     $va_values[$vn_row_id][$vn_locale_id][$vn_attr_id] = $va_attr_data[$va_path_components['subfield_name']];
                                 }
                             }
                         }
                     } else {
                         $va_processed_value_list = array();
                         foreach ($va_values as $vn_row_id => $va_value_list) {
                             foreach ($va_value_list as $vn_attr_id => $va_attr_data) {
                                 $va_processed_value_list[$vn_attr_id] = $va_attr_data[$va_path_components['subfield_name']];
                             }
                         }
                         $va_values = $va_processed_value_list;
                     }
                 } else {
                     if (!$vb_return_all_locales) {
                         $va_values = array_shift($va_values);
                     }
                 }
             }
             return $va_values;
         }
     } else {
         // Prefetch intrinsic fields in primary and related tables
         if (!isset($this->opa_prefetch_cache[$va_path_components['table_name']][$vn_row_id])) {
             $this->prefetch($va_path_components['table_name'], $this->opo_engine_result->currentRow(), $this->getOption('prefetch'), $pa_options);
             // try to prefetch ahead (usually doesn't hurt and very often helps performance)
         }
     }
     $va_return_values = array();
     if ($va_path_components['table_name'] !== $this->ops_table_name && $va_path_components['field_name'] !== 'relationship_typename' && !$t_instance->hasField($va_path_components['field_name']) && method_exists($t_instance, 'getAttributes')) {
         //
         // Return metadata attributes in a related table
         //
         $vs_pk = $t_instance->primaryKey();
         $vb_is_related = $this->ops_table_name !== $va_path_components['table_name'];
         $va_ids = array();
         $vs_opt_md5 = caMakeCacheKeyFromOptions($pa_options);
         if (!isset($this->opa_rel_prefetch_cache[$va_path_components['table_name']][$vn_row_id][$vs_opt_md5])) {
             $this->prefetchRelated($va_path_components['table_name'], $this->opo_engine_result->currentRow(), $this->getOption('prefetch'), $pa_options);
         }
         if (is_array($this->opa_rel_prefetch_cache[$va_path_components['table_name']][$vn_row_id][$vs_opt_md5])) {
             foreach ($this->opa_rel_prefetch_cache[$va_path_components['table_name']][$vn_row_id][$vs_opt_md5] as $vn_i => $va_values) {
                 //$vn_locale_id => $va_values_by_locale) {
                 $va_ids[] = $va_values[$vs_pk];
                 if (!$vb_return_as_array) {
                     $vs_val = $t_instance->getAttributesForDisplay($va_path_components['field_name'], $vs_template, array_merge(array('row_id' => $va_values[$vs_pk]), $pa_options));
                 } else {
                     $vs_val = $t_instance->getAttributeDisplayValues($va_path_components['field_name'], $va_values[$vs_pk], $pa_options);
                 }
                 if ($vs_val) {
                     if ($vb_return_as_array) {
                         if (!$vb_return_all_locales) {
                             foreach ($vs_val as $vn_i => $va_values_list) {
                                 foreach ($va_values_list as $vn_j => $va_values) {
                                     $va_return_values[] = $va_values;
                                 }
                             }
                         } else {
                             foreach ($vs_val as $vn_i => $va_values_list) {
                                 $va_return_values[] = $va_values_list;
                             }
                         }
                     } else {
                         $va_return_values[] = $vs_val;
                     }
                 }
             }
         }
         if ($vb_return_as_array || $vb_return_all_locales) {
             // return array
             if ($vb_return_as_link && $vb_is_related) {
                 $vs_table_name = $t_instance->tableName();
                 $vs_fld_key = $va_path_components['subfield_name'] ? $va_path_components['subfield_name'] : $va_path_components['field_name'];
                 if (!$vb_return_all_locales) {
                     $va_return_values_tmp = array();
                     foreach ($va_return_values as $vn_i => $va_value) {
                         if ($vs_template) {
                             $vs_value = caProcessTemplateForIDs($vs_template, $va_path_components['table_name'], array($va_ids[$vn_i][$vs_pk]), array('returnAsArray' => false));
                         } else {
                             $vs_value = $va_value[$vs_fld_key];
                         }
                         if ($vb_return_as_link) {
                             $va_return_values_tmp[$vn_i] = array_pop(caCreateLinksFromText(array($vs_value), $va_original_path_components['table_name'], array($va_ids[$vn_i]), $vs_return_as_link_class, $vs_return_as_link_target));
                         } else {
                             $va_return_values_tmp[$vn_i] = $vs_value;
                         }
                     }
                     $va_return_values = $va_return_values_tmp;
                 }
             }
             return $va_return_values;
         } else {
             // return scalar
             if ($vb_return_as_link && $vb_is_related) {
                 $va_return_values = caCreateLinksFromText($va_return_values, $va_original_path_components['table_name'], $va_ids, $vs_return_as_link_class, $vs_return_as_link_target);
             }
             if (isset($pa_options['convertLineBreaks']) && $pa_options['convertLineBreaks']) {
                 return caConvertLineBreaks(join($vs_delimiter, $va_return_values));
             } else {
                 return join($vs_delimiter, $va_return_values);
             }
         }
     } else {
         if ($vs_template) {
             return caProcessTemplateForIDs($vs_template, $this->opo_subject_instance->tableName(), array($vn_row_id), array_merge($pa_options, array('placeholderPrefix' => $va_path_components['field_name'])));
         }
         //
         // Return fields (intrinsics, labels) in primary or related table
         //
         $t_list = $this->opo_datamodel->getInstanceByTableName('ca_lists', true);
         $va_value_list = array($vn_row_id => $this->opa_prefetch_cache[$va_path_components['table_name']][$vn_row_id]);
         // Restrict to relationship types (related)
         if (isset($pa_options['restrict_to_relationship_types']) && $pa_options['restrict_to_relationship_types']) {
             if (!is_array($pa_options['restrict_to_relationship_types'])) {
                 $pa_options['restrict_to_relationship_types'] = array($pa_options['restrict_to_relationship_types']);
             }
             if (sizeof($pa_options['restrict_to_relationship_types'])) {
                 $t_rel_type = $this->opo_datamodel->getInstanceByTableName('ca_relationship_types', true);
                 $va_rel_types = array();
                 $va_rel_path = array_keys($this->opo_datamodel->getPath($this->ops_table_name, $va_path_components['table_name']));
                 foreach ($pa_options['restrict_to_relationship_types'] as $vm_type) {
                     if (!$vm_type) {
                         continue;
                     }
                     if ($vn_type_id = $t_rel_type->getRelationshipTypeID($va_rel_path[1], $vm_type)) {
                         $va_rel_types[] = $vn_type_id;
                         if (is_array($va_children = $t_rel_type->getHierarchyChildren($vn_type_id, array('idsOnly' => true)))) {
                             $va_rel_types = array_merge($va_rel_types, $va_children);
                         }
                     }
                 }
                 if (sizeof($va_rel_types)) {
                     $va_tmp = array();
                     foreach ($va_value_list as $vn_id => $va_by_locale) {
                         foreach ($va_by_locale as $vn_locale_id => $va_values) {
                             foreach ($va_values as $vn_i => $va_value) {
                                 if (!$va_value['rel_type_id'] || in_array($va_value['rel_type_id'], $va_rel_types)) {
                                     $va_tmp[$vn_id][$vn_locale_id][$vn_i] = $va_value;
                                 }
                             }
                         }
                     }
                     $va_value_list = $va_tmp;
                 }
             }
         }
         // Exclude relationship types (related)
         if (isset($pa_options['exclude_relationship_types']) && $pa_options['exclude_relationship_types']) {
             if (!is_array($pa_options['exclude_relationship_types'])) {
                 $pa_options['exclude_relationship_types'] = array($pa_options['exclude_relationship_types']);
             }
             if (sizeof($pa_options['exclude_relationship_types'])) {
                 $t_rel_type = $this->opo_datamodel->getInstanceByTableName('ca_relationship_types', true);
                 $va_rel_types = array();
                 $va_rel_path = array_keys($this->opo_datamodel->getPath($this->ops_table_name, $va_path_components['table_name']));
                 foreach ($pa_options['exclude_relationship_types'] as $vm_type) {
                     if ($vn_type_id = $t_rel_type->getRelationshipTypeID($va_rel_path[1], $vm_type)) {
                         $va_rel_types[] = $vn_type_id;
                         if (is_array($va_children = $t_rel_type->getHierarchyChildren($vn_type_id, array('idsOnly' => true)))) {
                             $va_rel_types = array_merge($va_rel_types, $va_children);
                         }
                     }
                 }
                 if (sizeof($va_rel_types)) {
                     $va_tmp = array();
                     foreach ($va_value_list as $vn_id => $va_by_locale) {
                         foreach ($va_by_locale as $vn_locale_id => $va_values) {
                             foreach ($va_values as $vn_i => $va_value) {
                                 if (!in_array($va_value['rel_type_id'], $va_rel_types)) {
                                     $va_tmp[$vn_id][$vn_locale_id][$vn_i] = $va_value;
                                 }
                             }
                         }
                     }
                     $va_value_list = $va_tmp;
                 }
             }
         }
         // Restrict to types (related)
         $va_type_ids = $vs_type_fld = null;
         if (method_exists($t_instance, "getTypeFieldName")) {
             $va_type_ids = caMergeTypeRestrictionLists($t_instance, $pa_options);
             $vs_type_fld = $t_instance->getTypeFieldName();
         } else {
             if (method_exists($t_instance, "getSubjectTableInstance")) {
                 $t_label_subj_instance = $t_instance->getSubjectTableInstance();
                 if (method_exists($t_label_subj_instance, "getTypeFieldName")) {
                     $va_type_ids = caMergeTypeRestrictionLists($t_label_subj_instance, $pa_options);
                     $vs_type_fld = 'item_type_id';
                 }
             }
         }
         if (is_array($va_type_ids) && sizeof($va_type_ids)) {
             $va_tmp = array();
             foreach ($va_value_list as $vn_id => $va_by_locale) {
                 foreach ($va_by_locale as $vn_locale_id => $va_values) {
                     foreach ($va_values as $vn_i => $va_value) {
                         if (!$va_value[$vs_type_fld ? $vs_type_fld : 'item_type_id'] || in_array($va_value[$vs_type_fld ? $vs_type_fld : 'item_type_id'], $va_type_ids)) {
                             $va_tmp[$vn_id][$vn_locale_id][$vn_i] = $va_value;
                         }
                     }
                 }
             }
             $va_value_list = $va_tmp;
         }
         // Restrict to sources (related)
         $va_source_ids = $vs_source_id_fld = null;
         if (method_exists($t_instance, "getSourceFieldName")) {
             $va_source_ids = caMergeSourceRestrictionLists($t_instance, $pa_options);
             $vs_source_id_fld = $t_instance->getSourceFieldName();
         } else {
             if (method_exists($t_instance, "getSubjectTableInstance")) {
                 $t_label_subj_instance = $t_instance->getSubjectTableInstance();
                 if (method_exists($t_label_subj_instance, "getSourceFieldName")) {
                     $va_source_ids = caMergeSourceRestrictionLists($t_label_subj_instance, $pa_options);
                     $vs_source_id_fld = 'item_source_id';
                 }
             }
         }
         if (is_array($va_source_ids) && sizeof($va_source_ids)) {
             $va_tmp = array();
             foreach ($va_value_list as $vn_id => $va_by_locale) {
                 foreach ($va_by_locale as $vn_locale_id => $va_values) {
                     foreach ($va_values as $vn_i => $va_value) {
                         if (!$va_value[$vs_source_id_fld ? $vs_source_id_fld : 'item_source_id'] || in_array($va_value[$vs_source_id_fld ? $vs_source_id_fld : 'item_source_id'], $va_source_ids)) {
                             $va_tmp[$vn_id][$vn_locale_id][$vn_i] = $va_value;
                         }
                     }
                 }
             }
             $va_value_list = $va_tmp;
         }
         // Exclude types (related)
         if (isset($pa_options['exclude_type']) && $pa_options['exclude_type']) {
             if (!isset($pa_options['exclude_types']) || !is_array($pa_options['exclude_types'])) {
                 $pa_options['exclude_types'] = array();
             }
             $pa_options['exclude_types'][] = $pa_options['exclude_type'];
         }
         if (isset($pa_options['exclude_types']) && is_array($pa_options['exclude_types'])) {
             $va_ids = caMakeTypeIDList($va_path_components['table_name'], $pa_options['exclude_types']);
             if (is_array($va_ids) && sizeof($va_ids) > 0) {
                 $va_tmp = array();
                 foreach ($va_value_list as $vn_id => $va_by_locale) {
                     foreach ($va_by_locale as $vn_locale_id => $va_values) {
                         foreach ($va_values as $vn_i => $va_value) {
                             if (!in_array($va_value[$vs_type_fld ? $vs_type_fld : 'item_type_id'], $va_type_ids)) {
                                 $va_tmp[$vn_id][$vn_locale_id][$vn_i] = $va_value;
                             }
                         }
                     }
                 }
                 $va_value_list = $va_tmp;
             }
         }
         // Handle 'relationship_typename' (related)
         $vb_get_relationship_typename = false;
         if ($va_path_components['field_name'] == 'relationship_typename') {
             $va_path_components['field_name'] = 'rel_type_id';
             $vb_get_relationship_typename = true;
         }
         if ($vb_return_as_array) {
             // return array (intrinsics or labels in primary or related table)
             if ($t_instance->hasField($va_path_components['field_name']) && $va_path_components['table_name'] === $t_instance->tableName()) {
                 // Intrinsic
                 $va_field_info = $t_instance->getFieldInfo($va_path_components['field_name']);
                 $vs_pk = $t_original_instance->primaryKey();
                 // Handle specific intrinsic types
                 switch ($va_field_info['FIELD_TYPE']) {
                     case FT_DATERANGE:
                     case FT_HISTORIC_DATERANGE:
                         foreach ($va_value_list as $vn_id => $va_values_by_locale) {
                             foreach ($va_values_by_locale as $vn_locale_id => $va_values) {
                                 foreach ($va_values as $vn_i => $va_value) {
                                     $va_ids[] = $va_value[$vs_pk];
                                     if (caGetOption('GET_DIRECT_DATE', $pa_options, false) || caGetOption('getDirectDate', $pa_options, false)) {
                                         if (caGetOption('sortable', $pa_options, false)) {
                                             $vs_prop = $va_value[$va_field_info['START']] . '/' . $va_value[$va_field_info['END']];
                                         } else {
                                             $vs_prop = $va_value[$va_field_info['START']];
                                         }
                                     } else {
                                         $this->opo_tep->init();
                                         if ($va_field_info['FIELD_TYPE'] == FT_DATERANGE) {
                                             $this->opo_tep->setUnixTimestamps($va_value[$va_field_info['START']], $va_value[$va_field_info['END']]);
                                         } else {
                                             $this->opo_tep->setHistoricTimestamps($va_value[$va_field_info['START']], $va_value[$va_field_info['END']]);
                                         }
                                         $vs_prop = $this->opo_tep->getText($pa_options);
                                     }
                                     if ($vb_return_all_locales) {
                                         $va_return_values[$vn_row_id][$vn_locale_id][] = $vs_prop;
                                     } else {
                                         $va_return_values[] = $vs_prop;
                                     }
                                 }
                             }
                         }
                         break;
                     case FT_MEDIA:
                         if (!($vs_version = $va_path_components['subfield_name'])) {
                             $vs_version = "largeicon";
                         }
                         foreach ($va_value_list as $vn_id => $va_values_by_locale) {
                             foreach ($va_values_by_locale as $vn_locale_id => $va_values) {
                                 foreach ($va_values as $vn_i => $va_value) {
                                     $va_ids[] = $va_value[$vs_pk];
                                     if (isset($pa_options['unserialize']) && $pa_options['unserialize']) {
                                         $vs_prop = caUnserializeForDatabase($va_value[$va_path_components['field_name']]);
                                         if ($vb_return_all_locales) {
                                             $va_return_values[$vn_row_id][$vn_locale_id][] = $vs_prop;
                                         } else {
                                             $va_return_values[] = $vs_prop;
                                         }
                                     } else {
                                         $o_media_settings = new MediaProcessingSettings($va_path_components['table_name'], $va_path_components['field_name']);
                                         $va_versions = $o_media_settings->getMediaTypeVersions('*');
                                         if (!isset($va_versions[$vs_version])) {
                                             $va_tmp = array_keys($va_versions);
                                             $vs_version = array_shift($va_tmp);
                                         }
                                         // See if an info element was passed, eg. ca_object_representations.media.icon.width should return the width of the media rather than a tag or url to the media
                                         $vs_info_element = $va_path_components['num_components'] == 4 ? $va_path_components['components'][3] : null;
                                         if ($vb_return_all_locales) {
                                             if ($vs_info_element) {
                                                 $va_return_values[$vn_row_id][$vn_locale_id][] = $this->getMediaInfo($va_path_components['table_name'] . '.' . $va_path_components['field_name'], $vs_version, $vs_info_element, $pa_options);
                                             } elseif (isset($pa_options['returnURL']) && $pa_options['returnURL']) {
                                                 $va_return_values[$vn_row_id][$vn_locale_id][] = $this->getMediaUrl($va_path_components['table_name'] . '.' . $va_path_components['field_name'], $vs_version, $pa_options);
                                             } else {
                                                 $va_return_values[$vn_row_id][$vn_locale_id][] = $this->getMediaTag($va_path_components['table_name'] . '.' . $va_path_components['field_name'], $vs_version, $pa_options);
                                             }
                                         } else {
                                             if ($vs_info_element) {
                                                 $va_return_values[] = $this->getMediaInfo($va_path_components['table_name'] . '.' . $va_path_components['field_name'], $vs_version, $vs_info_element, $pa_options);
                                             } elseif (isset($pa_options['returnURL']) && $pa_options['returnURL']) {
                                                 $va_return_values[] = $this->getMediaUrl($va_path_components['table_name'] . '.' . $va_path_components['field_name'], $vs_version, $pa_options);
                                             } else {
                                                 $va_return_values[] = $this->getMediaTag($va_path_components['table_name'] . '.' . $va_path_components['field_name'], $vs_version, $pa_options);
                                             }
                                         }
                                     }
                                 }
                             }
                         }
                         break;
                     default:
                         // is intrinsic field in primary table
                         $vb_supports_preferred = (bool) $t_instance->hasField('is_preferred');
                         foreach ($va_value_list as $vn_id => $va_values_by_locale) {
                             foreach ($va_values_by_locale as $vn_locale_id => $va_values) {
                                 foreach ($va_values as $vn_i => $va_value) {
                                     $va_ids[] = $vn_id = $va_value[$vs_pk];
                                     if ($vb_get_preferred_labels_only && $vb_supports_preferred && !$va_value['is_preferred']) {
                                         continue;
                                     }
                                     if ($vb_get_nonpreferred_labels_only && $vb_supports_preferred && $va_value['is_preferred']) {
                                         continue;
                                     }
                                     $vs_prop = $va_value[$va_path_components['field_name']];
                                     if (isset($pa_options['convertCodesToDisplayText']) && $pa_options['convertCodesToDisplayText'] && ($vs_list_code = $t_instance->getFieldInfo($va_path_components['field_name'], "LIST_CODE"))) {
                                         $vs_prop = $t_list->getItemFromListForDisplayByItemID($vs_list_code, $vs_prop);
                                     } else {
                                         if (isset($pa_options['convertCodesToDisplayText']) && $pa_options['convertCodesToDisplayText'] && ($vs_list_code = $t_instance->getFieldInfo($va_path_components['field_name'], "LIST"))) {
                                             $vs_prop = $t_list->getItemFromListForDisplayByItemValue($vs_list_code, $vs_prop);
                                         } else {
                                             if (isset($pa_options['convertCodesToDisplayText']) && $pa_options['convertCodesToDisplayText'] && $va_path_components['field_name'] === 'locale_id' && (int) $vs_prop > 0) {
                                                 $t_locale = new ca_locales($vs_prop);
                                                 $vs_prop = $t_locale->getName();
                                             } else {
                                                 if (isset($pa_options['convertCodesToDisplayText']) && $pa_options['convertCodesToDisplayText'] && is_array($va_list = $t_instance->getFieldInfo($va_path_components['field_name'], "BOUNDS_CHOICE_LIST"))) {
                                                     foreach ($va_list as $vs_option => $vs_value) {
                                                         if ($vs_value == $vs_prop) {
                                                             $vs_prop = $vs_option;
                                                             break;
                                                         }
                                                     }
                                                 }
                                             }
                                         }
                                     }
                                     if ($vb_return_all_locales) {
                                         $va_return_values[$vn_id][$vn_locale_id][] = $vs_prop;
                                     } else {
                                         $va_return_values[$vn_id][$vn_locale_id] = $vs_prop;
                                     }
                                 }
                             }
                         }
                         if (!$vb_return_all_locales) {
                             $va_return_values = array_values(caExtractValuesByUserLocale($va_return_values));
                         }
                         break;
                 }
             } else {
                 // Attributes
                 $vs_pk = $t_original_instance->primaryKey();
                 $vb_is_related = $this->ops_table_name !== $va_path_components['table_name'];
                 $va_ids = array();
                 $t_instance = $this->opo_datamodel->getInstanceByTableName($va_path_components['table_name'], true);
                 foreach ($va_value_list as $vn_i => $va_values_by_locale) {
                     foreach ($va_values_by_locale as $vn_locale_id => $va_values) {
                         foreach ($va_values as $vn_i => $va_value) {
                             if ($vb_is_related) {
                                 $va_ids[] = $va_value[$vs_pk];
                             }
                             if ($vb_get_preferred_labels_only && !$va_value['is_preferred']) {
                                 continue;
                             }
                             if ($vb_get_nonpreferred_labels_only && $va_value['is_preferred']) {
                                 continue;
                             }
                             // do we need to translate foreign key and choice list codes to display text?
                             $vs_prop = $vb_return_all_label_values && !$vb_return_as_link ? $va_value : $va_value[$va_path_components['field_name']];
                             if ($vb_get_relationship_typename) {
                                 if (!$t_rel_type) {
                                     $t_rel_type = $this->opo_datamodel->getInstanceByTableName('ca_relationship_types', true);
                                 }
                                 if (is_array($va_labels = $t_rel_type->getDisplayLabels(false, array('row_id' => (int) $vs_prop)))) {
                                     $va_label = array_shift($va_labels);
                                     $vs_prop = $va_label[0]['typename'];
                                 } else {
                                     $vs_prop = "?";
                                 }
                             } else {
                                 // Decode list items to text
                                 if (isset($pa_options['convertCodesToDisplayText']) && $pa_options['convertCodesToDisplayText'] && ($vs_list_code = $t_instance->getFieldInfo($va_path_components['field_name'], "LIST_CODE"))) {
                                     $vs_prop = $t_list->getItemFromListForDisplayByItemID($vs_list_code, $vs_prop);
                                 } else {
                                     if (isset($pa_options['convertCodesToDisplayText']) && $pa_options['convertCodesToDisplayText'] && ($vs_list_code = $t_instance->getFieldInfo($va_path_components['field_name'], "LIST"))) {
                                         $vs_prop = $t_list->getItemFromListForDisplayByItemValue($vs_list_code, $vs_prop);
                                     } else {
                                         if (isset($pa_options['convertCodesToDisplayText']) && $pa_options['convertCodesToDisplayText'] && $va_path_components['field_name'] === 'locale_id' && (int) $vs_prop > 0) {
                                             $t_locale = new ca_locales($vs_prop);
                                             $vs_prop = $t_locale->getName();
                                         } else {
                                             if (isset($pa_options['convertCodesToDisplayText']) && $pa_options['convertCodesToDisplayText'] && is_array($va_list = $t_instance->getFieldInfo($va_path_components['field_name'], "BOUNDS_CHOICE_LIST"))) {
                                                 foreach ($va_list as $vs_option => $vs_value) {
                                                     if ($vs_value == $vs_prop) {
                                                         $vs_prop = $vs_option;
                                                         break;
                                                     }
                                                 }
                                             }
                                         }
                                     }
                                 }
                             }
                             if ($vb_return_all_locales) {
                                 $va_return_values[$vn_row_id][$vn_locale_id][] = $vs_prop;
                             } else {
                                 if ($vb_get_nonpreferred_labels_only && is_array($vs_prop)) {
                                     // non-preferred labels are lists of lists because they can repeat
                                     $va_return_values[][] = $vs_prop;
                                 } else {
                                     $va_return_values[] = $vs_prop;
                                 }
                             }
                         }
                     }
                 }
             }
             if ($vb_return_as_link) {
                 if (!$vb_return_all_locales) {
                     $va_return_values = caCreateLinksFromText($va_return_values, $va_original_path_components['table_name'], $va_ids, $vs_return_as_link_class, $vs_return_as_link_target);
                 }
             }
             return $va_return_values;
         } else {
             // Return scalar (intrinsics or labels in primary or related table)
             if ($vb_get_preferred_labels_only || $vb_get_nonpreferred_labels_only) {
                 // We have to distinguish between preferred and non-preferred labels here
                 // so that only appropriate labels are passed for output.
                 $va_filtered_values = array();
                 foreach ($va_value_list as $vn_label_id => $va_labels_by_locale) {
                     foreach ($va_labels_by_locale as $vn_locale_id => $va_labels) {
                         foreach ($va_labels as $vn_i => $va_label) {
                             if ($vb_get_preferred_labels_only && (!isset($va_label['is_preferred']) || $va_label['is_preferred']) || $vb_get_nonpreferred_labels_only && !$va_label['is_preferred']) {
                                 $va_filtered_values[$vn_label_id][$vn_locale_id][] = $va_label;
                             }
                         }
                     }
                 }
                 $va_value_list = $va_filtered_values;
             }
             $va_value_list = caExtractValuesByUserLocale($va_value_list);
             // do we need to translate foreign key and choice list codes to display text?
             $t_instance = $this->opo_datamodel->getInstanceByTableName($va_path_components['table_name'], true);
             $va_field_info = $t_instance->getFieldInfo($va_path_components['field_name']);
             $vs_pk = $t_instance->primaryKey();
             $vb_is_related = $this->ops_table_name !== $va_path_components['table_name'];
             $va_ids = array();
             foreach ($va_value_list as $vn_i => $va_values) {
                 if (!is_array($va_values)) {
                     continue;
                 }
                 // Handle specific intrinsic types
                 $vs_template_value = $vs_template;
                 foreach ($va_values as $vn_j => $va_value) {
                     switch ($va_field_info['FIELD_TYPE']) {
                         case FT_BIT:
                             if ($pa_options['convertCodesToDisplayText']) {
                                 $va_value[$va_path_components['field_name']] = (bool) $vs_prop ? _t('yes') : _t('no');
                             }
                             break;
                         case FT_DATERANGE:
                             if (caGetOption('GET_DIRECT_DATE', $pa_options, false) || caGetOption('getDirectDate', $pa_options, false)) {
                                 if (isset($pa_options['sortable']) && $pa_options['sortable']) {
                                     $va_value[$va_path_components['field_name']] = $va_value[$va_field_info['START']] . '/' . $va_value[$va_field_info['END']];
                                 } else {
                                     $va_value[$va_path_components['field_name']] = $va_value[$va_field_info['START']];
                                 }
                             } else {
                                 $this->opo_tep->init();
                                 $this->opo_tep->setUnixTimestamps($va_value[$va_field_info['START']], $va_value[$va_field_info['END']]);
                                 $va_value[$va_path_components['field_name']] = $this->opo_tep->getText($pa_options);
                             }
                             break;
                         case FT_HISTORIC_DATERANGE:
                             if (caGetOption('GET_DIRECT_DATE', $pa_options, false) || caGetOption('getDirectDate', $pa_options, false)) {
                                 if (caGetOption('sortable', $pa_options, false)) {
                                     $va_value[$va_path_components['field_name']] = $va_value[$va_field_info['START']] . '/' . $va_value[$va_field_info['END']];
                                 } else {
                                     $va_value[$va_path_components['field_name']] = $va_value[$va_field_info['START']];
                                 }
                             } else {
                                 $this->opo_tep->init();
                                 $this->opo_tep->setHistoricTimestamps($va_value[$va_field_info['START']], $va_value[$va_field_info['END']]);
                                 $va_value[$va_path_components['field_name']] = $this->opo_tep->getText($pa_options);
                             }
                             break;
                         case FT_MEDIA:
                             if (!($vs_version = $va_path_components['subfield_name'])) {
                                 $vs_version = "largeicon";
                             }
                             // See if an info element was passed, eg. ca_object_representations.media.icon.width should return the width of the media rather than a tag or url to the media
                             $vs_info_element = $va_path_components['num_components'] == 4 ? $va_path_components['components'][3] : null;
                             if (isset($pa_options['unserialize']) && $pa_options['unserialize']) {
                                 return caUnserializeForDatabase($va_value[$va_path_components['field_name']]);
                             } else {
                                 $o_media_settings = new MediaProcessingSettings($va_path_components['table_name'], $va_path_components['field_name']);
                                 $va_versions = $o_media_settings->getMediaTypeVersions('*');
                                 if (!isset($va_versions[$vs_version])) {
                                     $va_tmp = array_keys($va_versions);
                                     $vs_version = array_shift($va_tmp);
                                 }
                                 if ($vs_info_element) {
                                     // Return media info
                                     $va_value[$va_path_components['field_name']] = $this->getMediaInfo($va_path_components['table_name'] . '.' . $va_path_components['field_name'], $vs_version, $vs_info_element, $pa_options);
                                 } elseif (isset($pa_options['returnURL']) && $pa_options['returnURL']) {
                                     $va_value[$va_path_components['field_name']] = $this->getMediaUrl($va_path_components['table_name'] . '.' . $va_path_components['field_name'], $vs_version, $pa_options);
                                 } else {
                                     $va_value[$va_path_components['field_name']] = $this->getMediaTag($va_path_components['table_name'] . '.' . $va_path_components['field_name'], $vs_version, $pa_options);
                                 }
                             }
                             break;
                         default:
                             // noop
                             break;
                     }
                     $vs_prop = $va_value[$va_path_components['field_name']];
                     // Decode list items to text
                     if (isset($pa_options['convertCodesToDisplayText']) && $pa_options['convertCodesToDisplayText'] && ($vs_list_code = $t_instance->getFieldInfo($va_path_components['field_name'], "LIST_CODE"))) {
                         $va_value[$va_path_components['field_name']] = $t_list->getItemFromListForDisplayByItemID($vs_list_code, $vs_prop);
                     } else {
                         if (isset($pa_options['convertCodesToDisplayText']) && $pa_options['convertCodesToDisplayText'] && ($vs_list_code = $t_instance->getFieldInfo($va_path_components['field_name'], "LIST"))) {
                             $va_value[$va_path_components['field_name']] = $t_list->getItemFromListForDisplayByItemValue($vs_list_code, $vs_prop);
                         } else {
                             if (isset($pa_options['convertCodesToDisplayText']) && $pa_options['convertCodesToDisplayText'] && $va_path_components['field_name'] === 'locale_id' && (int) $vs_prop > 0) {
                                 $t_locale = new ca_locales($vs_prop);
                                 $va_value[$va_path_components['field_name']] = $t_locale->getName();
                             } else {
                                 if (isset($pa_options['convertCodesToDisplayText']) && $pa_options['convertCodesToDisplayText'] && is_array($va_list = $t_instance->getFieldInfo($va_path_components['field_name'], "BOUNDS_CHOICE_LIST"))) {
                                     foreach ($va_list as $vs_option => $vs_value) {
                                         if ($vs_value == $vs_prop) {
                                             $va_value[$va_path_components['field_name']] = $vs_option;
                                             break;
                                         }
                                     }
                                 }
                             }
                         }
                     }
                     $vs_pk = $this->opo_datamodel->getTablePrimaryKeyName($va_original_path_components['table_name']);
                     if ($vs_template) {
                         foreach ($va_value_list as $vn_id => $va_values) {
                             foreach ($va_values as $vn_i => $va_value) {
                                 $vs_prop = caProcessTemplateForIDs($vs_template, $va_original_path_components['table_name'], array($va_value[$vs_pk]), array('returnAsArray' => false));
                                 $va_return_values[] = $vs_prop;
                                 $va_ids[] = $va_value[$vs_pk];
                             }
                         }
                     } else {
                         $vs_prop = $va_value[$va_path_components['field_name']];
                         $va_return_values[] = $vs_prop;
                         if ($vb_is_related) {
                             $va_ids[] = $va_value[$vs_pk];
                         }
                     }
                 }
             }
             if ($vb_return_as_link && $vb_is_related) {
                 $va_return_values = caCreateLinksFromText($va_return_values, $va_original_path_components['table_name'], $va_ids, $vs_return_as_link_class, $vs_return_as_link_target);
             }
             if (isset($pa_options['convertLineBreaks']) && $pa_options['convertLineBreaks']) {
                 return caConvertLineBreaks(join($vs_delimiter, $va_return_values));
             } else {
                 return join($vs_delimiter, $va_return_values);
             }
         }
     }
     return null;
 }
<?php 
    if ($vo_result->getMediaTag('ca_item_comments.media1', "thumbnail")) {
        print "<span style='white-space: nowrap;'>" . $vo_result->getMediaTag("ca_item_comments.media1", "thumbnail");
        print caNavButton($this->request, __CA_NAV_BUTTON_DOWNLOAD__, _t('Download'), '', 'manage', 'Comments', 'DownloadMedia', array('version' => 'original', 'comment_id' => $vo_result->get('ca_item_comments.comment_id'), 'mode' => 'search', 'download' => 1), array(), array('no_background' => true, 'dont_show_content' => true));
        print "</span>";
    }
    ?>
					</td>
					<td>
						<?php 
    print ($vn_tmp = $vo_result->get('ca_item_comments.rating')) ? $vn_tmp : "-";
    ?>
					</td>
					<td>
<?php 
    $o_tep->setUnixTimestamps($vn_tmp = $vo_result->get('ca_item_comments.created_on'), $vn_tmp);
    print $o_tep->getText();
    ?>
					</td>
					<td>
<?php 
    $vs_commented_on = "";
    if ($t_table->load($vo_result->get('ca_item_comments.row_id'))) {
        $vs_commented_on = $t_table->getLabelForDisplay(false);
        if ($vs_idno = $t_table->get('idno')) {
            $vs_commented_on .= ' [' . $vs_idno . ']';
        }
    }
    print $vs_commented_on;
    ?>
					</td>
Пример #13
0
 * This source code is free and modifiable under the terms of 
 * GNU General Public License. (http://www.gnu.org/copyleft/gpl.html). See
 * the "license.txt" file for details, or visit the CollectiveAccess web site at
 * http://www.CollectiveAccess.org
 *
 * ----------------------------------------------------------------------
 */
$po_request = $this->getVar('request');
$vs_widget_id = $this->getVar('widget_id');
$vn_table_num = $this->getVar('table_num');
$t_log = $this->getVar('change_log');
$vn_threshold_in_seconds = $this->getVar('threshold_in_hours') * 3600;
$vn_end_date_for_display = time();
$vn_start_date_for_display = $vn_end_date_for_display - $vn_threshold_in_seconds;
$o_tep = new TimeExpressionParser();
$o_tep->setUnixTimestamps($vn_start_date_for_display, $vn_end_date_for_display);
$vn_displayed_date_range = $o_tep->getText(array('timeOmit' => true));
$va_log_entries = array_reverse($t_log->getRecentChanges($vn_table_num, $vn_threshold_in_seconds, 1000));
// reverse to put most recent up top
?>
<div class="dashboardWidgetContentContainer">
<?php 
if (sizeof($va_log_entries) > 0) {
    ?>
			<div class="dashboardWidgetHeading"><?php 
    print _t("Changes to <strong>%1</strong> from %2", $this->getVar('table_name_plural'), $vn_displayed_date_range);
    ?>
</div>
			<div class="dashboardWidgetScrollMedium" style="padding-left:10px;"><ul>
<?php 
    foreach ($va_log_entries as $vs_log_key => $va_log_entry) {
 /**
  *
  */
 private function _getChangeLogFromRawData($pa_data, $pn_table_num, $pa_options = null)
 {
     //print "<pre>".print_r($pa_data, true)."</pre>\n";
     $va_log_output = array();
     $vs_blank_placeholder = '&lt;' . _t('BLANK') . '&gt;';
     $o_tep = new TimeExpressionParser();
     if (!$pa_options) {
         $pa_options = array();
     }
     if (sizeof($pa_data)) {
         //
         // Init
         //
         $o_datamodel = Datamodel::load();
         $va_change_types = array('I' => _t('Added'), 'U' => _t('Edited'), 'D' => _t('Deleted'));
         $vs_label_table_name = $vs_label_display_name = '';
         $t_item = $o_datamodel->getInstanceByTableNum($pn_table_num, true);
         $vs_label_table_name = $vn_label_table_num = $vs_label_display_name = null;
         if (method_exists($t_item, 'getLabelTableName')) {
             $t_item_label = $t_item->getLabelTableInstance();
             $vs_label_table_name = $t_item->getLabelTableName();
             $vn_label_table_num = $t_item_label->tableNum();
             $vs_label_display_name = $t_item_label->getProperty('NAME_SINGULAR');
         }
         //
         // Group data by unit
         //
         $va_grouped_data = array();
         foreach ($pa_data as $va_log_entry) {
             $va_grouped_data[$va_log_entry['unit_id']]['ca_table_num_' . $va_log_entry['logged_table_num']][] = $va_log_entry;
         }
         //
         // Process units
         //
         $va_attributes = array();
         foreach ($va_grouped_data as $vn_unit_id => $va_log_entries_by_table) {
             foreach ($va_log_entries_by_table as $vs_table_key => $va_log_entries) {
                 foreach ($va_log_entries as $va_log_entry) {
                     $va_changes = array();
                     if (!is_array($va_log_entry['snapshot'])) {
                         $va_log_entry['snapshot'] = array();
                     }
                     //
                     // Get date/time stamp for display
                     //
                     $o_tep->setUnixTimestamps($va_log_entry['log_datetime'], $va_log_entry['log_datetime']);
                     if ($this->opb_dont_show_timestamp_in_change_log) {
                         $vs_datetime = $o_tep->getText(array('timeOmit' => true));
                     } else {
                         $vs_datetime = $o_tep->getText();
                     }
                     //
                     // Get user name
                     //
                     $vs_user = $va_log_entry['fname'] . ' ' . $va_log_entry['lname'];
                     $vs_email = $va_log_entry['email'];
                     // The "logged" table/row is the row to which the change was actually applied
                     // The "subject" table/row is the row to which the change is considered to have been made for workflow purposes.
                     //
                     // For example: if an entity is related to an object, strictly speaking the logging occurs on the ca_objects_x_entities
                     // row (ca_objects_x_entities is the "logged" table), but the subject is ca_objects since it's only in the context of the
                     // object (and probably the ca_entities row as well) that you can about the change.
                     //
                     $t_obj = $o_datamodel->getInstanceByTableNum($va_log_entry['logged_table_num'], true);
                     // get instance for logged table
                     if (!$t_obj) {
                         continue;
                     }
                     $vs_subject_display_name = '???';
                     $vn_subject_row_id = null;
                     $vn_subject_table_num = null;
                     if (isset($pa_options['return_item_names']) && $pa_options['return_item_names']) {
                         if (!($vn_subject_table_num = $va_log_entry['subject_table_num'])) {
                             $vn_subject_table_num = $va_log_entry['logged_table_num'];
                             $vn_subject_row_id = $va_log_entry['logged_row_id'];
                         } else {
                             $vn_subject_row_id = $va_log_entry['subject_row_id'];
                         }
                         if ($t_subject = $o_datamodel->getInstanceByTableNum($vn_subject_table_num, true)) {
                             if ($t_subject->load($vn_subject_row_id)) {
                                 if (method_exists($t_subject, 'getLabelForDisplay')) {
                                     $vs_subject_display_name = $t_subject->getLabelForDisplay(false);
                                 } else {
                                     if ($vs_idno_field = $t_subject->getProperty('ID_NUMBERING_ID_FIELD')) {
                                         $vs_subject_display_name = $t_subject->getProperty('NAME_SINGULAR') . ' [' . $t_subject->get($vs_idno_field) . ']';
                                     } else {
                                         $vs_subject_display_name = $t_subject->getProperty('NAME_SINGULAR') . ' [' . $vn_subject_row_id . ']';
                                     }
                                 }
                             }
                         }
                     }
                     //
                     // Get item changes
                     //
                     // ---------------------------------------------------------------
                     // is this an intrinsic field?
                     if ($pn_table_num == $va_log_entry['logged_table_num']) {
                         foreach ($va_log_entry['snapshot'] as $vs_field => $vs_value) {
                             $va_field_info = $t_obj->getFieldInfo($vs_field);
                             if (isset($va_field_info['IDENTITY']) && $va_field_info['IDENTITY']) {
                                 continue;
                             }
                             if (isset($va_field_info['DISPLAY_TYPE']) && $va_field_info['DISPLAY_TYPE'] == DT_OMIT) {
                                 continue;
                             }
                             if (isset($va_field_info['DISPLAY_FIELD']) && is_array($va_field_info['DISPLAY_FIELD']) && ($va_disp_fields = $va_field_info['DISPLAY_FIELD'])) {
                                 //
                                 // Lookup value in related table
                                 //
                                 if (!$vs_value) {
                                     continue;
                                 }
                                 if (sizeof($va_disp_fields)) {
                                     $va_rel = $o_datamodel->getManyToOneRelations($t_obj->tableName(), $vs_field);
                                     $va_rel_values = array();
                                     if ($t_rel_obj = $o_datamodel->getTableInstance($va_rel['one_table'], true)) {
                                         $t_rel_obj->load($vs_value);
                                         foreach ($va_disp_fields as $vs_display_field) {
                                             $va_tmp = explode('.', $vs_display_field);
                                             if (($vs_tmp = $t_rel_obj->get($va_tmp[1])) !== '') {
                                                 $va_rel_values[] = $vs_tmp;
                                             }
                                         }
                                     }
                                     $vs_proc_val = join(', ', $va_rel_values);
                                 }
                             } else {
                                 // Is field a foreign key?
                                 $va_keys = $o_datamodel->getManyToOneRelations($t_obj->tableName(), $vs_field);
                                 if (sizeof($va_keys)) {
                                     // yep, it's a foreign key
                                     $va_rel_values = array();
                                     if ($t_rel_obj = $o_datamodel->getTableInstance($va_keys['one_table'], true)) {
                                         if ($t_rel_obj->load($vs_value)) {
                                             if (method_exists($t_rel_obj, 'getLabelForDisplay')) {
                                                 $vs_proc_val = $t_rel_obj->getLabelForDisplay(false);
                                             } else {
                                                 $va_disp_fields = $t_rel_obj->getProperty('LIST_FIELDS');
                                                 foreach ($va_disp_fields as $vs_display_field) {
                                                     if (($vs_tmp = $t_rel_obj->get($vs_display_field)) !== '') {
                                                         $va_rel_values[] = $vs_tmp;
                                                     }
                                                 }
                                                 $vs_proc_val = join(' ', $va_rel_values);
                                             }
                                             if (!$vs_proc_val) {
                                                 $vs_proc_val = '???';
                                             }
                                         } else {
                                             $vs_proc_val = _t("Not set");
                                         }
                                     } else {
                                         $vs_proc_val = _t('Non-existent');
                                     }
                                 } else {
                                     // Adjust display of value for different field types
                                     switch ($va_field_info['FIELD_TYPE']) {
                                         case FT_BIT:
                                             $vs_proc_val = $vs_value ? 'Yes' : 'No';
                                             break;
                                         default:
                                             $vs_proc_val = $vs_value;
                                             break;
                                     }
                                     // Adjust display of value for lists
                                     if ($va_field_info['LIST']) {
                                         $t_list = new ca_lists();
                                         if ($t_list->load(array('list_code' => $va_field_info['LIST']))) {
                                             $vn_list_id = $t_list->getPrimaryKey();
                                             $t_list_item = new ca_list_items();
                                             if ($t_list_item->load(array('list_id' => $vn_list_id, 'item_value' => $vs_value))) {
                                                 $vs_proc_val = $t_list_item->getLabelForDisplay();
                                             }
                                         }
                                     } else {
                                         if ($va_field_info['BOUNDS_CHOICE_LIST']) {
                                             // TODO
                                         }
                                     }
                                 }
                             }
                             $va_changes[] = array('label' => $va_field_info['LABEL'], 'description' => strlen((string) $vs_proc_val) ? $vs_proc_val : $vs_blank_placeholder, 'value' => $vs_value);
                         }
                     }
                     // ---------------------------------------------------------------
                     // is this a label row?
                     if ($va_log_entry['logged_table_num'] == $vn_label_table_num) {
                         foreach ($va_log_entry['snapshot'] as $vs_field => $vs_value) {
                             $va_changes[] = array('label' => $t_item_label->getFieldInfo($vs_field, 'LABEL'), 'description' => $vs_value);
                         }
                     }
                     // ---------------------------------------------------------------
                     // is this an attribute?
                     if ($va_log_entry['logged_table_num'] == 3) {
                         // attribute_values
                         if ($t_element = ca_attributes::getElementInstance($va_log_entry['snapshot']['element_id'])) {
                             if ($o_attr_val = Attribute::getValueInstance($t_element->get('datatype'))) {
                                 $o_attr_val->loadValueFromRow($va_log_entry['snapshot']);
                                 $vs_attr_val = $o_attr_val->getDisplayValue();
                             } else {
                                 $vs_attr_val = '?';
                             }
                             // Convert list-based attributes to text
                             if ($vn_list_id = $t_element->get('list_id')) {
                                 $t_list = new ca_lists();
                                 $vs_attr_val = $t_list->getItemFromListForDisplayByItemID($vn_list_id, $vs_attr_val, true);
                             }
                             if (!$vs_attr_val) {
                                 $vs_attr_val = $vs_blank_placeholder;
                             }
                             $vs_label = $t_element->getLabelForDisplay();
                             $va_attributes[$va_log_entry['snapshot']['attribute_id']]['values'][] = array('label' => $vs_label, 'value' => $vs_attr_val);
                             $va_changes[] = array('label' => $vs_label, 'description' => $vs_attr_val);
                         }
                     }
                     // ---------------------------------------------------------------
                     // is this a related (many-many) row?
                     $va_keys = $o_datamodel->getOneToManyRelations($t_item->tableName(), $t_obj->tableName());
                     if (sizeof($va_keys) > 0) {
                         if (method_exists($t_obj, 'getLeftTableNum')) {
                             if ($t_obj->getLeftTableNum() == $t_item->tableNum()) {
                                 // other side of rel is on right
                                 $t_related_table = $o_datamodel->getInstanceByTableNum($t_obj->getRightTableNum(), true);
                                 $t_related_table->load($va_log_entry['snapshot'][$t_obj->getRightTableFieldName()]);
                             } else {
                                 // other side of rel is on left
                                 $t_related_table = $o_datamodel->getInstanceByTableNum($t_obj->getLeftTableNum(), true);
                                 $t_related_table->load($va_log_entry['snapshot'][$t_obj->getLeftTableFieldName()]);
                             }
                             $t_rel = $o_datamodel->getInstanceByTableNum($t_obj->tableNum(), true);
                             $va_changes[] = array('label' => caUcFirstUTF8Safe($t_related_table->getProperty('NAME_SINGULAR')), 'idno' => ($vs_idno_field = $t_related_table->getProperty('ID_NUMBERING_ID_FIELD')) ? $t_related_table->get($vs_idno_field) : null, 'description' => method_exists($t_related_table, 'getLabelForDisplay') ? $t_related_table->getLabelForDisplay() : '', 'table_name' => $t_related_table->tableName(), 'table_num' => $t_related_table->tableNum(), 'row_id' => $t_related_table->getPrimaryKey(), 'rel_type_id' => $va_log_entry['snapshot']['type_id'], 'rel_typename' => $t_rel->getRelationshipTypename('ltor', $va_log_entry['snapshot']['type_id']));
                         }
                     }
                     // ---------------------------------------------------------------
                     // record log line
                     if (sizeof($va_changes)) {
                         $va_log_output[$vn_unit_id][] = array('datetime' => $vs_datetime, 'user_fullname' => $vs_user, 'user_email' => $vs_email, 'user' => $vs_user . ' (' . $vs_email . ')', 'changetype_display' => $va_change_types[$va_log_entry['changetype']], 'changetype' => $va_log_entry['changetype'], 'changes' => $va_changes, 'subject' => $vs_subject_display_name, 'subject_id' => $vn_subject_row_id, 'subject_table_num' => $vn_subject_table_num, 'logged_table_num' => $va_log_entry['logged_table_num'], 'logged_table' => $t_obj->tableName(), 'logged_row_id' => $va_log_entry['logged_row_id']);
                     }
                 }
             }
         }
     }
     return $va_log_output;
 }