aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engine/lib/metadata.php40
-rw-r--r--engine/lib/metastrings.php73
-rw-r--r--engine/tests/objects/metadata.php92
3 files changed, 170 insertions, 35 deletions
diff --git a/engine/lib/metadata.php b/engine/lib/metadata.php
index 5ca39b586..dc8107583 100644
--- a/engine/lib/metadata.php
+++ b/engine/lib/metadata.php
@@ -544,17 +544,24 @@ function find_metadata($meta_name = "", $meta_value = "", $entity_type = "", $en
* @param string $order_by Optional ordering.
* @param int $site_guid The site to get entities for. Leave as 0 (default) for the current site; -1 for all sites.
* @param true|false $count If set to true, returns the total number of entities rather than a list. (Default: false)
+ * @param true|false $case_sensitive If set to false this searches for the meta data without case sensitivity. (Default: true)
*
* @return int|array A list of entities, or a count if $count is set to true
*/
-function get_entities_from_metadata($meta_name, $meta_value = "", $entity_type = "", $entity_subtype = "", $owner_guid = 0, $limit = 10, $offset = 0, $order_by = "", $site_guid = 0, $count = false) {
+function get_entities_from_metadata($meta_name, $meta_value = "", $entity_type = "", $entity_subtype = "", $owner_guid = 0, $limit = 10, $offset = 0, $order_by = "", $site_guid = 0, $count = FALSE, $case_sensitive = TRUE) {
global $CONFIG;
$meta_n = get_metastring_id($meta_name);
- $meta_v = get_metastring_id($meta_value);
+ $meta_v = get_metastring_id($meta_value, $case_sensitive);
$entity_type = sanitise_string($entity_type);
- $entity_subtype = get_subtype_id($entity_type, $entity_subtype);
+ $entity_subtype_id = get_subtype_id($entity_type, $entity_subtype);
+ if ($entity_subtype != "" && $entity_subtype_id == FALSE) {
+ return false;
+ } else {
+ $entity_subtype = $entity_subtype_id;
+ }
+
$limit = (int)$limit;
$offset = (int)$offset;
if ($order_by == "") {
@@ -590,7 +597,16 @@ function get_entities_from_metadata($meta_name, $meta_value = "", $entity_type =
$where[] = "m.name_id='$meta_n'";
}
if ($meta_value!=="") {
- $where[] = "m.value_id='$meta_v'";
+ if (is_array($meta_v)) {
+ $meta_v_string = "";
+ foreach ($meta_v as $v) {
+ $meta_v_string .= "'$v',";
+ }
+ $meta_v_string = rtrim($meta_v_string, ",");
+ $where[] = "m.value_id in ($meta_v_string)";
+ } else {
+ $where[] = "m.value_id='$meta_v'";
+ }
}
if ($site_guid > 0) {
$where[] = "e.site_guid = {$site_guid}";
@@ -641,11 +657,11 @@ function get_entities_from_metadata($meta_name, $meta_value = "", $entity_type =
*
* @return string A list of entities suitable for display
*/
-function list_entities_from_metadata($meta_name, $meta_value = "", $entity_type = "", $entity_subtype = "", $owner_guid = 0, $limit = 10, $fullview = true, $viewtypetoggle = true, $pagination = true) {
+function list_entities_from_metadata($meta_name, $meta_value = "", $entity_type = "", $entity_subtype = "", $owner_guid = 0, $limit = 10, $fullview = true, $viewtypetoggle = true, $pagination = true, $case_sensitive = true ) {
$offset = (int) get_input('offset');
$limit = (int) $limit;
- $count = get_entities_from_metadata($meta_name, $meta_value, $entity_type, $entity_subtype, $owner_guid, $limit, $offset, "", 0, true);
- $entities = get_entities_from_metadata($meta_name, $meta_value, $entity_type, $entity_subtype, $owner_guid, $limit, $offset, "", 0, false);
+ $count = get_entities_from_metadata($meta_name, $meta_value, $entity_type, $entity_subtype, $owner_guid, $limit, $offset, "", 0, true, $case_sensitive );
+ $entities = get_entities_from_metadata($meta_name, $meta_value, $entity_type, $entity_subtype, $owner_guid, $limit, $offset, "", 0, false, $case_sensitive );
return elgg_view_entity_list($entities, $count, $offset, $limit, $fullview, $viewtypetoggle, $pagination);
}
@@ -972,4 +988,12 @@ function register_metadata_url_handler($function_name, $extender_name = "all") {
/** Register the hook */
register_plugin_hook("export", "all", "export_metadata_plugin_hook", 2);
/** Call a function whenever an entity is updated **/
-register_elgg_event_handler('update','all','metadata_update'); \ No newline at end of file
+register_elgg_event_handler('update','all','metadata_update');
+
+// unit testing
+register_plugin_hook('unit_test', 'system', 'metadata_test');
+function metadata_test($hook, $type, $value, $params) {
+ global $CONFIG;
+ $value[] = $CONFIG->path . 'engine/tests/objects/metadata.php';
+ return $value;
+} \ No newline at end of file
diff --git a/engine/lib/metastrings.php b/engine/lib/metastrings.php
index 3e8796d3f..a2f95b9f8 100644
--- a/engine/lib/metastrings.php
+++ b/engine/lib/metastrings.php
@@ -19,44 +19,63 @@ $METASTRINGS_DEADNAME_CACHE = array();
* Return the meta string id for a given tag, or false.
*
* @param string $string The value (whatever that is) to be stored
- * @param bool $case_sensitive Do we want to make the query case sensitive?
- * @return mixed Integer tag or false.
+ * @param bool $case_sensitive Do we want to make the query case sensitive? If not there may be more than one result
+ * @return int|array|false meta string id, array of ids or false if none found
*/
-function get_metastring_id($string, $case_sensitive = true) {
+function get_metastring_id($string, $case_sensitive = TRUE) {
global $CONFIG, $METASTRINGS_CACHE, $METASTRINGS_DEADNAME_CACHE;
$string = sanitise_string($string);
- $result = array_search($string, $METASTRINGS_CACHE);
- if ($result!==false) {
- elgg_log("** Returning id for string:$string from cache.");
- return $result;
- }
-
- // See if we have previously looked for this and found nothing
- if (in_array($string, $METASTRINGS_DEADNAME_CACHE)) {
- return false;
- }
+
+ // caching doesn't work for case insensitive searches
+ if ($case_sensitive) {
+ $result = array_search($string, $METASTRINGS_CACHE);
+
+ if ($result!==false) {
+ elgg_log("** Returning id for string:$string from cache.");
+ return $result;
+ }
- // Experimental memcache
- $msfc = null;
- static $metastrings_memcache;
- if ((!$metastrings_memcache) && (is_memcache_available())) {
- $metastrings_memcache = new ElggMemcache('metastrings_memcache');
- }
- if ($metastrings_memcache) {
- $msfc = $metastrings_memcache->load($string);
- }
- if ($msfc) {
- return $msfc;
+ // See if we have previously looked for this and found nothing
+ if (in_array($string, $METASTRINGS_DEADNAME_CACHE)) {
+ return false;
+ }
+
+ // Experimental memcache
+ $msfc = null;
+ static $metastrings_memcache;
+ if ((!$metastrings_memcache) && (is_memcache_available())) {
+ $metastrings_memcache = new ElggMemcache('metastrings_memcache');
+ }
+ if ($metastrings_memcache) {
+ $msfc = $metastrings_memcache->load($string);
+ }
+ if ($msfc) {
+ return $msfc;
+ }
}
// Case sensitive
- $cs = "";
if ($case_sensitive) {
- $cs = " BINARY ";
+ $query = "SELECT * from {$CONFIG->dbprefix}metastrings where string= BINARY '$string' limit 1";
+ } else {
+ $query = "SELECT * from {$CONFIG->dbprefix}metastrings where strcmp(string,'$string')=0";
}
- $row = get_data_row("SELECT * from {$CONFIG->dbprefix}metastrings where string=$cs'$string' limit 1");
+ $row = FALSE;
+ $metaStrings = get_data($query, "entity_row_to_elggstar");
+ if (is_array($metaStrings)) {
+ if (sizeof($metaStrings) > 1) {
+ $ids = array();
+ foreach($metaStrings as $metaString) {
+ $ids[] = $metaString->id;
+ }
+ return $ids;
+ } else {
+ $row = $metaStrings[0];
+ }
+ }
+
if ($row) {
$METASTRINGS_CACHE[$row->id] = $row->string; // Cache it
diff --git a/engine/tests/objects/metadata.php b/engine/tests/objects/metadata.php
new file mode 100644
index 000000000..eb635db4a
--- /dev/null
+++ b/engine/tests/objects/metadata.php
@@ -0,0 +1,92 @@
+<?php
+/**
+ * Elgg Test ElggMetadata
+ *
+ * @package Elgg
+ * @subpackage Test
+ * @author Curverider Ltd
+ * @link http://elgg.org/
+ */
+class ElggCoreMetadataTest extends ElggCoreUnitTest {
+ protected $metastrings;
+
+ /**
+ * Called before each test method.
+ */
+ public function setUp() {
+ $this->metastrings = array();
+ $this->object = new ElggObject();
+ }
+
+ /**
+ * Called after each test method.
+ */
+ public function tearDown() {
+ // do not allow SimpleTest to interpret Elgg notices as exceptions
+ $this->swallowErrors();
+
+ unset($this->object);
+ }
+
+ public function testGetMetastringById() {
+ foreach (array('metaUnitTest', 'metaunittest', 'METAUNITTEST') as $string) {
+ $this->create_metastring($string);
+ }
+
+ // lookup metastring id
+ $cs_ids = get_metastring_id('metaUnitTest', TRUE);
+ $this->assertEqual($cs_ids, $this->metastrings['metaUnitTest']);
+
+ // lookup all metastrings, ignoring case
+ $cs_ids = get_metastring_id('metaUnitTest', FALSE);
+ $this->assertEqual(count($cs_ids), 3);
+ $this->assertEqual(count($cs_ids), count($this->metastrings));
+ foreach ($cs_ids as $string )
+ {
+ $this->assertTrue(in_array($string, $this->metastrings));
+ }
+
+ // clean up
+ $this->delete_metastrings();
+ }
+
+ public function testGetEntitiesFromMetadata() {
+ $this->object->title = 'Meta Unit Test';
+ $this->object->save();
+ $this->create_metastring('metaUnitTest');
+ $this->create_metastring('tested');
+ $this->assertTrue(create_metadata($this->object->guid, 'metaUnitTest', 'tested'));
+
+ // check value with improper case
+ $this->assertFalse(get_entities_from_metadata('metaUnitTest', 'Tested', '', '', 0, 10, 0, '', 0, FALSE, TRUE));
+
+ // compare forced case with ignored case
+ $case_true = get_entities_from_metadata('metaUnitTest', 'tested', '', '', 0, 10, 0, '', 0, FALSE, TRUE);
+ $case_false = get_entities_from_metadata('metaUnitTest', 'Tested', '', '', 0, 10, 0, '', 0, FALSE, FALSE);
+ $this->assertIsA($case_true, 'array');
+ $this->assertIsA($case_false, 'array');
+ $this->assertIdentical($case_true, $case_false);
+
+ // check entity list
+ //$this->dump(list_entities_from_metadata('metaUnitTest', 'Tested', '', '', 0, 10, TRUE, TRUE, TRUE, FALSE));
+
+ // clean up
+ $this->delete_metastrings();
+ $this->object->delete();
+ }
+
+
+ protected function create_metastring($string) {
+ global $CONFIG;
+
+ mysql_query("INSERT INTO {$CONFIG->dbprefix}metastrings (string) VALUES ('$string')");
+ $this->metastrings[$string] = mysql_insert_id();
+ }
+
+ protected function delete_metastrings() {
+ global $CONFIG;
+
+ $strings = implode(', ', $this->metastrings);
+ mysql_query("DELETE FROM {$CONFIG->dbprefix}metastrings WHERE id IN ($strings)");
+ }
+}