/** * Searches media * * @author Ben Dodson * @version 12/26/04 * @since 9/21/04 */ function search($searchArray2, $type = 'both', $depth = -1, $limit = 0, $op = "and", $metasearch = array(), $exclude = array()) { global $sql_type, $sql_pw, $sql_usr, $sql_socket, $sql_db, $backend; // alias: if ($type == "tracks") { $type = "leaves"; } if ($depth === false) { $depth = $this->getNaturalDepth(); } // allow strings as well as arrays for searching: if (is_string($searchArray2) && $op != "exact") { if (stristr($searchArray2, "\"") === false) { if ($searchArray2 == "") { $searchArray = array(); } else { $searchArray = explode(" ", $searchArray2); } } else { // gets nasty.. $open_quote = false; $searchArray = array(); $word = ""; for ($i = 0; $i < strlen($searchArray2); $i++) { if ($searchArray2[$i] == ' ' && $open_quote == false) { $searchArray[] = $word; $word = ""; } else { if ($searchArray2[$i] == '"') { $open_quote = !$open_quote; } else { $word .= $searchArray2[$i]; } } } if ($word != "") { $searchArray[] = jz_db_escape($word); } } } else { $searchArray = $searchArray2; } // exclude array, too: if (is_string($exclude)) { if ($exclude == "") { $excludeArray = array(); } else { if (stristr($exclude, "\"") === false) { if ($exclude == "") { $excludeArray = array(); } else { $excludeArray = explode(" ", $exclude); } } else { // gets nasty.. $open_quote = false; $excludeArray = array(); $word = ""; for ($i = 0; $i < strlen($exclude); $i++) { if ($exclude[$i] == ' ' && $open_quote == false) { $excludeArray[] = $word; $word = ""; } else { if ($exclude[$i] == '"') { $open_quote = !$open_quote; } else { $word .= jz_db_escape($exclude[$i]); } } } if ($word != "") { $excludeArray[] = $word; } } } } else { $excludeArray = $exclude; } // Now that we have search array, let's jz_db_escape here so we don't have to later. for ($i = 0; $i < sizeof($searchArray); $i++) { $searchArray[$i] = jz_db_escape($searchArray[$i]); } // Clean up: $tmp = array(); if (is_array($searchArray)) { foreach ($searchArray as $term) { if (!($term == "" || $term == " ")) { $tmp[] = $term; } } $searchArray = $tmp; } $tmp = array(); foreach ($excludeArray as $term) { if (!($term == "" || $term == " ")) { $tmp[] = $term; } } $excludeArray = $tmp; // INSENSITIVE OPERATION: $INSOP = jz_db_case_insensitive(); // SEARCH: $constraints = array(); // LYRICS: a different kind of search. if ($type == "lyrics") { if ($this->getLevel() > 0) { $constraints[] = "path LIKE '" . jz_db_escape($this->getPath("String")) . "/%'"; } // Level if ($depth < 0) { $lvl = $this->getLevel(); $constraints[] = "level > {$lvl}"; } else { $lvl = $this->getLevel() + $depth; $constraints[] = "level = {$lvl}"; } if ($op == "exact") { $constraints[] = "lyrics {$INSOP} '%{$searchArray2}'%"; } else { if ($op == "or") { $OPR = "OR"; } else { // and $OPR = "AND"; } $string = ""; if (sizeof($searchArray) > 0) { $string .= "lyrics {$INSOP} '%{$searchArray['0']}%'"; } for ($i = 1; $i < sizeof($searchArray); $i++) { $string .= "{$OPR} lyrics {$INSOP} '%{$searchArray[$i]}%'"; } $constraints[] = $string; } // TERMS TO EXCLUDE if ($excludeArray != array()) { $string = "(lyrics NOT {$INSOP}"; $string .= " '%{$excludeArray['0']}%'"; for ($i = 1; $i < sizeof($excludeArray); $i++) { $string .= " AND lyrics NOT {$INSOP} '%{$excludeArray[$i]}%'"; } $string .= ")"; $constraints[] = $string; } if ($constraints == array()) { die("Error: no constraints in search."); } $sql = "SELECT path FROM jz_tracks WHERE"; $sql .= " ({$constraints['0']})"; for ($i = 1; $i < sizeof($constraints); $i++) { $sql .= " AND ({$constraints[$i]})"; } if ($limit > 0) { $sql .= " LIMIT {$limit}"; } if (!($link = jz_db_connect())) { die("could not connect to database."); } $results = jz_db_query($link, $sql); jz_db_close($link); $return = array(); if ($results === false) { return $return; } foreach ($results->data as $row) { $return[] =& new jzMediaTrack(jz_db_unescape($row['path'])); } return $return; } // MEDIA SEARCH (not lyrics) if ($this->getLevel() > 0) { $constraints[] = "path LIKE '" . jz_db_escape($this->getPath("String")) . "/%'"; } // Type if ($type == "leaves") { $constraints[] = "leaf = 'true'"; } else { if ($type == "nodes") { $constraints[] = "leaf = 'false'"; } } // Level if ($depth < 0) { $lvl = $this->getLevel(); $constraints[] = "level > {$lvl}"; } else { $lvl = $this->getLevel() + $depth; $constraints[] = "level = {$lvl}"; } // ID search: if ($type == "id") { if (sizeof($searchArray) > 1) { // for now. Maybe search on all terms? return array(); } $mid = jz_db_escape($searchArray[0]); $string = "my_id = '{$mid}'"; $constraints[] = $string; } else { // String search: if ($op == "exact") { $searchArray2 = str_replace("\"", "", $searchArray2); $constraints[] = "name {$INSOP} '{$searchArray2}'"; } else { if ($op == "or") { // "or" if (sizeof($searchArray) > 0) { $string = "name {$INSOP}"; $string .= " '%{$searchArray['0']}%'"; for ($i = 1; $i < sizeof($searchArray); $i++) { $string .= " OR name {$INSOP} '%{$searchArray[$i]}%'"; } } $constraints[] = $string; } else { // "and" // first match at least part in our name: if (sizeof($searchArray) > 0) { $string = "((name {$INSOP}"; // if at a specific level, don't worry about full path: if ($lvl > 0) { $string .= " '%{$searchArray['0']}%')"; // Otherwise, let's try to avoid repeat results: } else { $string .= " '%{$searchArray['0']}%' AND path NOT {$INSOP} '%{$searchArray['0']}%/%')"; } for ($i = 1; $i < sizeof($searchArray); $i++) { $string .= " OR (name {$INSOP} '%{$searchArray[$i]}%' AND path NOT {$INSOP} '%{$searchArray[$i]}%/%')"; } $string .= ")"; // Now require the rest to be in the path. $string .= " AND (path {$INSOP}"; $string .= " '%{$searchArray['0']}%'"; for ($i = 1; $i < sizeof($searchArray); $i++) { $string .= " AND path {$INSOP} '%{$searchArray[$i]}%'"; } $string .= ")"; $constraints[] = $string; } } } // Stuff to exclude: if ($excludeArray != array()) { $string = "(path NOT {$INSOP}"; $string .= " '%{$excludeArray['0']}%'"; for ($i = 1; $i < sizeof($excludeArray); $i++) { $string .= " AND path NOT {$INSOP} '%{$excludeArray[$i]}%'"; } $string .= ")"; $constraints[] = $string; } } // Put it all together. if ($constraints == array()) { die("Error: no constraints in search."); } $sql = "SELECT path,leaf FROM jz_nodes WHERE"; $sql .= " ({$constraints['0']})"; for ($i = 1; $i < sizeof($constraints); $i++) { $sql .= " AND ({$constraints[$i]})"; } if ($limit > 0) { $sql .= " LIMIT {$limit}"; } if (!($link = jz_db_connect())) { die("could not connect to database."); } $results = jz_db_query($link, $sql); jz_db_close($link); $return = array(); $hash = array(); if ($results === false) { return $return; } for ($i = 0; $i < $results->rows; $i++) { if ($results->data[$i]['leaf'] == "true") { $me =& new jzMediaTrack(jz_db_unescape($results->data[$i]['path'])); } else { $me =& new jzMediaNode(jz_db_unescape($results->data[$i]['path'])); } if ($default_importer == "id3tags") { if (!isset($hash[pathize(strtolower($me->getName()))])) { $return[] = $me; $hash[pathize(strtolower($me->getName()))] = true; } } else { $return[] = $me; } } if ($type == "leaves" && $metasearch != array()) { $return = filterSearchResults($return, $metasearch); } return $return; }
/** * Searches a specified level for elements. * The level is -1 for any level. * These parameters may change before the coding gets done. * The 'op' is one of: and|or|exact * If it is 'exact', the search term should be a string. * * @author Ben Dodson * @version 9/21/04 * @since 9/20/04 */ function search($searchArray2, $type = 'both', $depth = -1, $limit = 0, $op = "and", $metasearch = array(), $exclude = array()) { // for now, no search by id: if ($type == "id") { return array(); } // alias: if ($type == "tracks") { $type = "leaves"; } if ($depth === false) { $depth = $this->getNaturalDepth(); } // allow strings as well as arrays for searching: if (is_string($searchArray2) && $op != "exact") { if (stristr($searchArray2, "\"") === false) { if ($searchArray2 == "") { $searchArray = array(); } else { $searchArray = explode(" ", $searchArray2); } } else { // gets nasty.. $open_quote = false; $searchArray = array(); $word = ""; for ($i = 0; $i < strlen($searchArray2); $i++) { if ($searchArray2[$i] == ' ' && $open_quote == false) { $searchArray[] = $word; $word = ""; } else { if ($searchArray2[$i] == '"') { $open_quote = !$open_quote; } else { $word .= $searchArray2[$i]; } } } if ($word != "") { $searchArray[] = $word; } } } else { $searchArray = $searchArray2; } // Exclude array, too: if (is_string($exclude)) { if ($exclude == "") { $excludeArray = array(); } else { if (stristr($exclude, "\"") === false) { if ($exclude == "") { $excludeArray = array(); } else { $excludeArray = explode(" ", $exclude); } } else { // gets nasty.. $open_quote = false; $excludeArray = array(); $word = ""; for ($i = 0; $i < strlen($exclude); $i++) { if ($exclude[$i] == ' ' && $open_quote == false) { $excludeArray[] = $word; $word = ""; } else { if ($exclude[$i] == '"') { $open_quote = !$open_quote; } else { $word .= $exclude[$i]; } } } if ($word != "") { $excludeArray[] = $word; } } } } else { $excludeArray = $exclude; } // Clean up: $tmp = array(); if (is_array($searchArray)) { foreach ($searchArray as $term) { if (!($term == "" || $term == " ")) { $tmp[] = $term; } } $searchArray = $tmp; } $tmp = array(); foreach ($excludeArray as $term) { if (!($term == "" || $term == " ")) { $tmp[] = $term; } } $excludeArray = $tmp; // LYRICS SEARCHING: different kind of search. if ($type == "lyrics") { $matches = array(); $kids = $this->getSubNodes("tracks", $depth, "leave", 0); foreach ($kids as $kid) { $meta = $kid->getMeta(); $path = $kid->getPath("String"); if ($op == "exact") { if (stristr($meta['lyrics'], $searchArray2) !== false) { $matches[] = $kid; } } else { if ($op == "or") { $valid = true; if ($excludeArray != array()) { foreach ($excludeArray as $word) { if (stristr($meta['lyrics'], $word) !== false) { $valid = false; } } } if ($valid) { if (sizeof($searchArray) == 0) { $matches[] = $kid; if ($limit > 0 && sizeof($matches) >= $limit) { return $matches; } } else { foreach ($searchArray as $word) { if (stristr($meta['lyrics'], $word) !== false) { $matches[] = $kid; if ($limit > 0 && sizeof($matches) >= $limit) { return $matches; } } } } } } else { // $op == "and" $possible_match = false; $all_words = true; $valid = true; if ($excludeArray != array()) { foreach ($excludeArray as $word) { if (stristr($meta['lyrics'], $word) !== false) { $valid = false; } } } if ($valid) { if (sizeof($searchArray) == 0) { $matches[] = $kid; if ($limit > 0 && sizeof($matches) >= $limit) { return $matches; } } else { foreach ($searchArray as $word) { if (stristr($meta['lyrics'], $word) !== false) { $possible_match = true; } else { if (stristr($path, $word) === false) { $all_words = false; } } } } if ($possible_match && $all_words) { $matches[] = $kid; if ($limit > 0 && sizeof($matches) >= $limit) { return $matches; } } } } } } return $matches; } $kids = $this->getSubNodes($type, $depth, "leave", 0); // don't sort our nodes, because it takes time. // but don't randomize either. $matches = array(); foreach ($kids as $kid) { $path = $kid->getPath("String"); $pathArray = $kid->getPath(); // NOTE: The 'name' of the child is taken from the filename, // NOT from the ID3 or any other metadata method. // This is currently (9/21/04) DIFFERENT than what $this->getName() returns // ..and it is MUCH faster!! $name = $pathArray[sizeof($pathArray) - 1]; // op == 'exact' if ($op == "exact") { if ($name == $searchArray2) { $matches[] = $kid; if ($limit > 0 && sizeof($matches) >= $limit) { return $matches; } } // op == 'or' } else { if ($op == "or") { $valid = true; if ($excludeArray != array()) { foreach ($excludeArray as $word) { if (stristr($name, $word) !== false) { $valid = false; } } } if ($valid) { if (sizeof($searchArray) == 0) { $matches[] = $kid; if ($limit > 0 && sizeof($matches) >= $limit) { return $matches; } } else { foreach ($searchArray as $word) { if (stristr($name, $word) !== false) { $matches[] = $kid; if ($limit > 0 && sizeof($matches) >= $limit) { return $matches; } } } } } } else { // "and" $possible_match = false; $all_words = true; $valid = true; if ($excludeArray != array()) { foreach ($excludeArray as $word) { if (stristr($name, $word) !== false) { $valid = false; } } } if ($valid) { if (sizeof($searchArray) == 0) { $matches[] = $kid; if ($limit > 0 && sizeof($matches) >= $limit) { return $matches; } } else { foreach ($searchArray as $word) { if (stristr($name, $word) !== false) { $possible_match = true; } else { if (stristr($path, $word) === false) { $all_words = false; } } } } if ($possible_match && $all_words) { $matches[] = $kid; if ($limit > 0 && sizeof($matches) >= $limit) { return $matches; } } } } } } if ($metasearch != array() && $type == "leaves") { $matches = filterSearchResults($matches, $metasearch); } return $matches; }