17 require_once SQ_INCLUDE_PATH.
'/asset.inc';
18 require_once SQ_DATA_PATH.
'/private/conf/tools.inc';
33 var $standard_date_fields = NULL;
34 var $standard_text_fields = NULL;
43 var $_db_plugin = NULL;
54 $this->_ser_attrs = TRUE;
55 parent::__construct($assetid);
56 $this->standard_date_fields = Array(
57 'created' => translate(
'asset_created_date'),
58 'updated' => translate(
'asset_updated_date'),
59 'published' => translate(
'asset_published_date'),
60 'status_changed' => translate(
'asset_status_changed_date'),
62 $this->standard_text_fields = Array(
63 'assetid' => translate(
'asset_id'),
64 'name' => translate(
'asset_name'),
65 'short_name' => translate(
'asset_name_short'),
66 'contents' => translate(
'asset_contents'),
83 require_once SQ_CORE_PACKAGE_PATH.
'/system/system_asset_fns.inc';
84 if (!system_asset_fns_create_pre_check($this)) {
87 $GLOBALS[
'SQ_SYSTEM']->changeDatabaseConnection(
'db2');
88 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'BEGIN');
90 if ($linkid = parent::create($link)) {
91 if (!system_asset_fns_create_cleanup($this)) {
97 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'COMMIT');
99 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'ROLLBACK');
102 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
119 return $GLOBALS[
'SQ_SYSTEM']->am->getTypeInfo($this->
type(),
'name');
165 if (!$this->
attr(
'indexing'))
return FALSE;
185 if (!$this->
attr(
'indexing'))
return FALSE;
187 $this->
reindexAttributes($broadcaster, $GLOBALS[
'SQ_SYSTEM']->am->getAssetTypeAttributes($broadcaster->type(), Array(
'name')), TRUE);
206 if (!$this->
attr(
'indexing'))
return FALSE;
207 $this->
reindexAsset($broadcaster, Array(
'status_changed',
'published'));
225 if (!$this->
attr(
'indexing'))
return FALSE;
245 if (!$this->
attr(
'indexing'))
return FALSE;
265 if (!$this->
attr(
'indexing'))
return FALSE;
287 if (!$this->
attr(
'indexing'))
return FALSE;
313 if ($asset->id == $this->id)
return FALSE;
316 $flush_vars = Array();
317 if (!in_array(
'all', $vars)) {
318 foreach ($vars as $var) {
319 $flush_vars[] =
'__'.$var.
'__';
325 if (!empty($flush_vars)) {
335 $GLOBALS[
'SQ_SYSTEM']->am->forgetAsset($asset);
361 if ($asset->id == $this->id)
return FALSE;
364 if (empty($asset->vars))
return FALSE;
366 $contextid = (int)$GLOBALS[
'SQ_SYSTEM']->getContextId();
367 $all_contextids = array_keys($GLOBALS[
'SQ_SYSTEM']->getAllContexts());
370 $flush_vars = Array();
371 if (!in_array(
'all', $vars)) {
378 if ($all_contexts === TRUE) {
379 $contexts_todo = array_keys($GLOBALS[
'SQ_SYSTEM']->getAllContexts());
381 $contexts_todo = Array($contextid);
384 if (count($flush_vars) > 0) {
385 foreach ($flush_vars as &$flush_var) {
386 $flush_var =
'attr:'.$flush_var;
391 $all_indexable_content = Array();
396 $this->
flushIndexableContent($asset->id, $flush_vars, array_merge($all_contextids, Array(
'default')));
401 if ($all_contexts === TRUE) {
403 $this->
flushIndexableContent($asset->id, $flush_vars, array_merge($all_contextids, Array(
'default')));
405 if ($contextid === 0) {
416 $flush_non_contextable_vars = Array();
417 foreach($indexable_content as $attr_idx_data) {
418 if (isset($attr_idx_data[
'contextid']) && $attr_idx_data[
'contextid'] ==
'default' && isset($attr_idx_data[
'component'])) {
419 $flush_non_contextable_vars[$attr_idx_data[
'component']] = 1;
422 if (!empty($flush_non_contextable_vars)) {
433 $GLOBALS[
'SQ_SYSTEM']->am->forgetAsset($asset);
463 $contextid = $GLOBALS[
'SQ_SYSTEM']->getContextId();
465 $indexing_asset = $GLOBALS[
'SQ_SYSTEM']->am->getAsset($indexing_assetid);
472 if ($all_contexts === TRUE) {
473 $contexts_todo = array_keys($GLOBALS[
'SQ_SYSTEM']->getAllContexts());
475 $contexts_todo = Array($contextid);
480 foreach ($contexts_todo as $processed_contextid) {
481 $other_context = FALSE;
482 if (((
int)$contextid === (
int)$processed_contextid)) {
485 $contexted_asset =& $indexing_asset;
487 $other_context = TRUE;
489 $GLOBALS[
'SQ_SYSTEM']->changeContext($processed_contextid);
490 $contexted_asset = $GLOBALS[
'SQ_SYSTEM']->am->getAsset($asset->id);
495 foreach ($index_content as &$index_content_item) {
496 $index_content_item[
'contextid'] = $processed_contextid;
500 if ($other_context === TRUE) {
501 unset($contexted_asset);
502 $GLOBALS[
'SQ_SYSTEM']->restoreContext();
506 $GLOBALS[
'SQ_SYSTEM']->am->forgetAsset($indexing_asset);
521 $links = $GLOBALS[
'SQ_SYSTEM']->am->getLinks($asset->id, SQ_SC_LINK_ALL,
'', FALSE,
'minor');
522 if (empty($links))
return FALSE;
524 $parents = $GLOBALS[
'SQ_SYSTEM']->am->getDependantParents($asset->id);
525 $parents = $GLOBALS[
'SQ_SYSTEM']->am->getAssetInfo($parents, Array(), FALSE,
'type_code');
527 if (empty($parents))
return $asset->id;
530 $array_keys = array_keys($parents);
531 $parent = array_shift($array_keys);
549 require_once SQ_FUDGE_PATH.
'/general/text.inc';
553 $type_code = $asset->type();
554 $index_content = Array();
555 $reindex_all = in_array(
'all', $changed_vars);
559 foreach (Array(
'name',
'short_name') as $name_type) {
561 if (!in_array($name_type, $changed_vars) && !$reindex_all) {
565 $name_index =
'__'.$name_type.
'__';
567 if (!isset($weightings[$name_index]))
continue;
569 $name = ($name_type ==
'name') ? $asset->name : $asset->short_name;
570 $index_content = array_merge($index_content, $plugin->splitIndexableContent($name, $type_code,
'text', $name_index, $weightings[$name_index],
'default', TRUE));
574 'created' => $asset->created,
575 'updated' => $asset->updated,
577 if (!is_null($asset->published)) {
578 $dates[
'published'] = $asset->published;
580 if (!is_null($asset->status_changed)) {
581 $dates[
'status_changed'] = $asset->status_changed;
584 foreach ($dates as $type => $date) {
586 if (!in_array($type, $changed_vars) && !$reindex_all) {
591 if (!isset($weightings[
'__'.$type.
'__']))
continue;
593 $index_content[] = Array(
594 'value' => ts_iso8601($date),
595 'type_code' => $type_code,
596 'type' =>
'datetime',
597 'component' =>
'__'.$type.
'__',
598 'score' => $weightings[
'__'.$type.
'__'],
599 'contextid' =>
'default',
600 'use_default' =>
'1',
604 if (isset($weightings[
'__assetid__'])) {
606 if (in_array(
'assetid', $changed_vars) || $reindex_all) {
608 $index_content[] = Array(
609 'value' => $asset->id,
610 'type_code' => $type_code,
612 'component' =>
'__assetid__',
613 'score' => $weightings[
'__assetid__'],
614 'contextid' =>
'default',
615 'use_default' =>
'1',
620 foreach ($index_content as &$index_content_item) {
621 $index_content_item[
'contextid'] = NULL;
624 return $index_content;
642 $index_content = Array();
643 $type_code = $asset->type();
644 $reindex_all = in_array(
'all', $changed_vars);
645 $contextid = $GLOBALS[
'SQ_SYSTEM']->getContextId();
647 if ($all_contexts === TRUE) {
648 $asset_vars = Array();
649 $context_list = array_keys($GLOBALS[
'SQ_SYSTEM']->getAllContexts());
650 foreach ($context_list as $this_contextid) {
651 if ($this_contextid !== $contextid) {
652 $GLOBALS[
'SQ_SYSTEM']->changeContext($this_contextid);
653 $context_asset = $GLOBALS[
'SQ_SYSTEM']->am->getAsset($asset->id);
655 $context_asset = $asset;
658 $asset_vars[$this_contextid] = $context_asset->vars;
660 if ($this_contextid !== $contextid) {
661 $GLOBALS[
'SQ_SYSTEM']->am->forgetAsset($context_asset->id);
662 unset($context_asset);
663 $GLOBALS[
'SQ_SYSTEM']->restoreContext();
667 $context_list = Array();
669 if ($contextid !== 0) {
671 $GLOBALS[
'SQ_SYSTEM']->changeContext(0);
672 $context_asset = $GLOBALS[
'SQ_SYSTEM']->am->getAsset($asset->id);
673 $asset_vars[0] = $context_asset->vars;
674 $GLOBALS[
'SQ_SYSTEM']->am->forgetAsset($context_asset->id);
675 unset($context_asset);
676 $GLOBALS[
'SQ_SYSTEM']->restoreContext();
678 $context_list[] = $contextid;
679 $asset_vars[$contextid] = $asset->vars;
685 $default_value = Array();
686 foreach ($asset->vars as $var_name => $var_data) {
689 if (!in_array($var_name, $changed_vars) && !$reindex_all) {
694 if (!isset($weightings[$var_name]))
continue;
697 if ($var_data[
'type'] ==
'password' || $var_data[
'type'] ==
'serialise') {
701 $attrid = $var_data[
'attrid'];
703 if ((
int)$var_data[
'is_contextable'] === 0) {
704 $attr = $GLOBALS[
'SQ_SYSTEM']->am->getAttribute($attrid);
705 $attr->setValue($asset_vars[0][$var_name][
'value']);
706 $values[
'default'] = $attr->getContent();
708 foreach (array_keys($asset_vars) as $this_contextid) {
709 $attr = $GLOBALS[
'SQ_SYSTEM']->am->getAttribute($attrid);
710 $attr->setValue($asset_vars[$this_contextid][$var_name][
'value']);
712 if (array_key_exists(
'use_default', $asset_vars[$this_contextid][$var_name]) && (
int)$asset_vars[$this_contextid][$var_name][
'use_default'] === 1) {
715 if (isset($default_value[$var_name]) === FALSE) {
716 $default_value[$var_name] = $attr->getContent();
720 $values[$this_contextid] = $attr->getContent();
725 if ((
int)$var_data[
'is_contextable'] === 0) {
726 $list_to_test = Array(
'default');
728 $list_to_test = $context_list;
731 foreach ($list_to_test as $this_contextid) {
732 if ($this_contextid ===
'default') {
736 $use_default = ($this_contextid === 0 ? TRUE : FALSE);
737 if (array_key_exists($this_contextid, $values) === FALSE) {
738 $values[$this_contextid] = $default_value[$var_name];
743 $value = $values[$this_contextid];
746 $formatting_tags = Array(
'span',
'b',
'big',
'em',
'i',
'small',
'strong',
'sub',
'sup',
'ins',
'del');
747 $value = $this->
_strip_tags($formatting_tags, $value);
749 $value = preg_replace(
'/<\/?[^>]+>/i',
' ', $value);
750 if (empty($value))
continue;
752 $comp_name =
'attr:'.$var_name;
758 if ($var_data[
'type'] ==
'text') {
762 if ($var_data[
'type'] ==
'datetime') {
765 $index_content[] = Array(
767 'type_code' => $type_code,
768 'type' => $var_data[
'type'],
769 'component' => $comp_name,
770 'score' => $weightings[$var_name],
771 'contextid' => $this_contextid,
772 'use_default' => $use_default,
775 $index_content = array_merge($index_content, $plugin->splitIndexableContent($value, $type_code, $var_data[
'type'], $comp_name, $weightings[$var_name], $this_contextid, $use_default));
781 unset($default_value);
783 return $index_content;
799 $index_content = Array();
801 $type_code = $asset->type();
802 $contextid = $GLOBALS[
'SQ_SYSTEM']->getContextId();
805 if (isset($weightings[
'__contents__'])) {
810 $contents = $asset->getContent();
813 $formatting_tags = Array(
'span',
'b',
'big',
'em',
'i',
'small',
'strong',
'sub',
'sup',
'ins',
'del');
814 $contents = $this->
_strip_tags($formatting_tags, $contents);
816 $contents = preg_replace(
'/<\/?[^>]+>/i',
' ', $contents);
818 if (trim($contents) !=
'') {
819 $index_content = $plugin->splitIndexableContent($contents, $type_code,
'text',
'__contents__', $weightings[
'__contents__'], $contextid, FALSE);
823 return $index_content;
840 if (!$this->
attr(
'indexing'))
return FALSE;
841 if (!is_array($index_content))
return FALSE;
843 $index_content_found = FALSE;
844 $keys = array_keys($index_content);
850 $defaults_context = Array();
855 $add_content = Array();
859 foreach ($keys as $key) {
860 $data =& $index_content[$key];
861 $value = $data[
'value'];
863 if (trim($value) ==
'')
continue;
865 switch ($data[
'type']) {
867 require_once SQ_FUDGE_PATH.
'/general/datetime.inc';
868 if (!is_iso8601($value)) {
869 $value = ts_iso8601(strtotime($value));
889 $default_key = $assetid.
' '.$data[
'component'].
' '.sha1($value);
893 'assetid' => $assetid,
894 'type_code' => $data[
'type_code'],
895 'component' => $data[
'component'],
896 'contextid' => ($data[
'contextid'] === NULL) ?
'default' : (
string)$data[
'contextid'],
897 'type' => $data[
'type'],
898 'score' => $data[
'score'],
899 'use_default' => $data[
'use_default'] ?
'1' :
'0',
905 if (((
int)$bind_vars[
'use_default'] === 1) && ($bind_vars[
'contextid'] !==
'default')) {
906 if (array_key_exists($default_key, $defaults_context) === FALSE) {
907 $defaults_context[$default_key] = $bind_vars[
'contextid'];
909 if ($bind_vars[
'contextid'] === $defaults_context[$default_key]) {
910 $defaults[] = $bind_vars;
914 $add_content[] = $bind_vars;
923 $GLOBALS[
'SQ_SYSTEM']->changeDatabaseConnection(
'db2');
924 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'BEGIN');
932 if (!empty($add_content)) {
934 $query = $dal_query->prepare();
936 foreach ($add_content as $bind_vars) {
940 foreach ($bind_vars as $bind_var => $bind_value) {
944 $index_content_found = TRUE;
945 }
catch (Exception $e) {
946 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'ROLLBACK');
947 throw new Exception(
'Unable to add indexable content due to database error: '.$e->getMessage());
956 if (!empty($defaults)) {
964 $get_context_query = $dal_get_context_query->prepare();
967 $insert_query = $dal_insert_query->prepare();
970 foreach ($defaults as $bind_vars) {
976 foreach($result as $asset_context) {
977 $bind_vars[
'contextid'] = $asset_context[
'contextid'];
978 foreach ($bind_vars as $bind_var => $bind_value) {
984 $index_content_found = TRUE;
985 }
catch (Exception $e) {
986 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'ROLLBACK');
987 throw new Exception(
'Unable to add indexable content due to database error: '.$e->getMessage());
993 $query = $dal_query->prepare();
995 foreach ($defaults as $bind_vars) {
997 foreach ($bind_vars as $bind_var => $bind_value) {
998 if ($bind_var !==
'contextid') {
1007 $index_content_found = TRUE;
1008 }
catch (Exception $e) {
1009 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'ROLLBACK');
1010 throw new Exception(
'Unable to add indexable content due to database error: '.$e->getMessage());
1017 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'COMMIT');
1018 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
1020 return $index_content_found;
1044 if (!$this->
attr(
'indexing'))
return;
1049 $GLOBALS[
'SQ_SYSTEM']->changeDatabaseConnection(
'db2');
1050 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'BEGIN');
1053 if ($contextids === NULL) {
1054 $contextids = array_keys($GLOBALS[
'SQ_SYSTEM']->getAllContexts());
1055 $contextids[] =
'default';
1058 if (is_array($contextids) === FALSE) {
1059 $contextids = Array($contextids);
1064 'assetid' => $assetid,
1065 'contextids' => $contextids,
1068 if (!empty($components)) {
1069 $bind_vars[
'components'] = $components;
1071 $bind_vars[
'components'] = NULL;
1076 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'ROLLBACK');
1077 throw new Exception(
'Unable to flush indexable content due to database error: '.$e->getMessage());
1080 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'COMMIT');
1081 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
1108 if (!$this->
attr(
'indexing'))
return;
1113 $GLOBALS[
'SQ_SYSTEM']->changeDatabaseConnection(
'db2');
1114 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'BEGIN');
1118 'assetid' => $assetid,
1119 'use_default' =>
'1',
1122 if (!empty($components)) {
1123 $bind_vars[
'components'] = $components;
1125 $bind_vars[
'components'] = NULL;
1130 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'ROLLBACK');
1131 throw new Exception(
'Unable to flush default indexable content due to database error: '.$e->getMessage());
1134 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'COMMIT');
1135 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
1157 assetid = :assetid';
1163 }
catch (Exception $e) {
1164 throw new Exception(
'Unable to get indexed components due to database error: '.$e->getMessage());
1184 $result = $plugin->getAssetidsByWordIntersection($source_id, $type);
1199 $components = Array(
1200 '__assetid__' =>
'Asset ID',
1201 '__name__' =>
'Asset Name',
1202 '__short_name__' =>
'Asset Short Name',
1203 '__created__' =>
'Created Date',
1204 '__updated__' =>
'Updated Date',
1205 '__published__' =>
'Published Date',
1206 '__status_changed__' =>
'Status Changed Date',
1207 '__contents__' =>
'Asset Contents',
1225 $attrs = $GLOBALS[
'SQ_SYSTEM']->am->getAssetTypeAttributes($type_code, Array(
'name',
'type',
'is_admin'));
1227 $indexable_attrs = Array();
1228 foreach ($attrs as $attr => $info) {
1229 if (!$attrs[$attr][
'is_admin'] || $attrs[$attr][
'is_admin'] ==
'f') {
1230 $indexable_attrs[$attr] = $info;
1233 return $indexable_attrs;
1248 $info = $GLOBALS[
'SQ_SYSTEM']->am->getAttributeInfo($attrid);
1249 return !$info[$attrid][
'is_admin'];
1267 if (empty($weights)) {
1274 return (!isset($weights[
'indexed']) || $weights[
'indexed']);
1294 $max_length = $plugin->getMaxWordLength();
1295 if (($max_length > 0) && (strlen($word) > $max_length)) {
1299 $min_length = $this->
attr(
'min_word_length');
1318 if (is_array($value))
return $value;
1320 if (!preg_match(
'/[a-zA-Z]+/', $value)) {
1321 $pattern = Array(
',',
'+');
1322 $new_value = str_replace($pattern,
'', $value);
1323 $new_value = preg_replace(
'/\s+/',
'', $new_value);
1327 if (preg_match(
'/^\d+$/', $new_value)) {
1328 $value = $new_value;
1352 if (!$this->
attr(
'indexing'))
return FALSE;
1354 if ($broadcaster->shouldFastTrack(
'search_manager_reindex_metadata'))
return FALSE;
1374 $mm = $GLOBALS[
'SQ_SYSTEM']->getMetadataManager();
1375 $fieldids = array_keys($mm->getMetadataFields(Array($vars[
'schemaid'])));
1376 for (reset($fieldids); NULL !== ($key = key($fieldids)); next($fieldids)) {
1377 $fieldids[$key] =
'metadata:'.$fieldids[$key];
1397 assert_valid_assetid($assetid);
1398 $mm = $GLOBALS[
'SQ_SYSTEM']->getMetadataManager();
1400 $contextid = (int)$GLOBALS[
'SQ_SYSTEM']->getContextId();
1401 $all_contextids = array_keys($GLOBALS[
'SQ_SYSTEM']->getAllContexts());
1403 if (in_array(
'all', $vars)) {
1404 $schema_ids = array_keys($mm->getSchemas($assetid));
1405 $fieldids = $mm->getMetadataFields($schema_ids);
1406 }
else if (in_array(
'schemaid', array_keys($vars))) {
1407 $fieldids = $mm->getMetadataFields($vars[
'schemaid'], TRUE);
1409 $fieldids = $GLOBALS[
'SQ_SYSTEM']->am->getAssetInfo($vars[
'fieldids'], Array(), TRUE,
'type_code');
1412 if (empty($fieldids)) {
1413 $fieldids = $mm->getMetadataFields($mm->getSchemas($assetid, TRUE));
1416 $flush_fieldids = Array();
1417 foreach (array_keys($fieldids) as $fieldid) {
1418 $flush_fieldids[] =
'metadata:'.$fieldid;
1421 if (!empty($flush_fieldids)) {
1422 if ($all_contexts) {
1425 if ($contextid === 0) {
1435 $asset = $GLOBALS[
'SQ_SYSTEM']->am->getAsset($assetid);
1456 $index_content = Array();
1457 $mm = $GLOBALS[
'SQ_SYSTEM']->getMetadataManager();
1459 $type_code = $asset->type();
1461 if (is_null($asset))
return $index_content;
1464 $contextid = $GLOBALS[
'SQ_SYSTEM']->getContextId();
1465 $context_list = $all_contexts ? array_keys($GLOBALS[
'SQ_SYSTEM']->getAllContexts()) : Array($contextid);
1467 if (empty($fieldids)) {
1468 $fieldids = $mm->getMetadataFields($mm->getSchemas($asset->id, TRUE));
1473 $all_metadata = Array();
1474 foreach ($context_list as $c) {
1475 $all_metadata[$c] = $mm->getMetadata($asset->id, 0, $c);
1478 foreach ($fieldids as $fieldid => $field_type) {
1480 $flag_match_found = FALSE;
1481 $current_links = $GLOBALS[
'SQ_SYSTEM']->am->getLinks($fieldid, SQ_LINK_TYPE_2,
'metadata_section', FALSE,
'minor', NULL, TRUE);
1483 foreach ($current_links as $link) {
1484 $section = $GLOBALS[
'SQ_SYSTEM']->am->getAsset($link[
'majorid'], $link[
'major_type_code']);
1485 $restrictions = $section->attr(
'restrict');
1486 if (!empty($restrictions)) {
1487 foreach($restrictions as $type_code_restricted => $inherit_it) {
1488 if ($inherit_it && !$flag_match_found) {
1489 $asset_type_with_parents = $GLOBALS[
'SQ_SYSTEM']->am->getAssetTypeInfo(Array($asset->id));
1490 foreach($asset_type_with_parents[$asset->id] as $index => $asset_type) {
1491 if (array_key_exists($asset_type[0], $restrictions) && !$flag_match_found) {
1492 $flag_match_found = TRUE;
1496 if (array_key_exists($asset->type(), $restrictions)) {
1497 $flag_match_found = TRUE;
1503 $flag_match_found = TRUE;
1507 if ($flag_match_found)
break;
1510 if (!$flag_match_found) {
1520 if (is_array($field_type)) {
1521 $field_type = $field_type[0][
'type_code'];
1523 $field = $GLOBALS[
'SQ_SYSTEM']->am->getAsset($fieldid, $field_type);
1526 $is_contextable = (int)$field->attr(
'is_contextable') === 0 ? FALSE : TRUE;
1527 $context_to_index = $is_contextable ? $context_list : Array($context_list[0]);
1529 foreach($context_to_index as $this_contextid) {
1532 $metadata = $all_metadata[$this_contextid];
1534 if (isset($metadata[$field->id][0][
'value'])) {
1535 $value = $metadata[$field->id][0][
'value'];
1537 $value = $field->attr(
'default_html');
1539 $value = $field->attr(
'default');
1542 $use_default = empty($value) || $this_contextid ===
'default' || $this_contextid === 0 ? TRUE : FALSE;
1544 $value_components = Array();
1547 for($i = 0; $i < 3; $i++) {
1548 $keywords = retrieve_keywords_replacements($value,
'.');
1550 $the_replacement = $mm->generateKeywordReplacements($asset, $keywords, FALSE);
1552 foreach($keywords as $keyword) {
1554 if (!isset($the_replacement[$keyword])) {
1556 $the_replacement[$keyword] = str_replace(
'"',
'\"', $asset->getKeywordReplacement($keyword));
1558 }
else if ($the_replacement[$keyword] ==
'%'.$keyword.
'%' && substr($keyword, 0, 15) ==
'metadata_field_') {
1561 $full_keyword = $keyword;
1562 $keyword = parse_keyword($keyword, $modifiers);
1565 $fieldid = $mm->getFieldAssetIdFromName($asset->id, substr($keyword, 15));
1566 $keyword_replacement = $mm->getMetadataValueByAssetid($asset->id, $fieldid, TRUE, FALSE);
1568 if ($keyword_replacement !== NULL) {
1569 if (count($modifiers) > 0) {
1570 apply_keyword_modifiers($keyword_replacement, $modifiers, Array(
'assetid' => $asset->id));
1572 $the_replacement[$full_keyword] = $keyword_replacement;
1574 $the_replacement[$full_keyword] =
'%'.$full_keyword.
'%';
1581 replace_keywords($value, $the_replacement);
1585 if ($field_type ==
'metadata_field_date') {
1586 $index_content[] = Array(
1588 'type_code' => $type_code,
1589 'type' =>
'datetime',
1590 'component' =>
'metadata:'.$field->id,
1591 'score' => $weighting,
1592 'contextid' => $this_contextid,
1593 'use_default' => $use_default,
1597 switch ($field_type) {
1598 case 'metadata_field_hierarchy':
1599 $key_type =
'selection';
1602 case 'metadata_field_select':
1603 if ($field->attr(
'multiple')) {
1605 $value = $plugin->handleMultipleMetadataSelect($value);
1608 $key_type =
'selection';
1611 case 'metadata_field_multiple_text':
1613 $value = $plugin->handleMultipleMetadataSelect($value);
1614 $key_type =
'selection';
1617 case 'metadata_field_thesaurus':
1618 $key_type =
'thesaurus';
1620 $value = str_replace(
',',
' ', $value);
1623 case 'metadata_field_wysiwyg':
1624 $key_type =
'metadata_field_wysiwyg';
1626 $value = $plugin->handleMultipleMetadataSelect($value);
1634 $index_content = array_merge($index_content, $plugin->splitIndexableContent($value, $type_code, $key_type,
'metadata:'.$field->id, $weighting, $this_contextid, $use_default));
1639 $GLOBALS[
'SQ_SYSTEM']->am->forgetAsset($field);
1644 return $index_content;
1677 if (isset($this->_tmp[
'asset_weightings'][$assetid]) === FALSE) {
1682 if (empty($weightings)) {
1690 if (empty($weightings)) {
1691 $type_code = $GLOBALS[
'SQ_SYSTEM']->am->getAssetInfo(Array($assetid), Array(), TRUE,
'type_code');
1692 $type_code = array_get_index($type_code, $assetid,
'');
1693 if (!empty($type_code)) {
1699 if (empty($weightings)) {
1700 $weightings = Array();
1703 $components = array_merge($asset_comps, $attr_comps);
1705 foreach (array_keys($components) as $component) {
1706 $weightings[$component] = 1;
1708 $this->_tmp[
'asset_weightings'][$assetid] = $weightings;
1714 if (isset($this->_tmp[
'asset_weightings'][$assetid]) === FALSE) {
1715 $indexed_weightings = Array();
1717 foreach (Array(
'attr_weights',
'asset_weights') as $type) {
1718 foreach ($weightings[$type] as $component => $info) {
1719 if ($info[
'indexed']) {
1720 $indexed_weightings[$component] = $info[
'weight'];
1725 $this->_tmp[
'asset_weightings'][$assetid] = $indexed_weightings;
1730 return $this->_tmp[
'asset_weightings'][$assetid];
1756 $mm = $GLOBALS[
'SQ_SYSTEM']->getMetadataManager();
1758 $section_link = $GLOBALS[
'SQ_SYSTEM']->am->getLink($fieldid, SQ_LINK_TYPE_2,
'metadata_section', TRUE, NULL,
'minor');
1759 if (empty($section_link)) {
1764 $schema_links = $GLOBALS[
'SQ_SYSTEM']->am->getLinks($section_link[
'majorid'], SQ_LINK_TYPE_2,
'metadata_schema', TRUE,
'minor');
1765 if (empty($schema_links)) {
1770 $sectionid = $section_link[
'majorid'];
1771 $schemaids = Array();
1773 foreach ($schema_links as $schema_info) {
1774 $schemaids[] = $schema_info[
'majorid'];
1777 $info = $GLOBALS[
'SQ_SYSTEM']->am->getAssetInfo(Array($assetid), Array(), TRUE,
'type_code');
1778 $type_code = $info[$assetid];
1780 $weight_sources = Array(
1782 0 => Array(
'function_name' =>
'Asset' ,
'params' => Array($assetid)),
1784 1 => Array(
'function_name' =>
'AssetTree' ,
'params' => Array($assetid, FALSE, FALSE, TRUE, FALSE)),
1786 2 => Array(
'function_name' =>
'AssetTree' ,
'params' => Array($assetid, FALSE, FALSE, FALSE, FALSE)),
1788 3 => Array(
'function_name' =>
'AssetType' ,
'params' => Array($type_code)),
1790 4 => Array(
'function_name' =>
'AssetTree' ,
'params' => Array($GLOBALS[
'SQ_SYSTEM']->am->getSystemAssetid(
'root_folder'))),
1793 foreach ($weight_sources as $source) {
1794 $fn =
'get'.$source[
'function_name'].
'Weightings';
1795 $weightings = call_user_func_array(Array($this, $fn), $source[
'params']);
1796 if (!empty($weightings) && isset($weightings[
'metadata_weights'])) {
1800 if ($weight === FALSE)
return FALSE;
1804 if ($weight != -1)
return $weight;
1832 if (!empty($weightings)) {
1834 if (isset($weightings[$fieldid])) {
1835 if (!$weightings[$fieldid][
'indexed'])
return FALSE;
1836 return $weightings[$fieldid][
'weight'];
1839 if (isset($weightings[$sectionid])) {
1840 if (!$weightings[$sectionid][
'indexed'])
return FALSE;
1841 return $weightings[$sectionid][
'weight'];
1846 $highest_weight = -1;
1852 foreach ($schemaids as $schemaid) {
1853 if (isset($weightings[$schemaid])) {
1854 if ($weightings[$schemaid][
'indexed']) $index = TRUE;
1855 if ($weightings[$schemaid][
'weight'] > $highest_weight) {
1856 $highest_weight = $weightings[$schemaid][
'weight'];
1860 if (!$index && $highest_weight !== -1) {
1863 if ($highest_weight !== -1)
return $highest_weight;
1887 $root_folder_assetid = $GLOBALS[
'SQ_SYSTEM']->am->getSystemAssetid(
'root_folder');
1891 $type_weights = array_get_index($weights,
'type_weights', Array());
1893 if (is_null($type_code))
return $type_weights;
1895 if (!$strict_type_code) {
1896 $type_hier = $GLOBALS[
'SQ_SYSTEM']->am->getTypeAncestors($type_code, TRUE);
1897 array_unshift($type_hier, $type_code);
1899 $type_hier = Array($type_code);
1902 $customised_type_codes = array_keys($type_weights);
1903 foreach ($type_hier as $type_code) {
1904 if (in_array($type_code, $customised_type_codes)) {
1905 return $type_weights[$type_code];
1936 function getAssetTreeWeightings($assetid=NULL, $strict_assetid=TRUE, $strict_type_code=FALSE, $type_weights_only=TRUE, $include_global_weights=TRUE)
1938 $weightings_file = $this->data_path.
'/asset_tree_weightings.inc';
1939 if (file_exists($weightings_file)) {
1940 require $weightings_file;
1942 if (!$include_global_weights) {
1943 $root_folder_assetid = $GLOBALS[
'SQ_SYSTEM']->am->getSystemAssetid(
'root_folder');
1944 if (isset($asset_tree_weightings[$root_folder_assetid])) {
1945 unset($asset_tree_weightings[$root_folder_assetid]);
1949 if (!is_null($assetid)) {
1951 if ($strict_assetid) {
1952 if (isset($asset_tree_weightings[$assetid])) {
1953 return $asset_tree_weightings[$assetid];
1959 $parents = $GLOBALS[
'SQ_SYSTEM']->am->getParents($assetid);
1961 if ($type_weights_only){
1962 $type_code = $GLOBALS[
'SQ_SYSTEM']->am->getAssetInfo(Array($assetid), Array(), TRUE,
'type_code');
1963 $type_code = array_get_index($type_code, $assetid,
'');
1966 if (isset($asset_tree_weightings[$assetid][
'type_weights'][$type_code])) {
1967 return $asset_tree_weightings[$assetid][
'type_weights'][$type_code];
1971 if (isset($asset_tree_weightings[$assetid][
'type_weights'][
'asset'])) {
1972 return $asset_tree_weightings[$assetid][
'type_weights'][
'asset'];
1976 if (empty($type_code)) $type_code =
'asset';
1979 if (!$strict_type_code) {
1980 $type_hier = $GLOBALS[
'SQ_SYSTEM']->am->getTypeAncestors($type_code, TRUE);
1983 array_unshift($type_hier, $type_code);
1985 $type_hier = Array($type_code);
1991 $customised_assetids = array_keys($asset_tree_weightings);
1992 foreach (array_keys($parents) as $parentid) {
1993 if (in_array($parentid, $customised_assetids)) {
1994 if (isset($asset_tree_weightings[$parentid][
'type_weights'])) {
1995 $customised_type_codes = array_keys($asset_tree_weightings[$parentid][
'type_weights']);
1996 foreach ($type_hier as $parent_type_code) {
1997 if (in_array($parent_type_code, $customised_type_codes)) {
1998 return $asset_tree_weightings[$parentid][
'type_weights'][$parent_type_code];
2005 if (isset($asset_tree_weightings[$assetid])) {
2006 return $asset_tree_weightings[$assetid];
2009 foreach (array_keys($parents) as $parentid) {
2010 if (isset($asset_tree_weightings[$parentid])) {
2011 return $asset_tree_weightings[$parentid];
2017 return $asset_tree_weightings;
2053 $weightings_file = $this->data_path.
'/asset_weightings.inc';
2054 if (file_exists($weightings_file)) {
2055 require $weightings_file;
2056 if (!is_null($assetid)) {
2057 if (isset($asset_weightings[$assetid])) {
2058 return $asset_weightings[$assetid];
2061 return $asset_weightings;
2097 $weightings_file = $this->data_path.
'/metadata_weightings.inc';
2098 if (file_exists($weightings_file)) {
2099 require $weightings_file;
2100 if (!is_null($assetid)) {
2101 if (isset($metadata_weightings[$assetid])) {
2102 return $metadata_weightings[$assetid];
2105 return $metadata_weightings;
2140 if (!in_array($type, Array(
'asset_type',
'asset',
'asset_tree',
'metadata'))) {
2141 trigger_error(
'Invalid weightings type "'.$type.
'"', E_USER_ERROR);
2144 $weightings_file = $this->data_path.
'/'.$type.
'_weightings.inc';
2146 $output =
'<'.
'?php'.
"\n".
' $'.$type.
'_weightings = ';
2147 $output .= var_export($weightings, TRUE);
2148 $output .=
"\n?".
'>';
2150 require_once SQ_FUDGE_PATH.
'/general/file_system.inc';
2152 create_directory($this->data_path);
2153 if (!string_to_file($output, $weightings_file)) {
2154 trigger_error(
'Could not write out the '.str_replace(
'_',
' ', $type).
' weightings to file', E_USER_WARNING);
2159 unset($this->_tmp[
'asset_weightings']);
2183 return $plugin->extractKeywords($asset, $include_metadata, $include_scores);
2200 if (!is_array($tags)) {
2201 $tags = Array($tags);
2204 foreach ($tags as $tag) {
2209 $contents = preg_replace(
'/<\/?'.$tag.
'(\/|(\s+[^>]*))?>/i',
'', $contents);
2231 return $plugin->generateWordList($words);
2284 $GLOBALS[
'SQ_SYSTEM']->pm->startTimer($this,
'processSearch');
2286 require_once SQ_INCLUDE_PATH.
'/general_occasional.inc';
2287 $contextid = $GLOBALS[
'SQ_SYSTEM']->getContextId();
2293 $cm = $GLOBALS[
'SQ_SYSTEM']->am->getSystemAsset(
'cache_manager');
2294 if (empty($search_info[
'roots'])) {
2295 $search_cache_key =
'systemWide';
2297 $search_cache_key = implode(
',', $search_info[
'roots']);
2299 if (isset($search_info[
'statuses'])) {
2300 $search_cache_key .= implode(
':', $search_info[
'statuses']);
2302 if (isset($search_info[
'asset_types'])) {
2303 foreach ($search_info[
'asset_types'] as $type => $inherit) {
2304 $search_cache_key .= $type.($inherit ?
'i' :
'n').
':';
2307 $search_cache_key .=
'RL='.array_get_index($search_info,
'root_logic',
'OR');
2308 if ($include_context) {
2309 $search_cache_key .=
'includeContext';
2314 $search_cache_key .=
'-ctx'.$contextid;
2315 $this->_tmp[
'cache_key'] = $search_cache_key;
2316 $this->_tmp[
'cm'] =& $cm;
2321 foreach ($search_info[
'fields'] as $field_name => $field_details) {
2325 if (isset($search_info[
'exclude'])) {
2326 foreach ($search_info[
'exclude'] as $field_name => $field_details) {
2334 if (!empty($search_info[
'roots'])) {
2335 $root_info = $GLOBALS[
'SQ_SYSTEM']->am->getAssetInfo($search_info[
'roots']);
2336 $shadow_results = Array();
2337 foreach ($search_info[
'roots'] as $i => $assetid) {
2338 if (array_key_exists($assetid, $root_info)) {
2339 $root = $root_info[$assetid];
2340 $GLOBALS[
'SQ_SYSTEM']->am->includeAsset($root[
'type_code']);
2342 if (implements_interface($root[
'type_code'],
'bridge') && is_callable(Array($root[
'type_code'],
'processSearch'))) {
2343 $shadow_asset = $GLOBALS[
'SQ_SYSTEM']->am->getAsset($assetid);
2344 $shadow_results = $this->
_combineResults($shadow_results, $shadow_asset->processSearch($search_info, $include_context), array_get_index($search_info,
'root_logic',
'OR'));
2345 $GLOBALS[
'SQ_SYSTEM']->am->forgetAsset($shadow_asset);
2346 unset($search_info[
'roots'][$i]);
2347 $shadow_processed = TRUE;
2351 if (empty($search_info[
'roots'])) {
2352 return $shadow_results;
2360 $base_query[
'select'][] =
'ai.assetid';
2361 $base_query[
'select'][] =
'SUM(ai.score) as search_score';
2363 if (!in_array(
'ai.assetid', array_get_index($base_query,
'group_by', Array()))) {
2364 $base_query[
'group_by'][] =
'ai.assetid';
2367 if ($include_context) {
2368 $base_query[
'select'][] =
'ai.component as source';
2369 $base_query[
'group_by'][] =
'ai.component';
2372 $base_query[
'where'][] =
'(ai.contextid = '.MatrixDAL::quote($contextid).
' OR ai.contextid = '.
MatrixDAL::quote(
'default').
')';
2377 $term_totals = Array();
2380 $search_field_types = Array(
'search' => $search_info[
'fields']);
2381 if (isset($search_info[
'exclude'])) {
2382 $search_field_types[
'exclude'] = $search_info[
'exclude'];
2386 $search_results = Array();
2387 foreach($search_field_types as $search_field_type => $search_fields) {
2388 $final_search_type_results = NULL;
2391 $field_logic = $search_field_type ==
'exclude' ?
'OR' : array_get_index($search_info,
'field_logic',
'OR');
2393 foreach ($search_fields as $field_name => $field_details) {
2394 $field_results = NULL;
2395 $word_logic = array_get_index($field_details,
'word_logic',
'AND');
2396 $data_source_logic = array_get_index($field_details,
'data_source_logic',
'OR');
2398 if (empty($field_details[
'words']))
continue;
2400 if (isset($field_details[
'words'][
'from']) && isset($field_details[
'words'][
'to'])) {
2401 $search_type =
'date';
2402 }
else if (array_key_exists(
'lower', $field_details[
'words']) && array_key_exists(
'upper', $field_details[
'words'])) {
2404 $search_type =
'numeric';
2406 $search_type =
'word';
2409 $all_source_results = Array();
2410 $all_source_assetids = Array();
2412 foreach ($field_details[
'data_sources'] as $data_source) {
2413 if ($search_type ==
'numeric') {
2414 $data_source_results = $this->
_processNumericSearch($field_details[
'words'], $data_source, $base_query);
2415 }
else if ($search_type ==
'date') {
2416 $data_source_results = $this->
_processDateSearch($field_details[
'words'], $data_source, $base_query);
2418 $data_source_results = NULL;
2419 foreach ($field_details[
'words'] as $search_term) {
2422 $term_results = $this->
_processWordSearch($search_term, $data_source, $base_query, $word_logic);
2424 if (!is_null($term_results)) {
2425 if (!isset($all_source_results[$search_term])) {
2426 $all_source_results[$search_term] = Array();
2428 $all_source_results[$search_term] = $all_source_results[$search_term] + $term_results;
2431 $all_source_assetids = $all_source_assetids + $term_results;
2433 $term_totals[$search_term] = array_get_index($term_totals, $search_term, 0) + count($term_results);
2434 $data_source_results = $this->
_combineResults($data_source_results, $term_results, $word_logic);
2438 $field_results = $this->
_combineResults($field_results, $data_source_results, $data_source_logic);
2441 $cross_source_results = $all_source_assetids;
2442 foreach ($all_source_results as $term => $results) {
2443 $cross_source_results = array_intersect_assoc($cross_source_results, $results);
2446 if (is_null($field_results)) {
2447 $field_results = $cross_source_results;
2449 $field_results = $field_results + $cross_source_results;
2452 if(isset($field_details[
'specific_field_logic'])) {
2453 $final_search_type_results = $this->
_combineResults($final_search_type_results, $field_results, $field_details[
'specific_field_logic']);
2456 $final_search_type_results = $this->
_combineResults($final_search_type_results, $field_results, $field_logic);
2461 $search_results[$search_field_type] = $final_search_type_results;
2466 $final_results = array_get_index($search_results,
'search', NULL);
2471 if (!empty($search_results[
'exclude'])) {
2473 foreach (array_keys($search_results[
'exclude']) as $exclude_assetid) {
2474 if (isset($final_results[$exclude_assetid])) {
2475 unset($final_results[$exclude_assetid]);
2481 if (!empty($shadow_results)) {
2482 $final_results = $this->
_combineResults($final_results, $shadow_results, array_get_index($search_info,
'root_logic',
'OR'));
2485 if (is_null($final_results)) {
2488 $final_results = Array();
2494 if (!empty($search_info[
'requester'])) {
2495 $log_contents[
'terms'] = $term_totals;
2496 $log_contents[
'results'] = count($final_results);
2497 $log_contents[
'assetid'] = $search_info[
'requester'];
2498 log_write($log_contents,
'search');
2502 $GLOBALS[
'SQ_SYSTEM']->pm->stopTimer($this,
'processSearch');
2504 return $final_results;
2523 if (empty($field_details[
'data_sources'])) {
2524 $field_details[
'data_sources'] = Array();
2529 $is_datetime = TRUE;
2530 $is_numeric = FALSE;
2531 foreach ($field_details[
'data_sources'] as $i => $data_source) {
2532 switch ($data_source[
'type']) {
2534 case 'asset_attrib':
2535 $asset_type = array_get_index($data_source[
'params'],
'asset_type');
2536 $attrid = array_get_index($data_source[
'params'],
'attrid');
2537 if (empty($asset_type) || empty($attrid)) {
2538 unset($field_details[
'data_sources'][$i]);
2541 $attribute = $GLOBALS[
'SQ_SYSTEM']->am->getAttribute($attrid);
2542 if (is_null($attribute)) {
2543 unset($field_details[
'data_sources'][$i]);
2546 if (!($attribute instanceof Asset_Attribute_Datetime)) {
2547 $is_datetime = FALSE;
2552 if (!$is_datetime || $is_numeric) {
2558 if (empty($data_source[
'params'][
'assetid'])) {
2559 unset($field_details[
'data_sources'][$i]);
2562 $metadata_field = $GLOBALS[
'SQ_SYSTEM']->am->getAsset($data_source[
'params'][
'assetid']);
2563 if (is_null($metadata_field)) {
2564 unset($field_details[
'data_sources'][$i]);
2568 $is_datetime = FALSE;
2574 $asset_field = array_get_index($data_source[
'params'],
'field');
2575 if (empty($asset_field)) {
2576 unset($field_details[
'data_sources'][$i]);
2579 if (isset($this->standard_text_fields[$asset_field])) {
2580 $is_datetime = FALSE;
2582 }
else if (!isset($this->standard_date_fields[$asset_field])) {
2583 trigger_error(
'Invalid standard field "'.$asset_field.
'"', E_USER_WARNING);
2589 $is_datetime = FALSE;
2594 trigger_error(
'Unknown data source type '.$data_source[
'type'], E_USER_WARNING);
2601 $from = array_get_index($field_details[
'words'],
'from',
'---------- --:--:--');
2602 $to = array_get_index($field_details[
'words'],
'to',
'---------- --:--:--');
2603 if ($from !=
'---------- --:--:--') {
2604 $from = str_replace(
'--:--:--',
'00:00:00', $from);
2606 if ($to !=
'---------- --:--:--') {
2607 $to = str_replace(
'--:--:--',
'23:59:59', $to);
2609 $field_details[
'words'] = Array(
'from' => $from,
'to' => $to);
2610 }
else if ($is_numeric) {
2611 $lower = array_get_index($field_details[
'words'],
'lower', NULL);
2612 $upper = array_get_index($field_details[
'words'],
'upper', NULL);
2613 $field_details[
'words'] = Array(
'lower' => $lower,
'upper' => $upper);
2619 $mb_support = FALSE;
2620 if (function_exists(
'mb_strtolower')) {
2626 if (is_array($field_details[
'words'])) {
2628 foreach ($field_details[
'words'] as $selected_word) {
2630 $word_list .= $selected_word;
2634 $word_list .= (
DAL::getDbType() ===
'oci' && $field_details[
'word_logic'] ===
'OR' && count($field_details[
'words']) > $count ) ?
' OR ' :
' ';
2636 $word_list = trim($word_list);
2638 $word_list = $field_details[
'words'];
2643 $words[] = mb_strtolower($word, SQ_CONF_DEFAULT_CHARACTER_SET);
2646 $word = htmlentities($word, ENT_NOQUOTES, SQ_CONF_DEFAULT_CHARACTER_SET);
2647 $word = strtolower($word);
2648 $word = html_entity_decode($word, ENT_NOQUOTES, SQ_CONF_DEFAULT_CHARACTER_SET);
2654 if (
DAL::getDbType() ===
'oci' && $field_details[
'word_logic'] ===
'OR' ) {
2655 foreach ($words as $index => $word) {
2656 $words[$index] = str_replace(
' or ',
' OR ' , $word);
2659 $field_details[
'words'] = $words;
2679 $cache_key = $this->_tmp[
'cache_key'].$data_source[
'type'];
2680 switch ($data_source[
'type']) {
2681 case 'asset_attrib':
2682 $cache_key .= $data_source[
'params'][
'attrid'];
2686 $cache_key .= $data_source[
'params'][
'assetid'];
2690 $cache_key .= $data_source[
'params'][
'field'];
2693 $cache_key .= $search_term;
2695 $result = $this->_tmp[
'cm']->loadFromCache($this->
id, $this->
type(), $cache_key);
2696 if ($result === FALSE) {
2698 $result = $plugin->processWordSearch($this, $search_term, $data_source, $base_query, $word_logic);
2699 $r = $this->_tmp[
'cm']->saveToCache($this->
id, $this->
type(), $cache_key, serialize($result));
2701 $result = unserialize($result);
2720 $cache_key = $this->_tmp[
'cache_key'].$data_source[
'type'];
2721 switch ($data_source[
'type']) {
2722 case 'asset_attrib':
2723 $cache_key .= $data_source[
'params'][
'attrid'];
2727 $cache_key .= $data_source[
'params'][
'assetid'];
2731 $cache_key .= $data_source[
'params'][
'field'];
2734 $cache_key .=
'from'.$date_range[
'from'].
'to'.$date_range[
'to'];
2736 $result = $this->_tmp[
'cm']->loadFromCache($this->
id, $this->
type(), $cache_key);
2737 if ($result === FALSE) {
2739 $result = $plugin->processDateSearch($this, $date_range, $data_source, $base_query);
2740 $r = $this->_tmp[
'cm']->saveToCache($this->
id, $this->
type(), $cache_key, serialize($result));
2742 $result = unserialize($result);
2761 $cache_key = $this->_tmp[
'cache_key'].$data_source[
'type'];
2762 switch ($data_source[
'type']) {
2763 case 'asset_attrib':
2764 $cache_key .= $data_source[
'params'][
'attrid'];
2768 $cache_key .= $data_source[
'params'][
'assetid'];
2772 $cache_key .= $data_source[
'params'][
'field'];
2775 $cache_key .=
'l'.$numeric_range[
'lower'].
'u'.$numeric_range[
'upper'];
2777 $result = $this->_tmp[
'cm']->loadFromCache($this->
id, $this->
type(), $cache_key);
2778 if ($result === FALSE) {
2780 $result = $plugin->processNumericSearch($this, $numeric_range, $data_source, $base_query);
2781 $r = $this->_tmp[
'cm']->saveToCache($this->
id, $this->
type(), $cache_key, serialize($result));
2783 $result = unserialize($result);
2808 if (is_null($results_so_far)) {
2809 return $new_results;
2811 if ($logic ==
'OR') {
2812 $res_results = $results_so_far;
2814 $res_results = Array();
2816 if (isset($results_so_far[0])) {
2818 foreach ($new_results as $new_result) {
2821 foreach ($results_so_far as $i => $old_result) {
2822 if ($old_result[
'assetid'] == $new_result[
'assetid']) {
2824 if ($old_result[
'source'] == $new_result[
'source']) {
2825 if ($logic ==
'AND') {
2826 $old_result[
'search_score'] += $new_result[
'search_score'];
2827 $res_results[] = $old_result;
2829 $res_results[$i][
'search_score'] += $new_result[
'search_score'];
2833 }
else if ($logic ==
'AND') {
2836 $res_results[] = $old_result;
2840 if (!$added && ($found || ($logic ==
'OR'))) {
2843 $res_results[] = $new_result;
2847 foreach ($new_results as $assetid => $score) {
2848 if ($logic ==
'OR') {
2849 $res_results[$assetid] = $score + array_get_index($results_so_far, $assetid);
2850 }
else if (isset($results_so_far[$assetid])) {
2851 $res_results[$assetid] = $score + $results_so_far[$assetid];
2855 return $res_results;
2874 require_once SQ_INCLUDE_PATH.
'/general_occasional.inc';
2877 if (empty($query_comps))
return Array();
2878 $query_comps[
'select'][] =
'distinct ai.assetid';
2879 $query_comps[
'select'][] =
'1 as weight';
2881 $bind_vars = array_get_index($query_comps,
'bind_vars', Array());
2882 $search_sql = implode_sql($query_comps);
2883 $query = MatrixDAL::preparePDOQuery($search_sql);
2884 foreach ($bind_vars as $bind_var => $value) {
2888 $search_results = Array();
2892 }
catch (Exception $e) {
2893 throw new Exception(
'Unable to process basic search due to database error: '.$e->getMessage());
2896 if (isset($search_info[
'limit'])) {
2898 $search_results = array_slice($search_results, 0, $search_info[
'limit'], TRUE);
2902 $root_info = $GLOBALS[
'SQ_SYSTEM']->am->getAssetInfo($search_info[
'roots']);
2904 foreach ($root_info as $assetid => $root) {
2905 $shadow_results = Array();
2906 $GLOBALS[
'SQ_SYSTEM']->am->includeAsset($root[
'type_code']);
2909 if (implements_interface($root[
'type_code'],
'bridge') && is_callable(Array($root[
'type_code'],
'processBasicSearch'))) {
2910 $shadow_asset = $GLOBALS[
'SQ_SYSTEM']->am->getAsset($assetid);
2911 $shadow_results += $shadow_asset->processBasicSearch($search_info);
2912 $GLOBALS[
'SQ_SYSTEM']->am->forgetAsset($shadow_asset);
2916 if (!empty($shadow_results)) {
2917 $search_results += $shadow_results;
2920 return $search_results;
2945 $pspell_config = pspell_config_create($language);
2946 pspell_config_mode($pspell_config, PSPELL_FAST);
2947 $pspell_instance = pspell_new_config($pspell_config);
2949 if (!$pspell_instance)
return Array();
2951 $check_spelling = TRUE;
2954 if ($check_spelling) {
2955 $converted_word = (int)$word;
2956 if ((
string)$converted_word == $word) {
2957 $check_spelling = FALSE;
2962 if ($check_spelling) {
2963 $converted_word = strtoupper($word);
2964 if ($converted_word == $word) $check_spelling = FALSE;
2968 if (!$check_spelling || pspell_check($pspell_instance, $word)) {
2972 $suggestions = pspell_suggest($pspell_instance, $word);
2973 return $suggestions;
2991 return extension_loaded(
'pspell');
3032 'select' => Array(),
3033 'from' => Array(
'sq_sch_idx ai'),
3036 'where_joiner' =>
'AND',
3037 'order_by' => Array(),
3047 'select' => Array(
'a.assetid'),
3048 'from' => Array(
'sq_ast a'),
3051 'where_joiner' =>
'AND',
3052 'order_by' => Array(),
3059 $permission_check_query = Array(
3060 'select' => Array(
'p.assetid'),
3061 'from' => Array(
'sq_ast_perm p'),
3064 'where_joiner' =>
'AND',
3065 'order_by' => Array(),
3069 if (!empty($search_info[
'roots'])) {
3070 $root_logic = array_get_index($search_info,
'root_logic',
'OR');
3075 'minorids' => $search_info[
'roots'],
3078 }
catch (Exception $e) {
3079 throw new Exception(
'Unable to root tree id due to database error: '.$e->getMessage());
3082 if ($root_logic ==
'AND') {
3083 foreach (array_values($search_info[
'roots']) as $i => $rootid) {
3084 $subquery[
'join'][] =
'INNER JOIN sq_ast_lnk l'.$i.
' ON l'.$i.
'.minorid = a.assetid';
3085 $subquery[
'join'][] =
'INNER JOIN sq_ast_lnk_tree t'.$i.
' ON l'.$i.
'.linkid = t'.$i.
'.linkid';
3087 $treeid = $root_tree_ids[$rootid][0][
'treeid'];
3088 $subquery[
'where'][] =
't'.$i.
'.treeid LIKE '.
MatrixDAL::quote($treeid.
'%');
3091 $subquery[
'join'][] =
'INNER JOIN sq_ast_lnk l ON l.minorid = a.assetid';
3092 $subquery[
'join'][] =
'INNER JOIN sq_ast_lnk_tree t ON t.linkid = l.linkid';
3094 $treeid_wheres = Array();
3095 foreach ($root_tree_ids as $treeid) {
3096 $treeid_wheres[] =
'(t.treeid LIKE '.MatrixDAL::quote($treeid[0][
'treeid'].
'%').
')';
3098 if (!empty($treeid_wheres)) {
3099 if (count($treeid_wheres) > 1 ) {
3100 $subquery[
'where'][] =
'('.implode(
' OR ', $treeid_wheres).
')';
3102 $subquery[
'where'][] = implode(
' OR ', $treeid_wheres);
3109 $user_restrictions = (!$GLOBALS[
'SQ_SYSTEM']->userRoot() && !$GLOBALS[
'SQ_SYSTEM']->userSystemAdmin());
3110 if ($user_restrictions) {
3111 $no_roles = ((isset($search_info[
'no_roles_check']) && $search_info[
'no_roles_check'] == 1) || (SQ_CONF_ENABLE_ROLES_PERM_SYSTEM ==
'0')) ? TRUE : FALSE;
3112 $no_group_access_check = (isset($search_info[
'no_group_access_check']) && $search_info[
'no_group_access_check'] == 1) ? TRUE : FALSE;
3114 $permission_check_query[
'join'][] =
'LEFT JOIN sq_vw_ast_role r ON (p.userid = r.roleid AND r.assetid=p.assetid)';
3117 $public_user = $GLOBALS[
'SQ_SYSTEM']->am->getSystemAsset(
'public_user');
3118 $current_user =& $GLOBALS[
'SQ_SYSTEM']->user;
3119 if (isset($search_info[
'search_as_public_user'])) {
3120 $search_as_public_user = $search_info[
'search_as_public_user'];
3122 $search_as_public_user = 0;
3124 $public_user_access = (empty($current_user) || $search_as_public_user);
3125 if ($public_user_access) {
3126 if (!$no_group_access_check) {
3127 $userids = $public_user->getUserGroups();
3130 if (!$no_group_access_check) {
3131 $userids = $current_user->getUserGroups();
3133 $userids[] = $current_user->id;
3136 $userids[] = $public_user->id;
3138 $userids = array_unique($userids);
3140 $query[
'bind_vars'] = Array();
3141 $bind_vars = Array();
3142 for (reset($userids); NULL !== ($i = key($userids)); next($userids)) {
3143 $bind_vars[] =
':user'.$i;
3144 $query[
'bind_vars'][
'user'.$i] = $userids[$i];
3147 $usrids_str = implode(
',', $bind_vars);
3150 p.userid IN ('. $usrids_str .
')';
3152 $userid_check .=
' OR r.userid IN (' . $usrids_str .
')';
3154 $userid_check .=
') ';
3155 $permission_check_query[
'where'][] = $userid_check;
3159 $check_group_role =
'';
3160 if (!$public_user_access) {
3161 $check_group_role =
'(
3162 (p.permission = '.MatrixDAL::quote(SQ_PERMISSION_READ).
'
3166 if ($public_user_access) {
3167 $check_group_role .=
' OR ';
3169 $check_group_role .=
' AND ';
3171 $check_group_role .=
' (r.userid IS NULL OR r.userid <> '.MatrixDAL::quote($public_user->id).
')';
3173 $check_group_role .=
')
3174 OR (p.userid = '.MatrixDAL::quote($public_user->id).
' AND granted = \'1\')';
3176 $check_group_role .=
' OR (r.userid = '.MatrixDAL::quote($public_user->id).
' AND granted = \'1\')';
3179 $check_group_role .=
'
3183 (p.permission > '.MatrixDAL::quote(SQ_PERMISSION_READ).
' AND p.granted = \'1\')
3187 if (!empty($check_group_role)) {
3188 $permission_check_query[
'where'][] = $check_group_role;
3193 if (!empty($search_info[
'statuses'])) {
3194 $statuses = $search_info[
'statuses'];
3195 if (array_sum($statuses) != SQ_SC_STATUS_ALL) {
3196 foreach ($statuses as $i => $status) {
3199 $subquery[
'where'][] =
'a.status IN ('.implode(
', ', $statuses).
')';
3203 $subquery[
'where'][] =
'a.status >= '.MatrixDAL::quote(SQ_STATUS_LIVE);
3207 if (!empty($search_info[
'asset_types'])) {
3208 $inherited_types = Array();
3209 $normal_types = Array();
3210 for (reset($search_info[
'asset_types']); NULL !== ($i = key($search_info[
'asset_types'])); next($search_info[
'asset_types'])) {
3211 if ($search_info[
'asset_types'][$i] == 1) {
3218 $type_code_cond = Array();
3221 if (!empty($inherited_types)) {
3222 $type_code_cond[] =
'inhd_type_code IN ('.implode(
', ', $inherited_types).
')';
3223 if (!empty($normal_types)) {
3224 $type_code_cond[] =
'type_code IN ('.implode(
', ', $normal_types).
')';
3226 $type_code_cond = implode(
' OR ', $type_code_cond);
3227 $subquery[
'where'][] =
'a.type_code IN (
3229 FROM sq_ast_typ_inhd
3230 WHERE '.$type_code_cond.
'
3234 $subquery[
'where'][] =
'a.type_code IN ('.implode(
', ', $normal_types).
')';
3246 $subquery_string =
'SELECT ' . implode(
',', $subquery[
'select']) .
' FROM ' . implode(
',', $subquery[
'from']) .
' ' . implode(
' ', $subquery[
'join']);
3247 if (!empty($subquery[
'where'])) {
3248 $subquery_string .=
' WHERE ' . implode(
' ' . $subquery[
'where_joiner'] .
' ', $subquery[
'where']);
3258 if (!empty($permission_check_query[
'where'])) {
3265 $permission_check_query[
'where'][] =
'a.assetid=p.assetid';
3273 $permission_check_query_string =
'SELECT ' . implode(
',', $permission_check_query[
'select']) .
' FROM ' . implode(
',', $permission_check_query[
'from']) .
' ' . implode(
' ', $permission_check_query[
'join']);
3274 $permission_check_query_string .=
' WHERE ' . implode(
' ' . $permission_check_query[
'where_joiner'] .
' ', $permission_check_query[
'where']);
3275 $permission_check_query_string .=
' GROUP BY ' . implode(
',', $permission_check_query[
'select']);
3276 $permission_check_query_string .=
' HAVING MIN(p.granted) <> \'0\'';
3278 if (!empty($subquery[
'where'])) {
3279 $subquery_string .=
' AND ';
3281 $subquery_string .=
' WHERE ';
3283 $subquery_string .=
' a.assetid IN (';
3284 $subquery_string .= $permission_check_query_string;
3285 $subquery_string .=
')';
3293 if ($db_type ==
'oci') {
3294 $query[
'where'][] =
'ai.assetid IN (' . $subquery_string .
')';
3301 if ($db_type ==
'pgsql') {
3302 $subquery_string =
'(' . $subquery_string .
') asset_check';
3303 $query[
'from'][] = $subquery_string;
3304 $query[
'where'][] =
'ai.assetid=asset_check.assetid';
3327 $result_scores = NULL;
3328 if (!is_array($asset_scores1) && !is_array($asset_scores2)) {
3329 $result_scores = Array();
3330 }
else if (!is_array($asset_scores2)) {
3331 $result_scores = $asset_scores1;
3332 }
else if (!is_array($asset_scores1)) {
3333 $result_scores = $asset_scores2;
3336 if (!is_null($result_scores)) {
3337 if (is_array($result_scores) && !empty($result_scores) && !empty($word)) {
3338 foreach ($result_scores as $assetid => $data) {
3339 $this->_tmp[
'term_totals'][$assetid][$word] = $word;
3342 return $result_scores;
3346 $assets1 = array_keys($asset_scores1);
3347 $assets2 = array_keys($asset_scores2);
3349 $out_asset_scores = $asset_scores1;
3351 if ($logic ==
'AND') {
3352 $common_assets = array_intersect($assets1, $assets2);
3355 $removed_assets = array_diff($assets1, $assets2);
3356 foreach ($removed_assets as $assetid) {
3357 unset($out_asset_scores[$assetid]);
3358 if (isset($this->_tmp[
'term_totals'][$assetid])) {
3359 unset($this->_tmp[
'term_totals'][$assetid]);
3363 foreach ($common_assets as $assetid) {
3364 if (isset($out_asset_scores[$assetid])) {
3365 $out_asset_scores[$assetid][
'search_score'] = $out_asset_scores[$assetid][
'search_score'] + $asset_scores2[$assetid][
'search_score'];
3367 $out_asset_scores[$assetid] = $asset_scores2[$assetid];
3370 if (!empty($word)) {
3371 $this->_tmp[
'term_totals'][$assetid][$word] = $word;
3376 }
else if ($logic ==
'OR') {
3378 foreach ($asset_scores2 as $assetid => $data) {
3379 if (isset($out_asset_scores[$assetid])) {
3380 $out_asset_scores[$assetid][
'search_score'] += $asset_scores2[$assetid][
'search_score'];
3382 $out_asset_scores[$assetid] = $asset_scores2[$assetid];
3385 if (!empty($word)) {
3386 $this->_tmp[
'term_totals'][$assetid][$word] = $word;
3391 return $out_asset_scores;
3404 return $this->
attr(
'noise_word_list');
3417 return $this->
attr(
'white_word_list');
3432 $words = $this->
attr(
'noise_word_list');
3433 foreach ($words as $key => $value) {
3434 if (strcasecmp($key, $word) == 0)
return TRUE;
3451 $words = $this->
attr(
'white_word_list');
3452 foreach ($words as $key => $value) {
3453 if (strcasecmp($key, $word) == 0)
return TRUE;
3468 return $this->
attr(
'min_word_length');
3484 if (is_null($this->_db_plugin)) {
3487 $dir = dirname(__FILE__).
'/plugins/'.strtolower($db_type);
3488 $class_name =
'search_manager_plugin_'.$db_type;
3489 require_once $dir.
'/'.$class_name.
'.inc';
3490 $this->_db_plugin =
new $class_name();
3493 return $this->_db_plugin;
3508 $searched_results = Array();
3511 foreach ($results as $result) {
3512 if (empty($searched_results[$result[
'assetid']])) {
3513 $searched_results[$result[
'assetid']][
'score'] = 0;
3515 $searched_results[$result[
'assetid']][
'sources'][] = $result[
'source'];
3516 $searched_results[$result[
'assetid']][
'score'] += $result[
'search_score'];
3519 uasort($searched_results, create_function(
'$a,$b',
'return $b["score"] - $a["score"];'));
3521 return $searched_results;
3543 $search_string = preg_replace(
'/([\.\\\!\+\*\?\[\]\^\$\(\)\=\!<>\|\:]+)/i',
'\\\${1}',$search_string);
3544 $search_string = trim(preg_replace(
'/[\~\&\|\/]/i',
' ', $search_string));
3546 $mm = $GLOBALS[
'SQ_SYSTEM']->getMetadataManager();
3549 $formatted_results = Array();
3551 $words = $plugin->getWords($search_string);
3555 foreach ($results as $assetid => $content) {
3556 $content = $content[
'sources'];
3557 $asset = $GLOBALS[
'SQ_SYSTEM']->am->getAsset($assetid);
3559 foreach ($content as $content_type) {
3563 case preg_match(
'/contents/', $content_type) > 0:
3565 if(!$full_content) {
3566 $formatted_results[$assetid][
'contents'][0]=
'...'.$search_string.
'...';
3569 $asset_contents = $GLOBALS[
'SQ_SYSTEM']->am->getEditableContents($assetid);
3572 if (!$asset_contents) {
3573 $asset_contents = Array(
3574 $assetid => $asset->getContent(),
3578 foreach ($asset_contents as $contents_id => $contents_value) {
3580 foreach ($words as $word) {
3581 if (preg_match(
'/'.htmlentities($word).
'/i', $contents_value) || preg_match(
'/'.($word).
'/i', $contents_value)) {
3582 $formatted_results[$assetid][
'contents'][$contents_id] = $contents_value;
3591 case preg_match(
'/__(.+)__/', $content_type, $matches) > 0:
3592 case preg_match(
'/attr:(.+)$/', $content_type, $matches) > 0:
3593 if (isset($asset->vars[$matches[1]])) {
3594 $attribute = $asset->attr($matches[1]);
3596 foreach ($words as $word) {
3597 if (preg_match(
"/$word/i", $attribute)) {
3598 $formatted_results[$assetid][
'attributes'][$matches[1]] = $attribute;
3606 case preg_match(
'/metadata/', $content_type) > 0:
3608 if (isset($formatted_results[$assetid][
'metadata'])) {
3612 $metadata = $mm->getMetadata($assetid);
3614 foreach ($metadata as $fieldid => $data) {
3615 foreach ($words as $word) {
3616 if (preg_match(
"/$word/i", $data[0][
'value'])) {
3617 $formatted_results[$assetid][
'metadata'][$fieldid] = $data;
3624 if (!isset($formatted_results[$assetid][
'metadata'])) {
3625 $schemas = $mm->getSchemas($assetid, TRUE);
3627 foreach ($schemas as $schemaid) {
3628 $schema = $GLOBALS[
'SQ_SYSTEM']->am->getAsset($schemaid);
3629 $schema_data = $mm->getSchemaDefaultValues($schema->id);
3630 foreach ($schema_data as $fieldid => $data) {
3631 foreach ($words as $word) {
3632 if (preg_match(
"/$word/i", $data[
'value'])) {
3633 $formatted_results[$schema->id][
'schema'][$fieldid] = $data;
3639 $GLOBALS[
'SQ_SYSTEM']->am->forgetAsset($schema);
3650 $GLOBALS[
'SQ_SYSTEM']->am->forgetAsset($asset);
3654 return $formatted_results;