/** * @param \Zend_Search_Lucene_Index_Term $po_term * @return array */ function getFilterForTerm($po_term) { $va_return = array(); $va_parsed_values = caGetISODates($po_term->text); $va_return[str_replace('\\', '', $po_term->field)] = array('gte' => $va_parsed_values['start'], 'lte' => $va_parsed_values['end']); return $va_return; }
public function indexField($pn_content_tablenum, $ps_content_fieldname, $pn_content_row_id, $pm_content, $pa_options) { if (is_array($pm_content)) { $pm_content = serialize($pm_content); } $vn_rel_type_id = isset($pa_options['relationship_type_id']) && $pa_options['relationship_type_id'] > 0 ? (int) $pa_options['relationship_type_id'] : null; $ps_content_tablename = $this->ops_indexing_subject_tablename; if ($ps_content_fieldname[0] === 'A') { // attribute $vn_field_num_proc = (int) substr($ps_content_fieldname, 1); if (!($va_element_info = $this->_getMetadataElement($vn_field_num_proc))) { return null; } switch ($va_element_info['datatype']) { case 1: // text // text case 3: // list // list case 5: // url // url case 6: // currency // currency case 8: // length // length case 9: // weight // weight case 13: // LCSH // LCSH case 14: // geonames // geonames case 15: // file // file case 16: // media // media case 19: // taxonomy // taxonomy case 20: // information service // noop break; case 2: // daterange if (!is_array($pa_parsed_content = caGetISODates($pm_content))) { return null; } $this->opa_doc_content_buffer[$ps_content_tablename . '.' . $ps_content_fieldname . '_text'][] = $pm_content; $pm_content = $pa_parsed_content; break; case 4: // geocode if ($va_coords = $this->opo_geocode_parser->parseValue($pm_content, $va_element_info)) { if (isset($va_coords['value_longtext2']) && $va_coords['value_longtext2']) { $va_coords['value_longtext2'] = str_replace("[", "", $va_coords['value_longtext2']); $va_coords['value_longtext2'] = str_replace("]", "", $va_coords['value_longtext2']); $this->opa_doc_content_buffer[$ps_content_tablename . '.' . $ps_content_fieldname . '_text'][] = $pm_content; $pm_content = preg_split('![:;].!', $va_coords['value_longtext2']); } else { return; } } else { return; } break; case 10: // timecode // timecode case 12: // numeric/float $pm_content = (double) $pm_content; break; case 11: // integer $pm_content = (int) $pm_content; break; default: // noop break; } } else { // Intrinsic field $ps_content_tablename = $this->opo_datamodel->getTableName($pn_content_tablenum); $vn_field_num_proc = (int) substr($ps_content_fieldname, 1); $ps_content_fieldname = $this->opo_datamodel->getFieldName($ps_content_tablename, $vn_field_num_proc); // Type fields need a little special attention because we index their plain ids, their type codes AND their preferred label, // like so: "Publication publication 102". // That doesn't work too well with Solr. Solr does, however, have proper support for multivalued fields, so we split the string // to make sure "publication" and "102" become two distinct values in the index. // The getTableInstance call is cached, so in theory it should be cheap after it is issued once. $t_instance = $this->opo_datamodel->getTableInstance($ps_content_tablename, true); if ($t_instance instanceof BaseModelWithAttributes && $ps_content_fieldname == $t_instance->getTypeFieldName()) { $va_tmp = explode(' ', $pm_content); $pm_content = array(); // this is the type_id $pm_content[] = array_pop($va_tmp); // this is the type code - lets just assume it doesn't have spaces $pm_content[] = array_pop($va_tmp); // this is label information, which may have spaces. So we have to make sure that "Film & Media" doesn't become 3 values $pm_content[] = join(' ', $va_tmp); } } $this->opa_doc_content_buffer[$ps_content_tablename . '.' . $ps_content_fieldname][] = $pm_content; if ($vn_rel_type_id) { // add relationship type-specific indexing $this->opa_doc_content_buffer[$ps_content_tablename . '.' . $ps_content_fieldname . '/' . $vn_rel_type_id][] = $pm_content; } }
public function indexField($pn_content_tablenum, $ps_content_fieldname, $pn_content_row_id, $pm_content, $pa_options) { if (is_array($pm_content)) { $pm_content = serialize($pm_content); } $vn_rel_type_id = isset($pa_options['relationship_type_id']) && $pa_options['relationship_type_id'] > 0 ? (int) $pa_options['relationship_type_id'] : null; $ps_content_tablename = $this->opo_datamodel->getTableName($pn_content_tablenum); if ($ps_content_fieldname[0] === 'A') { // Metadata attribute $vn_field_num_proc = (int) substr($ps_content_fieldname, 1); if (!($va_element_info = $this->_getMetadataElement($vn_field_num_proc))) { return null; } switch ($va_element_info['datatype']) { case 1: // text // text case 3: // list // list case 5: // url // url case 6: // currency // currency case 8: // length // length case 9: // weight // weight case 13: // LCSH // LCSH case 14: // geonames // geonames case 15: // file // file case 16: // media // media case 19: // taxonomy // taxonomy case 20: // information service // noop break; case 2: // daterange if (!is_array($pa_parsed_content = caGetISODates($pm_content))) { return null; } $this->opa_doc_content_buffer[$ps_content_tablename . '.' . $va_element_info['element_code'] . '_text'][] = $pm_content; $ps_rewritten_start = $this->_rewriteDate($pa_parsed_content["start"], true); $ps_rewritten_end = $this->_rewriteDate($pa_parsed_content["end"], false); $pm_content = array($ps_rewritten_start, $ps_rewritten_end); break; case 4: // geocode if ($va_coords = $this->opo_geocode_parser->parseValue($pm_content, $va_element_info)) { if (isset($va_coords['value_longtext2']) && $va_coords['value_longtext2']) { $this->opa_doc_content_buffer[$ps_content_tablename . '.' . $va_element_info['element_code'] . '_text'][] = $pm_content; $va_coords = explode(':', $va_coords['value_longtext2']); foreach ($va_coords as $vs_point) { $this->opa_doc_content_buffer[$ps_content_tablename . '.' . $va_element_info['element_code']][] = $vs_point; } return; } else { break; } } else { break; } break; case 10: // timecode // timecode case 12: // numeric/float $pm_content = (double) $pm_content; break; case 11: // integer $pm_content = (int) $pm_content; break; default: // noop break; } $ps_content_fieldname = $va_element_info['element_code']; } else { // Intrinsic field $vn_field_num_proc = (int) substr($ps_content_fieldname, 1); $ps_content_fieldname = $this->opo_datamodel->getFieldName($ps_content_tablename, $vn_field_num_proc); } $this->opa_doc_content_buffer[$ps_content_tablename . '.' . $ps_content_fieldname][] = $pm_content; if ($vn_rel_type_id) { // add relationship type-specific indexing $this->opa_doc_content_buffer[$ps_content_tablename . '.' . $ps_content_fieldname . '/' . $vn_rel_type_id][] = $pm_content; } }
/** * Generate SIMILE timeline output in specified format * * @param array $pa_viz_settings Array of visualization settings taken from visualization.conf * @param string $ps_format Specifies format to generate output in. Currently only 'HTML' is supported. * @param array $pa_options Array of options to use when rendering output. Supported options are: * width = * height = * request = current request; required for generation of editor links */ public function render($pa_viz_settings, $ps_format = 'HTML', $pa_options = null) { if (!($vo_data = $this->getData())) { return null; } $this->opn_num_items_rendered = 0; $po_request = isset($pa_options['request']) && $pa_options['request'] ? $pa_options['request'] : null; list($vs_width, $vs_height) = $this->_parseDimensions(caGetOption('width', $pa_options, 500), caGetOption('height', $pa_options, 500)); $o_dm = Datamodel::load(); // generate events $va_events = array(); $va_sources = $pa_viz_settings['sources']; $vs_table = $vo_data->tableName(); $vs_pk = $o_dm->getTablePrimaryKeyName($vs_table); $vs_first_date = $vn_first_date = null; $vs_last_date = $vn_last_date = null; $va_dates = array(); while ($vo_data->nextHit()) { foreach ($va_sources as $vs_source_code => $va_source_info) { $vs_start = trim($vo_data->get($va_source_info['data'], array('start_as_iso8601' => true, 'dateFormat' => 'iso8601'))); $vs_end = trim($vo_data->get($va_source_info['data'], array('end_as_iso8601' => true, 'dateFormat' => 'iso8601'))); $vn_start = $vo_data->get($va_source_info['data'], array('startHistoricTimestamp' => true)); $vn_end = $vo_data->get($va_source_info['data'], array('endHistoricTimestamp' => true)); if ($vn_start < 0 || $vn_end < 0) { continue; } // TODO: negative numbers mean "BC" which apparently cannot be plotted if ($vn_end >= 2000000) { $va_iso = caGetISODates(_t("today")); $vs_end = $va_iso['end']; $va_historic = caDateToHistoricTimestamps(_t("today")); $vn_end = $va_historic['end']; } if (!$vs_start || !$vs_end) { continue; } if ($vs_start == _t('undated') || $vs_end == _t('undated')) { continue; } if (is_null($vn_first_date) || $vn_first_date > $vn_start) { $vn_first_date = $vn_start; $vs_first_date = $vs_start; } if (is_null($vn_last_date) || $vn_last_date < $vn_end) { $vn_last_date = $vn_end; $vs_last_date = $vs_end; } $va_dates[] = $vs_start; $va_events[] = array('id' => $vs_table . '_' . ($vn_id = $vo_data->get("{$vs_table}.{$vs_pk}")), 'start' => $vs_start, 'end' => $vs_end, 'isDuration' => (int) $vn_start != (int) $vn_end ? true : false, 'title' => caProcessTemplateForIDs(strip_tags($va_source_info['display']['title_template']), $vs_table, array($vn_id)), 'description' => caProcessTemplateForIDs($va_source_info['display']['description_template'], $vs_table, array($vn_id)), 'link' => $po_request ? caEditorUrl($po_request, $vo_data->tableName(), $vn_id) : null, 'image' => $va_source_info['display']['image'] ? $vo_data->getWithTemplate($va_source_info['display']['image'], array('returnURL' => true)) : null, 'icon' => $va_source_info['display']['icon'] ? $vo_data->getWithTemplate($va_source_info['display']['icon'], array('returnURL' => true)) : null); } } $this->opn_num_items_rendered = sizeof($va_events); // Find median date - timeline will open there (as good a place as any, no?) $vs_default_date = $va_dates[floor((sizeof($va_dates) - 1) / 2)]; // Derive scale for timeline bands $vn_span = $vn_last_date - $vn_first_date; if ($vn_span > 1000) { // millennia $vs_detail_band_scale = " Timeline.DateTime.CENTURY"; $vs_overview_band_scale = " Timeline.DateTime.MILLENNIUM"; } elseif ($vn_span > 100) { // centuries $vs_detail_band_scale = " Timeline.DateTime.DECADE"; $vs_overview_band_scale = " Timeline.DateTime.CENTURY"; } elseif ($vn_span > 10) { // decades $vs_detail_band_scale = " Timeline.DateTime.YEAR"; $vs_overview_band_scale = " Timeline.DateTime.DECADE"; } elseif ($vn_span > 1) { // years $vs_detail_band_scale = " Timeline.DateTime.MONTH"; $vs_overview_band_scale = " Timeline.DateTime.YEAR"; } elseif ($vn_span > 0.1) { // months $vs_detail_band_scale = " Timeline.DateTime.DAY"; $vs_overview_band_scale = " Timeline.DateTime.MONTH"; } else { // days $vs_detail_band_scale = " Timeline.DateTime.HOUR"; $vs_overview_band_scale = " Timeline.DateTime.DAY"; } $va_highlight_spans = array(); $vs_highlight_span = ''; if (isset($pa_options['highlightSpans']) && is_array($pa_options['highlightSpans'])) { foreach ($pa_options['highlightSpans'] as $vs_span_name => $va_span_info) { $va_range = caGetISODates($va_span_info['range']); $vs_span_color = isset($va_span_info['color']) && $va_span_info['color'] ? $va_span_info['color'] : '#FFC080'; $vs_start_label = isset($va_span_info['startLabel']) && $va_span_info['startLabel'] ? $va_span_info['startLabel'] : ''; $vs_end_label = isset($va_span_info['endLabel']) && $va_span_info['endLabel'] ? $va_span_info['endLabel'] : ''; $vs_span_css_class = isset($va_span_info['class']) && $va_span_info['class'] ? $va_span_info['class'] : 't-highlight1'; $va_highlight_spans[] = "new Timeline.SpanHighlightDecorator({\n\t\t\t\t\t\tdateTimeFormat: 'iso8601',\n startDate: '" . $va_range['start'] . "',\n endDate: '" . $va_range['end'] . "',\n color: '{$vs_span_color}', \n opacity: 50,\n startLabel: '{$vs_start_label}', \n endLabel: '{$vs_end_label}',\n cssClass: '{$vs_span_css_class}'\n })"; } $vs_highlight_span = "caTimelineBands[0].decorators = [" . join(",\n", $va_highlight_spans) . "];"; } $vs_buf = "\n\t<div id='caResultTimeline' style='width: {$vs_width}; height: {$vs_height}; border: 1px solid #aaa'></div>\n<script type='text/javascript'>\n\tvar caTimelineEventSource = new Timeline.DefaultEventSource();\n\tvar caTimelineEventJson = {\n\t\t\"dateTimeFormat\": \"iso8601\", \n\t\t\"events\" : " . json_encode($va_events) . "\n\t}; \n\tcaTimelineEventSource.loadJSON(caTimelineEventJson, '');\n\t\n\tvar theme = Timeline.ClassicTheme.create();\n\t\n\tvar caTimelineBands = [\n Timeline.createBandInfo({\n\t\t\teventPainter: Timeline.CompactEventPainter,\n\t\t\teventPainterParams: {\n\t\t\t\ticonLabelGap: 5,\n\t\t\t\tlabelRightMargin: 20,\n\n\t\t\t\ticonWidth: 72,\n\t\t\t\ticonHeight: 72,\n\n\t\t\t\tstackConcurrentPreciseInstantEvents: {\n\t\t\t\t\tlimit: 5,\n\t\t\t\t\tmoreMessageTemplate: '%0 More',\n\t\t\t\t\ticon: null,\n\t\t\t\t\ticonWidth: 72,\n\t\t\t\t\ticonHeight: 72\n\t\t\t\t}\n\t\t\t},\n\t\t\teventSource:\t caTimelineEventSource,\n\t\t\tdate:\t\t\t'{$vs_default_date}',\n\t\t\twidth: '85%', \n\t\t\tintervalUnit: \t{$vs_detail_band_scale}, \n\t\t\tintervalPixels: 100,\n\t\t\ttheme: \t\t\ttheme\n\t}),\n Timeline.createBandInfo({\n \t eventSource:\t caTimelineEventSource,\n \t date:\t\t\t'{$vs_default_date}',\n width: '10%', \n intervalUnit: {$vs_overview_band_scale}, \n intervalPixels: 200,\n layout: \t\t'overview',\n \t theme: \t\t theme\n })\n ];\n\tcaTimelineBands[1].syncWith = 0;\n\tcaTimelineBands[1].highlight = true;\n\t\n\t{$vs_highlight_span}\n\t\n\tvar caTimeline = Timeline.create(document.getElementById('caResultTimeline'), caTimelineBands);\n</script>\t\n"; return $vs_buf; }
/** * @param Db $po_db * @param int $pn_table_num * @param int $pn_row_id * @return array */ function caGetChangeLogForElasticSearch($po_db, $pn_table_num, $pn_row_id) { $qr_res = $po_db->query("\n\t\t\t\tSELECT ccl.log_id, ccl.log_datetime, ccl.changetype, u.user_name\n\t\t\t\tFROM ca_change_log ccl\n\t\t\t\tLEFT JOIN ca_users AS u ON ccl.user_id = u.user_id\n\t\t\t\tWHERE\n\t\t\t\t\t(ccl.logged_table_num = ?) AND (ccl.logged_row_id = ?)\n\t\t\t\t\tAND\n\t\t\t\t\t(ccl.changetype <> 'D')\n\t\t\t", $pn_table_num, $pn_row_id); $va_return = array(); while ($qr_res->nextRow()) { $vs_change_date = caGetISODates(date("c", $qr_res->get('log_datetime')))['start']; if ($qr_res->get('changetype') == 'I') { $va_return["created"][] = $vs_change_date; if ($vs_user = $qr_res->get('user_name')) { $va_return["created/{$qr_res->get('user_name')}"][] = $vs_change_date; } } else { $va_return["modified"][] = $vs_change_date; if ($vs_user = $qr_res->get('user_name')) { $va_return["modified/{$qr_res->get('user_name')}"][] = $vs_change_date; } } } return $va_return; }
public function indexField($pn_content_tablenum, $ps_content_fieldname, $pn_content_row_id, $pm_content, $pa_options) { if (is_array($pm_content)) { $pm_content = serialize($pm_content); } $ps_content_tablename = $this->ops_indexing_subject_tablename; if ($ps_content_fieldname[0] === 'A') { // attribute $vn_field_num_proc = (int) substr($ps_content_fieldname, 1); if (!($va_element_info = $this->_getMetadataElement($vn_field_num_proc))) { return null; } switch ($va_element_info['datatype']) { case 1: // text // text case 3: // list // list case 5: // url // url case 6: // currency // currency case 8: // length // length case 9: // weight // weight case 13: // LCSH // LCSH case 14: // geonames // geonames case 15: // file // file case 16: // media // media case 19: // taxonomy // taxonomy case 20: // information service // noop break; case 2: // daterange if (!is_array($pa_parsed_content = caGetISODates($pm_content))) { return null; } $this->opa_doc_content_buffer[$ps_content_tablename . '.' . $ps_content_fieldname . '_text'][] = $pm_content; $pm_content = $pa_parsed_content; break; case 4: // geocode if ($va_coords = $this->opo_geocode_parser->parseValue($pm_content, $va_element_info)) { if (isset($va_coords['value_longtext2']) && $va_coords['value_longtext2']) { $va_coords['value_longtext2'] = str_replace("[", "", $va_coords['value_longtext2']); $va_coords['value_longtext2'] = str_replace("]", "", $va_coords['value_longtext2']); $this->opa_doc_content_buffer[$ps_content_tablename . '.' . $ps_content_fieldname . '_text'][] = $pm_content; $pm_content = preg_split('![:;].!', $va_coords['value_longtext2']); } else { return; } } else { return; } break; case 10: // timecode // timecode case 12: // numeric/float $pm_content = (double) $pm_content; break; case 11: // integer $pm_content = (int) $pm_content; break; default: // noop break; } } else { // Intrinsic field $ps_content_tablename = $this->opo_datamodel->getTableName($pn_content_tablenum); $vn_field_num_proc = (int) substr($ps_content_fieldname, 1); $ps_content_fieldname = $this->opo_datamodel->getFieldName($ps_content_tablename, $vn_field_num_proc); } $this->opa_doc_content_buffer[$ps_content_tablename . '.' . $ps_content_fieldname][] = $pm_content; }